def test_matched_filter2(): """ Test recovering the original height from the convolved image. FIXME: Not sure this test is relevant anymore as we no longer use this approach for initializing peak heights. """ x_size = 80 y_size = 90 objects = numpy.zeros((1, 5)) # Make filter with unit sum. objects[0,:] = [x_size/2, y_size/2, 1.0, 2.0, 2.0] psf = dg.drawGaussians((x_size, y_size), objects) psf_norm = psf/numpy.sum(psf) flt = matchedFilterC.MatchedFilter(psf_norm) rescale = 1.0/numpy.sum(psf * psf_norm) # Create object with height 10 and the same shape as the filter. height = 10.0 objects[0,:] = [x_size/2, y_size/2, height, 2.0, 2.0] image = dg.drawGaussians((x_size, y_size), objects) # Apply filter. conv = flt.convolve(image) # Verify that final height is 'close enough'. assert (abs(numpy.amax(conv) * rescale - height)/height < 1.0e-2) flt.cleanup()
def test_matched_filter2(): """ Test recovering the original height from the convolved image. FIXME: Not sure this test is relevant anymore as we no longer use this approach for initializing peak heights. """ x_size = 80 y_size = 90 objects = numpy.zeros((1, 5)) # Make filter with unit sum. objects[0,:] = [x_size/2, y_size/2, 1.0, 2.0, 2.0] psf = dg.drawGaussians((x_size, y_size), objects) psf_norm = psf/numpy.sum(psf) flt = matchedFilterC.MatchedFilter(psf_norm) rescale = 1.0/numpy.sum(psf * psf_norm) # Create object with height 10 and the same shape as the filter. height = 10.0 objects[0,:] = [x_size/2, y_size/2, height, 2.0, 2.0] image = dg.drawGaussians((x_size, y_size), objects) # Apply filter. conv = flt.convolve(image) # Verify that final height is 'close enough'. assert (abs(numpy.amax(conv) * rescale - height)/height < 1.0e-2)
def getPSFs(self, h5_data): x = h5_data['x'] y = h5_data['y'] a = h5_data['sum'] sx = h5_data['ysigma'] sy = h5_data['xsigma'] h = 0.5 * a / (2.0 * numpy.pi * sx * sy) h5_data['height'] = h angle = numpy.pi * 0.9 * ((h5_data['z'] - self.z_min) / (self.z_max - self.z_min)) dx = 2.0 * sx * numpy.cos(angle) dy = 2.0 * sy * numpy.sin(angle) x1 = x + dx y1 = y + dy x2 = x - dx y2 = y - dy x = numpy.concatenate((x1, x2)) y = numpy.concatenate((y1, y2)) h = numpy.concatenate((h, h)) sx = numpy.concatenate((sx, sx)) sy = numpy.concatenate((sy, sy)) return dg.drawGaussians((self.x_size, self.y_size), numpy.stack((x, y, h, sx, sy), axis=1), res=5)
def test_matched_filter4(): """ Verify that fftw_estimate has no effect on the results. """ x_size = 80 y_size = 90 objects = numpy.zeros((1, 5)) # Make filter with unit sum. objects[0,:] = [x_size/2, y_size/2, 1.0, 1.0, 1.0] psf = dg.drawGaussians((x_size, y_size), objects) psf = psf/numpy.sum(psf) flt1 = matchedFilterC.MatchedFilter(psf, fftw_estimate = False) flt2 = matchedFilterC.MatchedFilter(psf, fftw_estimate = True) for i in range(1,5): image = numpy.zeros((x_size, y_size)) image[int(x_size/2), int(y_size/2)] = float(i) conv1 = flt1.convolve(image) conv2 = flt2.convolve(image) assert(numpy.allclose(conv1, conv2)) flt1.cleanup() flt2.cleanup()
def test_matched_filter5(): """ Verify that the filter results are correct. """ x_size = 80 y_size = 90 objects = numpy.zeros((1, 5)) # Make filter with unit sum. objects[0,:] = [x_size/2, y_size/2, 1.0, 1.0, 1.0] psf = dg.drawGaussians((x_size, y_size), objects) psf = psf/numpy.sum(psf) flt = matchedFilterC.MatchedFilter(psf) # Make test image. image = numpy.zeros((x_size, y_size)) image[int(x_size/2), int(y_size/2)] = float(100) mf_conv = flt.convolve(image) t1 = numpy.fft.fft2(recenterPSF.recenterPSF(psf)) t2 = numpy.fft.fft2(image) np_conv = numpy.real(numpy.fft.ifft2(t1*t2)) assert(numpy.allclose(mf_conv, np_conv)) flt.cleanup()
def test_mfit_9(): """ Test peak significance calculation. """ height = 10.0 sigma = 1.5 x_size = 100 y_size = 120 background = numpy.zeros((x_size, y_size)) + 10.0 image = dg.drawGaussians((x_size, y_size), numpy.array([[50.0, 30.0, height, sigma, sigma], [50.0, 50.0, 2.0*height, sigma, sigma], [50.0, 70.0, 3.0*height, sigma, sigma]])) image += background mfit = daoFitC.MultiFitter2D(sigma_range = [1.0, 2.0]) mfit.initializeC(image) mfit.newImage(image) mfit.newBackground(background) peaks = {"x" : numpy.array([30.0, 50.0, 70.0]), "y" : numpy.array([50.0, 50.0, 50.0]), "z" : numpy.array([0.0, 0.0, 0.0]), "sigma" : numpy.array([sigma, sigma, sigma])} mfit.newPeaks(peaks, "finder") if False: with tifffile.TiffWriter("test_mfit_9.tif") as tf: tf.save(image.astype(numpy.float32)) sig = mfit.getPeakProperty("significance") sig = sig/sig[0] assert(numpy.allclose(sig, numpy.arange(1,4)))
def test_mfit_9(): """ Test peak significance calculation. """ height = 10.0 sigma = 1.5 x_size = 100 y_size = 120 background = numpy.zeros((x_size, y_size)) + 10.0 image = dg.drawGaussians((x_size, y_size), numpy.array([[50.0, 30.0, height, sigma, sigma], [50.0, 50.0, 2.0*height, sigma, sigma], [50.0, 70.0, 3.0*height, sigma, sigma]])) image += background mfit = daoFitC.MultiFitter2D(sigma_range = [1.0, 2.0]) mfit.initializeC(image) mfit.newImage(image) mfit.newBackground(background) peaks = {"x" : numpy.array([30.0, 50.0, 70.0]), "y" : numpy.array([50.0, 50.0, 50.0]), "z" : numpy.array([0.0, 0.0, 0.0]), "sigma" : numpy.array([sigma, sigma, sigma])} mfit.newPeaks(peaks, "finder") if False: with tifffile.TiffWriter("test_mfit_9.tif") as tf: tf.save(image.astype(numpy.float32)) sig = mfit.getPeakProperty("significance") assert(abs((sig[1] - sig[0]) - (sig[2] - sig[1])) < 0.1)
def getPSFs(self, h5_data): x = h5_data['x'] y = h5_data['y'] a = h5_data['sum'] sx = h5_data['ysigma'] sy = h5_data['xsigma'] h = 0.5*a/(2.0 * numpy.pi * sx * sy) h5_data['height'] = h angle = numpy.pi * 0.9 * ((h5_data['z'] - self.z_min)/(self.z_max - self.z_min)) dx = 2.0 * sx * numpy.cos(angle) dy = 2.0 * sy * numpy.sin(angle) x1 = x + dx y1 = y + dy x2 = x - dx y2 = y - dy x = numpy.concatenate((x1, x2)) y = numpy.concatenate((y1, y2)) h = numpy.concatenate((h, h)) sx = numpy.concatenate((sx, sx)) sy = numpy.concatenate((sy, sy)) return dg.drawGaussians((self.x_size, self.y_size), numpy.stack((x, y, h, sx, sy), axis = 1), res = 5)
def test_mfit_12(): """ Test RQE correction is as expected. """ height = 10.0 rqe_term = 0.7 sigma = 1.5 x_size = 60 y_size = 120 # RQE corrected image. background = numpy.zeros((x_size, y_size)) + 10.0 image = dg.drawGaussians((x_size, y_size), numpy.array([[30.0, 30.0, height, sigma, sigma], [30.0, 60.0, height, sigma, sigma], [30.0, 90.0, height, sigma, sigma]])) image += background # Variable RQE. rqe = numpy.ones_like(image) rqe[:,:60] = rqe_term mfit = daoFitC.MultiFitter2D(rqe = rqe, sigma_range = [1.0, 2.0]) mfit.initializeC(image) mfit.newImage(image) mfit.newBackground(background) peaks = {"x" : numpy.array([30.0, 60.0, 90.0]), "y" : numpy.array([30.0, 30.0, 30.0]), "z" : numpy.array([0.0, 0.0, 0.0]), "sigma" : numpy.array([sigma, sigma, sigma])} mfit.newPeaks(peaks, "finder") # All localizations should have the same RQE. sig = mfit.getPeakProperty("significance") sig = sig/sig[0] assert(numpy.allclose(sig, numpy.ones_like(sig))) # Fit image should be RQE corrected. fit_image = mfit.getFitImage() + background assert(numpy.allclose(image, fit_image, atol = 0.2)) if False: with tifffile.TiffWriter("test_mfit_12.tif") as tf: tf.save(image.astype(numpy.float32)) tf.save(fit_image.astype(numpy.float32)) mfit.cleanup(verbose = False)
def test_matched_filter3(): """ Test memoization. """ x_size = 40 y_size = 50 objects = numpy.zeros((1, 5)) # Make filter with unit sum. objects[0,:] = [x_size/2, y_size/2, 1.0, 2.0, 2.0] psf = dg.drawGaussians((x_size, y_size), objects) psf_norm = psf/numpy.sum(psf) flt = matchedFilterC.MatchedFilter(psf_norm, memoize = True, max_diff = 0.1) # Convolve first image. image = numpy.zeros((x_size, y_size)) image[int(x_size/2),int(y_size/2)] = 1.0 res1 = flt.convolve(image) # Repeat with approximately the same image. image = numpy.zeros((x_size, y_size)) image[int(x_size/2),int(y_size/2)] = 1.05 res2 = flt.convolve(image) assert(abs(numpy.max(res2 - res1)) < 1.0e-12) # Repeat with a different image. image = numpy.zeros((x_size, y_size)) image[int(x_size/2),int(y_size/2)] = 1.1 res2 = flt.convolve(image) assert(abs(numpy.max(res2 - res1)) > 1.0e-12) # Repeat with original image to verify update. image = numpy.zeros((x_size, y_size)) image[int(x_size/2),int(y_size/2)] = 1.0 res1 = flt.convolve(image) assert(abs(numpy.max(res2 - res1)) > 1.0e-12) # Repeat with exactly the same image. image = numpy.zeros((x_size, y_size)) image[int(x_size/2),int(y_size/2)] = 1.0 res2 = flt.convolve(image) assert(abs(numpy.max(res2 - res1)) < 1.0e-12) flt.cleanup()
def test_mfit_5(): """ Test initialization and fitting. """ height = 20.0 sigma = 1.5 x_size = 100 y_size = 120 background = numpy.zeros((x_size, y_size)) + 10.0 image = dg.drawGaussians((x_size, y_size), numpy.array([[50.0, 50.0, height, sigma, sigma], [50.0, 54.0, height, sigma, sigma]])) image += background mfit = daoFitC.MultiFitter2D() mfit.initializeC(image) mfit.newImage(image) mfit.newBackground(background) peaks = { "x": numpy.array([50.0, 54.0]), "y": numpy.array([50.0, 50.0]), "z": numpy.array([0.0, 0.0]), "sigma": numpy.array([sigma, sigma]) } mfit.newPeaks(peaks, "finder") mfit.doFit() if False: with tifffile.TiffWriter("test_mfit_5.tif") as tf: tf.save((image - background).astype(numpy.float32)) tf.save(mfit.getFitImage().astype(numpy.float32)) # Check peak x,y. x = mfit.getPeakProperty("x") y = mfit.getPeakProperty("y") for i in range(x.size): assert (abs(x[i] - peaks["x"][i]) < 1.0e-2) assert (abs(y[i] - peaks["y"][i]) < 1.0e-2) # Check peak w. w = mfit.getPeakProperty("xsigma") for i in range(w.size): assert (abs((w[i] - sigma) / sigma) < 0.02) mfit.cleanup(verbose=False)
def getPSFs(self, h5_data): x = h5_data['x'] y = h5_data['y'] a = h5_data['sum'] sx = h5_data['ysigma'] sy = h5_data['xsigma'] h = a / (2.0 * numpy.pi * sx * sy) h5_data['height'] = h return dg.drawGaussians( (self.x_size, self.y_size), numpy.concatenate( (x[:, None], y[:, None], h[:, None], sx[:, None], sy[:, None]), axis=1), res=5)
def test_ia_util_3(): """ Test agreement with fitting regarding orientation. """ height = 20.0 sigma = 1.5 x_size = 100 y_size = 120 background = numpy.zeros((x_size, y_size)) + 10.0 image = dg.drawGaussians((x_size, y_size), numpy.array([[20.0, 40.0, height, sigma, sigma]])) image += background # Configure fitter. mfit = daoFitC.MultiFitter2D() mfit.initializeC(image) mfit.newImage(image) mfit.newBackground(background) # Configure finder. z_values = [0.0] mxf = iaUtilsC.MaximaFinder(margin=1, radius=2 * sigma, threshold=background[0, 0] + 0.5 * height, z_values=z_values) # Find peaks. [x, y, z] = mxf.findMaxima([image]) sigma = numpy.ones(x.size) * sigma peaks = {"x": x, "y": y, "z": z, "sigma": sigma} # Pass peaks to fitter. mfit.newPeaks(peaks, "finder") # Check height. h = mfit.getPeakProperty("height") for i in range(h.size): assert (abs(h[i] - height) / height < 0.1) # Check background. bg = mfit.getPeakProperty("background") for i in range(bg.size): assert (abs(bg[i] - 10.0) < 1.0e-6) mfit.cleanup(verbose=False)
def test_mfit_5(): """ Test initialization and fitting. """ height = 20.0 sigma = 1.5 x_size = 100 y_size = 120 background = numpy.zeros((x_size, y_size)) + 10.0 image = dg.drawGaussians((x_size, y_size), numpy.array([[50.0, 50.0, height, sigma, sigma], [50.0, 54.0, height, sigma, sigma]])) image += background mfit = daoFitC.MultiFitter2D(sigma_range = [1.0, 2.0]) mfit.initializeC(image) mfit.newImage(image) mfit.newBackground(background) peaks = {"x" : numpy.array([50.0, 54.0]), "y" : numpy.array([50.0, 50.0]), "z" : numpy.array([0.0, 0.0]), "sigma" : numpy.array([sigma, sigma])} mfit.newPeaks(peaks, "finder") mfit.doFit() if False: with tifffile.TiffWriter("test_mfit_5.tif") as tf: tf.save((image-background).astype(numpy.float32)) tf.save(mfit.getFitImage().astype(numpy.float32)) # Check peak x,y. x = mfit.getPeakProperty("x") y = mfit.getPeakProperty("y") for i in range(x.size): assert (abs(x[i] - peaks["x"][i]) < 1.0e-2) assert (abs(y[i] - peaks["y"][i]) < 1.0e-2) # Check peak w. w = mfit.getPeakProperty("xsigma") for i in range(w.size): assert (abs((w[i] - sigma)/sigma) < 0.02) mfit.cleanup(verbose = False)
def getPSFs(self, i3_data): x = i3_data['x'] - 1.0 y = i3_data['y'] - 1.0 a = i3_data['a'] ax = i3_data['ax'] w = i3_data['w'] sx = 0.5 * numpy.sqrt(w * w / ax) / self.nm_per_pixel sy = 0.5 * numpy.sqrt(w * w * ax) / self.nm_per_pixel h = a / (2.0 * numpy.pi * sx * sy) i3_data['h'] = h return dg.drawGaussians( (self.x_size, self.y_size), numpy.concatenate( (x[:, None], y[:, None], h[:, None], sx[:, None], sy[:, None]), axis=1))
def test_mfit_4(): """ Test height and background initialization. """ height = 20.0 sigma = 1.5 x_size = 100 y_size = 120 background = numpy.zeros((x_size, y_size)) + 10.0 image = dg.drawGaussians((x_size, y_size), numpy.array([[50.0, 50.0, height, sigma, sigma], [50.0, 54.0, height, sigma, sigma]])) image += background mfit = daoFitC.MultiFitter2D() mfit.initializeC(image) mfit.newImage(image) mfit.newBackground(background) peaks = { "x": numpy.array([50.0, 54.0]), "y": numpy.array([50.0, 50.0]), "z": numpy.array([0.0, 0.0]), "sigma": numpy.array([sigma, sigma]) } mfit.newPeaks(peaks, "finder") if False: with tifffile.TiffWriter("test_mfit_4.tif") as tf: tf.save((image - background).astype(numpy.float32)) tf.save(mfit.getFitImage().astype(numpy.float32)) # Check height. h = mfit.getPeakProperty("height") for i in range(h.size): assert (abs(h[i] - height) / height < 0.1) # Check background. bg = mfit.getPeakProperty("background") for i in range(bg.size): assert (abs(bg[i] - 10.0) < 1.0e-6) mfit.cleanup(verbose=False)
def getPSFs(self, h5_data): x = h5_data['x'] y = h5_data['y'] a = h5_data['sum'] sx = h5_data['ysigma'] sy = h5_data['xsigma'] h = a/(2.0 * numpy.pi * sx * sy) h5_data['height'] = h return dg.drawGaussians((self.x_size, self.y_size), numpy.concatenate((x[:,None], y[:,None], h[:,None], sx[:,None], sy[:,None]), axis = 1), res = 5)
def test_mfit_4(): """ Test height and background initialization. """ height = 20.0 sigma = 1.5 x_size = 100 y_size = 120 background = numpy.zeros((x_size, y_size)) + 10.0 image = dg.drawGaussians((x_size, y_size), numpy.array([[50.0, 50.0, height, sigma, sigma], [50.0, 54.0, height, sigma, sigma]])) image += background mfit = daoFitC.MultiFitter2D(sigma_range = [1.0, 2.0]) mfit.initializeC(image) mfit.newImage(image) mfit.newBackground(background) peaks = {"x" : numpy.array([50.0, 54.0]), "y" : numpy.array([50.0, 50.0]), "z" : numpy.array([0.0, 0.0]), "sigma" : numpy.array([sigma, sigma])} mfit.newPeaks(peaks, "finder") if False: with tifffile.TiffWriter("test_mfit_4.tif") as tf: tf.save((image-background).astype(numpy.float32)) tf.save(mfit.getFitImage().astype(numpy.float32)) # Check height. h = mfit.getPeakProperty("height") for i in range(h.size): assert (abs(h[i] - height)/height < 0.1) # Check background. bg = mfit.getPeakProperty("background") for i in range(bg.size): assert (abs(bg[i] - 10.0) < 1.0e-6) mfit.cleanup(verbose = False)
def test_matched_filter1(): """ Verify that the filter results are normalized correctly. """ x_size = 80 y_size = 90 objects = numpy.zeros((1, 5)) # Make filter with unit sum. objects[0, :] = [x_size / 2, y_size / 2, 1.0, 1.0, 1.0] psf = dg.drawGaussians((x_size, y_size), objects) psf = psf / numpy.sum(psf) flt = matchedFilterC.MatchedFilter(psf) for i in range(1, 5): image = numpy.zeros((x_size, y_size)) image[int(x_size / 2), int(y_size / 2)] = float(i) conv = flt.convolve(image) assert (abs(numpy.sum(image) - numpy.sum(conv)) < 1.0e-6)
def test_matched_filter1(): """ Verify that the filter results are normalized correctly. """ x_size = 80 y_size = 90 objects = numpy.zeros((1, 5)) # Make filter with unit sum. objects[0,:] = [x_size/2, y_size/2, 1.0, 1.0, 1.0] psf = dg.drawGaussians((x_size, y_size), objects) psf = psf/numpy.sum(psf) flt = matchedFilterC.MatchedFilter(psf) for i in range(1,5): image = numpy.zeros((x_size, y_size)) image[int(x_size/2), int(y_size/2)] = float(i) conv = flt.convolve(image) assert(abs(numpy.sum(image) - numpy.sum(conv)) < 1.0e-6)
def getPSFs(self, i3_data): x = i3_data['x'] - 1.0 y = i3_data['y'] - 1.0 a = i3_data['a'] ax = i3_data['ax'] w = i3_data['w'] sx = 0.5*numpy.sqrt(w*w/ax)/self.nm_per_pixel sy = 0.5*numpy.sqrt(w*w*ax)/self.nm_per_pixel h = a/(2.0 * numpy.pi * sx * sy) i3_data['h'] = h return dg.drawGaussians((self.x_size, self.y_size), numpy.concatenate((x[:,None], y[:,None], h[:,None], sx[:,None], sy[:,None]), axis = 1))
if (__name__ == "__main__"): import tifffile import storm_analysis.simulator.draw_gaussians_c as dg x_size = 200 y_size = 300 objects = numpy.zeros((1, 5)) # PSF of shape 1. objects[0,:] = [x_size/2, y_size/2, 1.0, 1.0, 1.0] psf1 = dg.drawGaussians((x_size, y_size), objects) psf1 = psf1/numpy.sum(psf1) flt1 = MatchedFilter(psf1) # PSF of shape 2. objects[0,:] = [x_size/2, y_size/2, 1.0, 2.0, 0.7] psf2 = dg.drawGaussians((x_size, y_size), objects) psf2 = psf2/numpy.sum(psf2) flt2 = MatchedFilter(psf2) result1 = flt1.convolve(10000.0 * psf2) result2 = flt2.convolve(10000.0 * psf2) print("Match to 1:", numpy.max(result1)) print("Match to 2:", numpy.max(result2))
y_size) * random.random() z_off = 0.8 * (random.random() - 0.4) z_vals[j] = z_off * 1000.0 # On a grid. if 1: x_vals[j] = 20.0 + 40.0 * (j % 6) y_vals[j] = 20.0 + 40.0 * math.floor(float(j) / 6.0) z_off = -0.75 + 1.5 * float(j) / float(num_objects - 1) z_vals[j] = z_off * 1000.0 # Generate objects. objects = PSF.PSF(x_vals, y_vals, z_vals, h_vals) # Draw the image. image = dg.drawGaussians([x_size, y_size], objects, background=50, res=5) #image = dg.drawGaussians([x_size, y_size], objects, background = 0, res = 5) #image[0:(x_size/2),:] += 50 # Add poisson noise and baseline. image = numpy.random.poisson(image) + 100.0 # Save the image. dax_data.addFrame(image) # Save the molecule locations. a_vals = PSF.PSFIntegral(z_vals, h_vals) ax = numpy.ones(num_objects) ww = 2.0 * 160.0 * numpy.ones(num_objects) if (PSF.psf_type == "astigmatic"):
y_vals[j] = 0.05 * float(y_size) + 0.9 * float(y_size) * random.random() z_off = 0.8*(random.random() - 0.4) z_vals[j] = z_off * 1000.0 # On a grid. if 1: x_vals[j] = 20.0 + 40.0*(j%6) y_vals[j] = 20.0 + 40.0*math.floor(float(j)/6.0) z_off = -0.75 + 1.5*float(j)/float(num_objects - 1) z_vals[j] = z_off * 1000.0 # Generate objects. objects = PSF.PSF(x_vals, y_vals, z_vals, h_vals) # Draw the image. image = dg.drawGaussians([x_size, y_size], objects, background = 50, res = 5) #image = dg.drawGaussians([x_size, y_size], objects, background = 0, res = 5) #image[0:(x_size/2),:] += 50 # Add poisson noise and baseline. image = numpy.random.poisson(image) + 100.0 # Save the image. dax_data.addFrame(image) # Save the molecule locations. a_vals = PSF.PSFIntegral(z_vals, h_vals) ax = numpy.ones(num_objects) ww = 2.0 * 160.0 * numpy.ones(num_objects) if (PSF.psf_type == "astigmatic"):