def apply_vanadium_absorb_corrections(van_ws, run_details, absorb_ws=None): def generate_det_id_list(ws): det_id_list = [] for i in range(0, ws.getNumberHistograms()): try: det_ids = ws.getSpectrum(i).getDetectorIDs() except RuntimeError: pass else: for det_id in det_ids: det_id_list.append(det_id) return det_id_list if absorb_ws is None: absorb_ws = mantid.Load(Filename=run_details.vanadium_absorption_path) van_original_units = van_ws.getAxis(0).getUnit().unitID() absorb_units = absorb_ws.getAxis(0).getUnit().unitID() if van_original_units != absorb_units: van_ws = mantid.ConvertUnits(InputWorkspace=van_ws, Target=absorb_units, OutputWorkspace=van_ws) # PEARL sometimes do special runs with different detector cards so extract common spectra before doing # RebinToWorkspace to ensure histogram by histogram by rebin abs_det_id_list = generate_det_id_list(absorb_ws) van_det_id_list = generate_det_id_list(van_ws) common_det_ids = [det_id for det_id in abs_det_id_list if det_id in van_det_id_list] if not common_det_ids: raise RuntimeError("No common detectors in Vanadium and sample workspaces") MSG_STEM = "Vanadium workspace and absorption workspaces have different spectra. " if common_det_ids != van_det_id_list: logger.warning(MSG_STEM + "Removing unmatched spectra from the Vanadium workspace") van_ws = mantid.ExtractSpectra(InputWorkspace=van_ws, DetectorList=common_det_ids) if common_det_ids != abs_det_id_list: logger.warning(MSG_STEM + "Removing unmatched spectra from the absorption workspace") absorb_ws = mantid.ExtractSpectra(InputWorkspace=absorb_ws, DetectorList=common_det_ids) absorb_ws = mantid.RebinToWorkspace(WorkspaceToRebin=absorb_ws, WorkspaceToMatch=van_ws, OutputWorkspace=absorb_ws) van_ws = mantid.Divide(LHSWorkspace=van_ws, RHSWorkspace=absorb_ws, OutputWorkspace=van_ws, AllowDifferentNumberSpectra=True) if van_original_units != absorb_units: van_ws = mantid.ConvertUnits(InputWorkspace=van_ws, Target=van_original_units, OutputWorkspace=van_ws) common.remove_intermediate_workspace(absorb_ws) return van_ws
def convert_monitors_ws(ws, converter, **ignored): import mantid.simpleapi as mantid dim, unit = validate_and_get_unit(ws.getAxis(0).getUnit().unitID()) spec_dim, spec_coord = init_spec_axis(ws) spec_info = spec_info = ws.spectrumInfo() comp_info = ws.componentInfo() monitors = [] indexes = (ws.getIndexFromSpectrumNumber(int(i)) for i in spec_coord.values) for index in indexes: definition = spec_info.getSpectrumDefinition(index) if not definition.size() == 1: raise RuntimeError("Cannot deal with grouped monitor detectors") det_index = definition[0][0] # Ignore time index # We only ExtractSpectra for compability with # exising convert_Workspace2D_to_dataarray. This could instead be # refactored if found to be slow monitor_ws = mantid.ExtractSpectra(InputWorkspace=ws, WorkspaceIndexList=[index], StoreInADS=False) single_monitor = converter(monitor_ws) # Remove redundant information that is duplicated from workspace # We get this extra information from the generic converter reuse del single_monitor.labels['sample_position'] del single_monitor.labels['detector_info'] del single_monitor.attrs['run'] del single_monitor.attrs['sample'] monitors.append((comp_info.name(det_index), single_monitor)) return monitors
def _calibration_processing(calibration_dir, calibration_runs, cross_correlate_params, get_det_offset_params, grouping_file_name, input_ws, instrument, offset_file, rebin_1_params, rebin_2_params): calibration_ws = input_ws if calibration_ws.getAxis(0).getUnit().unitID() != WORKSPACE_UNITS.d_spacing: calibration_ws = mantid.Rebin(InputWorkspace=input_ws, Params=rebin_1_params) calibration_ws = mantid.ConvertUnits(InputWorkspace=calibration_ws, Target="dSpacing") spectrum_list = [] for i in range(0, calibration_ws.getNumberHistograms()): try: calibration_ws.getDetector(i) except RuntimeError: pass else: spectrum_list.append(i) calibration_ws = mantid.ExtractSpectra(InputWorkspace=calibration_ws, WorkspaceIndexList=spectrum_list) rebinned = mantid.Rebin(InputWorkspace=calibration_ws, Params=rebin_2_params) cross_correlated = mantid.CrossCorrelate(InputWorkspace=rebinned, **cross_correlate_params) # Offsets workspace must be referenced as string so it can be deleted, as simpleapi doesn't recognise it as a ws offsets_ws_name = "offsets" mantid.GetDetectorOffsets(InputWorkspace=cross_correlated, GroupingFileName=offset_file, OutputWorkspace=offsets_ws_name, **get_det_offset_params) rebinned_tof = mantid.ConvertUnits(InputWorkspace=rebinned, Target="TOF") aligned = mantid.AlignDetectors(InputWorkspace=rebinned_tof, CalibrationFile=offset_file) grouping_file = os.path.join(calibration_dir, grouping_file_name) focused = mantid.DiffractionFocussing(InputWorkspace=aligned, GroupingFileName=grouping_file, OutputWorkspace=instrument._generate_output_file_name(calibration_runs) + "_grouped") print("Saved cal file to " + offset_file) common.remove_intermediate_workspace([calibration_ws, rebinned, cross_correlated, rebinned_tof, offsets_ws_name]) return focused
def generate_ts_pdf(run_number, focus_file_path, merge_banks=False, q_lims=None, cal_file_name=None, sample_details=None, delta_r=None, delta_q=None, pdf_type="G(r)", lorch_filter=None, freq_params=None, debug=False): focused_ws = _obtain_focused_run(run_number, focus_file_path) focused_ws = mantid.ConvertUnits(InputWorkspace=focused_ws, Target="MomentumTransfer", EMode='Elastic') raw_ws = mantid.Load(Filename='POLARIS'+str(run_number)+'.nxs') sample_geometry = common.generate_sample_geometry(sample_details) sample_material = common.generate_sample_material(sample_details) self_scattering_correction = mantid.TotScatCalculateSelfScattering( InputWorkspace=raw_ws, CalFileName=cal_file_name, SampleGeometry=sample_geometry, SampleMaterial=sample_material, CrystalDensity=sample_details.material_object.crystal_density) ws_group_list = [] for i in range(self_scattering_correction.getNumberHistograms()): ws_name = 'correction_' + str(i) mantid.ExtractSpectra(InputWorkspace=self_scattering_correction, OutputWorkspace=ws_name, WorkspaceIndexList=[i]) ws_group_list.append(ws_name) self_scattering_correction = mantid.GroupWorkspaces(InputWorkspaces=ws_group_list) self_scattering_correction = mantid.RebinToWorkspace(WorkspaceToRebin=self_scattering_correction, WorkspaceToMatch=focused_ws) focused_ws = mantid.Subtract(LHSWorkspace=focused_ws, RHSWorkspace=self_scattering_correction) if delta_q: focused_ws = mantid.Rebin(InputWorkspace=focused_ws, Params=delta_q) if merge_banks: q_min, q_max = _load_qlims(q_lims) merged_ws = mantid.MatchAndMergeWorkspaces(InputWorkspaces=focused_ws, XMin=q_min, XMax=q_max, CalculateScale=False) fast_fourier_filter(merged_ws, freq_params=freq_params) pdf_output = mantid.PDFFourierTransform(Inputworkspace="merged_ws", InputSofQType="S(Q)-1", PDFType=pdf_type, Filter=lorch_filter, DeltaR=delta_r, rho0=sample_details.material_object.crystal_density) else: for ws in focused_ws: fast_fourier_filter(ws, freq_params=freq_params) pdf_output = mantid.PDFFourierTransform(Inputworkspace='focused_ws', InputSofQType="S(Q)-1", PDFType=pdf_type, Filter=lorch_filter, DeltaR=delta_r, rho0=sample_details.material_object.crystal_density) pdf_output = mantid.RebinToWorkspace(WorkspaceToRebin=pdf_output, WorkspaceToMatch=pdf_output[4], PreserveEvents=True) if not debug: common.remove_intermediate_workspace('self_scattering_correction') # Rename output ws if 'merged_ws' in locals(): mantid.RenameWorkspace(InputWorkspace='merged_ws', OutputWorkspace=run_number + '_merged_Q') mantid.RenameWorkspace(InputWorkspace='focused_ws', OutputWorkspace=run_number+'_focused_Q') if isinstance(focused_ws, WorkspaceGroup): for i in range(len(focused_ws)): mantid.RenameWorkspace(InputWorkspace=focused_ws[i], OutputWorkspace=run_number+'_focused_Q_'+str(i+1)) mantid.RenameWorkspace(InputWorkspace='pdf_output', OutputWorkspace=run_number+'_pdf_R') if isinstance(pdf_output, WorkspaceGroup): for i in range(len(pdf_output)): mantid.RenameWorkspace(InputWorkspace=pdf_output[i], OutputWorkspace=run_number+'_pdf_R_'+str(i+1)) return pdf_output
def _get_focused_wks(self, wks_prop_name, index_prop_name): in_wks = self.getProperty(wks_prop_name).value in_idx = self.getProperty(index_prop_name).value if in_wks.getNumberHistograms() > 1 or 0 != in_idx: focused_wks = msapi.ExtractSpectra(InputWorkspace = in_wks, StartWorkspaceIndex = in_idx, EndworkspaceIndex = in_idx) else: focused_wks = in_wks return focused_wks
def _extract_spectrum_from_workspace(self): """ Extract a single spectrum from the input workspace. If the input workspace only has one spectrum then just return the input workspace :return: Single-spectrum workspace """ ws = self.getProperty(self.PROP_INPUT_WORKSPACE).value if ws.getNumberHistograms > 1: ws_index = self.getPropertyValue(self.PROP_WORKSPACE_INDEX) spectrum = mantid.ExtractSpectra(InputWorkspace=ws, StartWorkspaceIndex=ws_index, EndWorkspaceIndex=ws_index, StoreInADS=False) else: spectrum = mantid.CloneWorkspace(InputWorkspace=ws, StoreInADS=False) return spectrum
def _extract_spectrum_from_workspace(self): """ Extract a single spectrum from the input workspace. If the input workspace only has one spectrum then just return the input workspace :return: Single-spectrum workspace """ ws = self.getPropertyValue(self.PROP_INPUT_WORKSPACE) if mtd[ws].getNumberHistograms > 1: ws_index = self.getPropertyValue(self.PROP_WORKSPACE_INDEX) spectrum = mantid.ExtractSpectra(InputWorkspace=ws, StartWorkspaceIndex=ws_index, EndWorkspaceIndex=ws_index) mantid.DeleteWorkspace(Workspace=ws) return spectrum else: return ws
def generate_ts_pdf(run_number, focus_file_path, merge_banks=False, q_lims=None, cal_file_name=None, sample_details=None, output_binning=None, pdf_type="G(r)", freq_params=None): focused_ws = _obtain_focused_run(run_number, focus_file_path) focused_ws = mantid.ConvertUnits(InputWorkspace=focused_ws, Target="MomentumTransfer", EMode='Elastic') raw_ws = mantid.Load(Filename='POLARIS'+str(run_number)+'.nxs') sample_geometry = common.generate_sample_geometry(sample_details) sample_material = common.generate_sample_material(sample_details) self_scattering_correction = mantid.TotScatCalculateSelfScattering(InputWorkspace=raw_ws, CalFileName=cal_file_name, SampleGeometry=sample_geometry, SampleMaterial=sample_material) ws_group_list = [] for i in range(self_scattering_correction.getNumberHistograms()): ws_name = 'correction_' + str(i) mantid.ExtractSpectra(InputWorkspace=self_scattering_correction, OutputWorkspace=ws_name, WorkspaceIndexList=[i]) ws_group_list.append(ws_name) self_scattering_correction = mantid.GroupWorkspaces(InputWorkspaces=ws_group_list) self_scattering_correction = mantid.RebinToWorkspace(WorkspaceToRebin=self_scattering_correction, WorkspaceToMatch=focused_ws) focused_ws = mantid.Subtract(LHSWorkspace=focused_ws, RHSWorkspace=self_scattering_correction) if merge_banks: q_min, q_max = _load_qlims(q_lims) merged_ws = mantid.MatchAndMergeWorkspaces(InputWorkspaces=focused_ws, XMin=q_min, XMax=q_max, CalculateScale=False) fast_fourier_filter(merged_ws, freq_params) pdf_output = mantid.PDFFourierTransform(Inputworkspace="merged_ws", InputSofQType="S(Q)-1", PDFType=pdf_type, Filter=True) else: for ws in focused_ws: fast_fourier_filter(ws, freq_params) pdf_output = mantid.PDFFourierTransform(Inputworkspace='focused_ws', InputSofQType="S(Q)-1", PDFType=pdf_type, Filter=True) pdf_output = mantid.RebinToWorkspace(WorkspaceToRebin=pdf_output, WorkspaceToMatch=pdf_output[4], PreserveEvents=True) common.remove_intermediate_workspace('self_scattering_correction') if output_binning is not None: try: pdf_output = mantid.Rebin(InputWorkspace=pdf_output, Params=output_binning) except RuntimeError: return pdf_output return pdf_output
def rebin_workspace(self, input_ws, binning_param_list, output_ws_name): """ rebin input workspace with user specified binning parameters :param input_ws: :param binning_param_list: :param output_ws_name: :return: """ if binning_param_list is None: # no re-binning is required: clone the output workspace output_workspace = api.CloneWorkspace( InputWorkspace=input_ws, OutputWorkspace=output_ws_name) else: # rebin input workspace processed_single_spec_ws_list = list() for ws_index in range(input_ws.getNumberHistograms()): # rebin on each temp_out_name = output_ws_name + '_' + str(ws_index) processed_single_spec_ws_list.append(temp_out_name) # extract a spectrum out api.ExtractSpectra(input_ws, WorkspaceIndexList=[ws_index], OutputWorkspace=temp_out_name) # get binning parameter bin_params = binning_param_list[ws_index] if bin_params is None: continue # rebin # check if len(bin_params) % 2 == 0: # odd number and cannot be binning parameters raise RuntimeError( 'Binning parameter {0} cannot be accepted.'.format( bin_params)) api.Rebin(InputWorkspace=temp_out_name, OutputWorkspace=temp_out_name, Params=bin_params, PreserveEvents=True) rebinned_ws = AnalysisDataService.retrieve(temp_out_name) self.log().warning( 'Rebinnd workspace Size(x) = {0}, Size(y) = {1}'.format( len(rebinned_ws.readX(0)), len(rebinned_ws.readY(0)))) # Upon this point, the workspace is still HistogramData. # Check whether it is necessary to reset the X-values to reference TOF from VDRIVE temp_out_ws = AnalysisDataService.retrieve(temp_out_name) if len(bin_params) == 2 * len(temp_out_ws.readX(0)) - 1: reset_bins = True else: reset_bins = False # convert to point data api.ConvertToPointData(InputWorkspace=temp_out_name, OutputWorkspace=temp_out_name) # align the bin boundaries if necessary temp_out_ws = AnalysisDataService.retrieve(temp_out_name) if reset_bins: # good to align: for tof_i in range(len(temp_out_ws.readX(0))): temp_out_ws.dataX(0)[tof_i] = int( bin_params[2 * tof_i] * 10) / 10. # END-FOR (tof-i) # END-IF (align) # END-FOR # merge together api.RenameWorkspace( InputWorkspace=processed_single_spec_ws_list[0], OutputWorkspace=output_ws_name) for ws_index in range(1, len(processed_single_spec_ws_list)): api.ConjoinWorkspaces( InputWorkspace1=output_ws_name, InputWorkspace2=processed_single_spec_ws_list[ws_index]) # END-FOR output_workspace = AnalysisDataService.retrieve(output_ws_name) # END-IF-ELSE return output_workspace
def generate_ts_pdf(run_number, focus_file_path, sample_details, merge_banks=False, q_lims=None, cal_file_name=None, delta_r=None, delta_q=None, pdf_type="G(r)", lorch_filter=None, freq_params=None, debug=False): if sample_details is None: raise RuntimeError( "A SampleDetails object was not set. Please create a SampleDetails object and set the " "relevant properties it. Then set the new sample by calling set_sample_details()" ) focused_ws = _obtain_focused_run(run_number, focus_file_path) focused_ws = mantid.ConvertUnits(InputWorkspace=focused_ws, Target="MomentumTransfer", EMode='Elastic') raw_ws = mantid.Load(Filename='POLARIS' + str(run_number)) sample_geometry_json = sample_details.generate_sample_geometry() sample_material_json = sample_details.generate_sample_material() self_scattering_correction = mantid.TotScatCalculateSelfScattering( InputWorkspace=raw_ws, CalFileName=cal_file_name, SampleGeometry=sample_geometry_json, SampleMaterial=sample_material_json) ws_group_list = [] for i in range(self_scattering_correction.getNumberHistograms()): ws_name = 'correction_' + str(i) mantid.ExtractSpectra(InputWorkspace=self_scattering_correction, OutputWorkspace=ws_name, WorkspaceIndexList=[i]) ws_group_list.append(ws_name) self_scattering_correction = mantid.GroupWorkspaces( InputWorkspaces=ws_group_list) self_scattering_correction = mantid.RebinToWorkspace( WorkspaceToRebin=self_scattering_correction, WorkspaceToMatch=focused_ws) if not compare_ws_compatibility(focused_ws, self_scattering_correction): raise RuntimeError( "To use create_total_scattering_pdf you need to run focus with " "do_van_normalisation=true first.") focused_ws = mantid.Subtract(LHSWorkspace=focused_ws, RHSWorkspace=self_scattering_correction) if debug: dcs_corrected = mantid.CloneWorkspace(InputWorkspace=focused_ws) # convert diff cross section to S(Q) - 1 material_builder = MaterialBuilder() sample = material_builder.setFormula( sample_details.material_object.chemical_formula).build() sample_total_scatter_cross_section = sample.totalScatterXSection() sample_coh_scatter_cross_section = sample.cohScatterXSection() focused_ws = focused_ws - sample_total_scatter_cross_section / (4 * math.pi) focused_ws = focused_ws * 4 * math.pi / sample_coh_scatter_cross_section if debug: s_of_q_minus_one = mantid.CloneWorkspace(InputWorkspace=focused_ws) if delta_q: focused_ws = mantid.Rebin(InputWorkspace=focused_ws, Params=delta_q) if merge_banks: q_min, q_max = _load_qlims(q_lims) merged_ws = mantid.MatchAndMergeWorkspaces(InputWorkspaces=focused_ws, XMin=q_min, XMax=q_max, CalculateScale=False) fast_fourier_filter(merged_ws, rho0=sample_details.material_object.number_density, freq_params=freq_params) pdf_output = mantid.PDFFourierTransform( Inputworkspace="merged_ws", InputSofQType="S(Q)-1", PDFType=pdf_type, Filter=lorch_filter, DeltaR=delta_r, rho0=sample_details.material_object.number_density) else: for ws in focused_ws: fast_fourier_filter( ws, rho0=sample_details.material_object.number_density, freq_params=freq_params) pdf_output = mantid.PDFFourierTransform( Inputworkspace='focused_ws', InputSofQType="S(Q)-1", PDFType=pdf_type, Filter=lorch_filter, DeltaR=delta_r, rho0=sample_details.material_object.number_density) pdf_output = mantid.RebinToWorkspace(WorkspaceToRebin=pdf_output, WorkspaceToMatch=pdf_output[4], PreserveEvents=True) if not debug: common.remove_intermediate_workspace('self_scattering_correction') # Rename output ws if 'merged_ws' in locals(): mantid.RenameWorkspace(InputWorkspace='merged_ws', OutputWorkspace=run_number + '_merged_Q') mantid.RenameWorkspace(InputWorkspace='focused_ws', OutputWorkspace=run_number + '_focused_Q') target_focus_ws_name = run_number + '_focused_Q_' target_pdf_ws_name = run_number + '_pdf_R_' if isinstance(focused_ws, WorkspaceGroup): for i in range(len(focused_ws)): if str(focused_ws[i]) != (target_focus_ws_name + str(i + 1)): mantid.RenameWorkspace(InputWorkspace=focused_ws[i], OutputWorkspace=target_focus_ws_name + str(i + 1)) mantid.RenameWorkspace(InputWorkspace='pdf_output', OutputWorkspace=run_number + '_pdf_R') if isinstance(pdf_output, WorkspaceGroup): for i in range(len(pdf_output)): if str(pdf_output[i]) != (target_pdf_ws_name + str(i + 1)): mantid.RenameWorkspace(InputWorkspace=pdf_output[i], OutputWorkspace=target_pdf_ws_name + str(i + 1)) return pdf_output
def load_smoothed_vanadium(self, van_gsas_file): """ Load smoothed vanadium spectra from GSAS file :param van_gsas_file: :return: """ # check assert isinstance( van_gsas_file, str), 'Vanadium GSAS file name {0} must be a string.'.format(van_gsas_file) if os.path.exists(van_gsas_file) is False: raise RuntimeError('Vanadium GSAS file {0} cannot be found.'.format(van_gsas_file)) # load file and edit instrument for dSpacing mantidsimple.LoadGSS(Filename=van_gsas_file, OutputWorkspace='vanadium') # 3 banks mantidsimple.EditInstrumentGeometry(Workspace='vanadium', PrimaryFlightPath=43.753999999999998, SpectrumIDs='1, 2, 3', L2='2,2,2', Polar='-90,90,{}'.format(mantid_helper.HIGH_ANGLE_BANK_2THETA)) mantidsimple.ConvertUnits(InputWorkspace='vanadium', OutputWorkspace='vanadium', Target='dSpacing') # bank 1 and 2: extract, rebin and smooth for bank in [1, 2]: ws_name = 'van_bank_{0}'.format(bank) mantidsimple.ExtractSpectra(InputWorkspace='vanadium', OutputWorkspace='van2banks', WorkspaceIndexList=bank-1) mantidsimple.Rebin(InputWorkspace='van2banks', OutputWorkspace='van2banks', Params='0.3,-0.001, 3.5') mantidsimple.FFTSmooth(InputWorkspace='van2banks', OutputWorkspace=ws_name, Filter='Butterworth', Params='20,2', IgnoreXBins=True, AllSpectra=True) self._vanadiumWorkspaceDict[bank] = ws_name # END-FOR mantid_helper.delete_workspace('van2banks') # bank3: different algorithm because it has more bins than bank 1 and 2 but has some issue with Mantid for bank in [3]: # special processing for bank 3 mantidsimple.ExtractSpectra(InputWorkspace='vanadium', OutputWorkspace='vanhighbank', WorkspaceIndexList=bank-1) # sort the bins: FIXME might be better to use numpy array bank3ws = ADS.retrieve('vanhighbank') vecx = bank3ws.readX(0) vecy = bank3ws.readY(0) xy_list = list() for i in range(len(vecy)): xy_list.append((vecx[i], vecy[i])) # X might be out of order xy_list.sort() vec_x = numpy.ndarray(shape=(len(vecx),), dtype='float') vec_y = numpy.ndarray(shape=(len(vecy),), dtype='float') for i, xy in enumerate(xy_list): vec_x[i] = xy[0] vec_y[i] = xy[1] vec_x[-1] = vecx[-1] # re-create workspace mantidsimple.CreateWorkspace(DataX=vec_x, DataY=vec_y, NSpec=1, UnitX='dSpacing', OutputWorkspace='vanbank3') mantidsimple.Rebin(InputWorkspace='vanbank3', OutputWorkspace='vanbank3', Params='0.3,-0.001, 3.5') ws_name = 'van_bank_{0}'.format(bank) mantidsimple.FFTSmooth(InputWorkspace='vanbank3', OutputWorkspace=ws_name, WorkspaceIndex=0, Filter='Butterworth', Params='20,2', IgnoreXBins=True, AllSpectra=True) self._vanadiumWorkspaceDict[bank] = ws_name # clean mantid_helper.delete_workspace('vanbank3') mantid_helper.delete_workspace('vanhighbank') # END-FOR # make sure there won't be any less than 0 item for ws_name in self._vanadiumWorkspaceDict.keys(): van_bank_i_ws = mantid_helper.retrieve_workspace( self._vanadiumWorkspaceDict[ws_name], True) for i in range(len(van_bank_i_ws.readY(0))): if van_bank_i_ws.readY(0)[i] < 1.: van_bank_i_ws.dataY(0)[i] = 1. # END-FOR return