From eaa32fcf1c5735316f7ab26ef41cfaaa5696721e Mon Sep 17 00:00:00 2001 From: Martyn Gigg <martyn.gigg@gmail.com> Date: Fri, 2 Aug 2019 17:38:52 +0100 Subject: [PATCH] Move vanadium spline/peak masking to abstract instrument This makes it the default behaviour unless overridden, like GEM and PEARL. Refs #23731 --- .../Diffraction/isis_powder/abstract_inst.py | 12 +++- scripts/Diffraction/isis_powder/gem.py | 4 ++ scripts/Diffraction/isis_powder/hrpd.py | 6 -- .../hrpd_routines/hrpd_advanced_config.py | 1 + .../hrpd_routines/hrpd_param_mapping.py | 1 + scripts/Diffraction/isis_powder/polaris.py | 10 --- .../isis_powder/routines/common.py | 70 ++++++++++++++++--- 7 files changed, 76 insertions(+), 28 deletions(-) diff --git a/scripts/Diffraction/isis_powder/abstract_inst.py b/scripts/Diffraction/isis_powder/abstract_inst.py index 2c1bc9ee0ec..d5644f8b925 100644 --- a/scripts/Diffraction/isis_powder/abstract_inst.py +++ b/scripts/Diffraction/isis_powder/abstract_inst.py @@ -141,9 +141,15 @@ class AbstractInst(object): :param focused_vanadium_banks: The list processed (and cropped) vanadium banks to take a spline of :return: The splined vanadium workspaces as a list """ - # XXX: Although this could be moved to common if enough instruments spline the same way and have - # the instrument override the optional behaviour - raise NotImplementedError("spline_vanadium_ws must be implemented per instrument") + if self._inst_settings.masking_file_name is not None: + masking_file_path = os.path.join(self.calibration_dir, + self._inst_settings.masking_file_name) + bragg_mask_list = common.read_masking_file(masking_file_path) + focused_vanadium_banks = common.apply_bragg_peaks_masking(focused_vanadium_banks, + mask_list=bragg_mask_list) + output = common.spline_workspaces(focused_vanadium_spectra=focused_vanadium_banks, + num_splines=self._inst_settings.spline_coeff) + return output def _crop_banks_to_user_tof(self, focused_banks): """ diff --git a/scripts/Diffraction/isis_powder/gem.py b/scripts/Diffraction/isis_powder/gem.py index 075ed239dda..262a7c18ad5 100644 --- a/scripts/Diffraction/isis_powder/gem.py +++ b/scripts/Diffraction/isis_powder/gem.py @@ -209,6 +209,10 @@ class Gem(AbstractInst): return self._inst_settings.unit_to_keep def _spline_vanadium_ws(self, focused_vanadium_banks): + """ + GEM uses a Vanadium-Niobium mix and doesn't need to strip any Vanadium Bragg peaks + before splining + """ return common.spline_vanadium_workspaces(focused_vanadium_spectra=focused_vanadium_banks, spline_coefficient=self._inst_settings.spline_coeff) diff --git a/scripts/Diffraction/isis_powder/hrpd.py b/scripts/Diffraction/isis_powder/hrpd.py index 14f4cb7be34..748787090f4 100644 --- a/scripts/Diffraction/isis_powder/hrpd.py +++ b/scripts/Diffraction/isis_powder/hrpd.py @@ -149,12 +149,6 @@ class HRPD(AbstractInst): max_crop = middle + right_crop mantid.MaskBins(InputWorkspace=ws, OutputWorkspace=ws, XMin=min_crop, XMax=max_crop) - def _spline_vanadium_ws(self, focused_vanadium_banks, instrument_version=''): - spline_coeff = self._inst_settings.spline_coeff - output = hrpd_algs.process_vanadium_for_focusing(bank_spectra=focused_vanadium_banks, - spline_number=spline_coeff) - return output - def _switch_tof_window_inst_settings(self, tof_window): self._inst_settings.update_attributes( advanced_config=hrpd_advanced_config.get_tof_window_dict(tof_window=tof_window)) diff --git a/scripts/Diffraction/isis_powder/hrpd_routines/hrpd_advanced_config.py b/scripts/Diffraction/isis_powder/hrpd_routines/hrpd_advanced_config.py index fc724b05a69..2adac4400ca 100644 --- a/scripts/Diffraction/isis_powder/hrpd_routines/hrpd_advanced_config.py +++ b/scripts/Diffraction/isis_powder/hrpd_routines/hrpd_advanced_config.py @@ -64,6 +64,7 @@ window_180_280_params = { } file_names = { + "vanadium_peaks_masking_file": "VanaPeaks.dat", "grouping_file_name": "hrpd_new_072_01_corr.cal" } diff --git a/scripts/Diffraction/isis_powder/hrpd_routines/hrpd_param_mapping.py b/scripts/Diffraction/isis_powder/hrpd_routines/hrpd_param_mapping.py index 471d5a8aaaf..02eb39434b1 100644 --- a/scripts/Diffraction/isis_powder/hrpd_routines/hrpd_param_mapping.py +++ b/scripts/Diffraction/isis_powder/hrpd_routines/hrpd_param_mapping.py @@ -33,5 +33,6 @@ attr_mapping = \ ParamMapEntry(ext_name="user_name", int_name="user_name"), ParamMapEntry(ext_name="vanadium_normalisation", int_name="do_van_norm"), ParamMapEntry(ext_name="vanadium_tof_cropping", int_name="van_tof_cropping"), + ParamMapEntry(ext_name="vanadium_peaks_masking_file", int_name="masking_file_name"), ParamMapEntry(ext_name="window", int_name="tof_window", enum_class=HRPD_TOF_WINDOWS) ] diff --git a/scripts/Diffraction/isis_powder/polaris.py b/scripts/Diffraction/isis_powder/polaris.py index 496cfc40410..2a2e8bd9d05 100644 --- a/scripts/Diffraction/isis_powder/polaris.py +++ b/scripts/Diffraction/isis_powder/polaris.py @@ -6,7 +6,6 @@ # SPDX - License - Identifier: GPL - 3.0 + from __future__ import (absolute_import, division, print_function) -import os from isis_powder.routines import absorb_corrections, common, instrument_settings from isis_powder.abstract_inst import AbstractInst @@ -134,15 +133,6 @@ class Polaris(AbstractInst): return self._run_details_cached_obj[run_number_string_key] - def _spline_vanadium_ws(self, focused_vanadium_spectra, instrument_version=''): - masking_file_name = self._inst_settings.masking_file_name - spline_coeff = self._inst_settings.spline_coeff - masking_file_path = os.path.join(self.calibration_dir, masking_file_name) - output = polaris_algs.process_vanadium_for_focusing(bank_spectra=focused_vanadium_spectra, - spline_number=spline_coeff, - mask_path=masking_file_path) - return output - def _switch_mode_specific_inst_settings(self, mode): if mode is None and hasattr(self._inst_settings, "mode"): mode = self._inst_settings.mode diff --git a/scripts/Diffraction/isis_powder/routines/common.py b/scripts/Diffraction/isis_powder/routines/common.py index c1915bac8d9..58324df1c28 100644 --- a/scripts/Diffraction/isis_powder/routines/common.py +++ b/scripts/Diffraction/isis_powder/routines/common.py @@ -5,7 +5,7 @@ # & Institut Laue - Langevin # SPDX - License - Identifier: GPL - 3.0 + from __future__ import (absolute_import, division, print_function) -from six import iterkeys +from six import PY2, iterkeys import warnings import mantid.kernel as kernel @@ -13,6 +13,24 @@ import mantid.simpleapi as mantid from isis_powder.routines.common_enums import INPUT_BATCHING, WORKSPACE_UNITS +def apply_bragg_peaks_masking(workspaces_to_mask, mask_list): + """ + Mask a series of peaks defined by the lower/upper bounds + :param workspaces_to_mask: Mask these workspaces + :param mask_list: A list of pairs of peak X min/max for masking + :return: A list of masked workspaces + """ + output_workspaces = list(workspaces_to_mask) + + for ws_index, (bank_mask_list, workspace) in enumerate(zip(mask_list, output_workspaces)): + output_name = "masked_vanadium-" + str(ws_index + 1) + for mask_params in bank_mask_list: + output_workspaces[ws_index] = mantid.MaskBins(InputWorkspace=output_workspaces[ws_index], + OutputWorkspace=output_name, + XMin=mask_params[0], XMax=mask_params[1]) + return output_workspaces + + def cal_map_dictionary_key_helper(dictionary, key, append_to_error_message=None): """ Provides a light wrapper around the dictionary key helper and uses case insensitive lookup. @@ -460,6 +478,48 @@ def subtract_summed_runs(ws_to_correct, empty_sample_ws_string, instrument, scal return ws_to_correct +def read_masking_file(masking_file_path): + """ + Read a masking file in the ISIS powder format: + + # bank N(plus any other comments) + peak_min0 peak_max0 + peak_min1 peak_max1 + ... + # bank M(plus any other comments) + peak_min0 peak_max0 + peak_min1 peak_max1 + ... + :param masking_file_path: The full path to a masking file + :return: A list of peak min/max values for each bank + """ + all_banks_masking_list = [] + bank_masking_list = [] + + # Python > 3 requires the encoding to be included so an Angstrom + # symbol can be read, I'm assuming all file read here are + # `latin-1` which may not be true in the future. Python 2 `open` + # doesn't have an encoding option + if PY2: + encoding = {} + else: + encoding = {"encoding": "latin-1"} + with open(masking_file_path, **encoding) as mask_file: + for line in mask_file: + if 'bank' in line: + # Push back onto new bank + if bank_masking_list: + all_banks_masking_list.append(bank_masking_list) + bank_masking_list = [] + else: + # Parse and store in current list + bank_masking_list.append(line.strip().split()) + # deal with final bank + if bank_masking_list: + all_banks_masking_list.append(bank_masking_list) + return all_banks_masking_list + + def _crop_single_ws_in_tof(ws_to_rebin, x_max, x_min): """ Implementation of cropping the single workspace in TOF. First converts to TOF, crops then converts @@ -542,14 +602,6 @@ def _load_list_of_files(run_numbers_list, instrument, file_ext=None): return read_ws_list -def _strip_vanadium_peaks(workspaces_to_strip): - out_list = [] - for i, ws in enumerate(workspaces_to_strip): - out_name = ws.name() + "_toSpline-" + str(i+1) - out_list.append(mantid.StripVanadiumPeaks(InputWorkspace=ws, OutputWorkspace=out_name)) - return out_list - - def _sum_ws_range(ws_list): """ Sums a list of workspaces into a single workspace. This will take the name -- GitLab