def fast_fourier_filter(ws, freq_params=None): if freq_params: x_range = ws.dataX(0) q_max = x_range[-1] q_delta = (x_range[1] - x_range[0]) r_min = freq_params[0] # If no maximum r is given a high r_max prevents loss of detail on the output. if len(freq_params) > 1: r_max = min(freq_params[1], 1000) else: r_max = 1000 ws_name = str(ws) mantid.PDFFourierTransform(Inputworkspace=ws_name, OutputWorkspace=ws_name, SofQType="S(Q)-1", PDFType="G(r)", Filter=True, DeltaR=0.01, Rmax=r_max, Direction='Forward') mantid.PDFFourierTransform(Inputworkspace=ws_name, OutputWorkspace=ws_name, SofQType="S(Q)-1", PDFType="G(r)", Filter=True, Qmax=q_max, deltaQ=q_delta, Rmin=r_min, Rmax=r_max, Direction='Backward')
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 _generate_grouped_ts_pdf(focused_ws, q_lims): focused_ws = mantid.ConvertUnits(InputWorkspace=focused_ws, Target="MomentumTransfer", EMode='Elastic') min_x = np.inf max_x = -np.inf num_x = -np.inf for ws in focused_ws: x_data = ws.dataX(0) min_x = min(np.min(x_data), min_x) max_x = max(np.max(x_data), max_x) num_x = max(x_data.size, num_x) binning = [min_x, (max_x - min_x) / num_x, max_x] focused_ws = mantid.Rebin(InputWorkspace=focused_ws, Params=binning) focused_data_combined = mantid.ConjoinSpectra(InputWorkspaces=focused_ws) mantid.MatchSpectra(InputWorkspace=focused_data_combined, OutputWorkspace=focused_data_combined, ReferenceSpectrum=5) if type(q_lims) == str: q_min = [] q_max = [] try: with open(q_lims, 'r') as f: line_list = [line.rstrip('\n') for line in f] for line in line_list[1:]: value_list = line.split() q_min.append(float(value_list[2])) q_max.append(float(value_list[3])) q_min = np.array(q_min) q_max = np.array(q_max) except IOError: raise RuntimeError("q_lims is not valid") elif type(q_lims) == list or type(q_lims) == np.ndarray: q_min = q_lims[0, :] q_max = q_lims[1, :] else: raise RuntimeError("q_lims is not valid") bin_width = np.inf for i in range(q_min.size): pdf_x_array = focused_data_combined.readX(i) tmp1 = np.where(pdf_x_array >= q_min[i]) tmp2 = np.amin(tmp1) q_min[i] = pdf_x_array[tmp2] q_max[i] = pdf_x_array[np.amax(np.where(pdf_x_array <= q_max[i]))] bin_width = min(pdf_x_array[1] - pdf_x_array[0], bin_width) focused_data_combined = mantid.CropWorkspaceRagged( InputWorkspace=focused_data_combined, XMin=q_min, XMax=q_max) focused_data_combined = mantid.Rebin( InputWorkspace=focused_data_combined, Params=[min(q_min), bin_width, max(q_max)]) focused_data_combined = mantid.SumSpectra( InputWorkspace=focused_data_combined, WeightedSum=True, MultiplyBySpectra=False) pdf_output = mantid.PDFFourierTransform( Inputworkspace=focused_data_combined, InputSofQType="S(Q)", PDFType="G(r)", Filter=True) return pdf_output
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 generate_ts_pdf(run_number, focus_file_path, merge_banks=False): focused_ws = _obtain_focused_run(run_number, focus_file_path) pdf_output = mantid.ConvertUnits(InputWorkspace=focused_ws.getName(), Target="MomentumTransfer") if merge_banks: raise RuntimeError("Merging banks is currently not supported") pdf_output = mantid.PDFFourierTransform(Inputworkspace=pdf_output, InputSofQType="S(Q)", PDFType="G(r)", Filter=True) pdf_output = mantid.RebinToWorkspace(WorkspaceToRebin=pdf_output, WorkspaceToMatch=pdf_output[4], PreserveEvents=True) return pdf_output
def fast_fourier_filter(ws, rho0, freq_params=None): # To be improved - input workspace doesn't have regular bins but output from this filter process does (and typically # has a lot more bins since the width is taken from the narrowest bin in the input) if freq_params: q_data = ws.dataX(0) q_max = q_data[-1] q_delta = (q_data[1] - q_data[0]) r_min = freq_params[0] # If no maximum r is given a high r_max prevents loss of detail on the output. if len(freq_params) > 1: r_max = min(freq_params[1], 1000) else: r_max = 1000 ws_name = str(ws) mantid.PDFFourierTransform(Inputworkspace=ws_name, OutputWorkspace=ws_name, SofQType="S(Q)-1", PDFType="g(r)", Filter=True, DeltaR=0.01, Rmax=r_max, Direction='Forward', rho0=rho0) # apply filter so that g(r)=0 for r < rmin => RDF(r)=0, G(r)~-r ws = mantid.mtd[ws_name] r_data = ws.dataX(0) y_data = ws.dataY(0) for i in range(len(r_data)): if r_data[i] < r_min and i < len( y_data): # ws will be points but cope if it's bin edges y_data[i] = 0. mantid.PDFFourierTransform(Inputworkspace=ws_name, OutputWorkspace=ws_name, SofQType="S(Q)-1", PDFType="g(r)", Filter=True, Qmax=q_max, deltaQ=q_delta, Rmax=r_max, Direction='Backward', rho0=rho0)
def generate_ts_pdf(run_number, focus_file_path, merge_banks=False, q_lims=None): focused_ws = _obtain_focused_run(run_number, focus_file_path) if merge_banks: pdf_output = _generate_grouped_ts_pdf(focused_ws, q_lims) else: focused_ws = mantid.ConvertUnits(InputWorkspace=focused_ws.name(), Target="MomentumTransfer") pdf_output = mantid.PDFFourierTransform(Inputworkspace=focused_ws, InputSofQType="S(Q)", PDFType="G(r)", Filter=True) pdf_output = mantid.RebinToWorkspace(WorkspaceToRebin=pdf_output, WorkspaceToMatch=pdf_output[4], PreserveEvents=True) common.remove_intermediate_workspace('focused_ws') return pdf_output
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 calculate_gr(self, sq_ws_name, pdf_type, min_r, delta_r, max_r, min_q, max_q, pdf_filter, rho0): """ Calculate G(R) :param sq_ws_name: workspace name of S(q) :param pdf_type: type of PDF as G(r), g(r) and RDF(r) :param min_r: R_min :param delta_r: delta R :param max_r: :param min_q: :param max_q: :param pdf_filter: type of PDF filter :param rho0: average number density used for g(r) and RDF(r) conversions :return: string as G(r) workspace's name """ # check assert isinstance(sq_ws_name, str) and AnalysisDataService.doesExist(sq_ws_name) assert isinstance(pdf_type, str) and len(pdf_type) > 0, \ 'PDF type is %s is not supported.' % str(pdf_type) assert min_r < max_r, 'Rmin must be less than Rmax (%f >= %f)' % ( min_r, max_r) assert delta_r < (max_r - min_r), 'Must have more than one bin in G(r) (%f >= %f)' \ '' % (delta_r, (max_r - min_r)) assert min_q < max_q, 'Qmin must be less than Qmax (%f >= %f)' % ( min_q, max_q) assert isinstance( pdf_filter, str) or pdf_filter is None, 'PDF filter must be a string or None.' # set to the current S(q) workspace name self._currSqWsName = sq_ws_name # set up the parameters for FourierTransform # output workspace prefix = 'G' if pdf_type.startswith('g'): prefix = 'g' elif pdf_type.startswith('R'): prefix = 'RDF' if self._currSqWsName in self._sqIndexDict: # for S(q) loaded from file ws_seq_index = self._sqIndexDict[self._currSqWsName] update_index = True else: # for S(q) calculated from IPython console ws_seq_index = 0 update_index = False if pdf_filter is None: pdf_filter = False else: pdf_filter = True if pdf_filter != 'lorch': print('[WARNING] PDF filter {0} is not supported.'.format( pdf_filter)) gr_ws_name = '%s(R)_%s_%d' % (prefix, self._currSqWsName, ws_seq_index) kwargs = { 'OutputWorkspace': gr_ws_name, 'Qmin': min_q, 'Qmax': max_q, 'PDFType': pdf_type, 'DeltaR': delta_r, 'Rmax': max_r, 'Filter': pdf_filter } if rho0 is not None: kwargs['rho0'] = rho0 # Print warning about using G(r) and rho0 if 'rho0' in kwargs and pdf_type == "G(r)": print( "WARNING: Modifying the density does not affect G(r) function") # get the input unit sofq_type = 'S(Q)' # do the FFT simpleapi.PDFFourierTransform(InputWorkspace=self._currSqWsName, InputSofQType=sofq_type, **kwargs) # check assert AnalysisDataService.doesExist( gr_ws_name), 'Failed to do Fourier Transform.' self._grWsNameDict[(min_q, max_q)] = gr_ws_name # update state variable if update_index: self._sqIndexDict[self._currSqWsName] += 1 return gr_ws_name