def generate_output_file_name(ceria_path, instrument, bank, ext='.prm'): """ Generate an output filename in the form INSTRUMENT_ceriaRunNo_BANKS :param vanadium_path: Path to vanadium data file :param ceria_path: Path to ceria data file :param instrument: The instrument in use. :param bank: The bank being saved. :param ext: Extension to be used on the saved file :return: The filename, the vanadium run number, and ceria run number. """ ceria_no = path_handling.get_run_number_from_path(ceria_path, instrument) filename = instrument + "_" + ceria_no + "_" if bank == "all": filename = filename + "all_banks" + ext elif bank == "north": filename = filename + "bank_1" + ext elif bank == "south": filename = filename + "bank_2" + ext elif bank == "Cropped": filename = filename + "Cropped" + ext elif bank == "Custom": filename = filename + "Custom" + ext else: raise ValueError("Invalid bank name entered") return filename
def _load_run_and_convert_to_dSpacing(filepath, instrument, full_calib): runno = path_handling.get_run_number_from_path(filepath, instrument) ws = mantid.Load(Filename=filepath, OutputWorkspace=str(runno)) if ws.getRun().getProtonCharge() > 0: ws = mantid.NormaliseByCurrent(InputWorkspace=ws, OutputWorkspace=ws.name()) else: logger.warning(f"Run {ws.name()} has invalid proton charge.") mantid.DeleteWorkspace(ws) return None mantid.ApplyDiffCal(InstrumentWorkspace=ws, CalibrationWorkspace=full_calib) ws = mantid.ConvertUnits(InputWorkspace=ws, OutputWorkspace=ws.name(), Target='dSpacing') return ws
def fetch_correction_workspaces(vanadium_path: str, instrument: str): # -> Workspace2D, Workspace2D """ Fetch workspaces from the ADS or create new ones. :param vanadium_path: The path to the requested vanadium run raw data. :param instrument: The instrument the data came from. """ van_run_no = path_handling.get_run_number_from_path( vanadium_path, instrument) if not check_workspaces_exist(van_run_no): van_integration_ws, van_processed_inst_ws = create_vanadium_corrections( vanadium_path, instrument) else: van_integration_ws = Ads.retrieve( str(van_run_no) + '_' + INTEGRATED_WORKSPACE_NAME) van_processed_inst_ws = Ads.retrieve( str(van_run_no) + '_' + PROCESSED_WORKSPACE_NAME) return van_integration_ws, van_processed_inst_ws
def process_vanadium(vanadium_path, calibration, full_calib): van_run = path_handling.get_run_number_from_path( vanadium_path, calibration.get_instrument()) van_foc_name = CURVES_PREFIX + calibration.get_group_suffix() if ADS.doesExist(van_foc_name): ws_van_foc = ADS.retrieve(van_foc_name) else: if ADS.doesExist(van_run): ws_van = ADS.retrieve( van_run) # will exist if have only changed the ROI else: ws_van = _load_run_and_convert_to_dSpacing( vanadium_path, calibration.get_instrument(), full_calib) if not ws_van: raise RuntimeError( f"vanadium run {van_run} has no proton_charge - " f"please supply a valid vanadium run to focus.") ws_van_foc = _focus_run_and_apply_roi_calibration( ws_van, calibration, ws_foc_name=van_foc_name) ws_van_foc = _smooth_vanadium(ws_van_foc) return ws_van_foc, van_run
def create_vanadium_corrections(vanadium_path: str, instrument: str): # -> Workspace, Workspace """ Runs the vanadium correction algorithm. :param vanadium_path: The path to the vanadium data. :return: The integrated workspace and the processed instrument workspace generated. """ try: run_no = path_handling.get_run_number_from_path( vanadium_path, instrument) van_ws = Load(Filename=vanadium_path, OutputWorkspace=str(run_no) + '_' + VANADIUM_INPUT_WORKSPACE_NAME) except Exception as e: logger.error( "Error when loading vanadium sample data. " "Could not run Load algorithm with vanadium run number: " + str(vanadium_path) + ". Error description: " + str(e)) raise RuntimeError # get full instrument calibration for instrument processing calculation if Ads.doesExist("full_inst_calib"): full_calib_ws = 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_ws = 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 integral_ws = _calculate_vanadium_integral(van_ws, run_no) processed_ws = _calculate_vanadium_processed_instrument( van_ws, full_calib_ws, integral_ws, run_no) return integral_ws, processed_ws
def create_output_files(self, calibration_dir, difa, difc, tzero, bk2bk_params, ceria_path, instrument, bank, spectrum_numbers, calfile): """ Create output files from the algorithms in the specified directory :param calibration_dir: The directory to save the files into. :param difa: DIFA values from calibration algorithm. :param difc: DIFC values from the calibration algorithm. :param tzero: TZERO values from the calibration algorithm. :param bk2bk_params: BackToBackExponential parameters from Parameters.xml file. :param ceria_path: The path to the ceria data file. :param instrument: The instrument (ENGINX or IMAT). :param bank: Optional parameter to crop by bank. :param spectrum_numbers: Optional parameter to crop using spectrum numbers. :param calfile: Optional parameter to crop with a custom calfile """ kwargs = { "ceria_run": path_handling.get_run_number_from_path(ceria_path, instrument) } def south_kwargs(): kwargs["template_file"] = SOUTH_BANK_TEMPLATE_FILE kwargs["bank_names"] = ["South"] def north_kwargs(): kwargs["template_file"] = NORTH_BANK_TEMPLATE_FILE kwargs["bank_names"] = ["North"] 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_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) if not path.exists(calibration_dir): makedirs(calibration_dir) if not (bank or spectrum_numbers or calfile): # both banks generate_prm_output_file(difa, difc, tzero, "all", kwargs) north_kwargs() generate_prm_output_file([difa[0]], [difc[0]], [tzero[0]], "north", kwargs) save_pdcal_output_file("bank_1", "north") south_kwargs() generate_prm_output_file([difa[1]], [difc[1]], [tzero[1]], "south", kwargs) save_pdcal_output_file("bank_2", "south") elif bank == "1": north_kwargs() generate_prm_output_file([difa[0]], [difc[0]], [tzero[0]], "north", kwargs) save_pdcal_output_file("bank_1", "north") elif bank == "2": south_kwargs() generate_prm_output_file([difa[0]], [difc[0]], [tzero[0]], "south", kwargs) save_pdcal_output_file("bank_2", "south") elif spectrum_numbers: # Custom crops use the north bank template north_kwargs() generate_prm_output_file([difa[0]], [difc[0]], [tzero[0]], "Cropped", kwargs) save_pdcal_output_file("Cropped", "Cropped") else: # custom calfile north_kwargs() generate_prm_output_file([difa[0]], [difc[0]], [tzero[0]], "Custom", kwargs) save_pdcal_output_file("Custom", "Custom") logger.notice( f"\n\nCalibration files saved to: \"{calibration_dir}\"\n\n")
def get_ceria_runno(self): if self.ceria_path and self.instrument: return path_handling.get_run_number_from_path( self.ceria_path, self.instrument)
def update_calibration(self, calibration): instrument = calibration.get_instrument() sample_no = path_handling.get_run_number_from_path( calibration.get_sample(), instrument) self.statusbar_observable.notify_subscribers( f"CeO2: {sample_no}, Instrument: {instrument}")
def focus_run(self, sample_paths: list, vanadium_path: str, plot_output: bool, instrument: str, rb_num: str, regions_dict: dict) -> None: """ Focus some data using the current calibration. :param sample_paths: The paths to the data to be focused. :param vanadium_path: Path to the vanadium file from the current calibration :param plot_output: True if the output should be plotted. :param instrument: The instrument that the data came from. :param rb_num: Number to signify the user who is running this focus :param regions_dict: dict region name -> grp_ws_name, defining region(s) of interest to focus over """ full_calib_path = get_setting( output_settings.INTERFACES_SETTINGS_GROUP, output_settings.ENGINEERING_PREFIX, "full_calibration") if not Ads.doesExist("full_inst_calib"): try: full_calib_workspace = Load(full_calib_path, OutputWorkspace="full_inst_calib") except RuntimeError: logger.error( "Error loading Full instrument calibration - this is set in the interface settings." ) return else: full_calib_workspace = Ads.retrieve("full_inst_calib") van_integration_ws, van_processed_inst_ws = vanadium_corrections.fetch_correction_workspaces( vanadium_path, instrument) # check correct region calibration(s) and grouping workspace(s) exists inst_ws = path_handling.load_workspace(sample_paths[0]) for region in regions_dict: calib_exists = self._check_region_calib_ws_exists(region) grouping_exists = self._check_region_grouping_ws_exists( regions_dict[region], inst_ws) if not (calib_exists and grouping_exists): return # loop over samples provided, focus each over region(s) specified in regions_dict output_workspaces = [] # List of collated workspaces to plot. self._last_focused_files = [] van_run_no = path_handling.get_run_number_from_path( vanadium_path, instrument) for sample_path in sample_paths: sample_workspace = path_handling.load_workspace(sample_path) run_no = path_handling.get_run_number_from_path( sample_path, instrument) # perform prefocus operations on whole instrument workspace prefocus_success = self._whole_inst_prefocus( sample_workspace, van_integration_ws, full_calib_workspace) if not prefocus_success: continue sample_plots = [ ] # if both banks focused, pass list with both so plotted on same figure for region, grouping_kwarg in regions_dict.items(): tof_output_name = str( run_no) + "_" + FOCUSED_OUTPUT_WORKSPACE_NAME + region dspacing_output_name = tof_output_name + "_dSpacing" region_calib_ws = self._get_region_calib_ws(region) curves = self._get_van_curves_for_roi(region, van_processed_inst_ws, grouping_kwarg) # perform focus over chosen region of interest self._run_focus(sample_workspace, tof_output_name, curves, grouping_kwarg, region_calib_ws) sample_plots.append(tof_output_name) self._save_output(instrument, run_no, van_run_no, region, tof_output_name, rb_num) self._save_output(instrument, run_no, van_run_no, region, dspacing_output_name, rb_num, unit="dSpacing") self._output_sample_logs(instrument, run_no, van_run_no, sample_workspace, rb_num) output_workspaces.append(sample_plots) DeleteWorkspace(sample_workspace) # remove created grouping workspace if present if Ads.doesExist("grp_ws"): DeleteWorkspace("grp_ws") # Plot the output if plot_output: for ws_names in output_workspaces: self._plot_focused_workspaces(ws_names)