def load_existing_calibration_files(self, file_path): if not path.exists(file_path): msg = "Could not open GSAS calibration file: " + file_path logger.warning(msg) raise try: instrument, ceria_no, params_table = self.get_info_from_file( file_path) self.update_calibration_params_table(params_table) except RuntimeError: logger.error("Invalid file selected: " + file_path) raise try: bank = EnggUtils.load_relevant_calibration_files(file_path) except Exception as e: logger.error( "Unable to loading calibration files corresponding to " + file_path + ". Error: " + str(e)) raise try: grp_ws_name, roi_text = EnggUtils.load_custom_grouping_workspace( file_path) except Exception as e: logger.error( "Unable to load grouping workspace corresponding to " + file_path + ". Error: " + str(e)) raise return instrument, ceria_no, grp_ws_name, roi_text, bank
def save_calibration(ceria_run, van_run, calibration_directory, calibration_general, name, bank_names, zeros, difcs): """ save the calibration data @param ceria_run :: the run number of the ceria @param van_run :: the run number of the vanadium @param calibration_directory :: the user specific calibration directory to save to @param calibration_general :: the general calibration directory to save to @param name :: the name of the banks being saved @param bank_names :: the list of banks to save @param difcs :: the list of difc values to save @param zeros :: the list of tzero values to save """ gsas_iparm_fname = os.path.join(calibration_directory, "ENGINX_" + van_run + "_" + ceria_run + "_" + name + ".prm") # work out what template to use if name == "all_banks": template_file = None elif name == "bank_South": template_file = "template_ENGINX_241391_236516_South_bank.prm" else: template_file = "template_ENGINX_241391_236516_North_bank.prm" # write out the param file to the users directory Utils.write_ENGINX_GSAS_iparam_file(output_file=gsas_iparm_fname, bank_names=bank_names, difc=difcs, tzero=zeros, ceria_run=ceria_run, vanadium_run=van_run, template_file=template_file) if not calibration_general == calibration_directory: # copy the param file to the general directory if not os.path.exists(calibration_general): os.makedirs(calibration_general) copy2(gsas_iparm_fname, calibration_general)
def create_new_calibration(calibration, rb_num, plot_output, save_dir=output_settings.get_output_path()): full_calib = load_full_instrument_calibration() EnggUtils.create_new_calibration(calibration, rb_num, plot_output, save_dir, full_calib)
def save_calibration(ceria_run, van_run, calibration_directory, calibration_general, name, bank_names, zeros, difcs, difas): """ save the calibration data @param ceria_run :: the run number of the ceria @param van_run :: the run number of the vanadium @param calibration_directory :: the user specific calibration directory to save to @param calibration_general :: the general calibration directory to save to @param name :: the name of the banks being saved @param bank_names :: the list of banks to save @param difas :: the list of difa values to save @param difcs :: the list of difc values to save @param zeros :: the list of tzero values to save """ gsas_iparm_fname = os.path.join(calibration_directory, "ENGINX_" + van_run + "_" + ceria_run + "_" + name + ".prm") # work out what template to use if name == "all_banks": template_file = None elif name == "bank_South": template_file = "template_ENGINX_241391_236516_South_bank.prm" else: template_file = "template_ENGINX_241391_236516_North_bank.prm" # write out the param file to the users directory Utils.write_ENGINX_GSAS_iparam_file(output_file=gsas_iparm_fname, bank_names=bank_names, difa=difas, difc=difcs, tzero=zeros, ceria_run=ceria_run, vanadium_run=van_run, template_file=template_file) if not calibration_general == calibration_directory: # copy the param file to the general directory if not os.path.exists(calibration_general): os.makedirs(calibration_general) copy2(gsas_iparm_fname, calibration_general)
def _check_region_grouping_ws_exists(grouping_ws_name: str, inst_ws) -> bool: """ Check that the required grouping workspace for this focus exists, and if not present for a North/South bank focus, retrieve them from the user directories or create them (expected if first focus with loaded calibration) :param grouping_ws_name: Name of the grouping workspace whose presence in the ADS is being checked :param inst_ws: Workspace containing the instrument data for use in making a bank grouping workspace :return: True if the required workspace exists (or has just been loaded/created), False if not """ if not Ads.doesExist(grouping_ws_name): if "North" in grouping_ws_name: logger.notice( "NorthBank grouping workspace not present in ADS, loading") EnggUtils.get_bank_grouping_workspace(1, inst_ws) return True elif "South" in grouping_ws_name: logger.notice( "SouthBank grouping workspace not present in ADS, loading") EnggUtils.get_bank_grouping_workspace(2, inst_ws) return True else: logger.warning( f"Cannot focus as the grouping workspace \"{grouping_ws_name}\" is not present." ) return False return True
def generate_prm_output_file(difa_list, difc_list, tzero_list, bank_name, kwargs_to_pass): file_path = calibration_dir + EnggUtils.generate_output_file_name( ceria_path, instrument, bank=bank_name) EnggUtils.write_ENGINX_GSAS_iparam_file(file_path, difa_list, difc_list, tzero_list, bk2bk_params, **kwargs_to_pass) set_setting(output_settings.INTERFACES_SETTINGS_GROUP, output_settings.ENGINEERING_PREFIX, "last_calibration_path", file_path)
def save_calibration(ceria_run, calibration_directory, calibration_general, name, bank_names, zeros, difcs, difas, bk2bk_params): """ save the calibration data @param ceria_run :: the run number of the ceria @param calibration_directory :: the user specific calibration directory to save to @param calibration_general :: the general calibration directory to save to @param name :: the name of the banks being saved @param bank_names :: the list of banks to save @param difas :: the list of difa values to save @param difcs :: the list of difc values to save @param zeros :: the list of tzero values to save """ file_save_prefix = os.path.join(calibration_directory, "ENGINX_" + ceria_run + "_") gsas_iparm_fname = file_save_prefix + name + ".prm" pdcals_to_save = dict() # fname: workspace # work out what template to use, and which PDCalibration files to save if name == "all_banks": template_file = None pdcals_to_save[file_save_prefix + "bank_North.nxs"] = 'engg_calibration_bank_1' pdcals_to_save[file_save_prefix + "bank_South.nxs"] = 'engg_calibration_bank_2' elif name == "bank_2": template_file = "template_ENGINX_241391_South_bank.prm" pdcals_to_save[file_save_prefix + "bank_South.nxs"] = 'engg_calibration_bank_2' elif name == "bank_1": template_file = "template_ENGINX_241391_North_bank.prm" pdcals_to_save[file_save_prefix + "bank_North.nxs"] = 'engg_calibration_bank_1' else: # cropped uses North bank template template_file = "template_ENGINX_241391_North_bank.prm" pdcals_to_save[file_save_prefix + "cropped.nxs"] = 'engg_calibration_cropped' # write out the param file to the users directory Utils.write_ENGINX_GSAS_iparam_file(output_file=gsas_iparm_fname, bank_names=bank_names, difa=difas, difc=difcs, tzero=zeros, ceria_run=ceria_run, template_file=template_file, bk2bk_params=bk2bk_params) for fname, ws in pdcals_to_save.items(): simple.SaveNexus(InputWorkspace=ws, Filename=fname) if not calibration_general == calibration_directory: # copy the param file to the general directory if not os.path.exists(calibration_general): os.makedirs(calibration_general) copy2(gsas_iparm_fname, calibration_general) for fname in pdcals_to_save.keys(): copy2(fname, calibration_general)
def focus_cropped(run_number, van_curves, van_int, full_inst_calib, focus_directory, focus_general, do_pre_process, params, time_period, crop_on, use_spectra): """ focus a partial run, cropping either on banks or on specific spectra @param van_curves :: the path to the vanadium curves file @param van_int :: the path to the integrated vanadium file @param full_inst_calib :: workspace containing the full instrument calibration @param run_number :: the run nuumber to focus @param focus_directory :: the user specific focus directory to save to @param focus_general :: the general focus directory to save to @param do_pre_process :: whether or not to pre-process the run before focussing it @param params :: the rebin parameters for pre-processing @param time_period :: the time period for pre-processing @param crop_on :: the bank or spectra to crop on @param use_spectra :: whether to focus by spectra or banks """ van_curves_ws, van_integrated_ws, ws_to_focus = _prepare_focus(run_number, van_curves, van_int, do_pre_process, params, time_period) tof_output_name = "engg_focus_output{0}{1}" sample_ws_clone = simple.CloneWorkspace(ws_to_focus) curves_ws_clone = simple.CloneWorkspace(van_curves_ws) # check whether to crop on bank or spectra if not use_spectra: # get the bank to crop on, focus and save it out bank = {"North": "1", "South": "2"} bank_no = bank.get(crop_on) cal_file = NORTH_BANK_CAL if bank_no == 1 else SOUTH_BANK_CAL region_calib = 'engg_calibration_bank_1' if bank_no == 1 else 'engg_calibration_bank_2' df_kwarg = {"GroupingFileName": cal_file} tof_output_name = tof_output_name.format("_bank_", bank_no) dspacing_output_name = tof_output_name + "_dSpacing" _run_focus(input_workspace=sample_ws_clone, tof_output_name=tof_output_name, vanadium_integration_ws=van_integrated_ws, vanadium_curves_ws=curves_ws_clone, df_kwarg=df_kwarg, full_calib=full_inst_calib, region_calib=region_calib) _save_out(run_number, focus_directory, focus_general, tof_output_name, "ENGINX_{}_{}{{}}", crop_on) _save_out(run_number, focus_directory, focus_general, dspacing_output_name, "ENGINX_{}_{}{{}}", crop_on) else: # crop on the spectra passed in, focus and save it out tof_output_name = tof_output_name.format("_", "cropped") dspacing_output_name = tof_output_name + "_dSpacing" grp_ws = Utils.create_grouping_workspace_from_spectra_list(crop_on, ws_to_focus) df_kwarg = {"GroupingWorkspace": grp_ws} region_calib = 'engg_calibration_cropped' _run_focus(input_workspace=sample_ws_clone, tof_output_name=tof_output_name, vanadium_integration_ws=van_integrated_ws, vanadium_curves_ws=curves_ws_clone, df_kwarg=df_kwarg, region_calib=region_calib, full_calib=full_inst_calib) _save_out(run_number, focus_directory, focus_general, tof_output_name, "ENGINX_{}_bank_{}{{}}", "cropped") _save_out(run_number, focus_directory, focus_general, dspacing_output_name, "ENGINX_{}_bank_{}{{}}", "cropped") simple.DeleteWorkspace(sample_ws_clone) simple.DeleteWorkspace(curves_ws_clone)
def focus_run( self, sample_paths: list, vanadium_path: str, plot_output: bool, rb_num: str, calibration: CalibrationInfo, save_dir: Optional[str] = output_settings.get_output_path() ) -> None: full_calib = load_full_instrument_calibration() focused_files = EnggUtils.focus_run(sample_paths, vanadium_path, plot_output, rb_num, calibration, save_dir, full_calib) self._last_focused_files.extend(focused_files)
def focus_texture_mode(run_number, van_curves, van_int, full_inst_calib, focus_directory, focus_general, do_pre_process, params, time_period, dg_file): """ perform a texture mode focusing using the grouping csv file @param run_number :: the run number to focus @param van_curves :: the path to the vanadium curves file @param van_int :: the path to the integrated vanadium file @param full_inst_calib :: workspace containing the full instrument calibration @param focus_directory :: the user specific focus directory to save to @param focus_general :: the general focus directory to save to @param do_pre_process :: whether or not to pre-process the run before focussing it @param params :: the rebin parameters for pre-processing @param time_period :: the time period for pre-processing @param dg_file :: the grouping file to use for texture mode """ van_curves_ws, van_integrated_ws, ws_to_focus = _prepare_focus(run_number, van_curves, van_int, do_pre_process, params, time_period) banks = {} # read the csv file to work out the banks # ensure csv reading works on python 2 or 3 with open(dg_file, 'r', newline='', encoding='utf-8') as grouping_file: group_reader = csv.reader(_decomment_csv(grouping_file), delimiter=',') for row in group_reader: banks.update({row[0]: ','.join(row[1:])}) # loop through the banks described in the csv, focusing and saving them out for bank in banks: sample_ws_clone = simple.CloneWorkspace(ws_to_focus) curves_ws_clone = simple.CloneWorkspace(van_curves_ws) tof_output_name = "engg_focusing_output_ws_texture_bank_{}" tof_output_name = tof_output_name.format(bank) dspacing_output_name = tof_output_name + "_dSpacing" grp_ws = Utils.create_grouping_workspace_from_spectra_list(banks[bank], ws_to_focus) df_kwarg = {"GroupingWorkspace": grp_ws} _run_focus(input_workspace=sample_ws_clone, tof_output_name=tof_output_name, region_calib=full_inst_calib, vanadium_curves_ws=curves_ws_clone, full_calib=full_inst_calib, df_kwarg=df_kwarg, vanadium_integration_ws=van_integrated_ws) _save_out(run_number, focus_directory, focus_general, tof_output_name, "ENGINX_{}_texture_{}{{}}", bank) _save_out(run_number, focus_directory, focus_general, dspacing_output_name, "ENGINX_{}_texture_{}{{}}", bank) simple.DeleteWorkspace(sample_ws_clone) simple.DeleteWorkspace(curves_ws_clone)
def run(ceria_run, do_cal, do_van, full_inst_calib, van_run, calibration_directory, calibration_general, cropped, crop_name, crop_on, focus_directory, focus_general, do_pre_process, params, time_period, focus_run, grouping_file): """ calls methods needed based off of inputs @param ceria_run :: the run number of the ceria to use @param do_cal :: whether or not to force running calibration @param do_van :: whether or not to force calculating the vanadium @param full_inst_calib :: workspace containing the full instrument calibration @param van_run :: run number to use for the vanadium @param calibration_directory :: the users calibration directory @param calibration_general :: the non-user specific calibration directory @param crop_on :: where to crop using the cropping method @param crop_name :: how to name cropped banks @param cropped :: the cropping method to use @param focus_directory :: the users focus directory @param focus_general :: the non-user specific focus directory @param do_pre_process:: whether or not to pre-process before focussing @param params :: list of parameters to use for rebinning @param time_period :: time period to old binning @param focus_run :: run number to focus @param grouping_file :: grouping file to use with texture mode """ # check whether creating a vanadium is required or requested if (not os.path.isfile(_get_van_names(van_run, calibration_directory)[0])) or do_van: create_vanadium_integration(van_run, calibration_directory) # find the file names of calibration files that would be created by this run cal_endings = {"banks": ["all_banks", f"bank_{crop_on}"], "spectra": ["all_banks", f"bank_{crop_name}"], None: ["all_banks", "bank_North", "bank_South"]} expected_cals = [f"ENGINX_{van_run}_{ceria_run}_{ending}.prm" for ending in cal_endings.get(cropped)] expected_cals_present = [os.path.isfile(os.path.join(calibration_directory, cal_file)) for cal_file in expected_cals] pdcal_table_endings = {"banks": [f"bank_{crop_on}"], "spectra": ["cropped"], None: ["bank_North", "bank_South"]} expected_pdcal_tables = [f"ENGINX_{van_run}_{ceria_run}_{ending}.nxs" for ending in pdcal_table_endings.get(cropped)] expected_tables_present = [os.path.isfile(os.path.join(calibration_directory, cal_file)) for cal_file in expected_pdcal_tables] # if the calibration files that this run would create are not present, or the user has requested it, create the # calibration files if not all(expected_cals_present) or not all(expected_tables_present) or do_cal: create_calibration(ceria_run, van_run, full_inst_calib, calibration_directory, calibration_general, cropped, crop_name, crop_on) else: ending_to_load = {"banks": f"bank_{crop_on}", "spectra": crop_name, None: "all_banks"} file_name = os.path.join(calibration_directory, f"ENGINX_{van_run}_{ceria_run}_{ending_to_load.get(cropped)}.prm") Utils.load_relevant_calibration_files(file_name, "engg") # if a focus is requested, run the focus if focus_run is not None: focus(focus_run, van_run, full_inst_calib, calibration_directory, focus_directory, focus_general, do_pre_process, params, time_period, grouping_file, cropped, crop_on)
def load_existing_calibration_files(calibration): load_full_instrument_calibration() EnggUtils.load_existing_calibration_files(calibration)
def save_pdcal_output_file(ws_name_suffix, bank_name): file_path = calibration_dir + EnggUtils.generate_output_file_name( ceria_path, instrument, bank=bank_name, ext=".nxs") ws_name = "engggui_calibration_" + ws_name_suffix SaveNexus(InputWorkspace=ws_name, Filename=file_path)
def create_calibration_files(ceria_run, van_run, full_inst_calib, int_van, van_curves_file, calibration_directory, calibration_general, use_spectrum_number, crop_name, spec_nos): """ create and save a calibration @param ceria_run :: run number for the ceria used @param van_run :: the run number of the vanadium to use @param int_van :: name of the integrated vanadium workspace @param full_inst_calib :: workspace containing the full instrument calibration @param van_curves_file :: path to save vanadium curves to @param calibration_directory :: the user specific calibration directory to save to @param calibration_general :: the general calibration directory @param use_spectrum_number :: whether or not to crop using spectrum numbers or banks @param crop_name :: name of the output workspace @param spec_nos :: the value to crop on, either a spectra number, or a bank """ van_integrated_ws = load_van_integration_file(int_van) ceria_ws = simple.Load(Filename="ENGINX" + ceria_run, OutputWorkspace="engg_calib") van_file = _gen_filename(van_run) van_ws = simple.Load(Filename=van_file) bank_names = ["North", "South"] # check which cropping method to use if use_spectrum_number: spectrum_numbers = spec_nos bank = None else: if spec_nos.lower() == "north" or spec_nos == '1': spectrum_numbers = None bank = '1' elif spec_nos.lower() == "south" or spec_nos == '2': spectrum_numbers = None bank = '2' else: spectrum_numbers = None bank = None output, ceria_raw, curves = run_calibration(sample_ws=ceria_ws, vanadium_workspace=van_ws, van_integration=van_integrated_ws, bank=bank, spectrum_numbers=spectrum_numbers, full_inst_calib=full_inst_calib) handle_van_curves(curves, van_curves_file) bk2bk_params = extract_b2b_params(ceria_raw) if len(output) == 1: # get the values needed for saving out the .prm files difa = [output[0]['difa']] difc = [output[0]['difc']] tzero = [output[0]['tzero']] if bank is None and spectrum_numbers is None: save_calibration(ceria_run, calibration_directory, calibration_general, "all_banks", [crop_name], tzero, difc, difa, bk2bk_params) if spectrum_numbers is not None: save_calibration(ceria_run, calibration_directory, calibration_general, "bank_cropped", [crop_name], tzero, difc, difa, bk2bk_params) else: save_calibration(ceria_run, calibration_directory, calibration_general, "bank_{}".format(spec_nos), [crop_name], tzero, difc, difa, bk2bk_params) # create the table workspace containing the parameters param_tbl_name = crop_name if crop_name is not None else "Cropped" create_params_table(difc, tzero, difa) plot_dict = Utils.generate_tof_fit_dictionary(param_tbl_name) Utils.plot_tof_fit([plot_dict], [param_tbl_name]) else: difas = [row['difa'] for row in output] difcs = [row['difc'] for row in output] tzeros = [row['tzero'] for row in output] plot_dicts = list() for i in range(1, 3): save_calibration(ceria_run, calibration_directory, calibration_general, f"bank_{i}", [bank_names[i - 1]], [tzeros[i - 1]], [difcs[i - 1]], [difas[i - 1]], bk2bk_params) plot_dicts.append(Utils.generate_tof_fit_dictionary(f"bank_{i}")) save_calibration(ceria_run, calibration_directory, calibration_general, "all_banks", bank_names, tzeros, difcs, difas, bk2bk_params) # create the table workspace containing the parameters create_params_table(difcs, tzeros, difas) Utils.plot_tof_fit(plot_dicts, ["bank_1", "bank_2"])
def create_new_calibration(self, ceria_path, plot_output, instrument, rb_num=None, bank=None, calfile=None, spectrum_numbers=None): """ Create a new calibration from a ceria run :param ceria_path: Path to ceria (CeO2) data file :param plot_output: Whether the output should be plotted. :param instrument: The instrument the data relates to. :param rb_num: The RB number for file creation. :param bank: Optional parameter to crop by bank :param calfile: Optional parameter to crop using a custom calfile :param spectrum_numbers: Optional parameter to crop using spectrum numbers. """ ceria_workspace = path_handling.load_workspace(ceria_path) if Ads.doesExist("full_inst_calib"): full_calib = Ads.retrieve("full_inst_calib") else: full_calib_path = get_setting( output_settings.INTERFACES_SETTINGS_GROUP, output_settings.ENGINEERING_PREFIX, "full_calibration") try: full_calib = Load(full_calib_path, OutputWorkspace="full_inst_calib") except ValueError: logger.error( "Error loading Full instrument calibration - this is set in the interface settings." ) return cal_params, ceria_raw, grp_ws = self.run_calibration( ceria_workspace, bank, calfile, spectrum_numbers, full_calib) if plot_output: plot_dicts = list() if len(cal_params) == 1: if calfile: bank_name = "Custom" elif spectrum_numbers: bank_name = "Cropped" else: bank_name = bank plot_dicts.append( EnggUtils.generate_tof_fit_dictionary(bank_name)) EnggUtils.plot_tof_fit(plot_dicts, [bank_name]) else: plot_dicts.append( EnggUtils.generate_tof_fit_dictionary("bank_1")) plot_dicts.append( EnggUtils.generate_tof_fit_dictionary("bank_2")) EnggUtils.plot_tof_fit(plot_dicts, ["bank_1", "bank_2"]) difa = [row['difa'] for row in cal_params] difc = [row['difc'] for row in cal_params] tzero = [row['tzero'] for row in cal_params] bk2bk_params = self.extract_b2b_params(ceria_raw) DeleteWorkspace(ceria_raw) params_table = [] for i in range(len(difc)): params_table.append([i, difc[i], difa[i], tzero[i]]) self.update_calibration_params_table(params_table) calib_dir = path.join(output_settings.get_output_path(), "Calibration", "") if calfile: EnggUtils.save_grouping_workspace(grp_ws, calib_dir, ceria_path, instrument, calfile=calfile) elif spectrum_numbers: EnggUtils.save_grouping_workspace(grp_ws, calib_dir, ceria_path, instrument, spec_nos=spectrum_numbers) self.create_output_files(calib_dir, difa, difc, tzero, bk2bk_params, ceria_path, instrument, bank, spectrum_numbers, calfile) if rb_num: user_calib_dir = path.join(output_settings.get_output_path(), "User", rb_num, "Calibration", "") self.create_output_files(user_calib_dir, difa, difc, tzero, bk2bk_params, ceria_path, instrument, bank, spectrum_numbers, calfile)
def run_calibration(ceria_ws, bank, calfile, spectrum_numbers, full_calib): """ Creates Engineering calibration files with PDCalibration :param ceria_ws: The workspace with the ceria data. :param bank: The bank to crop to, both if none. :param calfile: The custom calibration file to crop to, not used if none. :param spectrum_numbers: The spectrum numbers to crop to, no crop if none. :return: dict containing calibrated diffractometer constants, and copy of the raw ceria workspace """ def run_pd_calibration(kwargs_to_pass) -> list: """ Call PDCalibration using the keyword arguments supplied, and return it's default list of output workspaces :param kwargs_to_pass: Keyword arguments to supply to the algorithm :return: List of output workspaces from PDCalibration """ return PDCalibration(**kwargs_to_pass) def calibrate_region_of_interest(ceria_d_ws, roi: str, grouping_kwarg: dict, cal_output: dict) -> None: """ Focus the processed ceria workspace (dSpacing) over the chosen region of interest, and run the calibration using this result :param ceria_d_ws: Workspace containing the processed ceria data converted to dSpacing :param roi: String describing chosen region of interest :param grouping_kwarg: Dict containing kwarg to pass to DiffractionFocussing to select the roi :param cal_output: Dictionary to append with the output of PDCalibration for the chosen roi """ # focus ceria focused_ceria = DiffractionFocussing(InputWorkspace=ceria_d_ws, **grouping_kwarg) ApplyDiffCal(InstrumentWorkspace=focused_ceria, ClearCalibration=True) ConvertUnits(InputWorkspace=focused_ceria, OutputWorkspace=focused_ceria, Target='TOF') # calibration of focused data over chosen region of interest kwargs["InputWorkspace"] = focused_ceria kwargs["OutputCalibrationTable"] = "engggui_calibration_" + roi kwargs["DiagnosticWorkspaces"] = "diag_" + roi cal_roi = run_pd_calibration(kwargs)[0] cal_output[roi] = cal_roi # need to clone the data as PDCalibration rebins ceria_raw = CloneWorkspace(InputWorkspace=ceria_ws) # initial process of ceria ws NormaliseByCurrent(InputWorkspace=ceria_ws, OutputWorkspace=ceria_ws) ApplyDiffCal(InstrumentWorkspace=ceria_ws, CalibrationWorkspace=full_calib) ConvertUnits(InputWorkspace=ceria_ws, OutputWorkspace=ceria_ws, Target='dSpacing') kwargs = { "PeakPositions": EnggUtils.default_ceria_expected_peaks(final=True), "TofBinning": [15500, -0.0003, 52000], # using a finer binning now have better stats "PeakWindow": 0.04, "MinimumPeakHeight": 0.5, "PeakFunction": 'BackToBackExponential', "CalibrationParameters": 'DIFC+TZERO+DIFA', "UseChiSq": True } cal_output = dict() grp_ws = None if (spectrum_numbers or calfile) is None: if bank == '1' or bank is None: grp_ws = EnggUtils.get_bank_grouping_workspace(1, ceria_raw) grouping_kwarg = {"GroupingWorkspace": grp_ws} calibrate_region_of_interest(ceria_ws, "bank_1", grouping_kwarg, cal_output) if bank == '2' or bank is None: grp_ws = EnggUtils.get_bank_grouping_workspace(2, ceria_raw) grouping_kwarg = {"GroupingWorkspace": grp_ws} calibrate_region_of_interest(ceria_ws, "bank_2", grouping_kwarg, cal_output) elif calfile is None: grp_ws = EnggUtils.create_grouping_workspace_from_spectra_list( spectrum_numbers, ceria_raw) grouping_kwarg = {"GroupingWorkspace": grp_ws} calibrate_region_of_interest(ceria_ws, "Cropped", grouping_kwarg, cal_output) else: grp_ws = EnggUtils.create_grouping_workspace_from_calfile( calfile, ceria_raw) grouping_kwarg = {"GroupingWorkspace": grp_ws} calibrate_region_of_interest(ceria_ws, "Custom", grouping_kwarg, cal_output) cal_params = list() # in the output calfile, rows are present for all detids, only read one from the region of interest for bank_cal in cal_output: mask_ws_name = "engggui_calibration_" + bank_cal + "_mask" mask_ws = Ads.retrieve(mask_ws_name) row_no = EnggUtils.get_first_unmasked_specno_from_mask_ws(mask_ws) row = cal_output[bank_cal].row(row_no) current_fit_params = { 'difc': row['difc'], 'difa': row['difa'], 'tzero': row['tzero'] } cal_params.append(current_fit_params) return cal_params, ceria_raw, grp_ws
def run_calibration(sample_ws, vanadium_workspace, van_integration, bank, spectrum_numbers, full_inst_calib): """ Creates Engineering calibration files with PDCalibration :param sample_ws: The workspace with the sample data. :param vanadium_workspace: The workspace with the vanadium data :param van_integration: The integration values from the vanadium corrections :param bank: The bank to crop to, both if none. :param spectrum_numbers: The spectrum numbers to crop to, no crop if none. :param full_inst_calib : workspace containing the full instrument calibration :return: The calibration output files, the vanadium curves workspace(s), and a clone of the sample file """ def run_pd_calibration(kwargs_to_pass): return simple.PDCalibration(**kwargs_to_pass) def focus_and_make_van_curves(ceria_d, vanadium_d, grouping_kwarg): # focus ceria focused_ceria = simple.DiffractionFocussing(InputWorkspace=ceria_d, **grouping_kwarg) simple.ApplyDiffCal(InstrumentWorkspace=focused_ceria, ClearCalibration=True) tof_focused = simple.ConvertUnits(InputWorkspace=focused_ceria, Target='TOF') # focus van data focused_van = simple.DiffractionFocussing(InputWorkspace=vanadium_d, **grouping_kwarg) background_van = simple.EnggEstimateFocussedBackground(InputWorkspace=focused_van, NIterations='15', XWindow=0.03) simple.DeleteWorkspace(focused_ceria) simple.DeleteWorkspace(focused_van) return tof_focused, background_van def ws_initial_process(ws): """Run some processing common to both the sample and vanadium workspaces""" simple.NormaliseByCurrent(InputWorkspace=ws, OutputWorkspace=ws) simple.ApplyDiffCal(InstrumentWorkspace=ws, CalibrationWorkspace=full_inst_calib) simple.ConvertUnits(InputWorkspace=ws, OutputWorkspace=ws, Target='dSpacing') return ws def calibrate_region_of_interest(roi, df_kwarg): focused_roi, curves_roi = focus_and_make_van_curves(ws_d, ws_van_d, df_kwarg) simple.RenameWorkspace(curves_roi, ("curves_" + roi)) curves_output.append(curves_roi) # final calibration of focused data kwargs["InputWorkspace"] = focused_roi kwargs["OutputCalibrationTable"] = "engg_calibration_" + roi kwargs["DiagnosticWorkspaces"] = "diag_" + roi cal_roi = run_pd_calibration(kwargs)[0] cal_output[roi] = cal_roi # need to clone the data as PDCalibration rebins sample_raw = simple.CloneWorkspace(InputWorkspace=sample_ws) ws_van = simple.CloneWorkspace(vanadium_workspace) ws_van_d = ws_initial_process(ws_van) # sensitivity correction ws_van_d /= van_integration simple.ReplaceSpecialValues(InputWorkspace=ws_van_d, OutputWorkspace=ws_van_d, NaNValue=0, InfinityValue=0) ws_d = ws_initial_process(sample_ws) simple.DeleteWorkspace(van_integration) kwargs = { "PeakPositions": Utils.default_ceria_expected_peaks(final=True), "TofBinning": [15500, -0.0003, 52000], # using a finer binning now have better stats "PeakWindow": 0.04, "MinimumPeakHeight": 0.5, "PeakFunction": 'BackToBackExponential', "CalibrationParameters": 'DIFC+TZERO+DIFA', "UseChiSq": True } cal_output = dict() curves_output = list() if spectrum_numbers is None: if bank == '1' or bank is None: df_kwarg = {"GroupingFileName": NORTH_BANK_CAL} calibrate_region_of_interest("bank_1", df_kwarg) if bank == '2' or bank is None: df_kwarg = {"GroupingFileName": SOUTH_BANK_CAL} calibrate_region_of_interest("bank_2", df_kwarg) else: grp_ws = Utils.create_grouping_workspace_from_spectra_list(spectrum_numbers, sample_raw) df_kwarg = {"GroupingWorkspace": grp_ws} calibrate_region_of_interest("Cropped", df_kwarg) simple.DeleteWorkspace(ws_van) simple.DeleteWorkspace("tof_focused") cal_params = list() # in the output calfile, rows are present for all detids, only read one from the region of interest bank_1_read_row = 0 bank_2_read_row = 1200 for bank_cal in cal_output: if bank_cal == "bank_1": read = bank_1_read_row elif bank_cal == "bank_2": read = bank_2_read_row else: read = int(Utils.create_spectrum_list_from_string(spectrum_numbers)[0]) # this can be int64 row = cal_output[bank_cal].row(read) current_fit_params = {'difc': row['difc'], 'difa': row['difa'], 'tzero': row['tzero']} cal_params.append(current_fit_params) return cal_params, sample_raw, curves_output