diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fd4555915..18af3cf2a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -79,7 +79,8 @@ jobs:
- name: Run PyRS tests
run: |
conda activate PyRS
- xvfb-run --server-args="-screen 0 640x480x24" -a pytest --cov=pyrs --cov-report=xml --cov-report=term tests
+ conda install conda-forge::pytest-xvfb
+ pytest tests
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
diff --git a/environment.yml b/environment.yml
index 04f37021a..e4286204c 100644
--- a/environment.yml
+++ b/environment.yml
@@ -1,12 +1,12 @@
name: PyRS
channels:
- conda-forge
-- mantid/label/nightly
+- mantid
dependencies:
- python=3.10
- anaconda-client
- boa
-- mantidworkbench>=6.8.20231213
+- mantidworkbench>=6.10
- qtpy
- pip
- pyqt=5.15,<6
diff --git a/pyrs/core/peak_profile_utility.py b/pyrs/core/peak_profile_utility.py
index 418f7268c..54e550305 100644
--- a/pyrs/core/peak_profile_utility.py
+++ b/pyrs/core/peak_profile_utility.py
@@ -6,13 +6,12 @@
# Effective peak and background parameters
-EFFECTIVE_PEAK_PARAMETERS = ['Center', 'Height', 'FWHM', 'Mixing', 'A0', 'A1', 'Intensity']
+EFFECTIVE_PEAK_PARAMETERS = ['Center', 'Height', 'FWHM', 'Mixing', 'Intensity', 'A0', 'A1', 'A2']
class PeakShape(Enum):
GAUSSIAN = 'Gaussian'
PSEUDOVOIGT = 'PseudoVoigt'
- VOIGT = 'Voigt'
def __str__(self):
return self.value
@@ -35,14 +34,14 @@ def getShape(shape):
def native_parameters(self):
# Native peak parameters in Mantid naming convention
NATIVE_PEAK_PARAMETERS = {'Gaussian': ['Height', 'PeakCentre', 'Sigma'],
- 'PseudoVoigt': ['Mixing', 'Intensity', 'PeakCentre', 'FWHM'],
- 'Voigt': ['LorentzAmp', 'LorentzPos', 'LorentzFWHM', 'GaussianFWHM']}
+ 'PseudoVoigt': ['Mixing', 'Intensity', 'PeakCentre', 'FWHM']}
return NATIVE_PEAK_PARAMETERS[self.value][:]
class BackgroundFunction(Enum):
LINEAR = 'Linear' # so far, one and only supported
+ QUADRATIC = 'Quadratic' # so far, one and only supported
def __str__(self):
return self.value
@@ -64,7 +63,8 @@ def getFunction(function):
@property
def native_parameters(self):
# Native background parameters in Mantid naming convention
- NATIVE_BACKGROUND_PARAMETERS = {'Linear': ['A0', 'A1']}
+ NATIVE_BACKGROUND_PARAMETERS = {'Linear': ['A0', 'A1'],
+ 'Quadratic': ['A0', 'A1', 'A2']}
return NATIVE_BACKGROUND_PARAMETERS[self.value][:]
@@ -106,8 +106,6 @@ def get_effective_parameters_converter(peak_profile):
converter = Gaussian()
elif peak_profile == PeakShape.PSEUDOVOIGT:
converter = PseudoVoigt()
- elif peak_profile == PeakShape.VOIGT:
- converter = Voigt()
else:
raise RuntimeError('if/else tree is incomplete')
@@ -223,6 +221,13 @@ def calculate_effective_parameters(self, param_value_array, param_error_array):
eff_error_array['A1'] = param_error_array['A1'] # A1
eff_error_array['Intensity'] = intensity_error_array[:] # intensity
+ try:
+ eff_value_array['A2'] = param_value_array['A2'] # A2
+ eff_error_array['A2'] = param_error_array['A2'] # A2
+ except ValueError:
+ eff_value_array['A2'] = np.zeros_like(param_value_array['A1']) # A2
+ eff_error_array['A2'] = np.zeros_like(param_value_array['A1']) + 0.01 # A2
+
return eff_value_array, eff_error_array
@staticmethod
@@ -396,6 +401,13 @@ def calculate_effective_parameters(self, param_value_array, param_error_array):
eff_error_array['A1'] = param_error_array['A1'] # A1
eff_error_array['Intensity'] = param_error_array['Intensity'] # intensity
+ try:
+ eff_value_array['A2'] = param_value_array['A2'] # A2
+ eff_error_array['A2'] = param_error_array['A2'] # A2
+ except ValueError:
+ eff_value_array['A2'] = np.zeros_like(param_value_array['A1']) # A2
+ eff_error_array['A2'] = np.zeros_like(param_value_array['A1']) + 0.01 # A2
+
return eff_value_array, eff_error_array
@staticmethod
@@ -496,37 +508,6 @@ def cal_intensity(height, fwhm, mixing):
return intensity
-class Voigt(PeakParametersConverter):
- """
- class for handling peak profile parameters' conversion
- """
- def __init__(self):
- super(Voigt, self).__init__(PeakShape.VOIGT)
-
- def calculate_effective_parameters(self, param_value_array, param_error_array):
- """Calculate effective peak parameter values
-
- If input parameter values include fitting error, then this method will calculate
- the propagation of error
-
- Native PseudoVoigt: ['Mixing', 'Intensity', 'PeakCentre', 'FWHM']
-
- Parameters
- ----------
- native_param_names: list or None
- param_value_array : numpy.ndarray
- (p, n, 1) or (p, n, 2) vector for parameter values and optionally fitting error
- p = number of native parameters , n = number of sub runs
- param_error_array : numpy.ndarray
- Returns
- -------
- np.ndarray
- (p', n, 1) or (p', n, 2) array for parameter values and optionally fitting error
- p' = number of effective parameters , n = number of sub runs
- """
- raise NotImplementedError('Somebody should write this')
-
-
"""
From here are a list of static method of peak profiles
"""
diff --git a/pyrs/interface/combine_runs/combine_runs_crtl.py b/pyrs/interface/combine_runs/combine_runs_crtl.py
new file mode 100644
index 000000000..a6903522d
--- /dev/null
+++ b/pyrs/interface/combine_runs/combine_runs_crtl.py
@@ -0,0 +1,45 @@
+import numpy as np
+from pyrs.utilities import get_input_project_file # type: ignore
+
+
+class CombineRunsCrtl:
+ def __init__(self, _model):
+ self._model = _model
+
+ def parse_file_path(self, runs):
+ filepaths = []
+ for run in runs:
+ try:
+ filepaths.append(get_input_project_file(int(run)))
+ except FileNotFoundError:
+ pass
+
+ return filepaths
+
+ def parse_entry_list(self, entry_list):
+ entry_list = entry_list.replace(' ', '')
+ split_text = entry_list.split(',')
+ ranges = [entry for entry in split_text if (':' in entry) or (';' in entry)]
+ entries = [entry for entry in split_text if (':' not in entry) and (';' not in entry)]
+
+ runs = np.array([np.int16(entry) for entry in entries])
+ for entry in ranges:
+ split_entry = None
+ if ':' in entry:
+ split_entry = np.array(entry.split(':'), dtype=np.int16)
+ elif ';' in entry:
+ split_entry = np.array(entry.split(';'), dtype=np.int16)
+
+ if split_entry is not None:
+ split_entry = np.sort(split_entry)
+ runs = np.append(runs, np.arange(split_entry[0],
+ split_entry[1]))
+
+ return self.parse_file_path(runs)
+
+ def load_combine_projects(self, project_files):
+ if len(project_files) > 1:
+ self._model.combine_project_files(project_files)
+ return 1
+ else:
+ return 0
diff --git a/pyrs/interface/combine_runs/combine_runs_model.py b/pyrs/interface/combine_runs/combine_runs_model.py
new file mode 100644
index 000000000..68c8a2d94
--- /dev/null
+++ b/pyrs/interface/combine_runs/combine_runs_model.py
@@ -0,0 +1,31 @@
+from qtpy.QtCore import Signal, QObject # type:ignore
+from pyrs.core.workspaces import HidraWorkspace
+from pyrs.projectfile import HidraProjectFile # type: ignore
+
+
+class CombineRunsModel(QObject):
+ propertyUpdated = Signal(str)
+ failureMsg = Signal(str, str, str)
+
+ def __init__(self):
+ super().__init__()
+ self._hidra_ws = None
+
+ def combine_project_files(self, project_files):
+ self._hidra_ws = HidraWorkspace('Combined Project Files')
+ _project = HidraProjectFile(project_files[0])
+ self._hidra_ws.load_hidra_project(_project, load_raw_counts=False, load_reduced_diffraction=True)
+ _project.close()
+
+ for project in project_files[1:]:
+ _project = HidraProjectFile(project)
+ self._hidra_ws.append_hidra_project(_project)
+ _project.close()
+
+ def export_project_files(self, fileout):
+ export_project = HidraProjectFile(fileout, 'w')
+ self._hidra_ws.save_experimental_data(export_project,
+ sub_runs=self._hidra_ws._sample_logs.subruns,
+ ignore_raw_counts=True)
+ self._hidra_ws.save_reduced_diffraction_data(export_project)
+ export_project.save()
diff --git a/pyrs/interface/combine_runs/combine_runs_viewer.py b/pyrs/interface/combine_runs/combine_runs_viewer.py
new file mode 100644
index 000000000..3be0d3219
--- /dev/null
+++ b/pyrs/interface/combine_runs/combine_runs_viewer.py
@@ -0,0 +1,130 @@
+from qtpy.QtWidgets import QHBoxLayout, QLabel, QWidget # type:ignore
+from qtpy.QtWidgets import QLineEdit, QPushButton # type:ignore
+from qtpy.QtWidgets import QFileDialog, QGroupBox # type:ignore
+
+from qtpy.QtWidgets import QGridLayout # type:ignore
+from qtpy.QtWidgets import QMainWindow # type:ignore
+from qtpy.QtCore import Qt # type: ignore
+
+from pyrs.interface.gui_helper import pop_message
+
+
+class FileLoad(QWidget):
+ def __init__(self, name=None, fileType="HidraProjectFile (*.h5);;All Files (*)", parent=None):
+ self._parent = parent
+ super().__init__(parent)
+ self.name = name
+ self.fileType = fileType
+ layout = QHBoxLayout()
+ if name == "Run Numbers:":
+ label = QLabel(name)
+ label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
+ layout.addWidget(label)
+ self.lineEdit = QLineEdit()
+ self.lineEdit.setReadOnly(False)
+ self.lineEdit.setFixedWidth(300)
+
+ layout.addWidget(self.lineEdit)
+
+ self.browse_button = QPushButton("Load")
+ self.browse_button.clicked.connect(self.loadRunNumbers)
+ else:
+ if name is None:
+ self.browse_button = QPushButton("Browse Exp Data")
+ else:
+ self.browse_button = QPushButton("Browse")
+
+ self.browse_button.clicked.connect(self.openFileDialog)
+
+ layout.addWidget(self.browse_button)
+ self.setLayout(layout)
+
+ def _reset_fit_data(self):
+ self._parent.fit_summary.fit_table_operator.fits = None
+ self._parent.fit_summary.fit_table_operator.fit_result = None
+
+ def openFileDialog(self):
+ self._parent._project_files, _ = QFileDialog.getOpenFileNames(self,
+ self.name,
+ "",
+ self.fileType,
+ options=QFileDialog.DontUseNativeDialog)
+
+ if self._parent._project_files:
+ self._parent.load_project_files = self._parent._project_files
+
+ self.load_project_files()
+
+ def saveFileDialog(self, combined_files):
+ if combined_files != 0:
+ self._parent._project_files, _ = QFileDialog.getSaveFileName(self,
+ 'Save Combined Proeject File',
+ "",
+ self.fileType,
+ options=QFileDialog.DontUseNativeDialog)
+
+ def loadRunNumbers(self):
+ self._parent._project_files = self._parent.controller.parse_entry_list(self.lineEdit.text())
+ combined_files = self._parent.controller.load_combine_projects(self._parent._project_files)
+ self.saveFileDialog(combined_files)
+
+ def load_project_files(self):
+ try:
+ combined_files = self._parent.controller.load_combine_projects(self._parent._project_files)
+ self.saveFileDialog(combined_files)
+
+ except (FileNotFoundError, RuntimeError, ValueError) as run_err:
+ pop_message(self, f'Failed to find run {self._parent._project_files}',
+ str(run_err), 'error')
+
+ self._parent.load_project_files = None
+
+ def setFilenamesText(self, filenames):
+ self.lineEdit.setText(filenames)
+
+
+class FileLoading(QGroupBox):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.setTitle("Load Project Files")
+ layout = QHBoxLayout()
+
+ self.file_load_run_number = FileLoad(name="Run Numbers:", parent=parent)
+ self.file_load_dilg = FileLoad(name=None, parent=parent)
+
+ layout.addWidget(self.file_load_run_number)
+ layout.addWidget(self.file_load_dilg)
+
+ self.setLayout(layout)
+
+ def set_text_values(self, direction, text):
+ getattr(self, f"file_load_e{direction}").setFilenamesText(text)
+
+
+class CombineRunsViewer(QMainWindow):
+ def __init__(self, combine_runs_model, combine_runs_ctrl, parent=None):
+
+ self._model = combine_runs_model
+ self._ctrl = combine_runs_ctrl
+ self._nexus_file = None
+ self._run_number = None
+ self._calibration_input = None
+
+ super().__init__(parent)
+
+ self.setWindowTitle("PyRS Combine Projectfiles Window")
+
+ self.fileLoading = FileLoading(self)
+
+ self.window = QWidget()
+ self.layout = QGridLayout()
+ self.setCentralWidget(self.fileLoading)
+ self.window.setLayout(self.layout)
+
+ @property
+ def controller(self):
+ return self._ctrl
+
+ @property
+ def model(self):
+ return self._model
diff --git a/pyrs/interface/designer/peakfitwindow.ui b/pyrs/interface/designer/peakfitwindow.ui
index 9e106a88d..c89359963 100644
--- a/pyrs/interface/designer/peakfitwindow.ui
+++ b/pyrs/interface/designer/peakfitwindow.ui
@@ -398,11 +398,6 @@
Gaussian
- -
-
- Voigt
-
-
-
@@ -412,11 +407,6 @@
Linear
- -
-
- Flat
-
-
-
Quadratic
@@ -942,7 +932,7 @@
0
0
1536
- 23
+ 22
diff --git a/pyrs/interface/peak_fitting/fit.py b/pyrs/interface/peak_fitting/fit.py
index 4ca8b2ac2..85240bab5 100644
--- a/pyrs/interface/peak_fitting/fit.py
+++ b/pyrs/interface/peak_fitting/fit.py
@@ -24,6 +24,7 @@ def fit_multi_peaks(self):
_peak_center_list = [np.mean([left, right]) for (left, right) in _peak_range_list]
_peak_tag_list = ["peak{}".format(_index) for _index, _ in enumerate(_peak_center_list)]
_peak_function_name = str(self.parent.ui.comboBox_peakType.currentText())
+ _peak_background_name = str(self.parent.ui.comboBox_backgroundType.currentText())
_peak_xmin_list = [left for (left, _) in _peak_range_list]
_peak_xmax_list = [right for (_, right) in _peak_range_list]
@@ -31,9 +32,10 @@ def fit_multi_peaks(self):
# Fit peak
hd_ws = self.parent.hidra_workspace
+ print(_peak_background_name)
_wavelength = hd_ws.get_wavelength(True, True)
fit_engine = PeakFitEngineFactory.getInstance(hd_ws,
- _peak_function_name, 'Linear',
+ _peak_function_name, _peak_background_name,
wavelength=_wavelength)
fit_result = fit_engine.fit_multiple_peaks(_peak_tag_list,
_peak_xmin_list,
diff --git a/pyrs/interface/pyrs_main.py b/pyrs/interface/pyrs_main.py
index 09cc53865..4e63b67eb 100644
--- a/pyrs/interface/pyrs_main.py
+++ b/pyrs/interface/pyrs_main.py
@@ -23,6 +23,10 @@
from pyrs.interface.detector_calibration.detector_calibration_model import DetectorCalibrationModel # noqa: E402
from pyrs.interface.detector_calibration.detector_calibration_crtl import DetectorCalibrationCrtl # noqa: E402
+from pyrs.interface.combine_runs.combine_runs_viewer import CombineRunsViewer # noqa: E402
+from pyrs.interface.combine_runs.combine_runs_model import CombineRunsModel # noqa: E402
+from pyrs.interface.combine_runs.combine_runs_crtl import CombineRunsCrtl # noqa: E402
+
class PyRSLauncher(QMainWindow):
"""
@@ -46,12 +50,14 @@ def __init__(self):
self.ui.actionQuit.triggered.connect(self.do_quit)
self.ui.actionCalibration.triggered.connect(self.do_launch_calibration_window)
+ self.ui.actionCombine_Runs.triggered.connect(self.do_launch_combeineruns)
# child windows
self.peak_fit_window = None
self.manual_reduction_window = None
self.strain_stress_window = None
self.texture_fit_window = None
+ self.combine_run_window = None
def do_launch_fit_texture_window(self):
"""
@@ -68,6 +74,17 @@ def do_launch_fit_texture_window(self):
# launch
self.texture_fit_window.show()
+ def do_launch_combeineruns(self):
+ if self.combine_run_window is not None:
+ self.combine_run_window.close()
+
+ self.combine_runs_model = CombineRunsModel()
+ self.combine_runs_ctrl = CombineRunsCrtl(self.combine_runs_model)
+ self.combine_run_window = CombineRunsViewer(self.combine_runs_model, self.combine_runs_ctrl)
+
+ # launch
+ self.combine_run_window.show()
+
def do_launch_calibration_window(self):
"""
launch peak fit window
diff --git a/pyrs/interface/strainstressviewer/strain_stress_view.py b/pyrs/interface/strainstressviewer/strain_stress_view.py
index 2d0ce9564..06cce6eb0 100644
--- a/pyrs/interface/strainstressviewer/strain_stress_view.py
+++ b/pyrs/interface/strainstressviewer/strain_stress_view.py
@@ -19,6 +19,8 @@
from qtpy.QtGui import QDoubleValidator # type:ignore
try:
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
+ # from vtkmodules.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
+ # from vtkmodules.util.numpy_support import numpy_to_vtk, get_vtk_array_type
from vtk.util.numpy_support import numpy_to_vtk, get_vtk_array_type
import vtk
DISABLE_3D = False
@@ -697,6 +699,11 @@ def __init__(self, ws, parent=None):
layout.addWidget(self.vtkWidget)
self.setLayout(layout)
+ camera = self.renderer.GetActiveCamera()
+ assert camera is not None
+
+ self.vtkWidget.show()
+
self.iren.Initialize()
def set_ws(self, ws):
diff --git a/pyrs/interface/texture_fitting/texture_fitting_crtl.py b/pyrs/interface/texture_fitting/texture_fitting_crtl.py
index 3a64630d8..3dce36240 100644
--- a/pyrs/interface/texture_fitting/texture_fitting_crtl.py
+++ b/pyrs/interface/texture_fitting/texture_fitting_crtl.py
@@ -271,6 +271,7 @@ def plot_2D_params(self, ax_object, xlabel, ylabel, peak_number, fit_object, out
fit_object=fit_object,
out_of_plane=out_of_plane)
+ print(xdata, ydata)
if isinstance(ydata[0], np.ndarray):
yerr = ydata[1]
ydata = ydata[0]
diff --git a/pyrs/interface/texture_fitting/texture_fitting_viewer.py b/pyrs/interface/texture_fitting/texture_fitting_viewer.py
index 1287ebdc3..017adc832 100644
--- a/pyrs/interface/texture_fitting/texture_fitting_viewer.py
+++ b/pyrs/interface/texture_fitting/texture_fitting_viewer.py
@@ -968,7 +968,7 @@ def __init__(self, fit_peak_model, fit_peak_ctrl, parent=None):
self.splitter.setStretchFactor(0, 1)
self.splitter.setStretchFactor(1, 5)
- self.resize(1024, 1024)
+ self.resize(1200, 1800)
@property
def controller(self):
diff --git a/pyrs/peaks/fit_factory.py b/pyrs/peaks/fit_factory.py
index fc288971e..26589c126 100644
--- a/pyrs/peaks/fit_factory.py
+++ b/pyrs/peaks/fit_factory.py
@@ -1,5 +1,5 @@
# Peak fitting engine
-SupportedPeakProfiles = ['Gaussian', 'PseudoVoigt', 'Voigt']
+SupportedPeakProfiles = ['Gaussian', 'PseudoVoigt']
SupportedBackgroundTypes = ['Flat', 'Linear', 'Quadratic']
__all__ = ['FitEngineFactory', 'SupportedPeakProfiles', 'SupportedBackgroundTypes']
diff --git a/tests/conftest.py b/tests/conftest.py
index c76fbf0b6..584822502 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -8,6 +8,8 @@
from pyrs.dataobjects.sample_logs import _coerce_to_ndarray, PointList
from pyrs.core.peak_profile_utility import get_parameter_dtype
from pyrs.peaks.peak_collection import PeakCollection
+from pytestqt.qtbot import QtBot
+from pytestqt.exceptions import format_captured_exceptions, capture_exceptions
# set to True when running on build servers
ON_GITHUB_ACTIONS = bool(os.environ.get('GITHUB_ACTIONS', False))
@@ -595,3 +597,16 @@ def strain_stress_object_1(strain_builder):
'in-plane-stress': StressField(strain11, strain22, None, 3. / 2, 1. / 2, 'in-plane-stress')
}
}
+
+
+@pytest.fixture(scope="session")
+def my_qtbot(qapp, request):
+ r"""
+ Fixture to provide a QtBot instance for testing Qt-based applications with a session scope. This fixture will
+ behave like the `qtbot` fixture, but with a session scope to avoid a segmentation fault when running UI tests.
+ """
+ result = QtBot(qapp)
+ with capture_exceptions() as exceptions:
+ yield result
+ if exceptions:
+ pytest.fail(format_captured_exceptions(exceptions))
diff --git a/tests/integration/pyrs/__init__.py b/tests/integration/pyrs/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/integration/test_peak_fitting.py b/tests/integration/test_peak_fitting.py
index 4ee45fc58..b0d81ac24 100644
--- a/tests/integration/test_peak_fitting.py
+++ b/tests/integration/test_peak_fitting.py
@@ -213,8 +213,7 @@ def test_retrieve_fit_metadata(source_project_file, output_project_file, peak_ty
[('data/Hidra_16-1_cor_log.h5', 'Hidra_16-1_cor_log_peak.h5', 'Gaussian',
PeakInfo(94.5, 91, 97, 'Fe111')), # NSFR2 peak
('data/HB2B_938.h5', 'HB2B_938_peak.h5', 'PseudoVoigt',
- PeakInfo(95.5, 91, 97, 'Si111'))],
- ids=('FakeHB2B', 'HB2B_938'))
+ PeakInfo(95.5, 91, 97, 'Si111'))], ids=('FakeHB2B', 'HB2B_938'))
def xtest_main(project_file_name, peak_file_name, peak_type, peak_info):
"""Test peak fitting
@@ -247,17 +246,6 @@ def xtest_main(project_file_name, peak_file_name, peak_type, peak_info):
os.remove(peak_file_name)
-# TODO - MAKE IT WORK!
-def test_calculating_com():
- # calculate_center_of_mass(self, peak_tag, peak_range):
- pass
-
-
-def test_convert_peaks_centers_to_dspacing():
- #
- pass
-
-
def test_improve_quality():
"""This is a test to improve the quality of peak fitting.
@@ -372,7 +360,7 @@ def test_write_csv():
# verify that the number of columns is correct
# columns are (subruns, one log, parameter values, uncertainties, chisq)
for line in contents[len(EXPECTED_HEADER) + 1:]: # skip past header and constant log
- assert len(line.split(',')) == 1 + 1 + 9 * 2 + 1
+ assert len(line.split(',')) == 1 + 1 + 10 * 2 + 1
# cleanup
os.remove(csv_filename)
@@ -465,7 +453,7 @@ def test_write_csv_from_project(project_file_name, csv_filename, expected_header
# columns are (subruns, seven logs, parameter values, uncertainties, d_spacing values,
# strain values and uncertainties, chisq)
for line in contents[len(expected_header) + 1:]: # skip past header and constant log
- assert len(line.split(',')) == 1 + num_logs + 7 * 2 + (2*2) + 1
+ assert len(line.split(',')) == 1 + num_logs + 8 * 2 + (2*2) + 1
# cleanup
os.remove(csv_filename)
diff --git a/tests/ui/test_calibration_ui.py b/tests/ui/test_calibration_ui.py
index 54b1ea307..59e32d00c 100644
--- a/tests/ui/test_calibration_ui.py
+++ b/tests/ui/test_calibration_ui.py
@@ -9,20 +9,25 @@
# import json
import pytest
-from tests.conftest import ON_GITHUB_ACTIONS # set to True when running on build servers
-
wait = 200
plot_wait = 100
-@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason="UI tests segfault on GitHub Actions")
-def test_texture_fitting_viewer(qtbot):
-
+@pytest.fixture(scope="session")
+def calibration_window(my_qtbot):
+ r"""
+ Fixture for the detector calibration window. Creating the window with a session scope and reusing it for all tests.
+ This is done to avoid the segmentation fault error that occurs when the window is created with a function scope.
+ """
model = DetectorCalibrationModel(pyrscore.PyRsCore())
ctrl = DetectorCalibrationCrtl(model)
window = DetectorCalibrationViewer(model, ctrl)
+ return window, my_qtbot
+
+
+def test_detector_calibration(calibration_window):
+ window, qtbot = calibration_window
- qtbot.addWidget(window)
window.show()
qtbot.wait(wait)
@@ -97,3 +102,5 @@ def handle_dialog(filename):
window.param_window.plot_paramX.setCurrentIndex(1)
qtbot.wait(wait)
+
+ window.hide()
diff --git a/tests/ui/test_manual_reduction.py b/tests/ui/test_manual_reduction.py
index 9aa0a05e6..274353d73 100644
--- a/tests/ui/test_manual_reduction.py
+++ b/tests/ui/test_manual_reduction.py
@@ -1,18 +1,26 @@
from qtpy import QtCore
import os
import pytest
-from tests.conftest import ON_GITHUB_ACTIONS # set to True when running on build servers
import matplotlib
matplotlib.use("Agg")
from pyrs.interface.manual_reduction import manualreductionwindow # noqa E402
+
wait = 100
-@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason="UI tests segfault on GitHub Actions")
-def test_manual_reduction(qtbot, tmpdir):
+@pytest.fixture(scope="session")
+def manual_reduction_window(my_qtbot):
+ r"""
+ Fixture for the detector calibration window. Creating the window with a session scope and reusing it for all tests.
+ This is done to avoid the segmentation fault error that occurs when the window is created with a function scope.
+ """
window = manualreductionwindow.ManualReductionWindow(None)
- qtbot.addWidget(window)
+ return window, my_qtbot
+
+
+def test_manual_reduction(tmpdir, manual_reduction_window):
+ window, qtbot = manual_reduction_window
window.show()
qtbot.wait(wait)
@@ -79,10 +87,8 @@ def test_manual_reduction(qtbot, tmpdir):
assert line.get_ydata()[1::].max() == pytest.approx(580.4936170212766)
-@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason="UI tests segfault on GitHub Actions")
-def test_manual_reduction_subruns(qtbot, tmpdir):
- window = manualreductionwindow.ManualReductionWindow(None)
- qtbot.addWidget(window)
+def test_manual_reduction_subruns(tmpdir, manual_reduction_window):
+ window, qtbot = manual_reduction_window
window.show()
qtbot.wait(wait)
@@ -142,3 +148,5 @@ def test_manual_reduction_subruns(qtbot, tmpdir):
for _ in range(10):
qtbot.keyClick(window.ui.comboBox_sub_runs, QtCore.Qt.Key_Up)
qtbot.wait(wait)
+
+ window.hide()
diff --git a/tests/ui/test_peak_fitting.py b/tests/ui/test_peak_fitting.py
index 79c769ef1..2fef689b5 100644
--- a/tests/ui/test_peak_fitting.py
+++ b/tests/ui/test_peak_fitting.py
@@ -5,16 +5,23 @@
import functools
import pytest
import os
-from tests.conftest import ON_GITHUB_ACTIONS # set to True when running on build servers
wait = 300
-@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason="UI tests segfault on GitHub Actions")
-def test_peak_fitting(qtbot, tmpdir):
+@pytest.fixture(scope="session")
+def fit_peaks_window(my_qtbot):
+ r"""
+ Fixture for the detector calibration window. Creating the window with a session scope and reusing it for all tests.
+ This is done to avoid the segmentation fault error that occurs when the window is created with a function scope.
+ """
fit_peak_core = pyrscore.PyRsCore()
window = fitpeakswindow.FitPeaksWindow(None, fit_peak_core=fit_peak_core)
- qtbot.addWidget(window)
+ return window, my_qtbot
+
+
+def test_peak_fitting(tmpdir, fit_peaks_window):
+ window, qtbot = fit_peaks_window
window.show()
qtbot.wait(wait)
@@ -83,7 +90,7 @@ def handle_dialog(filename):
# check number of lines
assert len(file_contents) == 127
# check number of values in line
- assert len(np.fromstring(file_contents[-1], dtype=np.float64, sep=',')) == 33
+ assert len(np.fromstring(file_contents[-1], dtype=np.float64, sep=',')) == 35
# look at 1D results plot
line = window.ui.graphicsView_fitResult.canvas().get_axis().lines[0]
@@ -127,7 +134,7 @@ def handle_dialog(filename):
# check number of lines
assert len(file_contents) == 127
# check number of values in line
- assert len(np.fromstring(file_contents[-1], dtype=np.float64, sep=',')) == 33
+ assert len(np.fromstring(file_contents[-1], dtype=np.float64, sep=',')) == 35
# look at 1D results plot
line = window.ui.graphicsView_fitResult.canvas().get_axis().lines[0]
@@ -170,11 +177,8 @@ def handle_dialog(filename):
qtbot.wait(wait)
-@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason="UI tests segfault on GitHub Actions")
-def test_peak_selection(qtbot, tmpdir):
- fit_peak_core = pyrscore.PyRsCore()
- window = fitpeakswindow.FitPeaksWindow(None, fit_peak_core=fit_peak_core)
- qtbot.addWidget(window)
+def test_peak_selection(tmpdir, fit_peaks_window):
+ window, qtbot = fit_peaks_window
window.show()
qtbot.wait(wait)
@@ -217,3 +221,5 @@ def handle_dialog(filename):
qtbot.wait(wait)
qtbot.mouseRelease(canvas, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier, QtCore.QPoint(int(end_x2), int(end_y2)))
qtbot.wait(wait)
+
+ window.hide()
diff --git a/tests/ui/test_pyrslauncher.py b/tests/ui/test_pyrslauncher.py
index 32d1d691e..d71aaad2e 100644
--- a/tests/ui/test_pyrslauncher.py
+++ b/tests/ui/test_pyrslauncher.py
@@ -1,15 +1,22 @@
from pyrs.interface.pyrs_main import PyRSLauncher
from qtpy import QtCore
-from tests.conftest import ON_GITHUB_ACTIONS # set to True when running on build servers
import pytest
wait = 100
-@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason="UI tests segfault on GitHub Actions")
-def test_launcher(qtbot):
- main_window = PyRSLauncher()
- qtbot.addWidget(main_window)
+@pytest.fixture(scope="session")
+def main_window(my_qtbot):
+ r"""
+ Fixture for the detector calibration window. Creating the window with a session scope and reusing it for all tests.
+ This is done to avoid the segmentation fault error that occurs when the window is created with a function scope.
+ """
+ window = PyRSLauncher()
+ return window, my_qtbot
+
+
+def test_launcher(main_window):
+ main_window, qtbot = main_window
main_window.show()
qtbot.wait(wait)
@@ -28,3 +35,6 @@ def test_launcher(qtbot):
qtbot.wait(wait)
assert main_window.peak_fit_window is not None
assert main_window.peak_fit_window.isVisible()
+ main_window.peak_fit_window.close()
+ main_window.manual_reduction_window.close()
+ main_window.close()
diff --git a/tests/ui/test_stress_strain_viewer.py b/tests/ui/test_stress_strain_viewer.py
index 2e4fc11cf..1f52db3ca 100644
--- a/tests/ui/test_stress_strain_viewer.py
+++ b/tests/ui/test_stress_strain_viewer.py
@@ -7,7 +7,6 @@
import os
import pytest
import json
-from tests.conftest import ON_GITHUB_ACTIONS # set to True when running on build servers
import mantid
mantid_version = mantid._version_str().split('.')
@@ -20,7 +19,6 @@
# This is a test of the model component of the strain/stress viewer
-@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason="UI tests segfault on GitHub Actions")
def test_model(tmpdir, test_data_dir):
model = Model()
@@ -336,7 +334,6 @@ def test_model(tmpdir, test_data_dir):
model.e11 is not None
-@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason="UI tests segfault on GitHub Actions")
def test_model_multiple_files(tmpdir, test_data_dir):
model = Model()
@@ -506,7 +503,6 @@ def test_model_multiple_files(tmpdir, test_data_dir):
assert len(open(filename).readlines()) == 318
-@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason="UI tests segfault on GitHub Actions")
def test_model_from_json(tmpdir, test_data_dir):
model_json = dict()
model_json['stress_case'] = 'in-plane-stress'
@@ -604,15 +600,23 @@ def test_model_from_json(tmpdir, test_data_dir):
assert d0.errors[0] == 0.000123
-# changes to SliceViewer from Mantid in the version 5.1 is needed for the stress/strain viewer to run
-@pytest.mark.skipif(ON_GITHUB_ACTIONS or old_mantid, reason='Need mantid version >= 5.1')
-def test_stress_strain_viewer(qtbot):
-
+@pytest.fixture(scope="session")
+def strain_stress_window(my_qtbot):
+ r"""
+ Fixture for the detector calibration window. Creating the window with a session scope and reusing it for all tests.
+ This is done to avoid the segmentation fault error that occurs when the window is created with a function scope.
+ """
model = Model()
ctrl = Controller(model)
window = StrainStressViewer(model, ctrl)
+ return window, my_qtbot
+
+
+# changes to SliceViewer from Mantid in the version 5.1 is needed for the stress/strain viewer to run
+@pytest.mark.skipif(old_mantid, reason='Need mantid version >= 5.1')
+def test_stress_strain_viewer(strain_stress_window):
+ window, qtbot = strain_stress_window
- qtbot.addWidget(window)
window.show()
qtbot.wait(wait)
@@ -704,3 +708,5 @@ def handle_dialog(filename):
qtbot.wait(wait)
# check that the sliceviewer widget is created
assert window.viz_tab.strainSliceViewer is not None
+
+ window.hide()
diff --git a/tests/ui/test_texture_fitting.py b/tests/ui/test_texture_fitting.py
index b54240df8..beaef1a49 100644
--- a/tests/ui/test_texture_fitting.py
+++ b/tests/ui/test_texture_fitting.py
@@ -16,14 +16,21 @@
plot_wait = 100
-@pytest.mark.skipif(ON_GITHUB_ACTIONS, reason="UI tests segfault on GitHub Actions")
-def test_texture_fitting_viewer(qtbot):
-
+@pytest.fixture(scope="session")
+def texture_fitting_window(my_qtbot):
+ r"""
+ Fixture for the detector calibration window. Creating the window with a session scope and reusing it for all tests.
+ This is done to avoid the segmentation fault error that occurs when the window is created with a function scope.
+ """
model = TextureFittingModel(pyrscore.PyRsCore())
ctrl = TextureFittingCrtl(model)
window = TextureFittingViewer(model, ctrl)
+ return window, my_qtbot
+
+
+def test_texture_fitting_viewer(texture_fitting_window):
+ window, qtbot = texture_fitting_window
- qtbot.addWidget(window)
window.show()
qtbot.wait(wait)
@@ -67,7 +74,7 @@ def handle_dialog(filename):
canvas = window.fit_window._myCanvas
# The get start and end mouse points to drag select
- fit_ranges = [[62.346, 66.568], [71.2917, 76.0151]]
+ fit_ranges = [[62.864, 66.9115], [71.87344, 76.5544]]
if ON_GITHUB_ACTIONS:
rtol = 0.5
@@ -76,13 +83,13 @@ def handle_dialog(filename):
for i_loop in range(len(fit_ranges)):
# Drag select with mouse control
+ canvas.figure.canvas.draw()
start_x, start_y = canvas.figure.axes[0].transData.transform((fit_ranges[i_loop][0], 40))
end_x, end_y = canvas.figure.axes[0].transData.transform((fit_ranges[i_loop][1], 40))
- # Drag select with mouse control
- qtbot.mousePress(canvas, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier, QtCore.QPoint(start_x / 2, 40))
+ qtbot.mousePress(canvas, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier, QtCore.QPoint(int(start_x), int(start_y)))
qtbot.wait(wait)
- qtbot.mouseRelease(canvas, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier, QtCore.QPoint(end_x / 2, 40))
+ qtbot.mouseRelease(canvas, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier, QtCore.QPoint(int(end_x), int(end_y)))
qtbot.wait(wait)
np.testing.assert_allclose(float(window.fit_setup.fit_range_table.item(i_loop, 0).text()),
@@ -166,3 +173,4 @@ def handle_dialog(filename):
qtbot.keyClick(window.plot_select.out_of_plane, QtCore.Qt.Key_Down)
# qtbot.wait(plot_wait)
+ window.hide()
diff --git a/tests/unit/pyrs/core/test_stress_facade.py b/tests/unit/pyrs/core/test_stress_facade.py
index 2147f23c9..a35beccfc 100644
--- a/tests/unit/pyrs/core/test_stress_facade.py
+++ b/tests/unit/pyrs/core/test_stress_facade.py
@@ -412,8 +412,8 @@ def test_set_d_reference(self, strain_stress_object_0, strain_stress_object_1):
def test_peak_parameters(self, strain_stress_object_1):
facade = StressFacade(strain_stress_object_1['stresses']['diagonal'])
- assert set(facade.peak_parameters) == {'d', 'Center', 'Height', 'FWHM', 'Mixing',
- 'A0', 'A1', 'Intensity'}
+ assert set(facade.peak_parameters) == {'d', 'Center', 'Height', 'FWHM', 'Mixing', 'Intensity',
+ 'A0', 'A1', 'A2'}
def test_peak_parameter_field(self, strain_stress_object_1):
r"""Retrieve the effective peak parameters for a particular run, or for a particular direction"""
diff --git a/tests/unit/pyrs/peaks/test_peak_collection.py b/tests/unit/pyrs/peaks/test_peak_collection.py
index 49dc2db88..e0ee8d509 100644
--- a/tests/unit/pyrs/peaks/test_peak_collection.py
+++ b/tests/unit/pyrs/peaks/test_peak_collection.py
@@ -56,7 +56,7 @@ def test_peak_collection_init():
np.testing.assert_equal(d_ref_err, np.asarray((0.,)))
-def check_peak_collection(peak_shape, NUM_SUBRUN, target_errors,
+def check_peak_collection(peak_shape, background, NUM_SUBRUN, target_errors,
wavelength=None, d_reference=None,
target_d_spacing_center=np.nan,
target_d_spacing_center_error=np.asarray([0., 0.]),
@@ -85,7 +85,7 @@ def check_peak_collection(peak_shape, NUM_SUBRUN, target_errors,
"""
subruns = np.arange(NUM_SUBRUN) + 1
chisq = np.array([42., 43.])
- raw_peaks_array = np.zeros(NUM_SUBRUN, dtype=get_parameter_dtype(peak_shape, 'Linear'))
+ raw_peaks_array = np.zeros(NUM_SUBRUN, dtype=get_parameter_dtype(peak_shape, background))
if peak_shape == 'PseudoVoigt':
raw_peaks_array['Intensity'] = [1, 2]
raw_peaks_array['FWHM'] = np.array([4, 5], dtype=float)
@@ -96,11 +96,11 @@ def check_peak_collection(peak_shape, NUM_SUBRUN, target_errors,
raw_peaks_array['PeakCentre'] = [90., 91.]
# background terms are both zeros
- raw_peaks_errors = np.zeros(NUM_SUBRUN, dtype=get_parameter_dtype(peak_shape, 'Linear'))
+ raw_peaks_errors = np.zeros(NUM_SUBRUN, dtype=get_parameter_dtype(peak_shape, background))
if wavelength is None:
- peaks = PeakCollection('testing', peak_shape, 'Linear')
+ peaks = PeakCollection('testing', peak_shape, background)
else:
- peaks = PeakCollection('testing', peak_shape, 'Linear', wavelength=wavelength)
+ peaks = PeakCollection('testing', peak_shape, background, wavelength=wavelength)
# uncertainties are being set to zero
peaks.set_peak_fitting_values(subruns, raw_peaks_array,
@@ -118,6 +118,7 @@ def check_peak_collection(peak_shape, NUM_SUBRUN, target_errors,
obs_raw_peaks, obs_raw_errors = peaks.get_native_params()
np.testing.assert_equal(obs_raw_peaks, raw_peaks_array)
np.testing.assert_equal(obs_raw_errors, raw_peaks_errors)
+
# check effective parameters
obs_eff_peaks, obs_eff_errors = peaks.get_effective_params()
assert obs_eff_peaks.size == NUM_SUBRUN
@@ -156,9 +157,15 @@ def check_peak_collection(peak_shape, NUM_SUBRUN, target_errors,
def test_peak_collection_Gaussian():
NUM_SUBRUN = 2
# without wavelength
- check_peak_collection('Gaussian', NUM_SUBRUN, np.zeros(NUM_SUBRUN, dtype=get_parameter_dtype(effective=True)))
+ check_peak_collection('Gaussian', 'Linear', NUM_SUBRUN,
+ np.array([(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01),
+ (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01)],
+ dtype=get_parameter_dtype(effective=True))) # Error array
# with wavelength
- check_peak_collection('Gaussian', NUM_SUBRUN, np.zeros(NUM_SUBRUN, dtype=get_parameter_dtype(effective=True)),
+ check_peak_collection('Gaussian', 'Linear', NUM_SUBRUN,
+ np.array([(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01),
+ (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01)],
+ dtype=get_parameter_dtype(effective=True)),
wavelength=1.53229, d_reference=1.08, target_d_spacing_center=[1.08, 1.07],
target_d_spacing_center_error=[0.0, 0.0], target_strain=[3234., -5408.],
target_strain_error=[0.0, 0.0])
@@ -167,14 +174,48 @@ def test_peak_collection_Gaussian():
def test_peak_collection_PseudoVoigt():
NUM_SUBRUN = 2
# without wavelength
- check_peak_collection('PseudoVoigt', NUM_SUBRUN,
- np.array([(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
- (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)],
+ check_peak_collection('PseudoVoigt', 'Linear', NUM_SUBRUN,
+ np.array([(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01),
+ (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01)],
+ dtype=get_parameter_dtype(effective=True)))
+ # with wavelength
+ check_peak_collection('PseudoVoigt', 'Linear', NUM_SUBRUN,
+ np.array([(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01),
+ (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01)],
+ dtype=get_parameter_dtype(effective=True)),
+ wavelength=1.53229, d_reference=1.08, target_d_spacing_center=[1.08, 1.07],
+ target_d_spacing_center_error=[0.0, 0.0], target_strain=[3234., -5408.],
+ target_strain_error=[0.0, 0.0])
+
+
+def test_peak_collection_Gaussian_Quadratic():
+ NUM_SUBRUN = 2
+ # without wavelength
+ check_peak_collection('Gaussian', 'Quadratic', NUM_SUBRUN,
+ np.array([(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
+ (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)],
+ dtype=get_parameter_dtype(effective=True))) # Error array
+ # with wavelength
+ check_peak_collection('Gaussian', 'Quadratic', NUM_SUBRUN,
+ np.array([(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
+ (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)],
+ dtype=get_parameter_dtype(effective=True)),
+ wavelength=1.53229, d_reference=1.08, target_d_spacing_center=[1.08, 1.07],
+ target_d_spacing_center_error=[0.0, 0.0], target_strain=[3234., -5408.],
+ target_strain_error=[0.0, 0.0])
+
+
+def test_peak_collection_PseudoVoigt_Quadratic():
+ NUM_SUBRUN = 2
+ # without wavelength
+ check_peak_collection('PseudoVoigt', 'Quadratic', NUM_SUBRUN,
+ np.array([(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
+ (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)],
dtype=get_parameter_dtype(effective=True)))
# with wavelength
- check_peak_collection('PseudoVoigt', NUM_SUBRUN,
- np.array([(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
- (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)],
+ check_peak_collection('PseudoVoigt', 'Quadratic', NUM_SUBRUN,
+ np.array([(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
+ (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)],
dtype=get_parameter_dtype(effective=True)),
wavelength=1.53229, d_reference=1.08, target_d_spacing_center=[1.08, 1.07],
target_d_spacing_center_error=[0.0, 0.0], target_strain=[3234., -5408.],
diff --git a/tests/unit/pyrs/peaks/test_peak_fit_engine.py b/tests/unit/pyrs/peaks/test_peak_fit_engine.py
index 0c101d1fc..fb82026b7 100644
--- a/tests/unit/pyrs/peaks/test_peak_fit_engine.py
+++ b/tests/unit/pyrs/peaks/test_peak_fit_engine.py
@@ -372,7 +372,7 @@ def test_2_gaussian_1_subrun(setup_1_subrun, fit_domain):
fit_costs = fit_result.peakcollections[0].fitting_costs
eff_param_values, eff_param_errors = fit_result.peakcollections[0].get_effective_params()
assert eff_param_values.size == 1, '1 sub run'
- assert len(eff_param_values.dtype.names) == 7, '7 effective parameters'
+ assert len(eff_param_values.dtype.names) == 8, '8 effective parameters'
'''
if abs(eff_param_values[2][0] - expected_intensity) < 1E-03:
plt.plot(data_x, data_y, label='Test 2 Gaussian')
@@ -492,7 +492,7 @@ def test_2_gaussian_3_subruns(target_values):
# Get effective peak parameters
effective_param_values, effective_param_errors = fit_result.peakcollections[0].get_effective_params()
assert effective_param_values.size == 3, '3 subruns'
- assert len(effective_param_values.dtype.names) == 7, '7 effective parameters'
+ assert len(effective_param_values.dtype.names) == 8, '8 effective parameters'
# TODO it is odd that there are only two in the the setup function and 3 in the result
np.testing.assert_allclose(param_values_lp['Height'][:2], target_values['peak_height'], atol=20.)
@@ -503,7 +503,7 @@ def test_2_gaussian_3_subruns(target_values):
effective_param_values, effective_param_errors = fit_result.peakcollections[1].get_effective_params()
assert effective_param_values.size == 3, '3 subruns'
- assert len(effective_param_values.dtype.names) == 7, '7 effective parameters'
+ assert len(effective_param_values.dtype.names) == 8, '8 effective parameters'
# Plot
# model_x, model_y = fit_engine.calculate_fitted_peaks(3, None)