diff --git a/pyproject.toml b/pyproject.toml index fa819adb..984758ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -106,7 +106,6 @@ quote-style = "single" "*test_*.py" = ["S101"] [tool.ruff.lint] -ignore-init-module-imports = true select = [ # flake8 settings from existing CI setup "E9", "F63", "F7", "F82", diff --git a/src/easyreflectometry/calculators/calculator_base.py b/src/easyreflectometry/calculators/calculator_base.py index 6a620fc5..1be7b568 100644 --- a/src/easyreflectometry/calculators/calculator_base.py +++ b/src/easyreflectometry/calculators/calculator_base.py @@ -7,6 +7,7 @@ from easyscience.fitting.calculators.interface_factory import ItemContainer from easyscience.io import SerializerComponent +#if TYPE_CHECKING: from easyreflectometry.model import Model from easyreflectometry.sample import BaseAssembly from easyreflectometry.sample import Layer diff --git a/src/easyreflectometry/data/data_store.py b/src/easyreflectometry/data/data_store.py index f176c014..8dde0bf7 100644 --- a/src/easyreflectometry/data/data_store.py +++ b/src/easyreflectometry/data/data_store.py @@ -9,7 +9,6 @@ from easyscience.io import SerializerComponent from easyscience.io import SerializerDict -# from easyscience.utils.io.dict import DictSerializer from easyreflectometry.model import Model T = TypeVar('T') @@ -77,7 +76,7 @@ def __init__( y: Optional[Union[np.ndarray, list]] = None, ye: Optional[Union[np.ndarray, list]] = None, xe: Optional[Union[np.ndarray, list]] = None, - model: Optional[Model] = None, + model: Optional['Model'] = None, # delay type checking until runtime (quotes) x_label: str = 'x', y_label: str = 'y', ): @@ -118,11 +117,11 @@ def __init__( self._color = None @property - def model(self) -> Model: + def model(self) -> 'Model': # delay type checking until runtime (quotes) return self._model @model.setter - def model(self, new_model: Model) -> None: + def model(self, new_model: 'Model') -> None: self._model = new_model self._model.background = np.min(self.y) diff --git a/src/easyreflectometry/data/measurement.py b/src/easyreflectometry/data/measurement.py index 1ba4addc..b24f32a8 100644 --- a/src/easyreflectometry/data/measurement.py +++ b/src/easyreflectometry/data/measurement.py @@ -6,10 +6,9 @@ import numpy as np import scipp as sc -from orsopy.fileio import Header -from orsopy.fileio import orso from easyreflectometry.data import DataSet1D +from easyreflectometry.orso_utils import load_data_from_orso_file def load(fname: Union[TextIO, str]) -> sc.DataGroup: @@ -18,7 +17,7 @@ def load(fname: Union[TextIO, str]) -> sc.DataGroup: :param fname: The file to be read. """ try: - return _load_orso(fname) + return load_data_from_orso_file(fname) except (IndexError, ValueError): return _load_txt(fname) @@ -39,42 +38,6 @@ def load_as_dataset(fname: Union[TextIO, str]) -> DataSet1D: ) -def _load_orso(fname: Union[TextIO, str]) -> sc.DataGroup: - """Load from an ORSO compatible file. - - :param fname: The path for the file to be read. - """ - data = {} - coords = {} - attrs = {} - f_data = orso.load_orso(fname) - for i, o in enumerate(f_data): - name = i - if o.info.data_set is not None: - name = o.info.data_set - coords[f'Qz_{name}'] = sc.array( - dims=[f'{o.info.columns[0].name}_{name}'], - values=o.data[:, 0], - variances=np.square(o.data[:, 3]), - unit=sc.Unit(o.info.columns[0].unit), - ) - try: - data[f'R_{name}'] = sc.array( - dims=[f'{o.info.columns[0].name}_{name}'], - values=o.data[:, 1], - variances=np.square(o.data[:, 2]), - unit=sc.Unit(o.info.columns[1].unit), - ) - except TypeError: - data[f'R_{name}'] = sc.array( - dims=[f'{o.info.columns[0].name}_{name}'], - values=o.data[:, 1], - variances=np.square(o.data[:, 2]), - ) - attrs[f'R_{name}'] = {'orso_header': sc.scalar(Header.asdict(o.info))} - return sc.DataGroup(data=data, coords=coords, attrs=attrs) - - def _load_txt(fname: Union[TextIO, str]) -> sc.DataGroup: """Load data from a simple txt file. diff --git a/src/easyreflectometry/model/model.py b/src/easyreflectometry/model/model.py index adca5cf6..6f7a203c 100644 --- a/src/easyreflectometry/model/model.py +++ b/src/easyreflectometry/model/model.py @@ -208,6 +208,12 @@ def as_dict(self, skip: Optional[list[str]] = None) -> dict: this_dict['interface'] = self.interface().name return this_dict + def as_orso(self) -> dict: + """Convert the model to a dictionary suitable for ORSO.""" + this_dict = self.as_dict() + + return this_dict + @classmethod def from_dict(cls, passed_dict: dict) -> Model: """ diff --git a/src/easyreflectometry/orso_utils.py b/src/easyreflectometry/orso_utils.py new file mode 100644 index 00000000..23756eba --- /dev/null +++ b/src/easyreflectometry/orso_utils.py @@ -0,0 +1,155 @@ +import logging + +import numpy as np +import scipp as sc +from orsopy.fileio import Header +from orsopy.fileio import model_language +from orsopy.fileio import orso +from orsopy.fileio.base import ComplexValue + +from easyreflectometry.data import DataSet1D + +from .sample.assemblies.multilayer import Multilayer +from .sample.collections.sample import Sample +from .sample.elements.layers.layer import Layer +from .sample.elements.materials.material import Material +from .sample.elements.materials.material_density import MaterialDensity + +# Set up logging +logger = logging.getLogger(__name__) + + +def LoadOrso(orso_str: str): + """Load a model from an ORSO file.""" + + sample = load_orso_model(orso_str) + data = load_orso_data(orso_str) + + return sample, data + +def load_data_from_orso_file(fname: str) -> sc.DataGroup: + """Load data from an ORSO file.""" + try: + orso_data = orso.load_orso(fname) + except Exception as e: + raise ValueError(f"Error loading ORSO file: {e}") + return load_orso_data(orso_data) + +def load_orso_model(orso_str: str) -> Sample: + """ + Load a model from an ORSO file and return a Sample object. + + The ORSO file .ort contains information about the sample, saved + as a simple "stack" string, e.g. 'air | m1 | SiO2 | Si'. + This gets parsed by the ORSO library and converted into an ORSO Dataset object. + + Args: + orso_str: The ORSO file content as a string + + Returns: + Sample: An EasyReflectometry Sample object + + Raises: + ValueError: If ORSO layers could not be resolved + """ + # Extract stack string and create ORSO sample model + stack_str = orso_str[0].info.data_source.sample.model.stack + orso_sample = model_language.SampleModel(stack=stack_str) + + # Try to resolve layers using different methods + try: + orso_layers = orso_sample.resolve_to_layers() + except ValueError: + orso_layers = orso_sample.resolve_stack() + + # Handle case where layers are not resolved correctly + if not orso_layers: + raise ValueError("Could not resolve ORSO layers.") + + logger.debug(f"Resolved layers: {orso_layers}") + + # Convert ORSO layers to EasyReflectometry layers + erl_layers = [] + for layer in orso_layers: + erl_layer = _convert_orso_layer_to_erl(layer) + erl_layers.append(erl_layer) + + # Create a Multilayer object with the extracted layers + multilayer = Multilayer(erl_layers, name='Multi Layer Sample from ORSO') + + # Create Sample from the file + sample_info = orso_str[0].info.data_source.sample + sample_name = sample_info.name if sample_info.name else 'ORSO Sample' + sample = Sample(multilayer, name=sample_name) + + return sample + + +def _convert_orso_layer_to_erl(layer): + """Helper function to convert an ORSO layer to an EasyReflectometry layer""" + material = layer.material + m_name = material.formula if material.formula is not None else layer.name + + # Get SLD values + m_sld, m_isld = _get_sld_values(material, m_name) + + # Create and return ERL layer + return Layer( + material=Material(sld=m_sld, isld=m_isld, name=m_name), + thickness=layer.thickness.magnitude if layer.thickness is not None else 0.0, + roughness=layer.roughness.magnitude if layer.roughness is not None else 0.0, + name=layer.original_name if layer.original_name is not None else m_name + ) + + +def _get_sld_values(material, material_name): + """Extract SLD values from material, calculating from density if needed""" + if material.sld is None and material.mass_density is not None: + # Calculate SLD from mass density + m_density = material.mass_density.magnitude + density = MaterialDensity( + chemical_structure=material_name, + density=m_density + ) + m_sld = density.sld.value + m_isld = density.isld.value + else: + if isinstance(material.sld, ComplexValue): + m_sld = material.sld.real + m_isld = material.sld.imag + else: + m_sld = material.sld + m_isld = 0.0 + + return m_sld, m_isld + +def load_orso_data(orso_str: str) -> DataSet1D: + data = {} + coords = {} + attrs = {} + for i, o in enumerate(orso_str): + name = i + if o.info.data_set is not None: + name = o.info.data_set + coords[f'Qz_{name}'] = sc.array( + dims=[f'{o.info.columns[0].name}_{name}'], + values=o.data[:, 0], + variances=np.square(o.data[:, 3]), + unit=sc.Unit(o.info.columns[0].unit), + ) + try: + data[f'R_{name}'] = sc.array( + dims=[f'{o.info.columns[0].name}_{name}'], + values=o.data[:, 1], + variances=np.square(o.data[:, 2]), + unit=sc.Unit(o.info.columns[1].unit), + ) + except TypeError: + data[f'R_{name}'] = sc.array( + dims=[f'{o.info.columns[0].name}_{name}'], + values=o.data[:, 1], + variances=np.square(o.data[:, 2]), + ) + attrs[f'R_{name}'] = {'orso_header': sc.scalar(Header.asdict(o.info))} + data_group = sc.DataGroup(data=data, coords=coords, attrs=attrs) + return data_group diff --git a/src/easyreflectometry/project.py b/src/easyreflectometry/project.py index 70c3cd36..b2487bb2 100644 --- a/src/easyreflectometry/project.py +++ b/src/easyreflectometry/project.py @@ -254,6 +254,22 @@ def get_index_d2o(self) -> int: self._materials.add_material(Material(name='D2O', sld=6.36, isld=0.0)) return [material.name for material in self._materials].index('D2O') + def load_orso_file(self, path: Union[Path, str]) -> None: + """Load an ORSO file and optionally create a model and a data from it.""" + from easyreflectometry.orso_utils import LoadOrso + + model, data = LoadOrso(path) + if model is not None: + self.models = ModelCollection([model]) + else: + self.default_model() + if data is not None: + self._experiments[0] = data + self._experiments[0].name = 'Experiment from ORSO' + self._experiments[0].model = self.models[0] + self._with_experiments = True + + pass def load_new_experiment(self, path: Union[Path, str]) -> None: new_experiment = load_as_dataset(str(path)) new_index = len(self._experiments) diff --git a/src/easyreflectometry/utils.py b/src/easyreflectometry/utils.py index 75c3abae..43be7821 100644 --- a/src/easyreflectometry/utils.py +++ b/src/easyreflectometry/utils.py @@ -54,22 +54,24 @@ def yaml_dump(dict_repr: dict) -> str: return yaml.dump(dict_repr, sort_keys=False, allow_unicode=True) -def collect_unique_names_from_dict(structure_dict: dict, unique_names: Optional[list[str]] = None) -> dict: +def collect_unique_names_from_dict(structure_dict: dict, unique_names: Optional[list[str]] = None) -> list[str]: """ This function returns a list with the 'unique_name' found the input dictionary. """ if unique_names is None: unique_names = [] - if isinstance(structure_dict, dict): - for key, value in structure_dict.items(): - if isinstance(value, dict): - collect_unique_names_from_dict(value, unique_names) - elif isinstance(value, list): - for element in value: - collect_unique_names_from_dict(element, unique_names) - if key == 'unique_name': - unique_names.append(value) + def _collect(item): + if isinstance(item, dict): + if 'unique_name' in item: + unique_names.append(item['unique_name']) + for value in item.values(): + _collect(value) + elif isinstance(item, list): + for element in item: + _collect(element) + + _collect(structure_dict) return unique_names diff --git a/tests/_static/Ni_example.ort b/tests/_static/Ni_example.ort new file mode 100644 index 00000000..d5ff67e7 --- /dev/null +++ b/tests/_static/Ni_example.ort @@ -0,0 +1,408 @@ +# # ORSO reflectivity data file | 1.1 standard | YAML encoding | https://www.reflectometry.org/ +# data_source: +# owner: +# name: Joe Bloggs +# affiliation: Unseen University +# experiment: +# title: Metal films +# instrument: Platypus +# start_date: 2025-04-08T00:00:00 +# probe: neutron +# facility: ANSTO +# proposalID: '1234' +# sample: +# name: Ni on Si +# category: from air +# description: ~1000 A of metal +# model: +# stack: air | m1 | SiO2 | Si +# layers: +# air: +# thickness: 0.0 +# roughness: 0.0 +# material: +# sld: {real: 0.0, imag: 0.0} +# m1: +# thickness: 1000.0 +# roughness: 4.0 +# material: +# formula: Ni +# mass_density: 8.9 +# SiO2: +# thickness: 10.0 +# roughness: 3.0 +# material: +# sld: {real: 3.4700000000000002e-06, imag: 0.0} +# Si: +# thickness: 0.0 +# roughness: 3.5 +# material: +# sld: {real: 2.0699999999999997e-06, imag: 0.0} +# globals: +# roughness: {magnitude: 0.3, unit: nm} +# length_unit: angstrom +# mass_density_unit: g/cm^3 +# number_density_unit: 1/nm^3 +# sld_unit: 1/angstrom^2 +# magnetic_moment_unit: muB +# reference: ORSO model language | 1.0 +# measurement: +# instrument_settings: +# incident_angle: {min: 0.8, max: 3.5, individual_magnitudes: [0.8, 3.5]} +# wavelength: {min: 2.8, max: 19.0} +# polarization: unpolarized +# data_files: +# - PLP000001.nx.hdf +# - PLP000002.nx.hdf +# - PLP0049278.nx.hdf +# - PLP0049278.nx.hdf +# reduction: +# software: {name: null} +# data_set: 0 +# columns: +# - {name: Qz, unit: 1/angstrom, physical_quantity: wavevector transfer} +# - {name: R, physical_quantity: reflectivity} +# - {error_of: R, error_type: uncertainty, value_is: sigma} +# - {error_of: Qz, error_type: resolution, value_is: sigma} +# # Qz (1/angstrom) R sR sQz +9.2345234388222733e-03 1.0226067496929858e+00 1.1170591114247284e-01 1.9607872088547379e-04 +9.3270815887540274e-03 1.0302767445066796e+00 8.7740064001103457e-02 1.9804402897813036e-04 +9.4205674542496166e-03 1.0039484579143043e+00 8.1560737197910890e-02 2.0002903546478720e-04 +9.5149903338545283e-03 9.8638695256781528e-01 7.2036173798839573e-02 2.0203393778355975e-04 +9.6103596193140937e-03 1.0159129527874478e+00 6.9679978071114715e-02 2.0405893535149682e-04 +9.7066847965076447e-03 9.9807289905163554e-01 6.8322380250923700e-02 2.0610422958441577e-04 +9.8039754463920114e-03 1.0118422604265040e+00 6.6119431576221452e-02 2.0817002391693588e-04 +9.9022412459544972e-03 9.8326004456477312e-01 6.0085041363151265e-02 2.1025652382271315e-04 +1.0001491969175397e-02 9.9345781265609967e-01 5.6758191132873302e-02 2.1236393683487766e-04 +1.0101737488000164e-02 9.5390591334203079e-01 5.3389009586286063e-02 2.1449247256667583e-04 +1.0202987773321310e-02 1.0280799159994747e+00 5.3960452935320119e-02 2.1664234273231932e-04 +1.0305252895970170e-02 1.0240559926586563e+00 5.3546127784158924e-02 2.1881376116804338e-04 +1.0408543027718592e-02 9.6142392942081001e-01 5.1408956499695284e-02 2.2100694385337593e-04 +1.0512868442290667e-02 9.8598982245362687e-01 5.1238043677378491e-02 2.2322210893261995e-04 +1.0618239516384607e-02 9.9771821971933494e-01 4.7845475252791071e-02 2.2545947673655104e-04 +1.0724666730704845e-02 1.0004491683361785e+00 4.6649437246202123e-02 2.2771926980433255e-04 +1.0832160671004516e-02 1.0104022731685744e+00 4.4731121260150858e-02 2.3000171290565052e-04 +1.0940732029138353e-02 9.9779785954886413e-01 4.2272693614001246e-02 2.3230703306307020e-04 +1.1050391604126159e-02 1.0055765686454907e+00 4.2091997673492705e-02 2.3463545957461693e-04 +1.1161150303226907e-02 1.0215476539811454e+00 4.3316952678977311e-02 2.3698722403658290e-04 +1.1273019143023654e-02 9.9179624949559697e-01 4.3205628682669729e-02 2.3936256036656309e-04 +1.1386009250519294e-02 9.9557002421276131e-01 4.1228076206464730e-02 2.4176170482672189e-04 +1.1500131864243290e-02 1.0117785655957505e+00 4.0333676962068431e-02 2.4418489604729256e-04 +1.1615398335369528e-02 9.7082084841886729e-01 3.7302065673985856e-02 2.4663237505031274e-04 +1.1731820128845348e-02 9.8972115580681308e-01 3.6119493472381345e-02 2.4910438527359752e-04 +1.1849408824531903e-02 1.0214482057249348e+00 3.6602865849168845e-02 2.5160117259495293e-04 +1.1968176118355954e-02 1.0062226288284248e+00 3.5810839565481131e-02 2.5412298535663230e-04 +1.2088133823473188e-02 1.0094821254146633e+00 3.5663573177725803e-02 2.5667007439003712e-04 +1.2209293871443226e-02 9.9328904517439520e-01 3.3890468638232349e-02 2.5924269304066644e-04 +1.2331668313416380e-02 9.9595106264864630e-01 3.3042227611611054e-02 2.6184109719331537e-04 +1.2455269321332327e-02 9.6970753452708558e-01 3.2412524189650627e-02 2.6446554529752694e-04 +1.2580109189130776e-02 9.8580467285213969e-01 3.3200232581555703e-02 2.6711629839329832e-04 +1.2706200333974293e-02 1.0110779814586568e+00 3.2502675385061602e-02 2.6979362013704550e-04 +1.2833555297483368e-02 1.0006234159785823e+00 3.1139905281436866e-02 2.7249777682782761e-04 +1.2962186746983854e-02 1.0028891555408590e+00 3.0904330346290781e-02 2.7522903743383418e-04 +1.3092107476766934e-02 1.0109874864527066e+00 3.0674448813075725e-02 2.7798767361913822e-04 +1.3223330409361685e-02 9.9993528898466988e-01 2.9008037318591088e-02 2.8077395977071695e-04 +1.3355868596820433e-02 1.0009062224492562e+00 2.9627872964887707e-02 2.8358817302574389e-04 +1.3489735222016954e-02 1.0051948111274847e+00 2.9037997918434449e-02 2.8643059329915395e-04 +1.3624943599957718e-02 1.0100574086007807e+00 2.9021067137744449e-02 2.8930150331148548e-04 +1.3761507179106250e-02 1.0070363426604387e+00 2.7845257813301300e-02 2.9220118861700040e-04 +1.3899439542720791e-02 1.0228789801753368e+00 2.7624839439227691e-02 2.9512993763208752e-04 +1.4038754410205342e-02 9.8120620658005386e-01 2.5908532689742612e-02 2.9808804166394905e-04 +1.4179465638474272e-02 9.9091687911414772e-01 2.5669010973521342e-02 3.0107579493957607e-04 +1.4321587223330573e-02 1.0100578304005647e+00 2.6779911419012009e-02 3.0409349463501303e-04 +1.4465133300857969e-02 1.0212211311592154e+00 2.5503666679671837e-02 3.0714144090491699e-04 +1.4610118148826949e-02 9.9843430761327401e-01 2.4791512182427533e-02 3.1021993691241189e-04 +1.4756556188114903e-02 9.9150424287391759e-01 2.4204361068658527e-02 3.1332928885924289e-04 +1.4904461984140482e-02 1.0109906460337783e+00 2.3797204319183758e-02 3.1646980601623243e-04 +1.5053850248312364e-02 1.0084635703240679e+00 2.3364895413259618e-02 3.1964180075404208e-04 +1.5204735839492493e-02 9.8497636519005338e-01 2.2465519788426966e-02 3.2284558857424185e-04 +1.5357133765474037e-02 9.9266391393106501e-01 2.2552274037604896e-02 3.2608148814069218e-04 +1.5511059184474119e-02 9.9379819287799709e-01 2.1652903800498724e-02 3.2934982131123917e-04 +1.5666527406641522e-02 9.9957564071876948e-01 2.1317733309187341e-02 3.3265091316972829e-04 +1.5823553895579517e-02 9.9739873843751425e-01 2.1226534618181133e-02 3.3598509205833867e-04 +1.5982154269883947e-02 1.0231111176708525e+00 2.1985977915483498e-02 3.3935268961024181e-04 +1.6142344304696722e-02 1.0094995877937936e+00 2.1531634618271994e-02 3.4275404078258712e-04 +1.6304139933274894e-02 9.8880720801514732e-01 2.0247827043464509e-02 3.4618948388981857e-04 +1.6467557248575446e-02 1.0045564471903636e+00 2.0528779120545165e-02 3.4965936063732474e-04 +1.6632612504855981e-02 9.8938030419539102e-01 1.9880736411034407e-02 3.5316401615542687e-04 +1.6799322119291436e-02 1.0079622287941787e+00 1.9539095906537136e-02 3.5670379903370643e-04 +1.6967702673607025e-02 9.9234395974412848e-01 1.8541908864204752e-02 3.6027906135567832e-04 +1.7137770915727532e-02 1.0091127646720504e+00 1.8408052677005529e-02 3.6389015873381040e-04 +1.7309543761443141e-02 1.0048799030908906e+00 1.8228178239221203e-02 3.6753745034489433e-04 +1.7483038296091942e-02 1.0146102994347941e+00 1.8681168998497335e-02 3.7122129896577084e-04 +1.7658271776259345e-02 1.0023002772623562e+00 1.7836579116657321e-02 3.7494207100941370e-04 +1.7835261631494487e-02 1.0015127533896482e+00 1.7370848678424786e-02 3.7870013656137439e-04 +1.8014025466043863e-02 9.9902468118544141e-01 1.7355453693366475e-02 3.8249586941659303e-04 +1.8194581060602316e-02 9.9121670715517596e-01 1.6780184652287547e-02 3.8632964711657716e-04 +1.8376946374081611e-02 9.9589143994661278e-01 1.6698001249891299e-02 3.9020185098695458e-04 +1.8561139545396683e-02 9.9063206283515870e-01 1.6287764591293396e-02 3.9411286617540100e-04 +1.8747178895269855e-02 1.0026277513033508e+00 1.6513882094021787e-02 3.9806308168994939e-04 +1.8935082928053067e-02 9.9774163058310306e-01 1.5889056989837478e-02 4.0205289043768194e-04 +1.9124870333568435e-02 9.9381139543521468e-01 1.5547121273131848e-02 4.0608268926381090e-04 +1.9316559988967214e-02 9.9817405189101605e-01 1.5680743832551046e-02 4.1015287899115032e-04 +1.9510170960607413e-02 9.9780788941958554e-01 1.5585230186560783e-02 4.1426386445998417e-04 +1.9705722505950221e-02 9.9540503907454458e-01 1.5228182462318666e-02 4.1841605456833326e-04 +1.9903234075475451e-02 9.9870650684345674e-01 1.4616600222144071e-02 4.2260986231262642e-04 +2.0102725314616172e-02 1.0043666753026035e+00 1.4571788966922714e-02 4.2684570482877897e-04 +2.0304216065712734e-02 9.9416297116877650e-01 1.4129403786591688e-02 4.3112400343368304e-04 +2.0507726369986393e-02 9.9165852319275660e-01 1.3938330624915221e-02 4.3544518366711387e-04 +2.0713276469532700e-02 9.8789604283045751e-01 1.3707138959807392e-02 4.3980967533405603e-04 +2.0920886809334856e-02 9.8767624565652945e-01 1.3571258955420896e-02 4.4421791254745324e-04 +2.1130578039297299e-02 9.8863268753738776e-01 1.3421469263522496e-02 4.4867033377138827e-04 +2.1342371016299627e-02 9.6520670035915268e-01 1.3334408563583552e-02 4.5316738186469403e-04 +2.1556286806271106e-02 9.1543764048970389e-01 1.2303156054638944e-02 4.5770950412500231e-04 +2.1772346686286005e-02 8.5093531176324455e-01 1.1087314611140660e-02 4.6229715233323437e-04 +2.1990572146679922e-02 7.4043465375775286e-01 9.6348985567908524e-03 4.6693078279853753e-04 +2.2210984893187291e-02 6.1201570432235664e-01 8.2355980643468770e-03 4.7161085640367109e-04 +2.2433606849100347e-02 4.8148218050122088e-01 6.4223373628770272e-03 4.7633783865084827e-04 +2.2658460157449725e-02 3.9587851288902831e-01 5.4368119042684637e-03 4.8111219970803734e-04 +2.2885567183206907e-02 3.6178647647934775e-01 5.0522872547196151e-03 4.8593441445572678e-04 +2.3114950515508749e-02 3.7490379732544610e-01 5.0580319981810779e-03 4.9080496253415900e-04 +2.3346632969904302e-02 3.9567620100227002e-01 5.1916269450845848e-03 4.9572432839103757e-04 +2.3580637590624138e-02 4.0245145485826145e-01 5.2421447414599809e-03 5.0069300132971246e-04 +2.3816987652872469e-02 3.9180270901102876e-01 5.0587573967727046e-03 5.0571147555784934e-04 +2.4055706665142201e-02 3.3616109362255836e-01 4.4514784456099613e-03 5.1078025023658488e-04 +2.4296818371553171e-02 2.6460927739052686e-01 3.6642293016717971e-03 5.1589982953017611e-04 +2.4540346754213883e-02 1.9357845404875079e-01 2.7557751854739424e-03 5.2107072265614673e-04 +2.4786316035606864e-02 1.3338287823514389e-01 2.1010682875220611e-03 5.2629344393593657e-04 +2.5034750680997957e-02 9.3956258240274551e-02 1.6448100975946962e-03 5.3156851284605821e-04 +2.5285675400869741e-02 8.4565320478321881e-02 1.4965678390670260e-03 5.3689645406976695e-04 +2.5539115153379359e-02 9.4288727871067624e-02 1.5844568264285993e-03 5.4227779754924754e-04 +2.5795095146840970e-02 1.1958392887906412e-01 1.8650390745008172e-03 5.4771307853832539e-04 +2.6053640842233095e-02 1.4533553480058772e-01 2.1585315700927803e-03 5.5320283765570536e-04 +2.6314777955731079e-02 1.7078486548559821e-01 2.4269139635056452e-03 5.5874762093874385e-04 +2.6578532461264938e-02 1.7927613361405265e-01 2.4922297612565854e-03 5.6434797989776079e-04 +2.6844930593102861e-02 1.7387068360287430e-01 2.3980092138673409e-03 5.7000447157089490e-04 +2.7113998848460590e-02 1.5923078232148424e-01 2.2181961006060430e-03 5.7571765857950983e-04 +2.7385763990136959e-02 1.3588074335308398e-01 1.9649061077362659e-03 5.8148810918415500e-04 +2.7660253049175833e-02 1.0792629572586239e-01 1.6477185218997201e-03 5.8731639734108706e-04 +2.7937493327554769e-02 7.7761112396733098e-02 1.3414855859211715e-03 5.9320310275935901e-04 +2.8217512400900584e-02 5.3147721067399484e-02 1.0489609334728587e-03 5.9914881095848025e-04 +2.8500338121232153e-02 3.4045835662571709e-02 7.8747634072141599e-04 6.0515411332665524e-04 +2.8785998619730722e-02 2.7544222561454060e-02 6.9122288225713043e-04 6.1121960717960605e-04 +2.9074522309537949e-02 2.8215604481712588e-02 6.9234657939962977e-04 6.1734589581998367e-04 +2.9365937888582008e-02 3.5757172776449568e-02 7.8849036190168102e-04 6.2353358859737582e-04 +2.9660274342432041e-02 4.7526541516524079e-02 9.4135185661918086e-04 6.2978330096891545e-04 +2.9957560947181178e-02 6.0923035072185723e-02 1.0806850170048358e-03 6.3609565456049732e-04 +3.0257827272358487e-02 7.0907817512036925e-02 1.1755730837921304e-03 6.4247127722860729e-04 +3.0561103183870088e-02 7.8032413682072838e-02 1.2486664018517442e-03 6.4891080312277243e-04 +3.0867418846969776e-02 7.6040758473109218e-02 1.2376163570241433e-03 6.5541487274863638e-04 +3.1176804729259388e-02 7.1427448522323286e-02 1.1701652872985323e-03 6.6198413303166707e-04 +3.1489291603719244e-02 6.1572163939032531e-02 1.0649506940031619e-03 6.6861923738150265e-04 +3.1804910551768983e-02 5.1213185767602358e-02 9.4421200248457097e-04 6.7532084575694297e-04 +3.2123692966359092e-02 3.7915281647409982e-02 7.9055502240391040e-04 6.8208962473159283e-04 +3.2445670555093342e-02 2.4267167067261432e-02 6.0728437251809952e-04 6.8892624756016103e-04 +3.2770875343382633e-02 1.7212525437734293e-02 5.0149205459287707e-04 6.9583139424542716e-04 +3.3099339677630346e-02 1.3114951142289215e-02 4.3187309113033807e-04 7.0280575160587631e-04 +3.3431096228449697e-02 1.0717341876813639e-02 3.8378390056357131e-04 7.0985001334401430e-04 +3.3766177993913321e-02 1.4789735200331342e-02 4.6084238958443588e-04 7.1696488011536704e-04 +3.4104618302835371e-02 1.9412561011890251e-02 5.3174496355224104e-04 7.2415105959816920e-04 +3.4446450818086609e-02 2.5085894453073469e-02 6.1892025839731897e-04 7.3140926656375515e-04 +3.4791709539942636e-02 3.0625302391273170e-02 6.9213431835133722e-04 7.3874022294765241e-04 +3.5140428809465732e-02 3.3914726759820935e-02 7.2734477876078849e-04 7.4614465792138894e-04 +3.5492643311920605e-02 3.5266444535845716e-02 7.5134962058331586e-04 7.5362330796502060e-04 +3.5848388080224315e-02 3.4126331563377757e-02 7.4593442791315767e-04 7.6117691694038388e-04 +3.6207698498430835e-02 3.0075544632542275e-02 6.9025920636650606e-04 7.6880623616508491e-04 +3.6570610305250502e-02 2.4621495660074818e-02 6.2117332962373622e-04 7.7651202448722836e-04 +3.6937159597604768e-02 1.9518715187579232e-02 5.5180238388446588e-04 7.8429504836089630e-04 +3.7307382834216564e-02 1.2766360025779779e-02 4.3695690687286972e-04 7.9215608192238340e-04 +3.7681316839236659e-02 9.0396002499889324e-03 3.6632529919812507e-04 8.0009590706719600e-04 +3.8058998805906380e-02 7.0841610516306011e-03 3.2350601015004182e-04 8.0811531352782370e-04 +3.8440466300256992e-02 5.9172751787641593e-03 2.9460816028020298e-04 8.1621509895228887e-04 +3.8825757264846231e-02 7.3085439594588637e-03 3.2947322156149565e-04 8.2439606898348551e-04 +3.9214910022532225e-02 1.0220066355130862e-02 3.9119996143509187e-04 8.3265903733931179e-04 +3.9607963280285249e-02 1.3549877140660051e-02 4.5665853010942275e-04 8.4100482589360569e-04 +4.0004956133037770e-02 1.6400940409022256e-02 5.1207453531588283e-04 8.4943426475789393e-04 +4.0377230170844186e-02 1.7684083008768524e-02 1.9599470016407245e-03 8.5733884344411817e-04 +4.0781933429083851e-02 1.8121795226683748e-02 1.5636202515109815e-03 8.6593199908875185e-04 +4.1190693050935805e-02 1.6232818290916995e-02 1.3462895103999789e-03 8.7461128441769596e-04 +4.1603549693561601e-02 1.4045967576803124e-02 1.0602325510142964e-03 8.8337756271364030e-04 +4.2020544421631834e-02 1.0950011151461669e-02 7.9936104049457639e-04 8.9223170591200610e-04 +4.2441718711410600e-02 7.9703336096466383e-03 6.0601474769985579e-04 9.0117459468767207e-04 +4.2867114454880943e-02 5.5607265265694263e-03 4.2950126815357551e-04 9.1020711854257149e-04 +4.3296773963911607e-02 3.7327462432893547e-03 2.9254619494297059e-04 9.1933017589416533e-04 +4.3730739974465596e-02 3.5902144046338763e-03 2.6656293404465740e-04 9.2854467416480385e-04 +4.4169055650850900e-02 4.3392365308113322e-03 3.0135975416070883e-04 9.3785152987198284e-04 +4.4611764590013758e-02 5.9828202635619585e-03 3.6716689220795236e-04 9.4725166871950401e-04 +4.5058910825875084e-02 7.6686631567578082e-03 4.4943295180136731e-04 9.5674602568955093e-04 +4.5510538833710298e-02 9.2593148449311123e-03 5.3645415162216763e-04 9.6633554513568672e-04 +4.5966693534572986e-02 9.8064773569369497e-03 5.4826228636872983e-04 9.7602118087678337e-04 +4.6427420299763010e-02 9.1522683317013902e-03 4.7752389683118407e-04 9.8580389629189351e-04 +4.6892764955339311e-02 8.3124266796875783e-03 4.2818581383470355e-04 9.9568466441607179e-04 +4.7362773786678025e-02 6.3765641271513306e-03 3.2564486962384010e-04 1.0056644680371588e-03 +4.7837493543076218e-02 4.6973469816344879e-03 2.4344637668031926e-04 1.0157442997935327e-03 +4.8316971442401810e-02 3.4911179687482671e-03 1.9185297665235104e-04 1.0259251622728430e-03 +4.8801255175790079e-02 2.6491186211760201e-03 1.5856149584095219e-04 1.0362080681117309e-03 +4.9290392912387196e-02 2.4945433187680581e-03 1.5528595349856319e-04 1.0465940400965518e-03 +4.9784433304141479e-02 2.7359400571739714e-03 1.5830681591048247e-04 1.0570841112651072e-03 +5.0283425490642422e-02 3.8987982666778697e-03 1.9900621935828877e-04 1.0676793250093942e-03 +5.0787419104008427e-02 4.4775230516417497e-03 2.1327493263911422e-04 1.0783807351793875e-03 +5.1296464273823401e-02 5.3706572151846566e-03 2.3418606810760110e-04 1.0891894061878589e-03 +5.1810611632122916e-02 5.4666516943297850e-03 2.3339516544317406e-04 1.1001064131162502e-03 +5.2329912318430288e-02 5.1595249944872438e-03 2.2042635251412701e-04 1.1111328418216047e-03 +5.2854417984843166e-02 4.2342571721708262e-03 1.8702191987583528e-04 1.1222697890445723e-03 +5.3384180801171091e-02 3.1748229248045475e-03 1.4575855742486723e-04 1.1335183625184962e-03 +5.3919253460124550e-02 2.3827706207634092e-03 1.1542331626266473e-04 1.1448796810795939e-03 +5.4459689182556045e-02 1.6016344767924714e-03 8.8547279516013177e-05 1.1563548747782412e-03 +5.5005541722753681e-02 1.5205095115076801e-03 8.6479829433768721e-05 1.1679450849913728e-03 +5.5556865373787838e-02 1.7991433515950124e-03 9.2469178120976910e-05 1.1796514645360083e-03 +5.6113714972911399e-02 2.4784186469425009e-03 1.1073207216453850e-04 1.1914751777839180e-03 +5.6676145907014149e-02 3.0946001781434161e-03 1.2862458663364797e-04 1.2034174007774367e-03 +5.7244214118131756e-02 3.1348785593077280e-03 1.2898755154705654e-04 1.2154793213464362e-03 +5.7817976109010114e-02 3.2701875737406508e-03 1.2708589001172923e-04 1.2276621392264761e-03 +5.8397488948725304e-02 2.8973374418736126e-03 1.1844566642260249e-04 1.2399670661781320e-03 +5.8982810278359978e-02 2.3942552115839579e-03 1.0046242713187986e-04 1.2523953261075248e-03 +5.9573998316736640e-02 1.6012525457674025e-03 7.5986951827399302e-05 1.2649481551880552e-03 +6.0171111866208327e-02 1.1257520356960924e-03 5.8543220112598048e-05 1.2776268019833602e-03 +6.0774210318507355e-02 1.2171749583228099e-03 6.0408956014869802e-05 1.2904325275714999e-03 +6.1383353660652770e-02 1.2214377084700774e-03 5.9324650937215584e-05 1.3033666056703919e-03 +6.1998602480916890e-02 1.7266024926723513e-03 7.2566459575815523e-05 1.3164303227645000e-03 +6.2620017974851672e-02 1.9088182606175012e-03 7.8892953115387670e-05 1.3296249782327942e-03 +6.3247661951375572e-02 2.0436424761625066e-03 7.8097541003850057e-05 1.3429518844779934e-03 +6.3881596838921306e-02 1.9745991524617234e-03 7.5938914239295695e-05 1.3564123670571028e-03 +6.4521885691645353e-02 1.6572587491879120e-03 6.6484261905472118e-05 1.3700077648132615e-03 +6.5168592195699510e-02 1.2731019187581735e-03 5.4222140550962528e-05 1.3837394300089078e-03 +6.5821780675565461e-02 9.7612029932686595e-04 4.5296483169128860e-05 1.3976087284602826e-03 +6.6481516100452859e-02 8.3831405677855988e-04 4.0321290305701749e-05 1.4116170396732816e-03 +6.7147864090761372e-02 8.2175196765976765e-04 3.9623126172755048e-05 1.4257657569806646e-03 +6.7820890924607663e-02 1.0419457743736575e-03 4.4500652354052739e-05 1.4400562876806453e-03 +6.8500663544417667e-02 1.2211195605860848e-03 4.8052799801934263e-05 1.4544900531768658e-03 +6.9187249563585046e-02 1.2757508082902286e-03 4.8788553428318568e-05 1.4690684891197777e-03 +6.9880717273196363e-02 1.2932214701585644e-03 4.9259734680359399e-05 1.4837930455494387e-03 +7.0581135648823540e-02 1.0227025853041395e-03 4.2073045087077818e-05 1.4986651870397389e-03 +7.1288574357384601e-02 7.7123066226309834e-04 3.4141497553335003e-05 1.5136863928440760e-03 +7.2003103764073012e-02 6.4639340261843251e-04 3.0684123085783204e-05 1.5288581570424881e-03 +7.2724794939356519e-02 6.2122827022503639e-04 2.9476864326683149e-05 1.5441819886902609e-03 +7.3453719666046191e-02 6.5712465082810206e-04 2.9788341410862492e-05 1.5596594119680269e-03 +7.4189950446436309e-02 8.0517042980101316e-04 3.2705100826110183e-05 1.5752919663333683e-03 +7.4933560509515704e-02 8.4436591642398392e-04 3.2993651519545569e-05 1.5910812066739365e-03 +7.5684623818251487e-02 8.8435440178810730e-04 3.3283128106019004e-05 1.6070287034621092e-03 +7.6443215076945778e-02 7.4109613909253470e-04 3.0387917953406828e-05 1.6231360429111981e-03 +7.7209409738666149e-02 6.0900656884563655e-04 2.6568842670110977e-05 1.6394048271332205e-03 +7.7983284012750523e-02 4.8588114792948162e-04 2.2515817568747301e-05 1.6558366742982532e-03 +7.8764914872387320e-02 4.9133397743353314e-04 2.2751956751536282e-05 1.6724332187953823e-03 +7.9554380062271557e-02 4.8167300259856064e-04 2.1858432213704073e-05 1.6891961113952685e-03 +8.0351758106337767e-02 5.7914974580619495e-04 2.4044249981113025e-05 1.7061270194143404e-03 +8.1157128315570246e-02 6.0701890515166865e-04 2.4463938314345818e-05 1.7232276268806322e-03 +8.1970570795891803e-02 6.0744500993008320e-04 2.4281756526845567e-05 1.7404996347012869e-03 +8.2792166456131439e-02 4.9391599027396173e-04 2.1090432496867733e-05 1.7579447608317362e-03 +8.3621997016071925e-02 4.0293974069453001e-04 1.8662701287552571e-05 1.7755647404465757e-03 +8.4460145014577992e-02 3.4513410934294673e-04 1.6854473065400812e-05 1.7933613261121538e-03 +8.5306693817806117e-02 3.5400231422051822e-04 1.6854118637826300e-05 1.8113362879608910e-03 +8.6161727627496451e-02 3.6035001641847314e-04 1.6930206448749201e-05 1.8294914138673446e-03 +8.7025331489347935e-02 4.1561524757069993e-04 1.7722683538165638e-05 1.8478285096260392e-03 +8.7897591301477340e-02 4.0579429094564096e-04 1.7469090451429605e-05 1.8663493991310802e-03 +8.8778593822963131e-02 3.4803937288943999e-04 1.5732582645387535e-05 1.8850559245575662e-03 +8.9668426682474961e-02 2.7637275519034113e-04 1.3738393954069073e-05 1.9039499465448226e-03 +9.0567178386989522e-02 2.5795989284127768e-04 1.3053649887606726e-05 1.9230333443814663e-03 +9.1474938330593919e-02 2.5929033224365524e-04 1.2912321387667314e-05 1.9423080161923290e-03 +9.2391796803377307e-02 2.7205931674795616e-04 1.2926518411615264e-05 1.9617758791272573e-03 +9.3317845000411487e-02 2.9506350749704529e-04 1.3487723214449451e-05 1.9814388695517985e-03 +9.4253175030821590e-02 2.6860759004609702e-04 1.2519900629924986e-05 2.0012989432397995e-03 +9.5197879926947698e-02 2.5710813410301177e-04 1.2064601919059524e-05 2.0213580755679399e-03 +9.6152053653598302e-02 2.2382151679423891e-04 1.1009384487639397e-05 2.0416182617122116e-03 +9.7115791117396544e-02 1.9164252276416025e-04 1.0142387843911584e-05 2.0620815168463681e-03 +9.8089188176219907e-02 2.0296194994089023e-04 1.0159084342278791e-05 2.0827498763423629e-03 +9.9072341648734838e-02 2.1252444681873160e-04 1.0418227989348250e-05 2.1036253959727971e-03 +1.0006534932402675e-01 2.1841155642911338e-04 1.0573561725731749e-05 2.1247101521153972e-03 +1.0106830997132660e-01 2.0320972492778960e-04 9.9572376777723250e-06 2.1460062419595425e-03 +1.0208132334983487e-01 1.6963386556292267e-04 8.8736185585519316e-06 2.1675157837148565e-03 +1.0310449021864418e-01 1.4954403575540020e-04 8.2476907646391963e-06 2.1892409168218995e-03 +1.0413791234676120e-01 1.5769325941974074e-04 8.4132688051687186e-06 2.2111838021649653e-03 +1.0518169252322918e-01 1.5290173998000982e-04 8.1707165813933776e-06 2.2333466222870134e-03 +1.0623593456735164e-01 1.7198932059140680e-04 8.6937158037812652e-06 2.2557315816067532e-03 +1.0730074333901890e-01 1.5695797819931386e-04 8.0969739615174258e-06 2.2783409066379078e-03 +1.0837622474913791e-01 1.2145777878044676e-04 7.0127581872725897e-06 2.3011768462106743e-03 +1.0946248577016658e-01 1.2536445501571585e-04 7.1074355619721148e-06 2.3242416716954006e-03 +1.1055963444675382e-01 1.3122577568156347e-04 7.1839496068436513e-06 2.3475376772285083e-03 +1.1166777990648613e-01 1.2483261661357917e-04 6.9171958211864256e-06 2.3710671799406775e-03 +1.1278703237074203e-01 1.2531746684009925e-04 6.8971016002051779e-06 2.3948325201873203e-03 +1.1391750316565510e-01 1.1327585073035701e-04 6.5135595996037527e-06 2.4188360617813640e-03 +1.1505930473318707e-01 9.8671271601250582e-05 6.0018096603250021e-06 2.4430801922283650e-03 +1.1621255064231176e-01 9.0846666228074964e-05 5.7174632854597513e-06 2.4675673229639836e-03 +1.1737735560031123e-01 9.6405973932800614e-05 5.8479339117228895e-06 2.4922998895938347e-03 +1.1855383546418520e-01 9.9096593328323960e-05 5.8768305460808737e-06 2.5172803521357483e-03 +1.1974210725217455e-01 9.0255716753518403e-05 5.5700984251621864e-06 2.5425111952644503e-03 +1.2094228915540056e-01 8.3537432885503020e-05 5.2607541938258925e-06 2.5679949285587009e-03 +1.2215450054962090e-01 7.0919200564906537e-05 4.8858446736161822e-06 2.5937340867509110e-03 +1.2337886200710316e-01 7.7807094074716613e-05 5.1104802142452584e-06 2.6197312299792589e-03 +1.2461549530861754e-01 7.4798739287167140e-05 4.9391338239551646e-06 2.6459889440423297e-03 +1.2586452345554980e-01 6.7802910823132017e-05 4.6747186461377110e-06 2.6725098406563150e-03 +1.2712607068213558e-01 6.8326196214897164e-05 4.6452106744457701e-06 2.6992965577147866e-03 +1.2840026246781722e-01 6.1753624181678067e-05 4.3791068189094831e-06 2.7263517595510706e-03 +1.2968722554972462e-01 6.6490596166605105e-05 4.5548824079085322e-06 2.7536781372032577e-03 +1.3098708793528108e-01 6.0995989361206812e-05 4.3054330984348768e-06 2.7812784086818643e-03 +1.3229997891493558e-01 5.3397265285091112e-05 4.0174508088434927e-06 2.8091553192401818e-03 +1.3362602907502247e-01 5.2323098526628479e-05 3.9272921511696189e-06 2.8373116416473263e-03 +1.3496537031075043e-01 4.6317675679093863e-05 3.7196022441391349e-06 2.8657501764640402e-03 +1.3631813583932118e-01 4.7961465129785060e-05 3.7674896813562249e-06 2.8944737523212416e-03 +1.3768446021317998e-01 4.6113209718828177e-05 3.6675767059740480e-06 2.9234852262013757e-03 +1.3906447933339888e-01 4.1698751979131673e-05 3.4695249549731982e-06 2.9527874837225855e-03 +1.4045833046319400e-01 4.0691573115226657e-05 3.4213503982710258e-06 2.9823834394257266e-03 +1.4186615224157853e-01 4.3994201753485872e-05 3.5317251844537550e-06 3.0122760370642635e-03 +1.4328808469715221e-01 3.4603319203038276e-05 3.1218615013549942e-06 3.0424682498970661e-03 +1.4472426926202936e-01 4.2733276773835051e-05 3.4631831822948957e-06 3.0729630809841466e-03 +1.4617484878590642e-01 2.6394829608747400e-05 2.6890989396700258e-06 3.1037635634853585e-03 +1.4763996755027042e-01 3.0617654043315975e-05 2.9308880793470097e-06 3.1348727609620867e-03 +1.4911977128274978e-01 3.2729913916928888e-05 3.0251292299597596e-06 3.1662937676819642e-03 +1.5061440717160923e-01 2.8942710542385375e-05 2.8626503586097323e-06 3.1980297089266446e-03 +1.5212402388038984e-01 2.3342490195200957e-05 2.5698536335791965e-06 3.2300837413026555e-03 +1.5364877156269563e-01 2.7033620548570466e-05 2.7538371342215601e-06 3.2624590530553688e-03 +1.5518880187712880e-01 2.7992151480691386e-05 2.8096883042841329e-06 3.2951588643861224e-03 +1.5674426800237418e-01 2.5868444955794890e-05 2.7360443863350994e-06 3.3281864277725113e-03 +1.5831532465243531e-01 1.9921490906356091e-05 2.4039222574382325e-06 3.3615450282919001e-03 +1.5990212809202281e-01 2.1270515592868077e-05 2.4960164685437760e-06 3.3952379839481662e-03 +1.6150483615209740e-01 2.2322332682307647e-05 2.5683995754032187e-06 3.4292686460017287e-03 +1.6312360824556837e-01 2.4230573813458117e-05 2.6684443192285419e-06 3.4636403993028790e-03 +1.6475860538314971e-01 2.0807592097060881e-05 2.4932749513969838e-06 3.4983566626284554e-03 +1.6640999018937477e-01 1.3163561848048164e-05 1.9875032714275680e-06 3.5334208890218871e-03 +1.6807792691877185e-01 1.4933364522090854e-05 2.1155464191695580e-06 3.5688365661366542e-03 +1.6976258147220169e-01 1.8010506655282482e-05 2.3301265754493936e-06 3.6046072165831855e-03 +1.7146412141335859e-01 1.7566726072671504e-05 2.2920040174762717e-06 3.6407363982792298e-03 +1.7318271598543739e-01 1.2001021248911241e-05 1.9005141443807266e-06 3.6772277048037500e-03 +1.7491853612796687e-01 1.6840406700029040e-05 2.2759722444633554e-06 3.7140847657543504e-03 +1.7667175449381256e-01 8.9548560644620356e-06 1.6649578385920348e-06 3.7513112471083015e-03 +1.7844254546634919e-01 1.3567441315267696e-05 2.0492816626546614e-06 3.7889108515871666e-03 +1.8023108517680606e-01 1.2974241716152104e-05 2.0299038119670052e-06 3.8268873190250990e-03 +1.8203755152178563e-01 1.2330563163742269e-05 1.9777740397416128e-06 3.8652444267408196e-03 +1.8386212418095815e-01 1.2628713617131250e-05 2.0255257463130243e-06 3.9039859899133297e-03 +1.8570498463493326e-01 1.1436783331674691e-05 1.9358956897482819e-06 3.9431158619613830e-03 +1.8756631618331110e-01 1.0409949227710477e-05 1.8719443027834636e-06 3.9826379349267695e-03 +1.8944630396291395e-01 1.2088199170425869e-05 2.0460186267999803e-06 4.0225561398614315e-03 +1.9134513496620092e-01 7.7955750958651852e-06 1.6634444142922833e-06 4.0628744472184673e-03 +1.9326299805986724e-01 6.3778681910112358e-06 1.5043814585084911e-06 4.1035968672470538e-03 +1.9520008400362948e-01 7.7632462640590888e-06 1.6567881240446571e-06 4.1447274503913180e-03 +1.9715658546919973e-01 7.2702167231774120e-06 1.5880491551650585e-06 4.1862702876932171e-03 +1.9913269705944964e-01 7.6493910567335658e-06 1.6323697659828366e-06 4.2282295111994578e-03 +2.0112861532776621e-01 8.0979455818751740e-06 1.6900346232030133e-06 4.2706092943724785e-03 +2.0314453879760236e-01 7.7446941688948198e-06 1.6526444235387667e-06 4.3134138525055708e-03 +2.0518066798222262e-01 6.7914029304230389e-06 1.5594354975521502e-06 4.3566474431421488e-03 +2.0723720540464735e-01 8.4867622025180450e-06 1.7341918114048475e-06 4.4003143664992223e-03 +2.0931435561779654e-01 5.3927146308178653e-06 1.3932134140922588e-06 4.4444189658951194e-03 +2.1141232522483577e-01 7.3206340638546523e-06 1.6384290017832545e-06 4.4889656281814974e-03 +2.1353132289972573e-01 2.2224115686616955e-06 9.0755221808498842e-07 4.5339587841796702e-03 +2.1567155940797800e-01 5.5571503407077703e-06 1.4357339839190631e-06 4.5794029091213266e-03 +2.1783324762761880e-01 4.5958235411236489e-06 1.3274697575302855e-06 4.6253025230936556e-03 +2.2001660257036282e-01 4.5061706931646484e-06 1.3015611257904173e-06 4.6716621914889341e-03 +2.2222184140299933e-01 4.2004444187720058e-06 1.2670694255142757e-06 4.7184865254586237e-03 +2.2444918346899256e-01 3.4238046096254786e-06 1.1417329010090161e-06 4.7657801823720184e-03 +2.2669885031029874e-01 5.5033723376006984e-06 1.4717480232083966e-06 4.8135478662794879e-03 +2.2897106568940151e-01 3.8747056328134613e-06 1.2258740668037813e-06 4.8617943283803620e-03 +2.3126605561156865e-01 3.9481782623403402e-06 1.2491275167114083e-06 4.9105243674955126e-03 +2.3358404834733143e-01 2.4401374675146049e-06 9.9647824715903815e-07 4.9597428305446630e-03 +2.3592527445518954e-01 4.0366713131340390e-06 1.2771329779568867e-06 5.0094546130284856e-03 +2.3828996680454359e-01 2.5107335408000604e-06 1.0253102214166232e-06 5.0596646595155344e-03 +2.4067836059885733e-01 5.0352443574405007e-06 1.4544293213902930e-06 5.1103779641340531e-03 +2.4309069339905207e-01 2.5839540446488106e-06 1.0552307643922826e-06 5.1615995710687125e-03 +2.4552720514713564e-01 1.2748714526030119e-06 7.3616346286551431e-07 5.2133345750623337e-03 +2.4798813819006826e-01 2.1771555772586392e-06 9.7389348689219080e-07 5.2655881219226324e-03 +2.5047373730386729e-01 3.0478465681526470e-06 1.1523872914802862e-06 5.3183654090340439e-03 +2.5298424971795397e-01 2.6963394665766627e-06 1.1010883979534718e-06 5.3716716858746814e-03 +2.5551992513974420e-01 2.7348167940481426e-06 1.1168417934041268e-06 5.4255122545384792e-03 +2.5808101577948506e-01 1.9108490708921077e-06 9.5562727464730792e-07 5.4798924702625504e-03 +2.6066777637534133e-01 4.8811671158663751e-06 1.5443837848774870e-06 5.5348177419598556e-03 +2.6328046421873297e-01 1.0150617421611806e-06 7.1784311992274717e-07 5.5902935327571983e-03 +2.6591933917992616e-01 3.2505046858869777e-06 1.3274559969207371e-06 5.6463253605386057e-03 +2.6858466373388146e-01 5.4981288414527732e-07 5.4984646469446897e-07 5.7029187984941714e-03 +2.7127670298636086e-01 5.7226267321108667e-07 5.7230193048785055e-07 5.7600794756743857e-03 +2.7399572470029626e-01 2.3809826595945604e-06 1.1907794860596826e-06 5.8178130775500313e-03 diff --git a/tests/test_data.py b/tests/test_data.py index 6657d1ce..c16aa259 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -12,11 +12,11 @@ import easyreflectometry from easyreflectometry.data import DataSet1D -from easyreflectometry.data.measurement import _load_orso from easyreflectometry.data.measurement import _load_txt from easyreflectometry.data.measurement import load from easyreflectometry.data.measurement import load_as_dataset from easyreflectometry.data.measurement import merge_datagroups +from easyreflectometry.orso_utils import load_data_from_orso_file PATH_STATIC = os.path.join(os.path.dirname(easyreflectometry.__file__), '..', '..', 'tests', '_static') @@ -55,7 +55,7 @@ def test_load_with_txt_commas(self): def test_orso1(self): fpath = os.path.join(PATH_STATIC, 'test_example1.ort') - er_data = _load_orso(fpath) + er_data = load_data_from_orso_file(fpath) o_data = load_orso(fpath) assert er_data['attrs']['R_spin_up']['orso_header'].value == Header.asdict(o_data[0].info) assert_almost_equal(er_data['data']['R_spin_up'].values, o_data[0].data[:, 1]) @@ -65,7 +65,7 @@ def test_orso1(self): def test_orso2(self): fpath = os.path.join(PATH_STATIC, 'test_example2.ort') - er_data = _load_orso(fpath) + er_data = load_data_from_orso_file(fpath) o_data = load_orso(fpath) for i, o in enumerate(list(reversed(o_data))): assert er_data['attrs'][f'R_{o.info.data_set}']['orso_header'].value == Header.asdict(o.info) @@ -76,7 +76,7 @@ def test_orso2(self): def test_orso3(self): fpath = os.path.join(PATH_STATIC, 'test_example3.ort') - er_data = _load_orso(fpath) + er_data = load_data_from_orso_file(fpath) o_data = load_orso(fpath) for i, o in enumerate(o_data): assert er_data['attrs'][f'R_{o.info.data_set}']['orso_header'].value == Header.asdict(o.info) @@ -87,7 +87,7 @@ def test_orso3(self): def test_orso4(self): fpath = os.path.join(PATH_STATIC, 'test_example4.ort') - er_data = _load_orso(fpath) + er_data = load_data_from_orso_file(fpath) o_data = load_orso(fpath) for i, o in enumerate(o_data): print(list(er_data.keys())) @@ -258,7 +258,7 @@ def test_load_txt_insufficient_columns(self): def test_load_orso_multiple_datasets(self): fpath = os.path.join(PATH_STATIC, 'test_example2.ort') - er_data = _load_orso(fpath) + er_data = load_data_from_orso_file(fpath) # Should handle multiple datasets assert len(er_data['data']) > 1 @@ -276,7 +276,7 @@ def test_load_orso_multiple_datasets(self): def test_load_orso_with_attrs(self): fpath = os.path.join(PATH_STATIC, 'test_example1.ort') - er_data = _load_orso(fpath) + er_data = load_data_from_orso_file(fpath) # Should have attrs with ORSO headers assert 'attrs' in er_data @@ -286,7 +286,7 @@ def test_load_orso_with_attrs(self): def test_load_orso_with_units(self): fpath = os.path.join(PATH_STATIC, 'test_example1.ort') - er_data = _load_orso(fpath) + er_data = load_data_from_orso_file(fpath) # Coords should have units for coord_key in er_data['coords']: @@ -295,7 +295,7 @@ def test_load_orso_with_units(self): assert hasattr(coord_data, 'unit') def test_load_fallback_to_txt(self): - # Test that load() falls back to _load_txt when _load_orso fails + # Test that load() falls back to _load_txt when load_data_from_orso_file fails fpath = os.path.join(PATH_STATIC, 'test_example1.txt') result = load(fpath) diff --git a/tests/test_measurement_comprehensive.py b/tests/test_measurement_comprehensive.py index e3d96277..3842fbb5 100644 --- a/tests/test_measurement_comprehensive.py +++ b/tests/test_measurement_comprehensive.py @@ -17,11 +17,11 @@ from easyreflectometry.data.data_store import DataSet1D from easyreflectometry.data.data_store import DataStore from easyreflectometry.data.data_store import ProjectData -from easyreflectometry.data.measurement import _load_orso from easyreflectometry.data.measurement import _load_txt from easyreflectometry.data.measurement import load from easyreflectometry.data.measurement import load_as_dataset from easyreflectometry.data.measurement import merge_datagroups +from easyreflectometry.orso_utils import load_data_from_orso_file PATH_STATIC = os.path.join(os.path.dirname(easyreflectometry.__file__), '..', '..', 'tests', '_static') @@ -132,7 +132,7 @@ def test_load_txt_with_insufficient_columns(self): def test_load_orso_with_multiple_datasets(self): """Test that _load_orso handles files with multiple datasets.""" fpath = os.path.join(PATH_STATIC, 'test_example2.ort') - result = _load_orso(fpath) + result = load_data_from_orso_file(fpath) # Should have multiple data entries assert len(result['data']) > 1 @@ -141,7 +141,7 @@ def test_load_orso_with_multiple_datasets(self): def test_load_orso_preserves_metadata(self): """Test that _load_orso preserves ORSO metadata in attrs.""" fpath = os.path.join(PATH_STATIC, 'test_example1.ort') - result = _load_orso(fpath) + result = load_data_from_orso_file(fpath) assert 'attrs' in result # Should have orso_header in attrs diff --git a/tests/test_orso_utils.py b/tests/test_orso_utils.py new file mode 100644 index 00000000..89dd07db --- /dev/null +++ b/tests/test_orso_utils.py @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2025 DMSC + +import os + +import pytest +from orsopy.fileio import orso + +import easyreflectometry +from easyreflectometry.orso_utils import LoadOrso +from easyreflectometry.orso_utils import load_data_from_orso_file +from easyreflectometry.orso_utils import load_orso_data +from easyreflectometry.orso_utils import load_orso_model + +PATH_STATIC = os.path.join(os.path.dirname(easyreflectometry.__file__), '..', '..', 'tests', '_static') + + +@pytest.fixture +def orso_data(): + """Load the test ORSO data from Ni_example.ort.""" + return orso.load_orso(os.path.join(PATH_STATIC, "Ni_example.ort")) + + +def test_load_orso_model(orso_data): + """Test loading a model from ORSO data.""" + sample = load_orso_model(orso_data) + assert sample is not None + assert sample.name == "Ni on Si" # Based on the file + + +def test_load_orso_data(orso_data): + """Test loading data from ORSO data.""" + data = load_orso_data(orso_data) + assert data is not None + # Check structure, e.g., has R_0 in data + assert "R_0" in data["data"] + + +def test_LoadOrso(orso_data): + """Test the LoadOrso function.""" + sample, data = LoadOrso(orso_data) + assert sample is not None + assert data is not None + # Similar checks as above + + +def test_load_data_from_orso_file(): + """Test loading data from ORSO file.""" + data = load_data_from_orso_file(os.path.join(PATH_STATIC, "Ni_example.ort")) + assert data is not None + # Check it's a sc.DataGroup + import scipp as sc + assert isinstance(data, sc.DataGroup) \ No newline at end of file