def test_create_run_details_object(self): # These attributes are based on a flat YAML file at the specified path expected_label = "16_4" expected_vanadium_runs = "11-12" expected_empty_runs = "13-14" expected_offset_file_name = "offset_file_name" run_number_string = "17-18" mock_inst = self.setup_mock_inst_settings(yaml_file_path="ISISPowderRunDetailsTest.yaml") run_number = common.get_first_run_number(run_number_string=run_number_string) cal_mapping_dict = yaml_parser.get_run_dictionary(run_number_string=run_number, file_path=mock_inst.cal_mapping_path) grouping_filename = mock_inst.grouping_file_name empty_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="empty_run_numbers") vanadium_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="vanadium_run_numbers") output_obj = run_details.create_run_details_object(run_number_string=run_number_string, inst_settings=mock_inst, is_vanadium_run=False, grouping_file_name=grouping_filename, empty_run_number=empty_runs, vanadium_string=vanadium_runs) self.assertEqual(output_obj.empty_runs, expected_empty_runs) self.assertEqual(output_obj.grouping_file_path, os.path.join(mock_inst.calibration_dir, mock_inst.grouping_file_name)) expected_file_ext = mock_inst.file_extension expected_file_ext = expected_file_ext if expected_file_ext.startswith('.') else '.' + expected_file_ext self.assertEqual(output_obj.file_extension, expected_file_ext) self.assertEqual(output_obj.label, expected_label) self.assertEqual(output_obj.offset_file_path, os.path.join(mock_inst.calibration_dir, expected_label, expected_offset_file_name)) self.assertEqual(output_obj.output_run_string, run_number_string) self.assertEqual(output_obj.run_number, 17) self.assertEqual(output_obj.vanadium_run_numbers, expected_vanadium_runs)
def get_run_details(run_number_string, inst_settings, is_vanadium): # Drill down to relevant section run_mapping_dict = get_cal_mapping_dict(run_number_string, inst_settings.cal_mapping_path) inst_mode_dict = common.cal_map_dictionary_key_helper(run_mapping_dict, key=inst_settings.mode) tof_window = common.cal_map_dictionary_key_helper(dictionary=inst_mode_dict, key=inst_settings.tof_window) empty_run = _get_run_numbers_for_key(tof_window, key="empty_run_numbers") vanadium_run = _get_run_numbers_for_key(tof_window, key="vanadium_run_numbers") grouping_file_name = inst_settings.grouping_file_name return create_run_details_object(run_number_string=run_number_string, inst_settings=inst_settings, is_vanadium_run=is_vanadium, empty_run_number=empty_run, vanadium_string=vanadium_run, grouping_file_name=grouping_file_name)
def get_run_details(run_number_string, inst_settings, is_vanadium_run): mode_run_numbers = _get_current_mode_dictionary(run_number_string, inst_settings) # Get empty and vanadium err_message = "this must be under the relevant Rietveld or PDF mode." empty_runs = common.cal_map_dictionary_key_helper(mode_run_numbers, key="empty_run_numbers", append_to_error_message=err_message) vanadium_runs = common.cal_map_dictionary_key_helper(mode_run_numbers, key="vanadium_run_numbers", append_to_error_message=err_message) grouping_file_name = inst_settings.grouping_file_name return create_run_details_object(run_number_string=run_number_string, inst_settings=inst_settings, is_vanadium_run=is_vanadium_run, empty_run_number=empty_runs, vanadium_string=vanadium_runs, grouping_file_name=grouping_file_name)
def _get_current_mode_dictionary(run_number_string, inst_settings): mapping_dict = get_cal_mapping_dict(run_number_string, inst_settings.cal_mapping_path) if inst_settings.mode is None: ws = mantid.Load('POLARIS'+run_number_string+'.nxs') mode, cropping_vals = _determine_chopper_mode(ws) inst_settings.mode = mode inst_settings.focused_cropping_values = cropping_vals mantid.DeleteWorkspace(ws) # Get the current mode "Rietveld" or "PDF" run numbers return common.cal_map_dictionary_key_helper(mapping_dict, inst_settings.mode)
def test_create_run_details_object_when_van_cal(self): # When we are running the vanadium calibration we expected the run number to take the vanadium # number instead run_number_string = "17-18" expected_vanadium_runs = "11-12" mock_inst = self.setup_mock_inst_settings(yaml_file_path="ISISPowderRunDetailsTest.yaml") run_number = common.get_first_run_number(run_number_string=run_number_string) cal_mapping_dict = yaml_parser.get_run_dictionary(run_number_string=run_number, file_path=mock_inst.cal_mapping_path) grouping_filename = mock_inst.grouping_file_name empty_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="empty_run_numbers") vanadium_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="vanadium_run_numbers") output_obj = run_details.create_run_details_object(run_number_string=run_number_string, inst_settings=mock_inst, is_vanadium_run=True, grouping_file_name=grouping_filename, empty_run_number=empty_runs, vanadium_string=vanadium_runs) self.assertEqual(expected_vanadium_runs, output_obj.run_number) self.assertEqual(output_obj.vanadium_run_numbers, output_obj.run_number) self.assertEqual(expected_vanadium_runs, output_obj.output_run_string)
def test_cal_map_dict_helper(self): missing_key_name = "wrong_key" correct_key_name = "right_key" expected_val = 123 dict_with_key = {correct_key_name: expected_val} # Check it correctly raises with assertRaisesRegex(self, KeyError, "The field '" + missing_key_name + "' is required"): common.cal_map_dictionary_key_helper(dictionary=dict_with_key, key=missing_key_name) # Check it correctly appends the passed error message when raising appended_e_msg = "test append message" with assertRaisesRegex(self, KeyError, appended_e_msg): common.cal_map_dictionary_key_helper(dictionary=dict_with_key, key=missing_key_name, append_to_error_message=appended_e_msg) # Check that it correctly returns the key value where it exists self.assertEqual(common.cal_map_dictionary_key_helper(dictionary=dict_with_key, key=correct_key_name), expected_val) # Check it is not case sensitive different_case_name = "tEsT_key" dict_with_mixed_key = {different_case_name: expected_val} try: self.assertEqual(common.cal_map_dictionary_key_helper(dictionary=dict_with_mixed_key, key=different_case_name.lower()), expected_val) except KeyError: # It tried to use the key without accounting for the case difference self.fail("cal_map_dictionary_key_helper attempted to use a key without accounting for case")
def test_run_details_splined_name_list_is_used(self): expected_vanadium_runs = "11-12" splined_name_list = ["bar", "bang", "baz"] run_number_string = "10" mock_inst = self.setup_mock_inst_settings(yaml_file_path="ISISPowderRunDetailsTest.yaml") run_number = common.get_first_run_number(run_number_string=run_number_string) cal_mapping_dict = yaml_parser.get_run_dictionary(run_number_string=run_number, file_path=mock_inst.cal_mapping_path) grouping_filename = mock_inst.grouping_file_name empty_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="empty_run_numbers") vanadium_runs = common.cal_map_dictionary_key_helper(dictionary=cal_mapping_dict, key="vanadium_run_numbers") output_obj = run_details.create_run_details_object(run_number_string, inst_settings=mock_inst, is_vanadium_run=False, splined_name_list=splined_name_list, grouping_file_name=grouping_filename, empty_run_number=empty_runs, vanadium_string=vanadium_runs) expected_splined_out_str = ''.join('_' + val for val in splined_name_list) expected_output_name = "VanSplined_" + expected_vanadium_runs + expected_splined_out_str expected_output_name += ".nxs" expected_path = os.path.join(mock_inst.calibration_dir, output_obj.label, expected_output_name) self.assertEqual(expected_path, output_obj.splined_vanadium_file_path)
def gem_get_chopper_config(forwarded_value, inst_settings): # Forwarded value should be a cal mapping cal_mapping = forwarded_value return common.cal_map_dictionary_key_helper(cal_mapping, inst_settings.mode)
def create_run_details_object(run_number_string, inst_settings, is_vanadium_run, empty_run_number, grouping_file_name, vanadium_string, splined_name_list=None, van_abs_file_name=None): """ Creates and returns a run details object which holds various properties about the current run. :param run_number_string: The user string for the current run :param inst_settings: The current instrument object :param is_vanadium_run: Boolean of if the current run is a vanadium run :param empty_run_number: Empty run number(s) from mapping file :param grouping_file_name: Filename of the grouping file found in the calibration folder :param vanadium_string: Vanadium run number(s) from mapping file :param splined_name_list: (Optional) List of unique properties to generate a splined vanadium name from :param van_abs_file_name: (Optional) The name of the vanadium absorption file :return: RunDetails object with attributes set to applicable values """ cal_map_dict = get_cal_mapping_dict(run_number_string=run_number_string, cal_mapping_path=inst_settings.cal_mapping_path) run_number = common.get_first_run_number(run_number_string=run_number_string) # Get names of files we will be using calibration_dir = os.path.normpath(os.path.expanduser(inst_settings.calibration_dir)) label = common.cal_map_dictionary_key_helper(dictionary=cal_map_dict, key="label") offset_file_name = common.cal_map_dictionary_key_helper(dictionary=cal_map_dict, key="offset_file_name") # Prepend the properties used for creating a van spline so we can fingerprint the file new_splined_list = splined_name_list if splined_name_list else [] new_splined_list.append(os.path.basename(offset_file_name)) splined_van_name = common.generate_splined_name(vanadium_string, new_splined_list) unsplined_van_name = common.generate_unsplined_name(vanadium_string, new_splined_list) summed_empty_name = common.generate_summed_empty_name(empty_run_number, new_splined_list) if is_vanadium_run: # The run number should be the vanadium number in this case run_number = vanadium_string output_run_string = vanadium_string if is_vanadium_run else run_number_string # Get the file extension if set file_extension = getattr(inst_settings, "file_extension") if file_extension: # Prefix dot if user has forgotten to file_extension = file_extension if file_extension.startswith('.') else '.' + file_extension # Get the output name suffix if set suffix = getattr(inst_settings, "suffix", None) # Sample empty if there is one as this is instrument specific sample_empty = getattr(inst_settings, "sample_empty", None) # By default, offset file sits in the calibration folder, but it can also be given as an absolute path if os.path.exists(offset_file_name): offset_file_path = offset_file_name else: offset_file_path = os.path.join(calibration_dir, label, offset_file_name) # Generate the paths grouping_file_path = os.path.join(calibration_dir, grouping_file_name) van_paths = os.path.join(calibration_dir, label) splined_van_path = os.path.join(van_paths, splined_van_name) unsplined_van_path = os.path.join(van_paths, unsplined_van_name) van_absorb_path = os.path.join(calibration_dir, van_abs_file_name) if van_abs_file_name else None summed_empty_path = os.path.join(van_paths, summed_empty_name) return _RunDetails(empty_run_number=empty_run_number, file_extension=file_extension, run_number=run_number, output_run_string=output_run_string, label=label, offset_file_path=offset_file_path, grouping_file_path=grouping_file_path, splined_vanadium_path=splined_van_path, vanadium_run_number=vanadium_string, sample_empty=sample_empty, vanadium_abs_path=van_absorb_path, unsplined_vanadium_path=unsplined_van_path, output_suffix=suffix,van_paths=van_paths, summed_empty_path=summed_empty_path)
def create_run_details_object(run_number_string, inst_settings, is_vanadium_run, empty_run_number, grouping_file_name, vanadium_string, splined_name_list=None, van_abs_file_name=None): """ Creates and returns a run details object which holds various properties about the current run. :param run_number_string: The user string for the current run :param inst_settings: The current instrument object :param is_vanadium_run: Boolean of if the current run is a vanadium run :param empty_run_number: Empty run number(s) from mapping file :param grouping_file_name: Filename of the grouping file found in the calibration folder :param vanadium_string: Vanadium run number(s) from mapping file :param splined_name_list: (Optional) List of unique properties to generate a splined vanadium name from :param van_abs_file_name: (Optional) The name of the vanadium absorption file :return: RunDetails object with attributes set to applicable values """ cal_map_dict = get_cal_mapping_dict(run_number_string=run_number_string, cal_mapping_path=inst_settings.cal_mapping_path) run_number = common.get_first_run_number(run_number_string=run_number_string) # Get names of files we will be using calibration_dir = os.path.normpath(os.path.expanduser(inst_settings.calibration_dir)) label = common.cal_map_dictionary_key_helper(dictionary=cal_map_dict, key="label") offset_file_name = common.cal_map_dictionary_key_helper(dictionary=cal_map_dict, key="offset_file_name") # Prepend the properties used for creating a van spline so we can fingerprint the file new_splined_list = splined_name_list if splined_name_list else [] new_splined_list.append(os.path.basename(offset_file_name)) splined_van_name = common.generate_splined_name(vanadium_string, new_splined_list) unsplined_van_name = common.generate_unsplined_name(vanadium_string, new_splined_list) if is_vanadium_run: # The run number should be the vanadium number in this case run_number = vanadium_string output_run_string = vanadium_string if is_vanadium_run else run_number_string # Get the file extension if set file_extension = getattr(inst_settings, "file_extension") if file_extension: # Prefix dot if user has forgotten to file_extension = file_extension if file_extension.startswith('.') else '.' + file_extension # Get the output name suffix if set suffix = getattr(inst_settings, "suffix", None) # Sample empty if there is one as this is instrument specific sample_empty = getattr(inst_settings, "sample_empty", None) # By default, offset file sits in the calibration folder, but it can also be given as an absolute path if os.path.exists(offset_file_name): offset_file_path = offset_file_name else: offset_file_path = os.path.join(calibration_dir, label, offset_file_name) # Generate the paths grouping_file_path = os.path.join(calibration_dir, grouping_file_name) splined_van_path = os.path.join(calibration_dir, label, splined_van_name) unsplined_van_path = os.path.join(calibration_dir, label, unsplined_van_name) van_absorb_path = os.path.join(calibration_dir, van_abs_file_name) if van_abs_file_name else None return _RunDetails(empty_run_number=empty_run_number, file_extension=file_extension, run_number=run_number, output_run_string=output_run_string, label=label, offset_file_path=offset_file_path, grouping_file_path=grouping_file_path, splined_vanadium_path=splined_van_path, vanadium_run_number=vanadium_string, sample_empty=sample_empty, vanadium_abs_path=van_absorb_path, unsplined_vanadium_path=unsplined_van_path, output_suffix=suffix)
def _get_run_numbers_for_key(current_mode_run_numbers, key): err_message = "this must be under the relevant Rietveld or PDF mode." return common.cal_map_dictionary_key_helper( current_mode_run_numbers, key=key, append_to_error_message=err_message)
def create_run_details_object(run_number_string, inst_settings, is_vanadium_run, empty_run_call=None, grouping_file_name_call=None, vanadium_run_call=None, splined_name_list=None, van_abs_file_name=None): """ Creates and returns a run details object which holds various properties about the current run. :param run_number_string: The user string for the current run :param inst_settings: The current instrument object :param is_vanadium_run: Boolean of if the current run is a vanadium run :param empty_run_call: (Optional) Callable to setup custom empty run number(s) from mapping file :param grouping_file_name_call: (Optional) Callable to setup custom grouping file name :param vanadium_run_call: (Optional) Callable to setup custom van run number(s) from mapping file :param splined_name_list: (Optional) List of unique properties to generate a splined vanadium name from :param van_abs_file_name: (Optional) The name of the vanadium absorption file :return: RunDetails object with attributes set to applicable values """ cal_map_dict = RunDetailsWrappedCommonFuncs.get_cal_mapping_dict( run_number_string=run_number_string, inst_settings=inst_settings) run_number = common.get_first_run_number(run_number_string=run_number_string) # Get names of files we will be using calibration_dir = os.path.normpath(os.path.expanduser(inst_settings.calibration_dir)) label = common.cal_map_dictionary_key_helper(dictionary=cal_map_dict, key="label") offset_file_name = common.cal_map_dictionary_key_helper(dictionary=cal_map_dict, key="offset_file_name") # Always make sure the offset file name is included if splined_name_list: # Force Python to make a copy so we don't modify original new_splined_list = list(splined_name_list) new_splined_list.append(os.path.basename(offset_file_name)) else: new_splined_list = [os.path.basename(offset_file_name)] # These can either be generic or custom so defer to another method results_dict = _get_customisable_attributes( cal_dict=cal_map_dict, inst_settings=inst_settings, empty_run_call=empty_run_call, grouping_name_call=grouping_file_name_call, vanadium_run_call=vanadium_run_call, splined_name_list=new_splined_list) vanadium_run_string = results_dict["vanadium_runs"] if is_vanadium_run: # The run number should be the vanadium number in this case run_number = vanadium_run_string output_run_string = vanadium_run_string else: # Otherwise set it to the user input output_run_string = run_number_string # Get the file extension if set file_extension = getattr(inst_settings, "file_extension") if file_extension: # Prefix dot if user has forgotten to file_extension = file_extension if file_extension.startswith('.') else '.' + file_extension # Get the output name suffix if set suffix = getattr(inst_settings, "suffix", None) # Sample empty if there is one as this is instrument specific sample_empty = getattr(inst_settings, "sample_empty", None) # Generate the paths grouping_file_path = os.path.join(calibration_dir, results_dict["grouping_file_name"]) # By default, offset file sits in correct label folder, but it can also be given as an absolute path if os.path.exists(offset_file_name): offset_file_path = offset_file_name else: offset_file_path = os.path.join(calibration_dir, label, offset_file_name) # splined vanadium is within the correct label folder splined_van_path = os.path.join(calibration_dir, label, results_dict["splined_van_name"]) unsplined_van_path = os.path.join(calibration_dir, label, results_dict["unsplined_van_name"]) van_absorb_path = os.path.join(calibration_dir, van_abs_file_name) if van_abs_file_name else None return _RunDetails(empty_run_number=results_dict["empty_runs"], file_extension=file_extension, run_number=run_number, output_run_string=output_run_string, label=label, offset_file_path=offset_file_path, grouping_file_path=grouping_file_path, splined_vanadium_path=splined_van_path, vanadium_run_number=vanadium_run_string, sample_empty=sample_empty, vanadium_abs_path=van_absorb_path, unsplined_vanadium_path=unsplined_van_path, output_suffix=suffix)
def _get_run_numbers_for_key(current_mode_run_numbers, key): err_message = "this must be under the relevant Rietveld or PDF mode." return common.cal_map_dictionary_key_helper(current_mode_run_numbers, key=key, append_to_error_message=err_message)
def hrpd_get_inst_mode(forwarded_value, inst_settings): cal_mapping = forwarded_value return common.cal_map_dictionary_key_helper(dictionary=cal_mapping, key=inst_settings.mode)
def hrpd_get_tof_window(forwarded_value, inst_settings): cal_mapping = forwarded_value return common.cal_map_dictionary_key_helper(dictionary=cal_mapping, key=inst_settings.tof_window)
def _get_current_mode_dictionary(run_number_string, inst_settings): mapping_dict = get_cal_mapping_dict(run_number_string, inst_settings.cal_mapping_path) # Get the current mode "Rietveld" or "PDF" run numbers return common.cal_map_dictionary_key_helper(mapping_dict, inst_settings.mode)
def _get_run_numbers_for_key(tof_dict, key): err_message = "this must be under 'coupled' or 'decoupled' and the time of flight window eg 10-110." return common.cal_map_dictionary_key_helper(tof_dict, key=key, append_to_error_message=err_message)
def polaris_get_chopper_config(forwarded_value, inst_settings): # Forwarded value should be a cal mapping cal_mapping = forwarded_value return common.cal_map_dictionary_key_helper(cal_mapping, inst_settings.mode)
def _get_current_mode_dictionary(run_number_string, inst_settings): mapping_dict = get_cal_mapping_dict(run_number_string, inst_settings.cal_mapping_path) # Get the current mode "Rietveld" or "PDF" run numbers return common.cal_map_dictionary_key_helper(mapping_dict, inst_settings.mode)
def cal_dictionary_key_helper(key, append_to_error_message=None, **kwargs): dictionary = kwargs.pop("forwarded_value") return common.cal_map_dictionary_key_helper(dictionary=dictionary, key=key, append_to_error_message=append_to_error_message)