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)
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
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