DMSC Integration Testing

Last updated: May 27, 2026 07:22:11

Test: scipp-analysis|estia|analyze_reduced_data|fit_model_reasonable

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


load_data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])

@pytest.fixture(scope="module")
def fit_model(load_data):
data = load_data
# Rescale data
reflectivity = data["data"]["R_0"].values
scale_factor = 1 / np.max(reflectivity)
data["data"]["R_0"].values *= scale_factor

# Create a model for the sample

si = Material(sld=2.07, isld=0.0, name="Si")
sio2 = Material(sld=3.47, isld=0.0, name="SiO2")
d2o = Material(sld=6.33, isld=0.0, name="D2O")
dlipids = Material(sld=5.0, isld=0.0, name="DLipids")

superphase = Layer(material=si, thickness=0, roughness=0, name="Si superphase")
sio2_layer = Layer(material=sio2, thickness=20, roughness=4, name="SiO2 layer")
dlipids_layer = Layer(
material=dlipids, thickness=40, roughness=4, name="DLipids layer"
)
subphase = Layer(material=d2o, thickness=0, roughness=5, name="D2O subphase")

multi_sample = Sample(
Multilayer(superphase),
Multilayer(sio2_layer),
Multilayer(dlipids_layer),
Multilayer(subphase),
name="Multilayer Structure",
)

multi_layer_model = Model(
sample=multi_sample,
scale=1,
background=0.000001,
resolution_function=PercentageFwhm(0),
name="Multilayer Model",
)

# Set the fitting parameters

sio2_layer.roughness.bounds = (3, 12)
sio2_layer.material.sld.bounds = (3.47, 5)
sio2_layer.thickness.bounds = (10, 30)

subphase.material.sld.bounds = (6, 6.35)
dlipids_layer.thickness.bounds = (30, 60)
dlipids_layer.roughness.bounds = (3, 10)
dlipids_layer.material.sld.bounds = (4, 6)
multi_layer_model.scale.bounds = (0.8, 1.2)
multi_layer_model.background.bounds = (1e-6, 1e-3)

sio2_layer.roughness.free = True
sio2_layer.material.sld.free = True
sio2_layer.thickness.free = True
subphase.material.sld.free = True
dlipids_layer.thickness.free = True
dlipids_layer.roughness.free = True
dlipids_layer.material.sld.free = True
multi_layer_model.scale.free = True
multi_layer_model.background.free = True

# Run the model and plot the results

multi_layer_model.interface = CalculatorFactory()

fitter1 = MultiFitter(multi_layer_model)
fitter1.switch_minimizer(AvailableMinimizers.Bumps_simplex)

> analysed = fitter1.fit(data)
^^^^^^^^^^^^^^^^^

tests/scipp-analysis/estia/ort_file_test.py:109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =
data = DataGroup(sizes={}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensionless] [0.947216, 0.94...ame': 'sQz', 'unit': '1/angstrom', 'physical_quantity': 'standard deviation of wavevector transfer resolution'}]}}},
])
id = 0, objective = None

def fit(self, data: sc.DataGroup, id: int = 0, objective: str | None = None) -> sc.DataGroup:
"""Perform the fitting and populate the DataGroups with the result.

:param data: DataGroup to be fitted to and populated.
:type data: sc.DataGroup
:param id: Unused parameter kept for backward compatibility.
:type id: int
:param objective: Per-call override for the zero-variance objective.
If ``None``, uses the instance default set at construction.
:type objective: str or None
:return: A new DataGroup with fitted model curves, SLD profiles, and fit statistics.
:rtype: sc.DataGroup

:note: Under the ``mighell`` objective all points are transformed,
so ``reduced_chi`` is not a classical chi-square statistic.
Under ``hybrid``, only zero-variance points are transformed;
when they are a small fraction of the data the chi-square
remains approximately classical.
"""
obj = _validate_objective(objective) if objective is not None else self._objective

refl_nums = [k[3:] for k in data['coords'].keys() if 'Qz' == k[:2]]
x = []
y = []
dy = []
original_arrays = []

# Process each reflectivity dataset
for i in refl_nums:
x_vals = data['coords'][f'Qz_{i}'].values
y_vals = data['data'][f'R_{i}'].values
variances = data['data'][f'R_{i}'].variances

x_out, y_eff, weights, stats = _prepare_fit_arrays(x_vals, y_vals, variances, obj)

if stats['masked'] > 0:
warnings.warn(
f'Masked {stats["masked"]} data point(s) in reflectivity {i} due to zero variance during fitting.',
UserWarning,
)
if stats.get('transformed_all_points'):
warnings.warn(
f'Applied Mighell transform to all {len(y_vals)} point(s) in reflectivity {i} during fitting.',
UserWarning,
)
elif stats['mighell_substituted'] > 0:
> warnings.warn(
f'Applied Mighell substitution to {stats["mighell_substituted"]} '
f'zero-variance point(s) in reflectivity {i} during fitting.',
UserWarning,
)
E UserWarning: Applied Mighell substitution to 11 zero-variance point(s) in reflectivity 0 during fitting.

.tox/scipp-analysis-estia/lib/python3.12/site-packages/easyreflectometry/fitting.py:215: UserWarning

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio...: Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.78451027729009,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.78451027729009 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio...: Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.78451027729009,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.78451027729009 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError

View job log here


fit_model = DataGroup(sizes={'Qz_0': 189, 'z_0': 500}, keys=[
data: {'R_0': (Qz_0: 189) float64 [dimensio... Variable({'Qz_0': 189}),
SLD_0: Variable({'z_0': 500}),
reduced_chi: 30.784510277290032,
success: True,
])

def test_analyze_reduced_data__fit_model_reasonable(fit_model):
> assert fit_model["reduced_chi"] < 0.01
E assert 30.784510277290032 < 0.01

tests/scipp-analysis/estia/ort_file_test.py:167: AssertionError