Beispiel #1
0
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')
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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)
Beispiel #7
0
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
Beispiel #8
0
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
Beispiel #9
0
    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