def updateGraph(self, ddict): width = ddict['width'] roi_min = ddict['roi_min'] roi_max = ddict['roi_max'] smoothing = ddict['smoothing'] if self.__image: if self.xMarkers == []: xMin, xMax = self.graph.getX1AxisLimits() yMin, yMax = self.graph.getY1AxisLimits() xMean = 0.5 * (xMin + xMax) yMean = 0.5 * (yMin + yMax) self.xMarkers.append(self.graph.insertX1Marker(roi_min[1], yMean, label='C Min')) self.xMarkers.append(self.graph.insertX1Marker(roi_max[1], yMean, label='C Max')) self.yMarkers.append(self.graph.insertY1Marker(xMean, roi_min[0], label='R Min')) self.yMarkers.append(self.graph.insertY1Marker(xMean, roi_max[0], label='R Max')) else: self.graph.markersdict[self.xMarkers[0]]['marker'].setXValue(roi_min[1]) self.graph.markersdict[self.xMarkers[1]]['marker'].setXValue(roi_max[1]) self.graph.markersdict[self.yMarkers[0]]['marker'].setYValue(roi_min[0]) self.graph.markersdict[self.yMarkers[1]]['marker'].setYValue(roi_max[0]) self.background = SNIPModule.getImageBackground(self.image, width, roi_min=roi_min, roi_max=roi_max, smoothing=smoothing) difference = self.image-self.background self.graphWidget.setImageData(difference) if OBJECT3D: if self.o3dScene is None: self.o3dScene = Object3DScene.Object3DScene() self.o3dScene.show() if 0: imageData =(self.image * 1).astype(numpy.float32) backgroundData = (self.background * 1).astype(numpy.float32) self.o3dScene.mesh(imageData, z=imageData * 1, legend='Data', update_scene=True) self.o3dScene.mesh(backgroundData, z=backgroundData , legend='Background', update_scene=True) else: self.o3dScene.mesh(difference, z=difference, legend='Data-Background') self.o3dScene.show() else: self.background = SNIPModule.getSpectrumBackground(self.spectrum, width, roi_min=roi_min, roi_max=roi_max, smoothing=smoothing) if self.__smooth: legend0 = "Smoothed Spectrum" else: legend0 = "Background" self.graph.newCurve(self.xValues, self.background, legend0, replace=False) #Force information update legend = self.graph.getActiveCurve(just_legend=True) if legend.startswith(legend0[0:5]): self.graph.setActiveCurve(legend)
def updateGraph(self, ddict): width = ddict['width'] roi_min = ddict['roi_min'] roi_max = ddict['roi_max'] smoothing = ddict['smoothing'] if self.__image: if self.xMarkers == []: xMin, xMax = self.graph.getGraphXLimits() yMin, yMax = self.graph.getGraphYLimits() xMean = 0.5 * (xMin + xMax) yMean = 0.5 * (yMin + yMax) self.xMarkers.append( self.graph.insertXMarker(roi_min[1], legend='C Min', text='C Min')) self.xMarkers.append( self.graph.insertXMarker(roi_max[1], legend='C Max', text='C Max')) self.yMarkers.append( self.graph.insertYMarker(roi_min[0], legend='R Min', text='R Min')) self.yMarkers.append( self.graph.insertYMarker(roi_max[0], legend='R Max', text='R Max')) else: self.graph.insertXMarker(roi_min[1], legend='C Min', text='C Min') self.graph.insertXMarker(roi_max[1], legend='C Max', text='C Max') self.graph.insertYMarker(roi_min[0], legend='R Min', text='R Min') self.graph.insertYMarker(roi_max[0], legend='R Max', text='R Max') self.background = SNIPModule.getImageBackground( self.image, width, roi_min=roi_min, roi_max=roi_max, smoothing=smoothing) difference = self.image - self.background self.graphWidget.setImageData(difference) if OBJECT3D: if self.o3dScene is None: self.o3dScene = Object3DScene.Object3DScene() self.o3dScene.show() if 0: imageData = (self.image * 1).astype(numpy.float32) backgroundData = (self.background * 1).astype( numpy.float32) self.o3dScene.mesh(imageData, z=imageData * 1, legend='Data', update_scene=True) self.o3dScene.mesh(backgroundData, z=backgroundData, legend='Background', update_scene=True) else: self.o3dScene.mesh(difference, z=difference, legend='Data-Background') self.o3dScene.show() else: self.background = SNIPModule.getSpectrumBackground( self.spectrum, width, roi_min=roi_min, roi_max=roi_max, smoothing=smoothing) if self.__smooth: legend0 = "Smoothed Spectrum" else: legend0 = "Background" self.graph.addCurve(self.xValues, self.background, legend0, replace=False) #Force information update legend = self.graph.getActiveCurve(just_legend=True) if legend.startswith(legend0[0:5]): self.graph.setActiveCurve(legend)
def findPeaks(self, x, y, thr, derivative): """ Input ----- x,y : ndarrays Arrays contain curve intformation thr : float Threshold in percent of normalized maximum derivative : bool The derivative of a curve is being fitted Finds most prominent feature contained in y and tries to estimate starting parameters for a Gaussian least squares fit (LSF). Recommends values used to fit the Gaussian. Return ------ xpeak, ypeak, fwhm : float Estimated values for x-position, amplitude and width of the Gaussian fwhmIdx : ndarray Indices determine the range on which the LSF is performed """ # Use SNIP algorithm for background substraction & # seek method for peak detection sffuns = SF.SpecfitFunctions() if derivative: # Avoid BG substraction & normalization if # fitting the derivate of a curve ybg = y ynorm = y/(abs(y.max())+abs(y.min())) else: ybg = y-snip.getSnip1DBackground(y, len(y)//thr) # USER INPUT!!! # Normalize background substracted data to # standardize the yscaling of seek method #ynorm = (ybg - ybg.min())/(ybg.max()-ybg.min()) ynorm = self.normalize(ybg) # Replace by max()? try: # Calculate array with all peak indices peakIdx = numpy.asarray(sffuns.seek(ybg, yscaling=1000.), dtype=int) # Extract highest peak sortIdx = y[peakIdx].argsort()[-1] except IndexError: if DEBUG == 1: print('No peaks found..') return None except SystemError: if DEBUG == 1: print('Peak search failed. Continue with y maximum') peakIdx = [ybg.argmax()] sortIdx = 0 xpeak = float(x[peakIdx][sortIdx]) ypeak = float(y[peakIdx][sortIdx]) ypeak_norm = float(ynorm[peakIdx][sortIdx]) ypeak_bg = float(ybg[peakIdx][sortIdx]) # Estimate FWHM fwhmIdx = numpy.nonzero(ynorm >= thr*ypeak_norm)[0] #fwhmIdx = numpy.nonzero(ybg >= thr*ypeak_bg)[0] # Underestimates FWHM x0, x1 = x[fwhmIdx].min(), x[fwhmIdx].max() fwhm = x1 - x0 return xpeak, ypeak, fwhm, fwhmIdx
def fitAlignment(image, params): idx0 = params.get('idx0', 0) axis = params.get('axis', -1) # Axis defines direction of curves snipWidth = params.get('snipWidth', None) peakSearch = params.get('peakSearch', False) # # Determine which axis defines curves # Make shure to convert image to float!!! # if axis < 0: # If axis not specified.. rows, cols = image.shape # ..align along smaller axis if rows < cols: axis = 0 else: axis = 1 if axis == 0: nCurves, nPoints = image.shape curves = numpy.float64(image) elif axis == 1: nPoints, nCurves = image.shape curves = numpy.float64(image.T) else: raise ValueError('Alignment instance -- Axis must be either -1, 0 or 1') # # Image preprocessing: Snip background # imRows, imCols = image.shape if snipWidth is None: snipWidth = max(imRows, imCols)//10 specfitObj = SF.SpecfitFunctions() background = numpy.zeros(shape=curves.shape, dtype=numpy.float64) for idx, curve in enumerate(curves): background[idx] = SNIP.getSnip1DBackground(curve, snipWidth) subtracted = curves-background normResult = Normalization.zeroToOne(image=subtracted, params={}) normalized = normResult['image'] # # Loop through curves: Find peak (max..), Estimate fit params, Perform Gaussian fit # fitList = nCurves * [float('NaN')] if DEBUG >= 1: print('Alignment.fitAlignment -- fitting..') for idx, y in enumerate(subtracted): # # Peak search # if peakSearch: try: # Calculate array with all peak indices peakIdx = numpy.asarray(specfitObj.seek(y, yscaling=100.), dtype=int) # Extract highest feature maxIdx = y[peakIdx].argsort()[-1] except IndexError: if DEBUG >= 1: print('Alignment.fitAlignment -- No peaks found..') return None except SystemError: if DEBUG >= 1: print('Alignment.fitAlignment -- Peak search failed. Continue with y maximum') peakIdx = [y.argmax()] maxIdx = 0 else: peakIdx = [y.argmax()] maxIdx = 0 height = float(y[peakIdx][maxIdx]) + curves[idx].min() pos = float(peakIdx[maxIdx]) # # Estimate FWHM # fwhmIdx = numpy.nonzero(y >= .5*normalized[idx])[0] # Underestimates FWHM, since carried out on normalized image fwhm = float(fwhmIdx.max()-fwhmIdx.min()) # # Peak fit: Uses actual data # #xrange = numpy.arange(0, len(y), dtype=y.dtype) # Full range mask = numpy.nonzero(y >= .1*normalized[idx])[0] ydata = curves[idx,mask] #ydata -= ydata.min() try: fitp, chisq, sigma = LSF(gaussianModel, numpy.asarray([height, pos, fwhm]), xdata=mask, ydata=(ydata-ydata.min())) if DEBUG >= 1: print('\tCurve %d -- fitp: %s' % (idx, str(fitp))) print('\tCurve %d -- chisq: %s' % (idx, str(chisq))) print('\tCurve %d -- sigma: %s' % (idx, str(sigma))) except numpy.linalg.linalg.LinAlgError: fitp, chisq, sigma = [None, None, None],\ float('Nan'),\ float('Nan') if DEBUG >= 1: print('\tCurve %d -- Fit failed!' % idx) fitList[idx] = fitp # ftip is 3-tuple.. posIdx = 1 # ..2nd argument of fitp is peak position shift0 = fitList[idx0][posIdx] shiftList = [shift0-fit[posIdx] for fit in fitList] #ddict = { # 'op': 'fitAlignment', # 'shiftList': shiftList #} #return ddict return shiftList