def getGoodPeaks(self, peaks, min_height, min_width): """ Create a new list from peaks containing only those peaks that meet the specified criteria for minimum peak height and width. """ if(peaks.shape[0]>0): min_width = 0.5 * min_width status_index = utilC.getStatusIndex() height_index = utilC.getHeightIndex() xwidth_index = utilC.getXWidthIndex() ywidth_index = utilC.getYWidthIndex() if self.verbose: tmp = numpy.ones(peaks.shape[0]) print("getGoodPeaks") for i in range(peaks.shape[0]): print(i, peaks[i,0], peaks[i,1], peaks[i,3], peaks[i,2], peaks[i,4], peaks[i,7]) print("Total peaks:", numpy.sum(tmp)) print(" fit error:", numpy.sum(tmp[(peaks[:,status_index] != 2.0)])) print(" min height:", numpy.sum(tmp[(peaks[:,height_index] > min_height)])) print(" min width:", numpy.sum(tmp[(peaks[:,xwidth_index] > min_width) & (peaks[:,ywidth_index] > min_width)])) print("") mask = (peaks[:,status_index] != 2.0) & (peaks[:,height_index] > min_height) & (peaks[:,xwidth_index] > min_width) & (peaks[:,ywidth_index] > min_width) return peaks[mask,:] else: return peaks
def getGoodPeaks(self, peaks, threshold): # # FIXME: We'd like to have a minimum height threshold, but the # threshold parameter is a relative value not an absolute. # For now we are just rejecting ERROR peaks. # if (peaks.size > 0): # # In the C library, the peaks that represent a single object # in multiple channels will all have the same status index # and height, so we can filter here with some confidence that # we'll keep or eliminate all the peaks in a particular group # at the same time. We attempt to enforce this with an assertion # statement, but it is an imperfect test as we could eliminate # 1 peak from each of 4 groups and still pass, even though this # would completely mess up the analysis. # status_index = utilC.getStatusIndex() height_index = utilC.getHeightIndex() #mask = (peaks[:,status_index] != 2.0) & (peaks[:,height_index] > min_height) mask = (peaks[:, status_index] != 2.0) if self.verbose: print(" ", numpy.sum(mask), "were good out of", peaks.shape[0]) # # For debugging. # if False: xw_index = utilC.getXWidthIndex() yw_index = utilC.getYWidthIndex() for i in range(peaks.shape[0]): if (peaks[i, xw_index] != peaks[i, yw_index]): print("bad peak width detected", i, peaks[i, xw_index], peaks[i, yw_index]) # # Debugging check that the peak status markings are actually # in sync. # if True: n_peaks = int(peaks.shape[0] / self.n_channels) not_bad = True for i in range(n_peaks): if (mask[i] != mask[i + n_peaks]): print("Problem detected with peak", i) print(" ", peaks[i, :]) print(" ", peaks[i + n_peaks, :]) not_bad = False assert not_bad masked_peaks = peaks[mask, :] # The number of peaks should always be a multiple of the number of channels. assert ((masked_peaks.shape[0] % self.n_channels) == 0) return masked_peaks else: return peaks
def getGoodPeaks(self, peaks, min_height, min_width): """ Create a new list from peaks containing only those peaks that meet the specified criteria for minimum peak height and width. """ if(peaks.shape[0]>0): min_width = 0.5 * min_width status_index = utilC.getStatusIndex() height_index = utilC.getHeightIndex() xwidth_index = utilC.getXWidthIndex() ywidth_index = utilC.getYWidthIndex() if self.verbose: tmp = numpy.ones(peaks.shape[0]) print("getGoodPeaks") for i in range(peaks.shape[0]): print(i, peaks[i,0], peaks[i,1], peaks[i,3], peaks[i,2], peaks[i,4]) print("Total peaks:", numpy.sum(tmp)) print(" fit error:", numpy.sum(tmp[(peaks[:,status_index] != 2.0)])) print(" min height:", numpy.sum(tmp[(peaks[:,height_index] > min_height)])) print(" min width:", numpy.sum(tmp[(peaks[:,xwidth_index] > min_width) & (peaks[:,ywidth_index] > min_width)])) print("") mask = (peaks[:,7] != status_index) & (peaks[:,height_index] > min_height) & (peaks[:,xwidth_index] > min_width) & (peaks[:,ywidth_index] > min_width) return peaks[mask,:] else: return peaks
def getConvergedPeaks(self, peaks, verbose = False): if (peaks.shape[0] > 0): status_index = utilC.getStatusIndex() mask = (peaks[:,status_index] == 1.0) # 0.0 = running, 1.0 = converged. if verbose: print(" ", numpy.sum(mask), "converged out of", peaks.shape[0]) return self.peak_fitter.rescaleZ(peaks[mask,:]) else: return peaks
def getConvergedPeaks(self, peaks, verbose=False): if (peaks.shape[0] > 0): status_index = utilC.getStatusIndex() mask = (peaks[:, status_index] == 1.0 ) # 0.0 = running, 1.0 = converged. if verbose: print(" ", numpy.sum(mask), "converged out of", peaks.shape[0]) return self.peak_fitter.rescaleZ(peaks[mask, :]) else: return peaks
def createFromMultiFit(molecules, x_size, y_size, frame, nm_per_pixel, inverted=False): """ Create an I3 data from the output of 3D-DAOSTORM, sCMOS or Spliner. """ n_molecules = molecules.shape[0] h = molecules[:, 0] if inverted: xc = y_size - molecules[:, utilC.getXCenterIndex()] yc = x_size - molecules[:, utilC.getYCenterIndex()] wx = 2.0 * molecules[:, utilC.getXWidthIndex()] * nm_per_pixel wy = 2.0 * molecules[:, utilC.getYWidthIndex()] * nm_per_pixel else: xc = molecules[:, utilC.getYCenterIndex()] + 1 yc = molecules[:, utilC.getXCenterIndex()] + 1 wx = 2.0 * molecules[:, utilC.getYWidthIndex()] * nm_per_pixel wy = 2.0 * molecules[:, utilC.getXWidthIndex()] * nm_per_pixel bg = molecules[:, utilC.getBackgroundIndex()] zc = molecules[:, utilC.getZCenterIndex( )] * 1000.0 # fitting is done in um, insight works in nm st = numpy.round(molecules[:, utilC.getStatusIndex()]) err = molecules[:, utilC.getErrorIndex()] # # Calculate peak area, which is saved in the "a" field. # # Note that this is assuming that the peak is a 2D gaussian. This # will not calculate the correct area for a Spline.. # parea = 2.0 * 3.14159 * h * molecules[:, utilC.getXWidthIndex( )] * molecules[:, utilC.getYWidthIndex()] ax = wy / wx ww = numpy.sqrt(wx * wy) i3data = createDefaultI3Data(xc.size) posSet(i3data, 'x', xc) posSet(i3data, 'y', yc) posSet(i3data, 'z', zc) setI3Field(i3data, 'h', h) setI3Field(i3data, 'bg', bg) setI3Field(i3data, 'fi', st) setI3Field(i3data, 'a', parea) setI3Field(i3data, 'w', ww) setI3Field(i3data, 'ax', ax) setI3Field(i3data, 'fr', frame) setI3Field(i3data, 'i', err) return i3data
def getGoodPeaks(self, peaks, min_height = 0.0): if (peaks.size > 0): status_index = utilC.getStatusIndex() height_index = utilC.getHeightIndex() mask = (peaks[:,status_index] != 2.0) & (peaks[:,height_index] > min_height) if self.verbose: print(" ", numpy.sum(mask), "were good out of", peaks.shape[0]) return peaks[mask,:] else: return peaks
def getGoodPeaks(self, peaks, min_height=0.0): if (peaks.size > 0): status_index = utilC.getStatusIndex() height_index = utilC.getHeightIndex() mask = (peaks[:, status_index] != 2.0) & (peaks[:, height_index] > min_height) if self.verbose: print(" ", numpy.sum(mask), "were good out of", peaks.shape[0]) return peaks[mask, :] else: return peaks
def analyzeImage(self, new_image, bg_estimate=None, save_residual=False, verbose=False): image = fitting.padArray(new_image, self.peak_finder.margin) if bg_estimate is not None: bg_estimate = fitting.padArray(bg_estimate, self.peak_finder.margin) self.peak_finder.newImage(image, bg_estimate) self.peak_fitter.newImage(image) # # This is a lot simpler than 3D-DAOSTORM as we only do one pass, # hopefully the compressed sensing (FISTA) deconvolution finds all the # peaks and then we do a single pass of fitting. # if True: peaks = self.peak_finder.findPeaks() [fit_peaks, residual] = self.peak_fitter.fitPeaks(peaks) # # This is for testing if just using FISTA followed by the center # of mass calculation is basically as good as also doing the # additional MLE spline fitting step. # # The short answer is that it appears that it is not. It about # 1.3x worse in XY and about 4x worse in Z. # else: fit_peaks = self.peak_finder.findPeaks() # Adjust z scale. z_index = utilC.getZCenterIndex() z_size = (self.peak_fitter.spline.shape[2] - 1.0) status_index = utilC.getStatusIndex() fit_peaks[:, z_index] = z_size * fit_peaks[:, z_index] # Mark as converged. fit_peaks[:, status_index] = 1.0 residual = None # # Subtract margin so that peaks are in the right # place with respect to the original image. # fit_peaks[:, utilC.getXCenterIndex()] -= float(self.peak_finder.margin) fit_peaks[:, utilC.getYCenterIndex()] -= float(self.peak_finder.margin) return [fit_peaks, residual]
def getConvergedPeaks(self, peaks, verbose=False): """ peaks - A 1D numpy array containing the peaks. return - A 1D numpy array containing only the converged peaks. """ if (peaks.shape[0] > 0): status_index = utilC.getStatusIndex() mask = (peaks[:, status_index] == 1.0 ) # 0.0 = running, 1.0 = converged. if verbose: print(" ", numpy.sum(mask), "converged out of", peaks.shape[0]) return peaks[mask, :] else: return peaks
def createFromMultiFit(molecules, x_size, y_size, frame, nm_per_pixel, inverted=False): """ Create an I3 data from the output of 3D-DAOSTORM, sCMOS or Spliner. """ n_molecules = molecules.shape[0] h = molecules[:,0] if inverted: xc = y_size - molecules[:,utilC.getXCenterIndex()] yc = x_size - molecules[:,utilC.getYCenterIndex()] wx = 2.0*molecules[:,utilC.getXWidthIndex()]*nm_per_pixel wy = 2.0*molecules[:,utilC.getYWidthIndex()]*nm_per_pixel else: xc = molecules[:,utilC.getYCenterIndex()] + 1 yc = molecules[:,utilC.getXCenterIndex()] + 1 wx = 2.0*molecules[:,utilC.getYWidthIndex()]*nm_per_pixel wy = 2.0*molecules[:,utilC.getXWidthIndex()]*nm_per_pixel bg = molecules[:,utilC.getBackgroundIndex()] zc = molecules[:,utilC.getZCenterIndex()] * 1000.0 # fitting is done in um, insight works in nm st = numpy.round(molecules[:,utilC.getStatusIndex()]) err = molecules[:,utilC.getErrorIndex()] # # Calculate peak area, which is saved in the "a" field. # # Note that this is assuming that the peak is a 2D gaussian. This # will not calculate the correct area for a Spline.. # parea = 2.0*3.14159*h*molecules[:,utilC.getXWidthIndex()]*molecules[:,utilC.getYWidthIndex()] ax = wy/wx ww = numpy.sqrt(wx*wy) i3data = createDefaultI3Data(xc.size) posSet(i3data, 'x', xc) posSet(i3data, 'y', yc) posSet(i3data, 'z', zc) setI3Field(i3data, 'h', h) setI3Field(i3data, 'bg', bg) setI3Field(i3data, 'fi', st) setI3Field(i3data, 'a', parea) setI3Field(i3data, 'w', ww) setI3Field(i3data, 'ax', ax) setI3Field(i3data, 'fr', frame) setI3Field(i3data, 'i', err) return i3data
def analyzeImage(self, new_image, bg_estimate = None, save_residual = False, verbose = False): image = fitting.padArray(new_image, self.peak_finder.margin) if bg_estimate is not None: bg_estimate = fitting.padArray(bg_estimate, self.peak_finder.margin) self.peak_finder.newImage(image, bg_estimate) self.peak_fitter.newImage(image) # # This is a lot simpler than 3D-DAOSTORM as we only do one pass, # hopefully the compressed sensing (FISTA) deconvolution finds all the # peaks and then we do a single pass of fitting. # if True: peaks = self.peak_finder.findPeaks() [fit_peaks, residual] = self.peak_fitter.fitPeaks(peaks) # # This is for testing if just using FISTA followed by the center # of mass calculation is basically as good as also doing the # additional MLE spline fitting step. # # The short answer is that it appears that it is not. It about # 1.3x worse in XY and about 4x worse in Z. # else: fit_peaks = self.peak_finder.findPeaks() # Adjust z scale. z_index = utilC.getZCenterIndex() z_size = (self.peak_fitter.spline.shape[2] - 1.0) status_index = utilC.getStatusIndex() fit_peaks[:,z_index] = z_size*fit_peaks[:,z_index] # Mark as converged. fit_peaks[:,status_index] = 1.0 residual = None # # Subtract margin so that peaks are in the right # place with respect to the original image. # fit_peaks[:,utilC.getXCenterIndex()] -= float(self.peak_finder.margin) fit_peaks[:,utilC.getYCenterIndex()] -= float(self.peak_finder.margin) return [fit_peaks, residual]
cubic_fit.initializeMultiFit.argtypes = [ ndpointer(dtype=numpy.float64), ctypes.c_double, ctypes.c_int, ctypes.c_int ] cubic_fit.newImage.argtypes = [ndpointer(dtype=numpy.float64)] cubic_fit.newPeaks2D.argtypes = [ndpointer(dtype=numpy.float64), ctypes.c_int] cubic_fit.newPeaks3D.argtypes = [ndpointer(dtype=numpy.float64), ctypes.c_int] # Globals default_tol = 1.0e-6 height_index = utilC.getHeightIndex() n_results_par = utilC.getNResultsPar() status_index = utilC.getStatusIndex() z_index = utilC.getZCenterIndex() # # Functions # def fSpline2D(x, y): return cubic_fit.fSpline2D(x, y) def fSpline3D(x, y, z): return cubic_fit.fSpline3D(x, y, z) #