diff --git a/scripts/Diffraction/isis_powder/abstract_inst.py b/scripts/Diffraction/isis_powder/abstract_inst.py index 4dfa3020de6f8bb21290e6af0a1c0bba8639c918..95ef5b5d55013261160c6ea59706615283c2c8aa 100644 --- a/scripts/Diffraction/isis_powder/abstract_inst.py +++ b/scripts/Diffraction/isis_powder/abstract_inst.py @@ -1,7 +1,7 @@ from __future__ import (absolute_import, division, print_function) import os -from isis_powder.routines import calibrate, focus +from isis_powder.routines import calibrate, focus, common_enums # This class provides common hooks for instruments to override @@ -47,16 +47,15 @@ class AbstractInst(object): return calibrate.create_van(instrument=self, van=vanadium_runs, empty=empty_runs, absorb=do_absorb_corrections, gen_absorb=gen_absorb_correction) - def _focus(self, run_number, input_batching, do_van_normalisation): + def _focus(self, run_number_string, do_van_normalisation): """ Focuses the user specified run - should be called by the concrete instrument - :param run_number: The run number(s) to be processed - :param input_batching: How to process the runs specified if a range. E.g. Individual/Batched. See common enums. + :param run_number_string: The run number(s) to be processed :param do_van_normalisation: True to divide by the vanadium run, false to not. :return: """ - return focus.focus(run_number=run_number, input_batching=input_batching, - perform_vanadium_norm=do_van_normalisation, instrument=self) + return focus.focus(run_number_string=run_number_string, perform_vanadium_norm=do_van_normalisation, + instrument=self) # Mandatory overrides @@ -160,6 +159,14 @@ class AbstractInst(object): # automatic calibration raise NotImplementedError("Automatic vanadium corrections have not been implemented for this instrument.") + def _get_input_batching_mode(self): + """ + Returns the user specified input batching (e.g. summed or individual processing). This is set to summed + by default for instruments who do not with to specify it + :return: The current input batching type from the InputBatchingEnum + """ + return common_enums.InputBatchingEnum.Summed + def _get_monitor_spectra_index(self, run_number): """ Returns the spectra number a monitor is located at @@ -196,7 +203,7 @@ class AbstractInst(object): :return: A dictionary containing the various output paths and generated output name """ output_directory = os.path.join(self._output_dir, run_details.label, self._user_name) - file_name = str(self._generate_output_file_name(run_number_string=run_details.run_number)) + file_name = str(self._generate_output_file_name(run_number_string=run_details.user_input_run_number)) nxs_file = os.path.join(output_directory, (file_name + ".nxs")) gss_file = os.path.join(output_directory, (file_name + ".gsas")) tof_xye_file = os.path.join(output_directory, (file_name + "_tof_xye.dat")) diff --git a/scripts/Diffraction/isis_powder/pearl.py b/scripts/Diffraction/isis_powder/pearl.py index ff84f4bd70f964772199fcb7f1a0c72f3ed13960..4a8db813a171e94cecade4135b2d2a54d5108f7e 100644 --- a/scripts/Diffraction/isis_powder/pearl.py +++ b/scripts/Diffraction/isis_powder/pearl.py @@ -27,7 +27,7 @@ class Pearl(AbstractInst): def focus(self, **kwargs): self._switch_long_mode_inst_settings(kwargs.get("long_mode")) self._inst_settings.update_attributes(kwargs=kwargs) - return self._focus(run_number=self._inst_settings.run_number, input_batching=InputBatchingEnum.Summed, + return self._focus(run_number_string=self._inst_settings.run_number, do_van_normalisation=self._inst_settings.van_norm) def create_vanadium(self, **kwargs): @@ -53,14 +53,12 @@ class Pearl(AbstractInst): # Params # def _get_run_details(self, run_number_string): - input_run_number_list = common.generate_run_numbers(run_number_string=run_number_string) - first_run = input_run_number_list[0] - if self._cached_run_details_number == first_run: + if self._cached_run_details_number == run_number_string: return self._cached_run_details run_details = pearl_algs.get_run_details(run_number_string=run_number_string, inst_settings=self._inst_settings) - self._cached_run_details_number = first_run + self._cached_run_details_number = run_number_string self._cached_run_details = run_details return run_details @@ -102,7 +100,8 @@ class Pearl(AbstractInst): pearl_output.generate_and_save_focus_output(self, processed_spectra=processed_spectra, run_details=run_details, focus_mode=output_mode, perform_attenuation=self._inst_settings.perform_atten) - group_name = "PEARL" + str(run_details.run_number) + '_' + self._inst_settings.tt_mode + "-Results-D-Grp" + group_name = "PEARL" + str(run_details.user_input_run_number) + group_name += '_' + self._inst_settings.tt_mode + "-Results-D-Grp" grouped_d_spacing = mantid.GroupWorkspaces(InputWorkspaces=output_spectra, OutputWorkspace=group_name) return grouped_d_spacing diff --git a/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py b/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py index 21953c18815245e2e03c9e7bd8cdb88ecb77bf1c..43443ca52767142bb60087469e10e68e66766e8e 100644 --- a/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py +++ b/scripts/Diffraction/isis_powder/pearl_routines/pearl_algs.py @@ -70,7 +70,12 @@ def generate_vanadium_absorb_corrections(van_ws): def get_run_details(run_number_string, inst_settings): - mapping_dict = yaml_parser.get_run_dictionary(run_number=run_number_string, file_path=inst_settings.cal_map_path) + if isinstance(run_number_string, str) and not run_number_string.isdigit(): + run_number_list = common.generate_run_numbers(run_number_string=run_number_string) + first_run_number = run_number_list[0] + else: + first_run_number = run_number_string + mapping_dict = yaml_parser.get_run_dictionary(run_number_string=first_run_number, file_path=inst_settings.cal_map_path) calibration_file_name = mapping_dict["calibration_file"] empty_run_numbers = mapping_dict["empty_run_numbers"] @@ -95,7 +100,8 @@ def get_run_details(run_number_string, inst_settings): splined_vanadium_path = os.path.join(cycle_calibration_dir, splined_vanadium_name) - run_details = RunDetails(run_number=run_number_string) + run_details = RunDetails(run_number=first_run_number) + run_details.user_input_run_number = run_number_string run_details.calibration_file_path = calibration_file_path run_details.grouping_file_path = grouping_file_path run_details.empty_runs = empty_run_numbers diff --git a/scripts/Diffraction/isis_powder/pearl_routines/pearl_output.py b/scripts/Diffraction/isis_powder/pearl_routines/pearl_output.py index 501e783241b0eb37d81be39edb304ec0723e53e9..69449cb2576f9eb11f4024b0b52e3ab971468296 100644 --- a/scripts/Diffraction/isis_powder/pearl_routines/pearl_output.py +++ b/scripts/Diffraction/isis_powder/pearl_routines/pearl_output.py @@ -24,12 +24,12 @@ def generate_and_save_focus_output(instrument, processed_spectra, run_details, p return processed_nexus_files -def _attenuate_workspace(instrument, output_file_paths, ws_to_attenuate): +def _attenuate_workspace(instrument, output_file_paths, attenuated_ws): # Clone a workspace which is not attenuated no_att = output_file_paths["output_name"] + "_noatten" - mantid.CloneWorkspace(InputWorkspace=ws_to_attenuate, OutputWorkspace=no_att) - ws_to_attenuate = instrument._attenuate_workspace(ws_to_attenuate) - return ws_to_attenuate + mantid.CloneWorkspace(InputWorkspace=attenuated_ws, OutputWorkspace=no_att) + attenuated_ws = instrument._attenuate_workspace(attenuated_ws) + return attenuated_ws def _focus_mode_mods(output_file_paths, calibrated_spectra): diff --git a/scripts/Diffraction/isis_powder/polaris.py b/scripts/Diffraction/isis_powder/polaris.py index bfccfaea67505132e36f0095456f29a8e6708f22..a20f0c7c8dda294bef1cc5f555717f69dcd6e5dc 100644 --- a/scripts/Diffraction/isis_powder/polaris.py +++ b/scripts/Diffraction/isis_powder/polaris.py @@ -29,7 +29,7 @@ class Polaris(AbstractInst): def focus(self, **kwargs): self._inst_settings.update_attributes(kwargs=kwargs) - return self._focus(run_number=self._inst_settings.run_number, input_batching=self._inst_settings.input_mode, + return self._focus(run_number_string=self._inst_settings.run_number, do_van_normalisation=self._inst_settings.do_van_normalisation) def create_vanadium(self, **kwargs): @@ -42,19 +42,31 @@ class Polaris(AbstractInst): do_absorb_corrections=self._inst_settings.do_absorb_corrections, gen_absorb_correction=None) # TODO POLARIS doesn't need this flag to gen abs. corrections does PEARL? - def _get_run_details(self, run_number_string): - input_run_number_list = common.generate_run_numbers(run_number_string=run_number_string) - first_run = input_run_number_list[0] - if self._run_details_last_run_number == first_run: - return self._run_details_cached_obj + # Overrides - run_details = polaris_algs.get_run_details(run_number=first_run, inst_settings=self._inst_settings) + def _apply_absorb_corrections(self, run_details, van_ws, gen_absorb=False): + return polaris_algs.calculate_absorb_corrections(ws_to_correct=van_ws, + multiple_scattering=self._inst_settings.multiple_scattering) - # Hold obj in case same run range is requested - self._run_details_last_run_number = first_run - self._run_details_cached_obj = run_details + @staticmethod + def _can_auto_gen_vanadium_cal(): + return True - return run_details + def _crop_banks_to_user_tof(self, focused_banks): + return common.crop_banks_in_tof(focused_banks, self._inst_settings.tof_cropping_values) + + def _crop_raw_to_expected_tof_range(self, ws_to_crop): + cropped_ws = common.crop_in_tof(ws_to_crop=ws_to_crop, x_min=self._inst_settings.raw_data_crop_values[0], + x_max=self._inst_settings.raw_data_crop_values[1]) + return cropped_ws + + def _crop_van_to_expected_tof_range(self, van_ws_to_crop): + cropped_ws = common.crop_banks_in_tof(bank_list=van_ws_to_crop, + crop_values_list=self._inst_settings.van_crop_values) + return cropped_ws + + def _generate_auto_vanadium_calibration(self, run_details): + self.create_vanadium(run_in_range=run_details.run_number) @staticmethod def _generate_input_file_name(run_number): @@ -70,15 +82,34 @@ class Polaris(AbstractInst): return updated_list else: # Select between old and new prefix - prefix = polaris_new_name if int(run_number) >= first_run_new_name else polaris_old_name + # Test if it can be converted to an int or if we need to ask Mantid to do it for us + if isinstance(run_number, str) and not run_number.isdigit(): + # Convert using Mantid and take the first element which is most likely to be the lowest digit + use_new_name = True if int(common.generate_run_numbers(run_number)[0]) >= first_run_new_name else False + else: + use_new_name = True if int(run_number) >= first_run_new_name else False + + prefix = polaris_new_name if use_new_name else polaris_old_name return prefix + str(run_number) def _generate_output_file_name(self, run_number_string): return self._generate_input_file_name(run_number=run_number_string) - @staticmethod - def _can_auto_gen_vanadium_cal(): - return True + def _get_input_batching_mode(self): + return self._inst_settings.input_mode + + def _get_run_details(self, run_number_string): + if self._run_details_last_run_number == run_number_string: + return self._run_details_cached_obj + + run_details = polaris_algs.get_run_details(run_number_string=run_number_string, + inst_settings=self._inst_settings) + + # Hold obj in case same run range is requested + self._run_details_last_run_number = run_number_string + self._run_details_cached_obj = run_details + + return run_details def _normalise_ws_current(self, ws_to_correct, run_details=None): normalised_ws = mantid.NormaliseByCurrent(InputWorkspace=ws_to_correct, OutputWorkspace=ws_to_correct) @@ -93,32 +124,13 @@ class Polaris(AbstractInst): mask_path=masking_file_path) return output - def _apply_absorb_corrections(self, run_details, van_ws, gen_absorb=False): - return polaris_algs.calculate_absorb_corrections(ws_to_correct=van_ws, - multiple_scattering=self._inst_settings.multiple_scattering) - def _output_focused_ws(self, processed_spectra, run_details, output_mode=None): d_spacing_group, tof_group = polaris_algs.split_into_tof_d_spacing_groups(run_details=run_details, processed_spectra=processed_spectra) output_paths = self._generate_out_file_paths(run_details=run_details) polaris_output.save_polaris_focused_data(d_spacing_group=d_spacing_group, tof_group=tof_group, - output_paths=output_paths, run_number=run_details.run_number) - + output_paths=output_paths, + run_number_string=run_details.user_input_run_number) return d_spacing_group - def _crop_raw_to_expected_tof_range(self, ws_to_crop): - cropped_ws = common.crop_in_tof(ws_to_crop=ws_to_crop, x_min=self._inst_settings.raw_data_crop_values[0], - x_max=self._inst_settings.raw_data_crop_values[1]) - return cropped_ws - - def _crop_van_to_expected_tof_range(self, van_ws_to_crop): - cropped_ws = common.crop_banks_in_tof(bank_list=van_ws_to_crop, - crop_values_list=self._inst_settings.van_crop_values) - return cropped_ws - - def _crop_banks_to_user_tof(self, focused_banks): - return common.crop_banks_in_tof(focused_banks, self._inst_settings.tof_cropping_values) - - def _generate_auto_vanadium_calibration(self, run_details): - self.create_calibration_vanadium(run_in_range=run_details.run_number) diff --git a/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py b/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py index 08e8259fe11917a541b13cc31cd45c25a5692c96..4275138490bdc130c9be64fa960bba0c6a0f0cec 100644 --- a/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py +++ b/scripts/Diffraction/isis_powder/polaris_routines/polaris_algs.py @@ -25,8 +25,12 @@ def calculate_absorb_corrections(ws_to_correct, multiple_scattering): return ws_to_correct -def get_run_details(run_number, inst_settings): - yaml_dict = yaml_parser.get_run_dictionary(run_number=run_number, file_path=inst_settings.cal_mapping_file) +def get_run_details(run_number_string, inst_settings): + run_number = common.generate_run_numbers(run_number_string=run_number_string) + if isinstance(run_number, list): + # Only take first run number + run_number = run_number[0] + yaml_dict = yaml_parser.get_run_dictionary(run_number_string=run_number, file_path=inst_settings.cal_mapping_file) if inst_settings.chopper_on: chopper_config = yaml_dict["chopper_on"] @@ -47,6 +51,7 @@ def get_run_details(run_number, inst_settings): splined_vanadium = os.path.join(in_calib_dir, splined_vanadium_name) run_details = RunDetails(run_number=run_number) + run_details.user_input_run_number = run_number_string run_details.empty_runs = empty_runs run_details.vanadium_run_numbers = vanadium_runs run_details.label = label @@ -59,14 +64,12 @@ def get_run_details(run_number, inst_settings): def split_into_tof_d_spacing_groups(run_details, processed_spectra): - name_index = 1 d_spacing_output = [] tof_output = [] - run_number = str(run_details.run_number) - for ws in processed_spectra: - d_spacing_out_name = run_number + "-ResultD-" + str(name_index) - tof_out_name = run_number + "-ResultTOF-" + str(name_index) - name_index += 1 + run_number = str(run_details.user_input_run_number) + for name_index, ws in enumerate(processed_spectra): + d_spacing_out_name = run_number + "-ResultD-" + str(name_index + 1) + tof_out_name = run_number + "-ResultTOF-" + str(name_index + 1) d_spacing_output.append(mantid.ConvertUnits(InputWorkspace=ws, OutputWorkspace=d_spacing_out_name, Target="dSpacing")) diff --git a/scripts/Diffraction/isis_powder/polaris_routines/polaris_output.py b/scripts/Diffraction/isis_powder/polaris_routines/polaris_output.py index 80dcf7d61151d84bccef68edce65f1430a9aebb9..bb9997c17576dcd27bd06439c7b57936687b3e57 100644 --- a/scripts/Diffraction/isis_powder/polaris_routines/polaris_output.py +++ b/scripts/Diffraction/isis_powder/polaris_routines/polaris_output.py @@ -4,7 +4,7 @@ import mantid.simpleapi as mantid import os -def save_polaris_focused_data(d_spacing_group, tof_group, output_paths, run_number): +def save_polaris_focused_data(d_spacing_group, tof_group, output_paths, run_number_string): mantid.SaveGSS(InputWorkspace=tof_group, Filename=output_paths["gss_filename"], SplitFiles=False, Append=False) mantid.SaveNexusProcessed(InputWorkspace=tof_group, Filename=output_paths["nxs_filename"], Append=False) @@ -13,9 +13,9 @@ def save_polaris_focused_data(d_spacing_group, tof_group, output_paths, run_numb if not os.path.exists(dat_file_destination): os.makedirs(dat_file_destination) - _save_xye(ws_group=d_spacing_group, ws_units="d", run_number=run_number, + _save_xye(ws_group=d_spacing_group, ws_units="d", run_number=run_number_string, output_folder=dat_file_destination) - _save_xye(ws_group=tof_group, ws_units="TOF", run_number=run_number, + _save_xye(ws_group=tof_group, ws_units="TOF", run_number=run_number_string, output_folder=dat_file_destination) diff --git a/scripts/Diffraction/isis_powder/routines/RunDetails.py b/scripts/Diffraction/isis_powder/routines/RunDetails.py index bc674c8e84e91af5792510353ea507209a037526..9d6a5f9265901925d8be5f8778d87d35ca3baace 100644 --- a/scripts/Diffraction/isis_powder/routines/RunDetails.py +++ b/scripts/Diffraction/isis_powder/routines/RunDetails.py @@ -9,6 +9,7 @@ class RunDetails(object): def __init__(self, run_number): # Essential attribute self.run_number = run_number + self.user_input_run_number = None self.empty_runs = None self.label = None diff --git a/scripts/Diffraction/isis_powder/routines/common.py b/scripts/Diffraction/isis_powder/routines/common.py index 35b2760cb120f5e8edf62486306ae979458dd64b..64cb8975c69cd6bdc2030c0b810e6979a5a88d6a 100644 --- a/scripts/Diffraction/isis_powder/routines/common.py +++ b/scripts/Diffraction/isis_powder/routines/common.py @@ -84,7 +84,10 @@ def get_monitor_ws(ws_to_process, run_number_string, instrument): return load_monitor_ws -def load_current_normalised_ws_list(run_number_string, instrument, input_batching): +def load_current_normalised_ws_list(run_number_string, instrument, input_batching=None): + if not input_batching: + input_batching = instrument._get_input_batching_mode() + run_information = instrument._get_run_details(run_number_string=run_number_string) raw_ws_list = _load_raw_files(run_number_string=run_number_string, instrument=instrument) diff --git a/scripts/Diffraction/isis_powder/routines/focus.py b/scripts/Diffraction/isis_powder/routines/focus.py index 150c5ac91f2152b0ec90c95c6a7d458544f6a16b..4caf712b4a5c3c3d8647211ee668bc632c9e9877 100644 --- a/scripts/Diffraction/isis_powder/routines/focus.py +++ b/scripts/Diffraction/isis_powder/routines/focus.py @@ -8,12 +8,12 @@ import os import warnings -def focus(run_number, instrument, input_batching, perform_vanadium_norm=True): +def focus(run_number_string, instrument, perform_vanadium_norm=True): + input_batching = instrument._get_input_batching_mode() if input_batching.lower() == InputBatchingEnum.Individual.lower(): - return _individual_run_focusing(input_batching, instrument, perform_vanadium_norm, - run_number) + return _individual_run_focusing(instrument, perform_vanadium_norm, run_number_string) else: - return _batched_run_focusing(input_batching, instrument, perform_vanadium_norm, run_number) + return _batched_run_focusing(instrument, perform_vanadium_norm, run_number_string) def _focus_one_ws(ws, run_number, instrument, perform_vanadium_norm): @@ -24,13 +24,14 @@ def _focus_one_ws(ws, run_number, instrument, perform_vanadium_norm): # Subtract and crop to largest acceptable TOF range input_workspace = common.subtract_sample_empty(ws_to_correct=ws, instrument=instrument, empty_sample_ws_string=run_details.empty_runs) + input_workspace = instrument._crop_raw_to_expected_tof_range(ws_to_crop=input_workspace) # Align / Focus - input_workspace = mantid.AlignDetectors(InputWorkspace=input_workspace, - CalibrationFile=run_details.calibration_file_path) + aligned_ws = mantid.AlignDetectors(InputWorkspace=input_workspace, + CalibrationFile=run_details.calibration_file_path) - focused_ws = mantid.DiffractionFocussing(InputWorkspace=input_workspace, + focused_ws = mantid.DiffractionFocussing(InputWorkspace=aligned_ws, GroupingFileName=run_details.grouping_file_path) calibrated_spectra = _apply_vanadium_corrections(instrument=instrument, run_number=run_number, @@ -42,6 +43,7 @@ def _focus_one_ws(ws, run_number, instrument, perform_vanadium_norm): # Tidy workspaces from Mantid common.remove_intermediate_workspace(input_workspace) + common.remove_intermediate_workspace(aligned_ws) common.remove_intermediate_workspace(focused_ws) common.remove_intermediate_workspace(calibrated_spectra) @@ -62,12 +64,12 @@ def _apply_vanadium_corrections(instrument, run_number, input_workspace, perform return processed_spectra -def _batched_run_focusing(input_batching, instrument, perform_vanadium_norm, run_number): - read_ws_list = common.load_current_normalised_ws_list(run_number_string=run_number, - input_batching=input_batching, instrument=instrument) +def _batched_run_focusing(instrument, perform_vanadium_norm, run_number_string): + read_ws_list = common.load_current_normalised_ws_list(run_number_string=run_number_string, + instrument=instrument) output = None for ws in read_ws_list: - output = _focus_one_ws(ws=ws, run_number=run_number, instrument=instrument, + output = _focus_one_ws(ws=ws, run_number=run_number_string, instrument=instrument, perform_vanadium_norm=perform_vanadium_norm) return output @@ -82,13 +84,12 @@ def _divide_by_vanadium_splines(spectra_list, spline_file_path): return output_list -def _individual_run_focusing(input_batching, instrument, perform_vanadium_norm, run_number): +def _individual_run_focusing(instrument, perform_vanadium_norm, run_number): # Load and process one by one run_numbers = common.generate_run_numbers(run_number_string=run_number) output = None for run in run_numbers: - ws = common.load_current_normalised_ws_list(run_number_string=run, instrument=instrument, - input_batching=input_batching) + ws = common.load_current_normalised_ws_list(run_number_string=run, instrument=instrument) output = _focus_one_ws(ws=ws[0], run_number=run, instrument=instrument, perform_vanadium_norm=perform_vanadium_norm) return output diff --git a/scripts/Diffraction/isis_powder/routines/yaml_parser.py b/scripts/Diffraction/isis_powder/routines/yaml_parser.py index 4a3a5972a1a938721b099c827af4193efd584e65..476fadbe00c0747648196464ea2d14784dc914fc 100644 --- a/scripts/Diffraction/isis_powder/routines/yaml_parser.py +++ b/scripts/Diffraction/isis_powder/routines/yaml_parser.py @@ -6,17 +6,17 @@ from isis_powder.routines import common as common from isis_powder.routines import yaml_sanity -def get_run_dictionary(run_number, file_path): - if isinstance(run_number, str): - run_number_list = common.generate_run_numbers(run_number_string=run_number) - run_number = run_number_list[0] +def get_run_dictionary(run_number_string, file_path): + if isinstance(run_number_string, str): + run_number_list = common.generate_run_numbers(run_number_string=run_number_string) + run_number_string = run_number_list[0] config_file = open_yaml_file_as_dictionary(file_path) yaml_sanity.calibration_file_sanity_check(config_file) - run_key = _find_dictionary_key(dict_to_search=config_file, run_number=run_number) + run_key = _find_dictionary_key(dict_to_search=config_file, run_number=run_number_string) if not run_key: - raise ValueError("Run number " + str(run_number) + " not recognised in calibration mapping") + raise ValueError("Run number " + str(run_number_string) + " not recognised in calibration mapping") return config_file[run_key]