From 05f5d9ee16fcda4f7da6013bb4d8089d55169c3c Mon Sep 17 00:00:00 2001 From: Marie Backman Date: Mon, 9 Dec 2024 14:24:34 -0500 Subject: [PATCH] - make the minimum number of events in a workspace a configuration parameter - filter out workspaces with too few events before applying dead-time correction - add user docs on advanced parameters --- docs/user/advanced_parameters.rst | 15 ++++++++++ docs/user/index.rst | 1 + reflectivity_ui/interfaces/configuration.py | 10 +++++++ .../interfaces/data_handling/data_set.py | 2 +- .../interfaces/data_handling/instrument.py | 28 ++++++++++++++++++- test/data/reflectivity_ui-data | 2 +- .../data_handling/test_instrument.py | 23 +++++++++++++++ 7 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 docs/user/advanced_parameters.rst diff --git a/docs/user/advanced_parameters.rst b/docs/user/advanced_parameters.rst new file mode 100644 index 0000000..0dc011b --- /dev/null +++ b/docs/user/advanced_parameters.rst @@ -0,0 +1,15 @@ +.. _advanced_parameters: + +Advanced parameters +=================== + +Advanced parameters are only configurable in the local configuration file +``~/.config/.refredm.conf``. + +``nbr_events_min`` +------------------ + +Default: 100 + +During loading of data files and direct beam files, any polarization cross-section event workspaces +with number of events below this cut-off will be ignored. diff --git a/docs/user/index.rst b/docs/user/index.rst index 62ae412..33f1733 100644 --- a/docs/user/index.rst +++ b/docs/user/index.rst @@ -9,3 +9,4 @@ TODO :maxdepth: 2 dead_time_correction + advanced_parameters diff --git a/reflectivity_ui/interfaces/configuration.py b/reflectivity_ui/interfaces/configuration.py index 70ee775..d2613a2 100644 --- a/reflectivity_ui/interfaces/configuration.py +++ b/reflectivity_ui/interfaces/configuration.py @@ -44,6 +44,9 @@ class Configuration(object): deadtime_tof_step = 100 # Direct beam uses the same low res roi as the data run lock_direct_beam_y = False + # Number of events below which we throw away a workspace + # Note: not exposed in the UI, but can be modified in ~/.config/.refredm.conf + nbr_events_min = 100 def __init__(self, settings=None): self.instrument = Instrument() @@ -241,6 +244,9 @@ def to_q_settings(self, settings): settings.setValue("deadtime_value", self.deadtime_value) settings.setValue("deadtime_tof_step", self.deadtime_tof_step) + # Number of events below which we throw away a workspace + settings.setValue("nbr_events_min", self.nbr_events_min) + # Off-specular options settings.setValue("off_spec_x_axis", self.off_spec_x_axis) settings.setValue("off_spec_slice", self.off_spec_slice) @@ -346,6 +352,9 @@ def _verify_true(parameter, default): Configuration.deadtime_value = float(settings.value("deadtime_value", self.deadtime_value)) Configuration.deadtime_tof_step = float(settings.value("deadtime_tof_step", self.deadtime_tof_step)) + # Number of events below which we throw away a workspace + Configuration.nbr_events_min = int(settings.value("nbr_events_min", self.nbr_events_min)) + # Off-specular options self.off_spec_x_axis = int(settings.value("off_spec_x_axis", self.off_spec_x_axis)) self.off_spec_slice = _verify_true("off_spec_slice", self.off_spec_slice) @@ -403,6 +412,7 @@ def setup_default_values(cls): cls.deadtime_value = 4.2 cls.deadtime_tof_step = 100 cls.lock_direct_beam_y = False + cls.nbr_events_min = 100 def get_direct_beam_low_res_roi(data_conf, direct_beam_conf): diff --git a/reflectivity_ui/interfaces/data_handling/data_set.py b/reflectivity_ui/interfaces/data_handling/data_set.py index a6b0e49..1d862e1 100644 --- a/reflectivity_ui/interfaces/data_handling/data_set.py +++ b/reflectivity_ui/interfaces/data_handling/data_set.py @@ -431,7 +431,7 @@ def load(self, update_parameters=True, progress=None): # Get rid of empty workspaces logging.info("Loading %s: %s events", str(channel), ws.getNumberEvents()) - if ws.getNumberEvents() < N_EVENTS_CUTOFF: + if ws.getNumberEvents() < self.configuration.nbr_events_min: logging.warning("Too few events for %s: %s", channel, ws.getNumberEvents()) continue diff --git a/reflectivity_ui/interfaces/data_handling/instrument.py b/reflectivity_ui/interfaces/data_handling/instrument.py index d75a485..5ad9adf 100644 --- a/reflectivity_ui/interfaces/data_handling/instrument.py +++ b/reflectivity_ui/interfaces/data_handling/instrument.py @@ -212,7 +212,6 @@ def load_data(self, file_path, configuration=None): """ fp_instance = FilePath(file_path) xs_list = list() - err_list = list() temp_workspace_root_name = "".join(random.sample(string.ascii_letters, 12)) # random string of 12 characters workspace_root_name = fp_instance.run_numbers(string_representation="short") for path in fp_instance.single_paths: @@ -231,6 +230,8 @@ def load_data(self, file_path, configuration=None): logging.warning("Could not filter data, using getDI") ws = api.LoadEventNexus(Filename=path, OutputWorkspace="raw_events") _path_xs_list = self.dummy_filter_cross_sections(ws, name_prefix=temp_workspace_root_name) + # Remove workspaces with too few events + _path_xs_list = self.remove_low_event_workspaces(_path_xs_list, configuration.nbr_events_min) if configuration is not None and configuration.apply_deadtime: # Load error events from the bank_error_events entry err_ws = api.LoadErrorEventsNexus(path) @@ -424,3 +425,28 @@ def integrate_detector(self, ws, specular=True): integrated = api.Integration(ws_summed) integrated = api.Transpose(integrated) return integrated + + @staticmethod + def remove_low_event_workspaces(ws_list, nbr_events_cutoff): + """ + Removes workspaces with number of events below the cutoff from a list of workspaces + + Parameters + ---------- + ws_list: list[EventWorkspace] + nbr_events_cutoff: int + Minimum number of events + + Returns + ------- + list[EventWorkspace] + Input list with low event workspaces removes + """ + pruned_list = [] + for ws in ws_list: + xs_name = ws.getRun()["cross_section_id"].value + if ws.getNumberEvents() < nbr_events_cutoff: + logging.warning("Too few events for %s: %s", xs_name, ws.getNumberEvents()) + else: + pruned_list.append(ws) + return pruned_list diff --git a/test/data/reflectivity_ui-data b/test/data/reflectivity_ui-data index e389ecf..702ae75 160000 --- a/test/data/reflectivity_ui-data +++ b/test/data/reflectivity_ui-data @@ -1 +1 @@ -Subproject commit e389ecfecc531b50168df1af8597acf21b849e44 +Subproject commit 702ae7524589c371fa3e6c2901e8f29b021d178c diff --git a/test/unit/reflectivity_ui/interfaces/data_handling/test_instrument.py b/test/unit/reflectivity_ui/interfaces/data_handling/test_instrument.py index 5bc1d6a..be6a0e1 100644 --- a/test/unit/reflectivity_ui/interfaces/data_handling/test_instrument.py +++ b/test/unit/reflectivity_ui/interfaces/data_handling/test_instrument.py @@ -59,3 +59,26 @@ def PyExec(self): custom_value = 4 ws_out = mantid_algorithm_exec(TestMantidAlgo, Value=custom_value, OutputWorkspace="output") assert ws_out.readY(0)[0] == custom_value + + +@pytest.mark.datarepo +def test_load_data_nbr_events_min(data_server): + """Test load data with one cross-section with too few events""" + conf = Configuration() + file_path = data_server.path_to("REF_M_40776") + + # load with no cut-off on number of events + conf.nbr_events_min = 0 + ws_list = conf.instrument.load_data(file_path, conf) + assert len(ws_list) == 3 + + # load with cut-off on number of events + conf.nbr_events_min = 100 + ws_list = conf.instrument.load_data(file_path, conf) + assert len(ws_list) == 2 + + # test loading with dead-time correction + conf.nbr_events_min = 100 + conf.apply_deadtime = True + ws_list = conf.instrument.load_data(file_path, conf) + assert len(ws_list) == 2