diff --git a/src/shiver/configuration_template.ini b/src/shiver/configuration_template.ini index 78b79d4..0c7ae6f 100644 --- a/src/shiver/configuration_template.ini +++ b/src/shiver/configuration_template.ini @@ -12,5 +12,11 @@ display_title = full #the flag (bool: True/False) indicates the plot scale (logarithmic or not) logarithmic_intensity = False +[main_tab.sample_logs] +#the flag (bool = True/False) indicates whether the data are saved as sample logs in the MDHistogram workspace +save_instrument = True +save_sample = True +save_logs = True + [global.other] help_url = https://neutrons.github.io/Shiver/GUI/ diff --git a/src/shiver/models/convert_dgs_to_single_mde.py b/src/shiver/models/convert_dgs_to_single_mde.py index c28aa4d..234bec4 100644 --- a/src/shiver/models/convert_dgs_to_single_mde.py +++ b/src/shiver/models/convert_dgs_to_single_mde.py @@ -36,7 +36,6 @@ FileAction, ) from mantid.kernel import ( - config, Direction, Property, StringArrayProperty, @@ -247,7 +246,6 @@ def validateInputs(self): return issues def PyExec(self): # pylint: disable=too-many-branches - config["default.facility"] = "SNS" # get properties data = self.getProperty("InputWorkspace").value data_m = self.getProperty("InputMonitorWorkspace").value diff --git a/src/shiver/models/histogram.py b/src/shiver/models/histogram.py index 7a4917f..e6b5509 100644 --- a/src/shiver/models/histogram.py +++ b/src/shiver/models/histogram.py @@ -26,7 +26,7 @@ SpaceGroupFactory, PointGroupFactory, ) - +from shiver.configuration import get_data from shiver.models.generate import GenerateModel from shiver.models.polarized import PolarizedModel @@ -195,8 +195,19 @@ def rename(self, old_name, new_name): def save(self, ws_name, filename): """Save the workspace to Nexus file.""" - save_params = {"SaveInstrument": False, "SaveSample": False, "SaveLogs": False} - SaveMD(ws_name, filename, **save_params) + save_instrument = get_data("main_tab.sample_logs", "save_instrument") + save_sample = get_data("main_tab.sample_logs", "save_sample") + save_logs = get_data("main_tab.sample_logs", "save_logs") + + if isinstance(save_instrument, bool) and isinstance(save_sample, bool) and isinstance(save_logs, bool): + save_params = {"SaveInstrument": save_instrument, "SaveSample": save_sample, "SaveLogs": save_logs} + print("here", save_instrument, save_sample, save_logs) + SaveMD(ws_name, filename, **save_params) + else: + if self.error_callback: + err = "Save_logs in configuration file has invalid input. Please update it and try again." + logger.error(err) + self.error_callback(err) def save_to_ascii( self, diff --git a/src/shiver/models/sample.py b/src/shiver/models/sample.py index d70f259..c989c5e 100644 --- a/src/shiver/models/sample.py +++ b/src/shiver/models/sample.py @@ -12,6 +12,7 @@ LoadNexusProcessed, LoadMD, ) +from mantid.api import AlgorithmManager from mantid.geometry import OrientedLattice from mantid.kernel import Logger from mantidqtinterfaces.DGSPlanner.LoadNexusUB import LoadNexusUB @@ -164,11 +165,11 @@ def load_nexus_processed(self, filename): def is_nexus_processed(self, filename): """Return true if the file is NexusProcessed - can be loaded through LoadNexusProcessed, else false""" - try: - _ = LoadNexusProcessed(filename) - return True - except RuntimeError: - return False + + alg = AlgorithmManager.create("Load") + alg.initialize() + alg.setProperty("Filename", filename) + return alg.getProperty("LoaderName").value == "LoadNexusProcessed" def load_nexus_ub(self, filename): """Mantid SetUB with Nexus file""" diff --git a/tests/models/test_generatemde.py b/tests/models/test_generatemde.py index e8a21bf..64d0400 100644 --- a/tests/models/test_generatemde.py +++ b/tests/models/test_generatemde.py @@ -1,7 +1,14 @@ """Tests for the ConvertDGSToSingleMDE algorithm""" import os from pytest import approx, raises -from mantid.simpleapi import ( # pylint: disable=no-name-in-module +from mantid.kernel import amend_config + +# Need to import the new algorithms so they are registered with mantid +import shiver.models.convert_dgs_to_single_mde # noqa: F401, E402 pylint: disable=unused-import, wrong-import-order +import shiver.models.generate_dgs_mde # noqa: F401, E402 pylint: disable=unused-import, wrong-import-order + +from mantid.simpleapi import ( # pylint: disable=no-name-in-module, ungrouped-imports + ConfigService, ConvertDGSToSingleMDE, GenerateDGSMDE, MergeMD, @@ -142,6 +149,34 @@ def test_convert_dgs_to_single_mde_calculate_t0_ei(): assert md1.getExperimentInfo(0).run()["Ei"].value == 25 +def test_convert_dgs_to_single_mde_facility(): + """Test for ConvertDGSToSingleMDE facility""" + + with amend_config(facility="HFIR"): + facility = ConfigService.getFacility().name() + assert facility == "HFIR" + print("facility", facility) + data_files = [ + "HYS_178921.nxs.h5", + "HYS_178922.nxs.h5", + "HYS_178923.nxs.h5", + "HYS_178924.nxs.h5", + "HYS_178925.nxs.h5", + "HYS_178926.nxs.h5", + ] + + raw_data_folder = os.path.join(os.path.dirname(__file__), "../data/raw") + + _ = GenerateDGSMDE( + Filenames=",".join(os.path.join(raw_data_folder, data_file) for data_file in data_files), + Ei=25.0, + T0=112.0, + TimeIndependentBackground="Default", + ) + print("facility", facility) + assert ConfigService.getFacility().name() == "HFIR" + + def test_convert_dgs_to_single_mde_merged(): """Test for merging results and compare to existing data ConvertDGSToSingleMDE""" @@ -257,17 +292,17 @@ def test_generate_dgs_mde_seq(): LoadNexusMonitors(Filename=datafile, OutputWorkspace="__MonWS") e_i, t_0 = GetEiT0atSNS(MonitorWorkspace="__MonWS", IncidentEnergyGuess="35") - - DgsReduction( - SampleInputWorkspace="data", - SampleInputMonitorWorkspace="__MonWS", - IncidentEnergyGuess=e_i, - UseIncidentEnergyGuess=True, - TimeZeroGuess=t_0, - EnergyTransferRange="-17.5,1,31.5", - SofPhiEIsDistribution=False, - OutputWorkspace="dgs", - ) + with amend_config(facility="SNS"): + DgsReduction( + SampleInputWorkspace="data", + SampleInputMonitorWorkspace="__MonWS", + IncidentEnergyGuess=e_i, + UseIncidentEnergyGuess=True, + TimeZeroGuess=t_0, + EnergyTransferRange="-17.5,1,31.5", + SofPhiEIsDistribution=False, + OutputWorkspace="dgs", + ) CropWorkspace(InputWorkspace="dgs", OutputWorkspace="dgs", XMin="-17.5", XMax="31.5") min_values, max_values = ConvertToMDMinMaxGlobal( InputWorkspace="dgs", QDimensions="Q3D", dEAnalysisMode="Direct", Q3DFrames="Q" diff --git a/tests/models/test_histogram_saving.py b/tests/models/test_histogram_saving.py index 9530152..ec7b259 100644 --- a/tests/models/test_histogram_saving.py +++ b/tests/models/test_histogram_saving.py @@ -2,7 +2,12 @@ # pylint: disable=too-many-lines import os import ast +import h5py +import pytest from pytest import approx + +# Need to import the new algorithms so they are registered with mantid +import shiver.models.makeslice # noqa: F401, E402 pylint: disable=unused-import, wrong-import-order from mantid.simpleapi import ( # pylint: disable=no-name-in-module CreateMDHistoWorkspace, CompareMDWorkspaces, @@ -55,6 +60,242 @@ def test_saving(tmp_path): ) +@pytest.mark.parametrize( + "user_conf_file", + [ + """ + [main_tab.sample_logs] + save_instrument = True + save_sample = False + save_logs = False + """ + ], + indirect=True, +) +def test_save_with_save_instrument(user_conf_file, monkeypatch, tmp_path): + """Test saving with Nexus and save_instrument set to True""" + + # mock get sample_logs info + monkeypatch.setattr("shiver.configuration.CONFIG_PATH_FILE", user_conf_file) + + # clear mantid workspace + mtd.clear() + + workspace = "test_workspace" + filepath = f"{tmp_path}/{workspace}.nxs" + + # load mde workspace + LoadMD( + Filename=os.path.join(os.path.dirname(os.path.abspath(__file__)), "../data/mde/px_mini_NSF.nxs"), + OutputWorkspace="data", + ) + + MakeSlice( + InputWorkspace="data", + BackgroundWorkspace=None, + NormalizationWorkspace=None, + QDimension0="0,0,1", + QDimension1="1,1,0", + QDimension2="-1,1,0", + Dimension0Name="QDimension1", + Dimension0Binning="0.35,0.025,0.65", + Dimension1Name="QDimension0", + Dimension1Binning="0.45,0.55", + Dimension2Name="QDimension2", + Dimension2Binning="-0.2,0.2", + Dimension3Name="DeltaE", + Dimension3Binning="-0.5,0.5", + SymmetryOperations=None, + Smoothing=1, + OutputWorkspace=workspace, + ) + model = HistogramModel() + model.save(workspace, filepath) + + with h5py.File(filepath, "r") as file_data: + assert "experiment0" in file_data["MDHistoWorkspace"] + assert "instrument" in file_data["MDHistoWorkspace"]["experiment0"] + assert "logs" not in file_data["MDHistoWorkspace"]["experiment0"] + assert "sample" not in file_data["MDHistoWorkspace"]["experiment0"] + + +@pytest.mark.parametrize( + "user_conf_file", + [ + """ + [main_tab.sample_logs] + save_instrument = False + save_sample = True + save_logs = False + """ + ], + indirect=True, +) +def test_save_with_save_sample(user_conf_file, monkeypatch, tmp_path): + """Test saving with Nexus and save_sample set to True""" + + # mock get sample_logs info + monkeypatch.setattr("shiver.configuration.CONFIG_PATH_FILE", user_conf_file) + + # clear mantid workspace + mtd.clear() + + workspace = "test_workspace" + filepath = f"{tmp_path}/{workspace}.nxs" + + # load mde workspace + LoadMD( + Filename=os.path.join(os.path.dirname(os.path.abspath(__file__)), "../data/mde/px_mini_NSF.nxs"), + OutputWorkspace="data", + ) + + MakeSlice( + InputWorkspace="data", + BackgroundWorkspace=None, + NormalizationWorkspace=None, + QDimension0="0,0,1", + QDimension1="1,1,0", + QDimension2="-1,1,0", + Dimension0Name="QDimension1", + Dimension0Binning="0.35,0.025,0.65", + Dimension1Name="QDimension0", + Dimension1Binning="0.45,0.55", + Dimension2Name="QDimension2", + Dimension2Binning="-0.2,0.2", + Dimension3Name="DeltaE", + Dimension3Binning="-0.5,0.5", + SymmetryOperations=None, + Smoothing=1, + OutputWorkspace=workspace, + ) + + model = HistogramModel() + model.save(workspace, filepath) + + with h5py.File(filepath, "r") as file_data: + assert "experiment0" in file_data["MDHistoWorkspace"] + assert "instrument" not in file_data["MDHistoWorkspace"]["experiment0"] + assert "logs" not in file_data["MDHistoWorkspace"]["experiment0"] + assert "sample" in file_data["MDHistoWorkspace"]["experiment0"] + + +@pytest.mark.parametrize( + "user_conf_file", + [ + """ + [main_tab.sample_logs] + save_instrument = False + save_sample = False + save_logs = True + """ + ], + indirect=True, +) +def test_save_with_save_logs(user_conf_file, monkeypatch, tmp_path): + """Test saving with Nexus and save_logs set to True""" + + # mock get sample_logs info + monkeypatch.setattr("shiver.configuration.CONFIG_PATH_FILE", user_conf_file) + + # clear mantid workspace + mtd.clear() + + workspace = "test_workspace" + filepath = f"{tmp_path}/{workspace}.nxs" + + # load mde workspace + LoadMD( + Filename=os.path.join(os.path.dirname(os.path.abspath(__file__)), "../data/mde/px_mini_NSF.nxs"), + OutputWorkspace="data", + ) + + MakeSlice( + InputWorkspace="data", + BackgroundWorkspace=None, + NormalizationWorkspace=None, + QDimension0="0,0,1", + QDimension1="1,1,0", + QDimension2="-1,1,0", + Dimension0Name="QDimension1", + Dimension0Binning="0.35,0.025,0.65", + Dimension1Name="QDimension0", + Dimension1Binning="0.45,0.55", + Dimension2Name="QDimension2", + Dimension2Binning="-0.2,0.2", + Dimension3Name="DeltaE", + Dimension3Binning="-0.5,0.5", + SymmetryOperations=None, + Smoothing=1, + OutputWorkspace=workspace, + ) + + model = HistogramModel() + model.save(workspace, filepath) + + with h5py.File(filepath, "r") as file_data: + assert "experiment0" in file_data["MDHistoWorkspace"] + assert "instrument" not in file_data["MDHistoWorkspace"]["experiment0"] + assert "logs" in file_data["MDHistoWorkspace"]["experiment0"] + assert "sample" not in file_data["MDHistoWorkspace"]["experiment0"] + + +@pytest.mark.parametrize( + "user_conf_file", + [ + """ + [main_tab.sample_logs] + save_instrument = False + save_sample = False + save_logs = False + """ + ], + indirect=True, +) +def test_save_with_no_save_sample_logs(user_conf_file, monkeypatch, tmp_path): + """Test saving with Nexus and sample_logs set to False""" + + # mock get sample_logs info + monkeypatch.setattr("shiver.configuration.CONFIG_PATH_FILE", user_conf_file) + + # clear mantid workspace + mtd.clear() + + workspace = "test_workspace" + filepath = f"{tmp_path}/{workspace}.nxs" + + # load mde workspace + LoadMD( + Filename=os.path.join(os.path.dirname(os.path.abspath(__file__)), "../data/mde/px_mini_NSF.nxs"), + OutputWorkspace="data", + ) + + MakeSlice( + InputWorkspace="data", + BackgroundWorkspace=None, + NormalizationWorkspace=None, + QDimension0="0,0,1", + QDimension1="1,1,0", + QDimension2="-1,1,0", + Dimension0Name="QDimension1", + Dimension0Binning="0.35,0.025,0.65", + Dimension1Name="QDimension0", + Dimension1Binning="0.45,0.55", + Dimension2Name="QDimension2", + Dimension2Binning="-0.2,0.2", + Dimension3Name="DeltaE", + Dimension3Binning="-0.5,0.5", + SymmetryOperations=None, + Smoothing=1, + OutputWorkspace=workspace, + ) + + model = HistogramModel() + model.save(workspace, filepath) + + with h5py.File(filepath, "r") as file_data: + assert "experiment0" not in file_data["MDHistoWorkspace"] + + def test_experiment_sample_log_valid(tmp_path): """Test the polarization state is retrieved as a sample log in the workspace: unpolarized state""" @@ -1080,8 +1321,7 @@ def mock_finish(workspaces, error): def test_save_mde_workspace(shiver_app): """Test the MDEConfig in save mde workspace.""" - shiver = shiver_app - histogram_presenter = shiver.main_window.histogram_presenter + histogram_presenter = shiver_app.main_window.histogram_presenter # clear mantid workspace mtd.clear()