diff --git a/scripts/Diffraction/isis_powder/abstract_inst.py b/scripts/Diffraction/isis_powder/abstract_inst.py index d93e103be057c0158952b1a5d879eea9584a786e..9c87f9002a2b5112dc508878bc8dd8e779a27973 100644 --- a/scripts/Diffraction/isis_powder/abstract_inst.py +++ b/scripts/Diffraction/isis_powder/abstract_inst.py @@ -200,7 +200,7 @@ class AbstractInst(object): """ raise NotImplementedError("Create calibration from a silicon run is not yet implemented for this instrument") - def _normalise_ws(self, ws_to_correct, monitor_ws=None, spline_terms=20): + def _normalise_ws(self, ws_to_correct, run_details=None): return _empty_hook_return_none() def _get_monitor_spectra(self, run_number): @@ -244,9 +244,6 @@ class AbstractInst(object): def _apply_solid_angle_efficiency_corr(self, ws_to_correct, vanadium_number=None, run_details=None): return ws_to_correct - def _load_monitor(self, number, cycle): - return None - def _apply_van_calibration_tof_rebinning(self, vanadium_ws, tof_rebin_pass, return_units): return vanadium_ws @@ -262,7 +259,7 @@ class AbstractInst(object): def calculate_focus_binning_params(self, sample): return None - def PEARL_populate_user_dirs(self, run_number): + def PEARL_setup_input_directories(self, run_number): return None # ----- Private Implementation ----- # diff --git a/scripts/Diffraction/isis_powder/calibrate.py b/scripts/Diffraction/isis_powder/calibrate.py index 116d573c6dff6f99cab985d929d2eb4aefa82bb1..8fa4a9d12765991ce60feb8f96955f69d5f3f5aa 100644 --- a/scripts/Diffraction/isis_powder/calibrate.py +++ b/scripts/Diffraction/isis_powder/calibrate.py @@ -7,15 +7,15 @@ import isis_powder.common as common def create_van(instrument, van, empty, output_van_file_name, num_of_splines, absorb, gen_absorb): - input_van_ws = common._load_current_normalised_ws(number=van, instrument=instrument) - input_empty_ws = common._load_current_normalised_ws(number=empty, instrument=instrument) + input_van_ws = common._load_current_normalised_ws(run_number=van, instrument=instrument) + input_empty_ws = common._load_current_normalised_ws(run_number=empty, instrument=instrument) corrected_van_ws = mantid.Minus(LHSWorkspace=input_van_ws, RHSWorkspace=input_empty_ws) common.remove_intermediate_workspace(input_empty_ws) common.remove_intermediate_workspace(input_van_ws) - run_details = instrument._get_run_details(run_number=van) + run_details = instrument._get_run_details(run_number_input=van) corrected_van_ws = instrument. _apply_van_calibration_tof_rebinning(vanadium_ws=corrected_van_ws, tof_rebin_pass=1, return_units="TOF") @@ -39,7 +39,7 @@ def create_van(instrument, van, empty, output_van_file_name, num_of_splines, abs common.remove_intermediate_workspace(corrected_van_ws) - cycle_information = instrument._get_run_details(run_number=van) + cycle_information = instrument._get_run_details(run_number_input=van) splined_ws_list = instrument._spline_background(focused_van_file, num_of_splines, cycle_information.instrument_version) # Figure out who will provide the path name diff --git a/scripts/Diffraction/isis_powder/common.py b/scripts/Diffraction/isis_powder/common.py index 142d625405768ba4806809dc8a41980c3a6b1fcb..d088328b264e31ff7825be5eb68ad404af4e04ef 100644 --- a/scripts/Diffraction/isis_powder/common.py +++ b/scripts/Diffraction/isis_powder/common.py @@ -6,6 +6,7 @@ import mantid.simpleapi as mantid # --- Public API --- # + def create_calibration_by_names(calibration_runs, startup_objects, grouping_file_name, group_names): _create_blank_cal_file(calibration_runs=calibration_runs, group_names=group_names, out_grouping_file_name=grouping_file_name, instrument=startup_objects) @@ -42,88 +43,71 @@ def _create_blank_cal_file(calibration_runs, out_grouping_file_name, instrument, remove_intermediate_workspace(input_ws) -def _load_monitor(number, input_dir, instrument): - if isinstance(number, int): - full_file_path = instrument._generate_input_full_path(run_number=number, input_dir=input_dir) - mspectra = instrument._get_monitor_spectra(number) - load_monitor_ws = mantid.LoadRaw(Filename=full_file_path, SpectrumMin=mspectra, SpectrumMax=mspectra, - LoadLogFiles="0") +def load_monitor(run_numbers, instrument): + number_list = generate_run_numbers(run_numbers) + monitor_spectra = instrument._get_monitor_spectra(number_list[0]) + + if len(number_list) == 1: + file_name = instrument._generate_inst_file_name(run_number=number_list[0]) + load_monitor_ws = mantid.Load(Filename=file_name, LoadLogFiles="0", + SpectrumMin=monitor_spectra, SpectrumMax=monitor_spectra) else: - load_monitor_ws = _load_monitor_sum_range(files=number, input_dir=input_dir, instrument=instrument) + load_monitor_ws = _load_sum_file_range(run_numbers=number_list, instrument=instrument) + load_monitor_ws = mantid.ExtractSingleSpectrum(InputWorkspace=load_monitor_ws, WorkspaceIndex=monitor_spectra) return load_monitor_ws -def _load_monitor_sum_range(files, input_dir, instrument): - # TODO refactor this - it probably doesn't work at the moment - loop = 0 - num = files.split("_") - frange = xrange(int(num[0]), int(num[1]) + 1) - mspectra = instrument._get_monitor_spectra(int(num[0])) - for i in frange: - file_path = instrument._generate_input_full_path(i, input_dir) - outwork = "mon" + str(i) - mantid.LoadRaw(Filename=file_path, OutputWorkspace=outwork, SpectrumMin=mspectra, SpectrumMax=mspectra, - LoadLogFiles="0") - loop += 1 - if loop == 2: - firstwk = "mon" + str(i - 1) - secondwk = "mon" + str(i) - load_monitor_summed = mantid.Plus(LHSWorkspace=firstwk, RHSWorkspace=secondwk) - mantid.mtd.remove(firstwk) - mantid.mtd.remove(secondwk) - elif loop > 2: - secondwk = "mon" + str(i) - load_monitor_summed = mantid.Plus(LHSWorkspace=load_monitor_summed, RHSWorkspace=secondwk) - mantid.mtd.remove(secondwk) - - return load_monitor_summed +def _load_raw_files(run_number, instrument): + run_number_list = generate_run_numbers(run_number_string=run_number) + instrument.PEARL_setup_input_directories(run_number=run_number_list[0]) + if len(run_number_list) == 1: + run_number = instrument._generate_inst_file_name(run_number=run_number_list[0]) + load_raw_ws = mantid.Load(Filename=run_number, LoadLogFiles="0") + else: + load_raw_ws = _load_sum_file_range(run_number_list, instrument) + return load_raw_ws -def _load_raw_files(run_number, instrument): - run_name = instrument._generate_inst_file_name(run_number=run_number) +def _load_sum_file_range(run_numbers, instrument): + read_ws_list = [] + for run_number in run_numbers: + file_name = instrument._generate_inst_file_name(run_number=run_number) + read_ws = mantid.Load(Filename=file_name, LoadLogFiles="0") + output_name = "read_ws_output-" + str(g_ads_workaround["read_ws"]) + g_ads_workaround["read_ws"] += 1 + read_ws_list.append(mantid.RenameWorkspace(InputWorkspace=read_ws, OutputWorkspace=output_name)) - instrument.PEARL_populate_user_dirs(run_number=run_number) + # Sum all workspaces + out_ws_name = "summed_range_load-" + str(g_ads_workaround["read_ws"]) + g_ads_workaround["read_ws"] += 1 - if isinstance(run_number, int): - load_raw_ws = mantid.Load(Filename=run_name, LoadLogFiles="0") - else: - load_raw_ws = _load_raw_file_range(run_number, instrument) - return load_raw_ws + summed_ws = mantid.RenameWorkspace(InputWorkspace=read_ws_list[0], OutputWorkspace=out_ws_name) + for ws in read_ws_list[1:]: # Skip first member + summed_ws = mantid.Plus(LHSWorkspace=summed_ws, RHSWorkspace=ws, OutputWorkspace=out_ws_name) + remove_intermediate_workspace(ws) + + return summed_ws + + +def generate_run_numbers(run_number_string): + # Check its not a single run + if isinstance(run_number_string, int) or run_number_string.isdigit(): + return [int(run_number_string)] # Cast into a list and return + + # If its a string we must parse it + run_boundaries = run_number_string.replace('_', '-') # Accept either _ or - delimiters + run_boundaries = run_boundaries.split("-") + run_range = xrange(int(run_boundaries[0]), int(run_boundaries[-1]) + 1) # TODO test for skip conditions + return run_range + + +def _load_current_normalised_ws(run_number, instrument): + read_in_ws = _load_raw_files(run_number=run_number, instrument=instrument) + run_information = instrument._get_run_details(run_number_input=run_number) -def _load_raw_file_range(files, instrument): - loop = 0 - num = files.split("_") - frange = xrange(int(num[0]), int(num[1]) + 1) - out_ws = None - for i in frange: - file_name = instrument._generate_inst_file_name(run_number=i) - outwork = "run" + str(i) - mantid.Load(Filename=file_name, OutputWorkspace=outwork, LoadLogFiles="0") - loop += 1 - if loop == 2: - firstwk = "run" + str(i - 1) - secondwk = "run" + str(i) - out_ws = mantid.Plus(LHSWorkspace=firstwk, RHSWorkspace=secondwk) - mantid.mtd.remove(firstwk) - mantid.mtd.remove(secondwk) - elif loop > 2: - secondwk = "run" + str(i) - out_ws = mantid.Plus(LHSWorkspace=out_ws, RHSWorkspace=secondwk) - mantid.mtd.remove(secondwk) - return out_ws - - -def _load_current_normalised_ws(number, instrument): - # TODO monitor loading should be instrument specific and not in common - - read_in_ws = _load_raw_files(run_number=number, instrument=instrument) - - run_information = instrument._get_run_details(run_number=number) - load_monitor_ws = instrument._load_monitor(number=number, cycle=run_information.label) - - read_ws = instrument._normalise_ws(ws_to_correct=read_in_ws, monitor_ws=load_monitor_ws, spline_terms=20) + read_ws = instrument._normalise_ws(ws_to_correct=read_in_ws, run_details=run_information) output_name = "read_ws_output-" + str(g_ads_workaround["read_ws"]) g_ads_workaround["read_ws"] += 1 diff --git a/scripts/Diffraction/isis_powder/focus.py b/scripts/Diffraction/isis_powder/focus.py index ff688ffe0fd88f63a49dad69def397b3565d5a6b..bd96d609ecd1235e246a4324ea8e7fbc5040a64c 100644 --- a/scripts/Diffraction/isis_powder/focus.py +++ b/scripts/Diffraction/isis_powder/focus.py @@ -11,10 +11,10 @@ def focus(number, instrument, attenuate=True, van_norm=True): def _run_focus(instrument, run_number, perform_attenuation, perform_vanadium_norm): # Read - read_ws = common._load_current_normalised_ws(number=run_number, instrument=instrument) + read_ws = common._load_current_normalised_ws(run_number=run_number, instrument=instrument) input_workspace = instrument._do_tof_rebinning_focus(read_ws) # Rebins for PEARL - calibration_file_paths = instrument._get_run_details(run_number=run_number) + calibration_file_paths = instrument._get_run_details(run_number_input=run_number) # Compensate for empty sample if specified input_workspace = instrument._subtract_sample_empty(input_workspace) @@ -55,7 +55,7 @@ def _run_focus(instrument, run_number, perform_attenuation, perform_vanadium_nor def _divide_sample_by_vanadium(instrument, run_number, input_workspace, perform_vanadium_norm): processed_spectra = [] - run_details = instrument._get_run_details(run_number=run_number) + run_details = instrument._get_run_details(run_number_input=run_number) alg_range, save_range = instrument._get_instrument_alg_save_ranges(run_details.instrument_version) diff --git a/scripts/Diffraction/isis_powder/pearl.py b/scripts/Diffraction/isis_powder/pearl.py index 0c7c9a6a4297385f07bb434c5a821846aebebb12..1b48f7d69c58a61b9c3886c0f08fa87113deabde 100644 --- a/scripts/Diffraction/isis_powder/pearl.py +++ b/scripts/Diffraction/isis_powder/pearl.py @@ -125,7 +125,7 @@ class Pearl(AbstractInst): return self._run_attenuate_workspace(input_workspace=input_workspace) def _create_calibration(self, calibration_runs, offset_file_name, grouping_file_name): - input_ws = common._load_current_normalised_ws(number=calibration_runs, instrument=self) + input_ws = common._load_current_normalised_ws(run_number=calibration_runs, instrument=self) cycle_information = self._get_label_information(calibration_runs) if cycle_information["instrument_version"] == "new" or cycle_information["instrument_version"] == "new2": @@ -166,9 +166,12 @@ class Pearl(AbstractInst): def _create_calibration_silicon(self, calibration_runs, cal_file_name, grouping_file_name): self._do_silicon_calibration(calibration_runs, cal_file_name, grouping_file_name) - def _normalise_ws(self, ws_to_correct, monitor_ws=None, spline_terms=20): + def _normalise_ws(self, ws_to_correct, run_details=None): + if not run_details: + raise RuntimeError("Run details was not passed into PEARL: normalise_ws") + monitor_ws = common.load_monitor(run_numbers=run_details.run_number, instrument=self) return self._normalise_current_ws(ws_to_correct=ws_to_correct, load_monitor_ws=monitor_ws, - spline_terms=spline_terms) + spline_terms=20) def _get_monitor_spectra(self, run_number): return self._get_monitor_spectrum(run_number=run_number) @@ -201,19 +204,6 @@ class Pearl(AbstractInst): run_number=run_number, perform_attenuation=attenuate, focus_mode=self._focus_mode) - def _load_monitor(self, number, cycle): - input_dir = self._generate_raw_data_cycle_dir(run_cycle=cycle) - # TODO refactor all of this - if isinstance(number, int): - full_file_path = self._generate_input_full_path(run_number=number, input_dir=input_dir) - mspectra = self._get_monitor_spectra(number) - load_monitor_ws = mantid.LoadRaw(Filename=full_file_path, SpectrumMin=mspectra, SpectrumMax=mspectra, - LoadLogFiles="0") - else: - load_monitor_ws = common._load_monitor_sum_range(files=number, input_dir=input_dir, instrument=self) - - return load_monitor_ws - def _apply_van_calibration_tof_rebinning(self, vanadium_ws, tof_rebin_pass, return_units): tof_rebin_param_dict = self._get_create_van_tof_binning() tof_rebin_param = tof_rebin_param_dict[str(tof_rebin_pass)] @@ -289,7 +279,7 @@ class Pearl(AbstractInst): def _do_silicon_calibration(self, runs_to_process, cal_file_name, grouping_file_name): # TODO fix all of this as the script is too limited to be useful - create_si_ws = common._load_current_normalised_ws(number=runs_to_process, instrument=self) + create_si_ws = common._load_current_normalised_ws(run_number=runs_to_process, instrument=self) cycle_details = self._get_label_information(runs_to_process) instrument_version = cycle_details["instrument_version"] @@ -424,7 +414,7 @@ class Pearl(AbstractInst): def _PEARL_filename_is_full_path(self): return self._old_api_uses_full_paths - def PEARL_populate_user_dirs(self, run_number): + def PEARL_setup_input_directories(self, run_number): run_details = self._get_run_details(run_number=run_number) generated_path = self._generate_raw_data_cycle_dir(run_cycle=run_details.label) user_dirs = config['datasearch.directories'] diff --git a/scripts/Diffraction/isis_powder/polaris.py b/scripts/Diffraction/isis_powder/polaris.py index 651dfe6513c334153ffa2ad6932f98585b25ae66..2b9a4d104450df16fcd3fc79aa9afca4c931f1e1 100644 --- a/scripts/Diffraction/isis_powder/polaris.py +++ b/scripts/Diffraction/isis_powder/polaris.py @@ -47,32 +47,34 @@ class Polaris(AbstractInst): def _get_default_group_names(self): return self._calibration_grouping_names - def _get_run_details(self, run_number): - # TODO rename this from get calibration to get run details - if self._run_details_last_run_number == run_number: + def _get_run_details(self, run_number_input): + if self._run_details_last_run_number == run_number_input: return self._run_details_cached_obj - configuration = polaris_calib_parser.get_calibration_dict(run_number=run_number) + run_number_list = common.generate_run_numbers(run_number_string=run_number_input) + configuration = polaris_calib_parser.get_calibration_dict(run_number=run_number_list[0]) calibration_dir = self.calibration_dir - # Common to all runs calibration_full_path = os.path.join(calibration_dir, configuration["offset_file_name"]) grouping_full_path = os.path.join(calibration_dir, configuration["grouping_file_name"]) + if self._chopper_on: chopper_config = configuration["chopper_on"] else: chopper_config = configuration["chopper_off"] + vanadium_file = self._generate_inst_file_name(run_number=chopper_config["vanadium_file_name"]) splined_vanadium = os.path.join(calibration_dir, chopper_config["splined_vanadium_file_name"]) solid_angle_file_path = os.path.join(calibration_dir, chopper_config["solid_angle_file_name"]) calibration_details = RunDetails(calibration_path=calibration_full_path, grouping_path=grouping_full_path, - vanadium_name=vanadium_file, run_number=run_number) + vanadium_name=vanadium_file, run_number=run_number_input) + calibration_details.label = configuration["label"] calibration_details.splined_vanadium = splined_vanadium calibration_details.solid_angle_corr = solid_angle_file_path - calibration_details.label = configuration["label"] - self._run_details_last_run_number = run_number + # Hold obj in case same run range is requested + self._run_details_last_run_number = run_number_input self._run_details_cached_obj = calibration_details return calibration_details @@ -86,7 +88,7 @@ class Polaris(AbstractInst): alg_range = 5 return alg_range, None - def _normalise_ws(self, ws_to_correct, monitor_ws=None, spline_terms=20): + def _normalise_ws(self, ws_to_correct, run_details=None): normalised_ws = mantid.NormaliseByCurrent(InputWorkspace=ws_to_correct) return normalised_ws @@ -144,7 +146,7 @@ class Polaris(AbstractInst): def generate_solid_angle_corrections(self, run_details, vanadium_number): if vanadium_number: - solid_angle_vanadium_ws = common._load_raw_files(run_number=vanadium_number, instrument=self) + solid_angle_vanadium_ws = common._load_raw_files(run_number_list=vanadium_number, instrument=self) elif run_details: solid_angle_vanadium_ws = mantid.Load(Filename=run_details.vanadium) else: diff --git a/scripts/Diffraction/isis_powder/polaris_routines/polaris_calib_parser.py b/scripts/Diffraction/isis_powder/polaris_routines/polaris_calib_parser.py index 42d54b3294ee4e028db94950280b7bd34b413011..f9ecfac3cea1f87359b45fca5fd65366c0c845a9 100644 --- a/scripts/Diffraction/isis_powder/polaris_routines/polaris_calib_parser.py +++ b/scripts/Diffraction/isis_powder/polaris_routines/polaris_calib_parser.py @@ -7,7 +7,20 @@ import yaml def get_calibration_dict(run_number): config_file = _open_yaml_file() - run_key = _get_dictionary_key(config_handle=config_file, run_number=run_number) + + # First check exceptions list as it should be shorter + exception_key = _check_if_run_is_exception(config_handle=config_file, run_number=run_number) + if exception_key: + exceptions_dict = config_file["exceptions"] + return exceptions_dict[exception_key] + + # Otherwise parse the entire YAML file + run_key = _find_dictionary_key(dict_to_search=config_file, run_number=run_number) + + # If we have not found the run in either + if not run_key: + raise ValueError("Run number " + str(run_number) + " not recognised in calibration mapping") + return config_file[run_key] @@ -27,16 +40,24 @@ def _open_yaml_file(): return read_config -def _get_dictionary_key(config_handle, run_number): +def _check_if_run_is_exception(config_handle, run_number): + try: + exceptions_dict = config_handle["exceptions"] + except KeyError: + return None + + return _find_dictionary_key(dict_to_search=exceptions_dict, run_number=run_number) + + +def _find_dictionary_key(dict_to_search, run_number): - for key in config_handle: + for key in dict_to_search: run_generator = _parse_number_key(input_string=key) for run_list in run_generator: if run_number in run_list: return key - # If we hit this point the run_number isn't in any of the keys in the YAML file - raise ValueError("Run number " + str(run_number) + " not recognised in calibration mapping") + return None def _parse_number_key(input_string):