def guess_fwhm(self, **kw): if 'y' in kw: y=kw['y'] else: return self.config['FwhmPoints'] if 'x' in kw: x=kw['x'] else: x=numpy.arange(len(y))*1.0 #set at least a default value for the fwhm fwhm=4 zz=SpecfitFuns.subac(y,1.000,1000) yfit=y-zz #now I should do some sort of peak search ... maximum = max(yfit) idx = numpy.nonzero(yfit == maximum)[0] pos = numpy.take(x,idx)[-1] posindex = idx[-1] height = yfit[posindex] imin = posindex while ((yfit[imin] > 0.5*height) & (imin >0)): imin=imin - 1 imax=posindex while ((yfit[imax] > 0.5*height) & (imax <(len(yfit)-1))): imax=imax + 1 fwhm=max(imax-imin-1,fwhm) return fwhm
def bkg_internal(self,pars,x): """ Internal Background """ #fast #return self.zz #slow: recalculate the background as function of the parameters #yy=SpecfitFuns.subac(self.ydata*self.fitconfig['Yscaling'], # pars[0],pars[1]) yy=SpecfitFuns.subac(self.ydata*1.0, pars[0],pars[1]) nrx=shape(x)[0] nry=shape(yy)[0] if nrx == nry: return SpecfitFuns.subac(yy,pars[0],pars[1]) else: return SpecfitFuns.subac(numpy.take(yy,numpy.arange(0,nry,2)),pars[0],pars[1])
def interpolate(self, factor=1.): ''' Input ----- factor : float factor used to oversample existing data, use with caution. Interpolates all existing curves to an equidistant x-range using the either the active or the first curve do determine the number of data points. Use this method instead of self.getAllCurves() when performin FFT related tasks. Returns ------- interpCurves : ndarray Array containing the interpolated curves shown in the plot window. Format: [(x0, y0, legend0, info0), ...] ''' curves = self.getAllCurves() if len(curves) < 1: raise ValueError("At least 1 curve needed") if DEBUG: print('interpolate -- no curves present') return activeCurve = self.getActiveCurve() if not activeCurve: activeCurve = curves[0] else: activeLegend = activeCurve[2] idx = list.index([curve[2] for curve in curves], activeLegend) activeCurve = curves[idx] activeX, activeY, activeLegend, activeInfo = activeCurve[0:4] # Determine average spaceing between Datapoints step = numpy.average(numpy.diff(activeX)) xmin, xmax = self.getXLimits([x for (x,y,leg,info) in curves], overlap=False) num = factor * numpy.ceil((xmax-xmin)/step) # Create equidistant x-range, exclude first and last point xeq = numpy.linspace(xmin, xmax, num, endpoint=False)[:-1] # Interpolate on sections of xeq interpCurves = [] for (x,y,legend,info) in curves: idx = numpy.nonzero((x.min()<xeq) & (xeq<x.max()))[0] xi = numpy.take(xeq, idx) yi = SpecfitFuns.interpol([x], y, xi.reshape(-1,1), y.min()) yi.shape = -1 interpCurves += [(xi, yi, legend, info)] return interpCurves
def periodic_gauss(self, pars, x): """ Fit function periodic_gauss(pars, x) pars = [npeaks, delta, height, position, fwhm] """ newpars = numpy.zeros((pars[0], 3), numpy.float) for i in range(int(pars[0])): newpars[i, 0] = pars[2] newpars[i, 1] = pars[3] + i * pars[1] newpars[:, 2] = pars[4] return SpecfitFuns.gauss(newpars,x)
def estimateXANESEdge(spectrum, energy=None, full=False): if energy is None: x = numpy.arange(len(spectrum)).astype(numpy.float) else: x = numpy.array(energy, dtype=numpy.float, copy=True) y = numpy.array(spectrum, dtype=numpy.float, copy=True) # make sure data are sorted idx = energy.argsort(kind='mergesort') x = numpy.take(energy, idx) y = numpy.take(spectrum, idx) # make sure data are strictly increasing delta = x[1:] - x[:-1] dmin = delta.min() dmax = delta.max() if delta.min() <= 1.0e-10: # force data are strictly increasing # although we do not consider last point idx = numpy.nonzero(delta>0)[0] x = numpy.take(x, idx) y = numpy.take(y, idx) delta = None sortedX = x sortedY = y # use a regularly spaced spectrum if dmax != dmin: # choose the number of points or deduce it from # the input data length? nchannels = 5 * len(spectrum) xi = numpy.linspace(x[1], x[-2], nchannels).reshape(-1, 1) x.shape = -1 y.shape = -1 y = SpecfitFuns.interpol([x], y, xi, y.min()) x = xi x.shape = -1 y.shape = -1 # take the first derivative npoints = 7 xPrime = x[npoints:-npoints] yPrime = SGModule.getSavitzkyGolay(y, npoints=npoints, degree=2, order=1) # get the index at maximum value iMax = numpy.argmax(yPrime) if full: # return intermediate information return x[iMax], sortedX, sortedY, xPrime, yPrime else: # return the corresponding x value return x[iMax]
def _getSmooth(self, x, y): f=[0.25,0.5,0.25] try: if hasattr(y, "shape"): if len(y.shape) > 1: result=SpecfitFuns.SavitskyGolay(numpy.ravel(y).astype(numpy.float), self._fitConfiguration['fit']['stripfilterwidth']) else: result=SpecfitFuns.SavitskyGolay(numpy.array(y).astype(numpy.float), self._fitConfiguration['fit']['stripfilterwidth']) else: result=SpecfitFuns.SavitskyGolay(numpy.array(y).astype(numpy.float), self._fitConfiguration['fit']['stripfilterwidth']) except: err = sys.exc_info()[1] raise ValueError("Unsuccessful Savitsky-Golay smoothing: %s" % err) result=numpy.array(y).astype(numpy.float) if len(result) > 1: result[1:-1]=numpy.convolve(result,f,mode=0) result[0]=0.5*(result[0]+result[1]) result[-1]=0.5*(result[-1]+result[-2]) return result
def test(): import numpy from PyMca import SpecfitFuns x = numpy.arange(1000.) data = numpy.zeros((50, 1000), numpy.float) #the peaks to be fitted p0 = [100., 300., 50., 200., 500., 30., 300., 800., 65] #generate the data to be fitted for i in range(data.shape[0]): nPeaks = 3 - i % 3 data[i, :] = SpecfitFuns.gauss(p0[:3 * nPeaks], x) oldShape = data.shape data.shape = 1, oldShape[0], oldShape[1] instance = StackSimpleFit() instance.setData(x, data) instance.setConfigurationFile("C:\StackSimpleFit.cfg") instance.processStack()
def test(): import numpy from PyMca import SpecfitFuns x = numpy.arange(1000.) data = numpy.zeros((50, 1000), numpy.float) #the peaks to be fitted p0 = [100., 300., 50., 200., 500., 30., 300., 800., 65] #generate the data to be fitted for i in range(data.shape[0]): nPeaks = 3 - i % 3 data[i,:] = SpecfitFuns.gauss(p0[:3*nPeaks],x) oldShape = data.shape data.shape = 1,oldShape[0], oldShape[1] instance = StackSimpleFit() instance.setData(x, data) instance.setConfigurationFile("C:\StackSimpleFit.cfg") instance.processStack()
def seek(self,y,x=None,yscaling=None, fwhm=None, sensitivity=None, mca=None): """ SpecfitFunctions.seek(self,y, x=None, yscaling=None,fwhm=None,sensitivity=None, mca=None) It searches for peaks in the y array. If x it is given, it gives back the closest x(s) to the position of the peak(s). Otherways it gives back the index of the closest point to the peak. """ if yscaling is None: yscaling=self.config['Yscaling'] if fwhm is None: if self.config['AutoFwhm']: fwhm=self.guess_fwhm(x=x,y=y) else: fwhm=self.config['FwhmPoints'] if sensitivity is None: sensitivity=self.config['Sensitivity'] if mca is None: mca=self.config['McaMode'] search_fwhm=int(max(fwhm,3)) search_sensitivity=max(1.0,sensitivity) mca=1.0 if mca: ysearch = numpy.array(y) * yscaling else: ysearch = numpy.ones([len(y) + 2 * search_fwhm,], numpy.float) if y[0]: ysearch[0:(search_fwhm+1)]=ysearch[0:(search_fwhm+1)]*y[0]*yscaling else: ysearch[0:(search_fwhm+1)]=ysearch[0:(search_fwhm+1)]*yscaling*sum(y[0:3])/3.0 ysearch[-1:-(search_fwhm+1):-1]=ysearch[-1:-(search_fwhm+1):-1]*y[len(y)-1]*yscaling ysearch[search_fwhm:(search_fwhm+len(y))]=y*yscaling npoints=len(ysearch) if npoints > (1.5)*search_fwhm: peaks=SpecfitFuns.seek(ysearch,0,npoints, search_fwhm, search_sensitivity) else: peaks=[] if len(peaks) > 0: if mca == 0: for i in range(len(peaks)): peaks[i]=int(peaks[i]-search_fwhm) for i in peaks: if (i < 1) | (i > (npoints-1)): peaks.remove(i) if x is not None: if len(x) == len(y): for i in range(len(peaks)): peaks[i]=x[int(max(peaks[i],0))] #print "peaks found = ",peaks,"mca =",mca,"fwhm=",search_fwhm,\ # "sensi=",search_sensitivity,"scaling=",yscaling return peaks
self.connect(self.dismissButton, qt.SIGNAL("clicked()"), self.reject) self.connect(self.okButton, qt.SIGNAL("clicked()"), self.accept) def getParameters(self): parametersDict = self.parametersWidget.getParameters() return parametersDict def setParameters(self, ddict): return self.parametersWidget.setParameters(ddict) if __name__ == "__main__": app = qt.QApplication([]) if len(sys.argv) > 1: from PyMca import specfilewrapper as specfile sf = specfile.Specfile(sys.argv[1]) scan = sf[0] data = scan.data() energy = data[0, :] spectrum = data[1, :] w = XASNormalizationDialog(None, spectrum, energy=energy) else: from PyMca import SpecfitFuns noise = numpy.random.randn(1500.) x = 8000. + numpy.arange(1500.) y = SpecfitFuns.upstep([100, 8500., 50], x) w = XASNormalizationDialog(None, y + numpy.sqrt(y) * noise, energy=x) ret = w.exec_() if ret: print(w.getParameters())
def update(self): if self._y is None: return pars = self.getParameters() #smoothed data y = numpy.ravel(numpy.array(self._y)).astype(numpy.float) ysmooth = SpecfitFuns.SavitskyGolay(y, pars['stripfilterwidth']) f = [0.25, 0.5, 0.25] ysmooth[1:-1] = numpy.convolve(ysmooth, f, mode=0) ysmooth[0] = 0.5 * (ysmooth[0] + ysmooth[1]) ysmooth[-1] = 0.5 * (ysmooth[-1] + ysmooth[-2]) #loop for anchors x = self._x niter = pars['stripiterations'] anchorslist = [] if pars['stripanchorsflag']: if pars['stripanchorslist'] is not None: ravelled = x for channel in pars['stripanchorslist']: if channel <= ravelled[0]: continue index = numpy.nonzero(ravelled >= channel)[0] if len(index): index = min(index) if index > 0: anchorslist.append(index) if niter > 1000: stripBackground = SpecfitFuns.subac(ysmooth, pars['stripconstant'], niter, pars['stripwidth'], anchorslist) #final smoothing stripBackground = SpecfitFuns.subac(stripBackground, pars['stripconstant'], 500, 1, anchorslist) elif niter > 0: stripBackground = SpecfitFuns.subac(ysmooth, pars['stripconstant'], niter, pars['stripwidth'], anchorslist) else: stripBackground = 0.0 * ysmooth + ysmooth.min() if len(anchorslist) == 0: anchorslist = [0, len(ysmooth) - 1] anchorslist.sort() snipBackground = 0.0 * ysmooth lastAnchor = 0 width = pars['snipwidth'] for anchor in anchorslist: if (anchor > lastAnchor) and (anchor < len(ysmooth)): snipBackground[lastAnchor:anchor] =\ SpecfitFuns.snip1d(ysmooth[lastAnchor:anchor], width, 0) lastAnchor = anchor if lastAnchor < len(ysmooth): snipBackground[lastAnchor:] =\ SpecfitFuns.snip1d(ysmooth[lastAnchor:], width, 0) self.graphWidget.addCurve(x, y, \ legend='Input Data',\ replace=True, replot=False) self.graphWidget.addCurve(x, stripBackground,\ legend='Strip Background',\ replot=False) self.graphWidget.addCurve(x, snipBackground,\ legend='SNIP Background', replot=True)
def XASNormalize(self): #all curves curves = self.getAllCurves() nCurves = len(curves) if nCurves < 1: raise ValueError("At least one curve needed") return #get active curve activeCurve = self.getActiveCurve() if activeCurve is None: raise ValueError("Please select an active curve") return x, y, legend0, info = activeCurve #sort the values idx = numpy.argsort(x, kind='mergesort') x0 = numpy.take(x, idx) y0 = numpy.take(y, idx) xmin, xmax = self.getGraphXLimits() # get calculation parameters if self.widget is None: self._createWidget(y0, x0) parameters = self.parameters if parameters['auto_edge']: edge = None else: edge = parameters['edge_energy'] energy = x pre_edge_regions = parameters['pre_edge']['regions'] post_edge_regions = parameters['post_edge']['regions'] algorithm = 'polynomial' algorithm_parameters = {} algorithm_parameters['pre_edge_order'] = parameters['pre_edge']\ ['polynomial'] algorithm_parameters['post_edge_order'] = parameters['post_edge']\ ['polynomial'] i = 0 lastCurve = None for curve in curves: x, y, legend, info = curve[0:4] #take the portion ox x between limits idx = numpy.nonzero((x >= xmin) & (x <= xmax))[0] if not len(idx): #no overlap continue x = numpy.take(x, idx) y = numpy.take(y, idx) idx = numpy.nonzero((x0 >= x.min()) & (x0 <= x.max()))[0] if not len(idx): #no overlap continue xi = numpy.take(x0, idx) yi = numpy.take(y0, idx) #perform interpolation xi.shape = -1, 1 yw = SpecfitFuns.interpol([x], y, xi, yi.min()) # try: ... except: here? yw.shape = -1 xi.shape = -1 x, y = XASNormalization.XASNormalization( yw, energy=xi, edge=edge, pre_edge_regions=pre_edge_regions, post_edge_regions=post_edge_regions, algorithm=algorithm, algorithm_parameters=algorithm_parameters)[0:2] # if i == 0: replace = True replot = True i = 1 else: replot = False replace = False newLegend = " ".join(legend.split(" ")[:-1]) if not newLegend.startswith('Norm.'): newLegend = "Norm. " + newLegend self.addCurve(x, y, legend=newLegend, info=info, replot=replot, replace=replace) lastCurve = [x, y, newLegend] self.addCurve(lastCurve[0], lastCurve[1], legend=lastCurve[2], info=info, replot=True, replace=False)
def stepup(self,pars,x): """ A fit function. """ return 0.5*SpecfitFuns.upstep(pars,x)
def slit(self,pars,x): """ A fit function. """ return 0.5*SpecfitFuns.slit(pars,x)
def fftAlignment(self): curves = self.getAllCurves() nCurves = len(curves) if nCurves < 2: raise ValueError("At least 2 curves needed") return # get active curve activeCurve = self.getActiveCurve() if activeCurve is None: activeCurve = curves[0] # apply between graph limits x0 = activeCurve[0][:] y0 = activeCurve[1][:] xmin, xmax = self.getGraphXLimits() idx = numpy.nonzero((x0 >= xmin) & (x0 <= xmax))[0] x0 = numpy.take(x0, idx) y0 = numpy.take(y0, idx) #sort the values idx = numpy.argsort(x0, kind='mergesort') x0 = numpy.take(x0, idx) y0 = numpy.take(y0, idx) #remove duplicates x0 = x0.ravel() idx = numpy.nonzero((x0[1:] > x0[:-1]))[0] x0 = numpy.take(x0, idx) y0 = numpy.take(y0, idx) #make sure values are regularly spaced xi = numpy.linspace(x0[0], x0[-1], len(idx)).reshape(-1, 1) yi = SpecfitFuns.interpol([x0], y0, xi, y0.min()) x0 = xi y0 = yi y0.shape = -1 fft0 = numpy.fft.fft(y0) y0.shape = -1, 1 x0.shape = -1, 1 nChannels = x0.shape[0] # built a couple of temporary array of spectra for handy access tmpArray = numpy.zeros((nChannels, nCurves), numpy.float) fftList = [] shiftList = [] curveList = [] i = 0 for idx in range(nCurves): x, y, legend, info = curves[idx][0:4] #sort the values x = x[:] idx = numpy.argsort(x, kind='mergesort') x = numpy.take(x, idx) y = numpy.take(y, idx) #take the portion of x between limits idx = numpy.nonzero((x >= xmin) & (x <= xmax))[0] if not len(idx): # no overlap continue x = numpy.take(x, idx) y = numpy.take(y, idx) #remove duplicates x = x.ravel() idx = numpy.nonzero((x[1:] > x[:-1]))[0] x = numpy.take(x, idx) y = numpy.take(y, idx) x.shape = -1, 1 if numpy.allclose(x, x0): # no need for interpolation pass else: # we have to interpolate x.shape = -1 y.shape = -1 xi = x0[:] y = SpecfitFuns.interpol([x], y, xi, y0.min()) y.shape = -1 tmpArray[:, i] = y i += 1 # now calculate the shift ffty = numpy.fft.fft(y) fftList.append(ffty) if 0: self.addCurve(x, y, legend="NEW Y%d" % i, info=None, replot=True, replace=False) elif numpy.allclose(fft0, ffty): shiftList.append(0.0) else: shift = numpy.fft.ifft(fft0 * ffty.conjugate()).real shift2 = numpy.zeros(shift.shape, dtype=shift.dtype) m = shift2.size // 2 shift2[m:] = shift[:-m] shift2[:m] = shift[-m:] if 0: self.addCurve(numpy.arange(len(shift2)), shift2, legend="SHIFT", info=None, replot=True, replace=False) threshold = 0.50 * shift2.max() #threshold = shift2.mean() idx = numpy.nonzero(shift2 > threshold)[0] #print("max indices = %d" % (m - idx)) shift = (shift2[idx] * idx / shift2[idx].sum()).sum() #print("shift = ", shift - m, "in x units = ", (shift - m) * (x[1]-x[0])) # shift the curve shift = (shift - m) * (x[1] - x[0]) x.shape = -1 y = numpy.fft.ifft(numpy.exp(-2.0*numpy.pi*numpy.sqrt(numpy.complex(-1))*\ numpy.fft.fftfreq(len(x), d=x[1]-x[0])*shift)*numpy.fft.fft(y)) y = y.real y.shape = -1 curveList.append([x, y, legend + "SHIFT", False, False]) tmpArray = None curveList[-1][-2] = True curveList[-1][-1] = False x, y, legend, replot, replace = curveList[0] self.addCurve(x, y, legend=legend, replot=True, replace=True) for i in range(1, len(curveList)): x, y, legend, replot, replace = curveList[i] self.addCurve(x, y, legend=legend, info=None, replot=replot, replace=False) return # now get the final spectrum y = medianSpectra.sum(axis=1) / nCurves x0.shape = -1 y.shape = x0.shape legend = "%d Median from %s to %s" % (width, curves[0][2], curves[-1][2]) self.addCurve(x0, y, legend=legend, info=None, replot=True, replace=True)
def hypermet(self,pars,x): """ A fit function. """ return SpecfitFuns.ahypermet(pars,x,self.config['HypermetTails'],0)
def stepDown(self, pars, x): """ Complementary error function like. """ return 0.5 * SpecfitFuns.downstep(pars, x)
def slit(self, pars, x): """ Function to calulate slit width and knife edge cut """ return 0.5 * SpecfitFuns.slit(pars, x)
def estimate_periodic_gauss(self,xx,yy,zzz,xscaling=1.0,yscaling=None): if yscaling == None: try: yscaling=self.config['Yscaling'] except: yscaling=1.0 if yscaling == 0: yscaling=1.0 fittedpar=[] zz=SpecfitFuns.subac(yy,1.000,10000) npoints = len(zz) if self.config['AutoFwhm']: search_fwhm=self.guess_fwhm(x=xx,y=yy) else: search_fwhm=int(float(self.config['FwhmPoints'])) search_sens=float(self.config['Sensitivity']) search_mca=int(float(self.config['McaMode'])) if search_fwhm < 3: search_fwhm = 3 self.config['FwhmPoints']=3 if search_sens < 1: search_sens = 1 self.config['Sensitivity']=1 if npoints > 1.5*search_fwhm: peaks=self.seek(yy,fwhm=search_fwhm, sensitivity=search_sens, yscaling=yscaling, mca=search_mca) else: peaks = [] npeaks = len(peaks) if not npeaks: fittedpar = [] cons = numpy.zeros((3,len(fittedpar)), numpy.float) return fittedpar, cons fittedpar = [0.0, 0.0, 0.0, 0.0, 0.0] #The number of peaks fittedpar[0] = npeaks #The separation between peaks in x units delta = 0.0 height = 0.0 for i in range(npeaks): height += yy[int(peaks[i])] - zz [int(peaks[i])] if i != ((npeaks)-1): delta += (xx[int(peaks[i+1])] - xx[int(peaks[i])]) #delta between peaks if npeaks > 1: fittedpar[1] = delta/(npeaks-1) #starting height fittedpar[2] = height/npeaks #position of the first peak fittedpar[3] = xx[int(peaks[0])] #Estimate the fwhm fittedpar[4] = search_fwhm #setup constraints cons = numpy.zeros((3, 5), numpy.float) cons [0] [0] = CFIXED #the number of gaussians if npeaks == 1: cons[0][1] = CFIXED #the delta between peaks else: cons[0][1] = CFREE #the delta between peaks j = 2 #Setup height area constrains if self.config['NoConstrainsFlag'] == 0: if self.config['HeightAreaFlag']: #POSITIVE = 1 cons[0] [j] = 1 cons[1] [j] = 0 cons[2] [j] = 0 j=j+1 #Setup position constrains if self.config['NoConstrainsFlag'] == 0: if self.config['PositionFlag']: #QUOTED = 2 cons[0][j]=2 cons[1][j]=min(xx) cons[2][j]=max(xx) j=j+1 #Setup positive FWHM constrains if self.config['NoConstrainsFlag'] == 0: if self.config['PosFwhmFlag']: #POSITIVE=1 cons[0][j]=1 cons[1][j]=0 cons[2][j]=0 j=j+1 return fittedpar,cons
def alorentz(self,pars,x): """ Fit function. """ return SpecfitFuns.alorentz(pars,x)
def lorentz(self,pars,x): """ Fit function. """ #return pars[0] + pars [1] * x + SpecfitFuns.lorentz(pars[2:len(pars)],x) return SpecfitFuns.lorentz(pars,x)
def estimate_gauss(self,xx,yy,zzz,xscaling=1.0,yscaling=None): if yscaling == None: try: yscaling=self.config['Yscaling'] except: yscaling=1.0 if yscaling == 0: yscaling=1.0 fittedpar=[] zz=SpecfitFuns.subac(yy,1.000,10000) npoints = len(zz) if self.config['AutoFwhm']: search_fwhm=self.guess_fwhm(x=xx,y=yy) else: search_fwhm=int(float(self.config['FwhmPoints'])) search_sens=float(self.config['Sensitivity']) search_mca=int(float(self.config['McaMode'])) if search_fwhm < 3: search_fwhm = 3 self.config['FwhmPoints']=3 if search_sens < 1: search_sens = 1 self.config['Sensitivity']=1 if npoints > 1.5*search_fwhm: peaks=self.seek(yy,fwhm=search_fwhm, sensitivity=search_sens, yscaling=yscaling, mca=search_mca) #print "estimate peaks = ",peaks #peaks=self.seek(yy-zz,fwhm=search_fwhm, # sensitivity=search_sens, # yscaling=yscaling, # mca=search_mca) else: peaks = [] if not len(peaks): mca = int(float(self.config.get('McaMode', 0))) forcePeak = int(float(self.config.get('ForcePeakPresence', 0))) if (not mca) and forcePeak: delta = yy - zz peaks = [int(numpy.nonzero(delta == delta.max())[0])] #print "peaks = ",peaks #print "peaks subac = ",self.seek(yy-zz,fwhm=search_fwhm, # sensitivity=search_sens, # yscaling=yscaling, # mca=search_mca) largest_index = 0 if len(peaks) > 0: j = 0 for i in peaks: if j == 0: sig=5*abs(xx[npoints-1]-xx[0])/npoints peakpos = xx[int(i)] if abs(peakpos) < 1.0e-16: peakpos = 0.0 param = numpy.array([yy[int(i)] - zz[int(i)], peakpos ,sig]) largest = param else: param2 = numpy.array([yy[int(i)] - zz [int(i)], xx[int(i)] ,sig]) param = numpy.concatenate((param,param2),1) if (param2[0] > largest[0]): largest = param2 largest_index = j j = j + 1 xw = numpy.resize(xx,(npoints,1)) if (0): sy = numpy.sqrt(abs(yy)) yw = numpy.resize(yy-zz,(npoints,1)) sy = numpy.resize(sy,(npoints,1)) datawork = numpy.concatenate((xw,yw,sy),1) else: yw = numpy.resize(yy-zz,(npoints,1)) datawork = numpy.concatenate((xw,yw),1) cons = numpy.zeros((3,len(param)),numpy.float) cons [0] [0:len(param):3] = CPOSITIVE #force peaks to stay around their position if (1): cons [0] [1:len(param):3] = CQUOTED #This does not work!!!! #FWHM should be given in terms of X not of points! #cons [1] [1:len(param):3] = param[1:len(param):3]-0.5*search_fwhm #cons [2] [1:len(param):3] = param[1:len(param):3]+0.5*search_fwhm if len(xw) > search_fwhm: fwhmx = numpy.fabs(xw[int(search_fwhm)]-xw[0]) cons [1] [1:len(param):3] = param[1:len(param):3]-0.5*fwhmx cons [2] [1:len(param):3] = param[1:len(param):3]+0.5*fwhmx else: cons [1] [1:len(param):3] = numpy.ones(shape(param[1:len(param):3]),numpy.float)*min(xw) cons [2] [1:len(param):3] = numpy.ones(shape(param[1:len(param):3]),numpy.float)*max(xw) if 0: cons [0] [2:len(param):3] = CFACTOR cons [1] [2:len(param):3] = 2 cons [2] [2:len(param):3] = 1.0 cons [0] [2] = CPOSITIVE cons [1] [2] = 0 cons [2] [2] = 0 else: cons [0] [2:len(param):3] = CPOSITIVE fittedpar, chisq, sigmapar = LeastSquaresFit(SpecfitFuns.gauss,param, datawork, weightflag=self.config['WeightFlag'], maxiter=4,constrains=cons.tolist()) #I already have the estimation #yw=yy-zz-SpecfitFuns.gauss(fittedpar,xx) #if DEBUG: # SimplePlot.plot([xx,yw]) #print self.seek(yw,\ # fwhm=search_fwhm,\ # sensitivity=search_sens,\ # yscaling=yscaling) #else: # #Use SPEC estimate ... # peakpos,height,myidx = SpecArithmetic.search_peak(xx,yy-zz) # fwhm,cfwhm = SpecArithmetic.search_fwhm(xx,yy-zz, # peak=peakpos,index=myidx) # xx = numpy.array(xx) # if npoints > 2: # #forget SPEC estimation of fwhm # fwhm=5*abs(xx[npoints-1]-xx[0])/npoints # fittedpar=[height,peakpos,fwhm] # largest=numpy.array([height,peakpos,fwhm]) # peaks=[peakpos] cons = numpy.zeros((3,len(fittedpar)),numpy.float) j=0 for i in range(len(peaks)): #Setup height area constrains if self.config['NoConstrainsFlag'] == 0: if self.config['HeightAreaFlag']: #POSITIVE = 1 cons[0] [j] = 1 cons[1] [j] = 0 cons[2] [j] = 0 j=j+1 #Setup position constrains if self.config['NoConstrainsFlag'] == 0: if self.config['PositionFlag']: #QUOTED = 2 cons[0][j]=2 cons[1][j]=min(xx) cons[2][j]=max(xx) j=j+1 #Setup positive FWHM constrains if self.config['NoConstrainsFlag'] == 0: if self.config['PosFwhmFlag']: #POSITIVE=1 cons[0][j]=1 cons[1][j]=0 cons[2][j]=0 if self.config['SameFwhmFlag']: if (i != largest_index): #FACTOR=4 cons[0][j]=4 cons[1][j]=3*largest_index+2 cons[2][j]=1.0 j=j+1 return fittedpar,cons
def stepdown(self,pars,x): """ A fit function. """ return 0.5*SpecfitFuns.downstep(pars,x)
def apvoigt(self,pars,x): """ Fit function. """ return SpecfitFuns.apvoigt(pars,x)
def agauss(self,pars,x): """ A fit function. """ return SpecfitFuns.agauss(pars,x)
def hypermet(self, pars, x): """ Default hypermet function """ return SpecfitFuns.ahypermet(pars, x, 15, 0)
def splitgauss(self,pars,x): """ Asymmetric gaussian. """ return SpecfitFuns.splitgauss(pars,x)
def stepUp(self, pars, x): """ Error function like. """ return 0.5 * SpecfitFuns.upstep(pars, x)
def splitlorentz(self,pars,x): """ Asymmetric lorentz. """ return SpecfitFuns.splitlorentz(pars,x)
def divideByActiveCurve(self): #all curves curves = self.getAllCurves() nCurves = len(curves) if nCurves < 2: raise ValueError("At least two curves needed") return #get active curve activeCurve = self.getActiveCurve() if activeCurve is None: raise ValueError("Please select an active curve") return x, y, legend0, info = activeCurve xmin, xmax = self.getGraphXLimits() y = y.astype(numpy.float) #get the nonzero values idx = numpy.nonzero(abs(y) != 0.0)[0] if not len(idx): raise ValueError("All divisor values are zero!") x0 = numpy.take(x, idx) y0 = numpy.take(y, idx) #sort the values idx = numpy.argsort(x0, kind='mergesort') x0 = numpy.take(x0, idx) y0 = numpy.take(y0, idx) i = 0 for curve in curves: x, y, legend, info = curve[0:4] if legend == legend0: continue #take the portion ox x between limits idx = numpy.nonzero((x>=xmin) & (x<=xmax))[0] if not len(idx): #no overlap continue x = numpy.take(x, idx) y = numpy.take(y, idx) idx = numpy.nonzero((x0>=x.min()) & (x0<=x.max()))[0] if not len(idx): #no overlap continue xi = numpy.take(x0, idx) yi = numpy.take(y0, idx) #perform interpolation xi.shape = -1, 1 yw = SpecfitFuns.interpol([x], y, xi, yi.min()) y = yw / yi if i == 0: replace = True replot = True i = 1 else: replot = False replace = False self.addCurve(x, y, legend=legend, info=info, replot=replot, replace=replace) lastCurve = [x, y, legend] self.addCurve(lastCurve[0], lastCurve[1], legend=lastCurve[2], info=info, replot=True, replace=False)
def splitpvoigt(self,pars,x): """ Asymmetric pseudovoigt. """ return SpecfitFuns.splitpvoigt(pars,x)