Ejemplo n.º 1
0
def fast_fourier_filter(ws, freq_params=None):
    if not freq_params:
        return
    # This is a simple fourier filter using the FFTSmooth to get a WS with only the low radius components, then
    # subtracting that from the merged WS

    x_range = ws.dataX(0)
    # The param p in FFTSmooth defined such that if the input ws has Nx bins then in the fourier space ws it will cut of
    # all frequencies in bins nk=Nk/p and above, calculated by p = pi/(k_c*dQ) when k_c is the cutoff frequency desired.
    # The input ws of FFTSmooth has binning [x_min, dx, x_max], with Nx bins.
    # FFTSmooth doubles the length of the input ws and preforms an FFT with output ws binning
    # [0, dk, k_max]=[0, 1/2*(x_max-x_min), 1/(2*dx)], and Nk=Nx bins.
    # k_max/k_c = Nk/nk
    # 1/(k_c*2*dx) = p
    # because FFT uses sin(2*pi*k*x) while PDFFourierTransform uses sin(Q*r) we need to include a factor of 2*pi
    # p = pi/(k_c*dQ)
    lower_freq_param = round(np.pi / (freq_params[0] * (x_range[1] - x_range[0])))
    # This is giving the FFTSmooth the data in the form of S(Q)-1, later we use PDFFourierTransform with Q(S(Q)-1)
    # it does not matter which we use in this case.
    tmp = mantid.FFTSmooth(InputWorkspace=ws, Filter="Zeroing", Params=str(lower_freq_param), StoreInADS=False,
                           IgnoreXBins=True)
    mantid.Minus(LHSWorkspace=ws, RHSWorkspace=tmp, OutputWorkspace=ws)
    if len(freq_params) > 1:
        upper_freq_param = round(np.pi / (freq_params[1] * (x_range[1] - x_range[0])))
        mantid.FFTSmooth(InputWorkspace=ws, OutputWorkspace=ws, Filter="Zeroing",
                         Params=str(upper_freq_param), IgnoreXBins=True)
Ejemplo n.º 2
0
    def smoothVanadiumSpectrum(self, expno, scanno, smoothparams_str):
        """
        """
        # Get reduced workspace
        wsmanager = self.getWorkspace(expno, scanno, raiseexception=True)
        vanRun = wsmanager.getProcessedVanadiumWS()
        outws = vanRun.name() + "_smooth"

        outws = api.FFTSmooth(InputWorkspace=vanRun,
                              OutputWorkspace=outws,
                              Filter="Butterworth",
                              Params=smoothparams_str,
                              IgnoreXBins=True,
                              AllSpectra=True)

        if outws is not None:
            wsmanager.setProcessedVanadiumDataTemp(outws, "FFT smooth")

        return True
Ejemplo n.º 3
0
    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