def initFitter(finder, parameters, psf_fn): """ Initialize and return a fftFitC.CFFTFit object. """ # Load variance, scale by gain. # # Offset is in units of ADU. # Variance is in units of ADU*ADU. # Gain is ADU/photo-electron. # RQE is dimensionless, it should be around 1.0. # rqe = None variance = None if parameters.hasAttr("camera_calibration"): [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration( parameters.getAttr("camera_calibration")) variance = variance / (gain * gain) # Set variance in the peak finder, this method also pads the # variance to the correct size. variance = finder.setVariance(variance) # Pad relative quantum efficiency array to the correct size. rqe = finder.padArray(rqe) # Create C fitter object. return fftFitC.CFFTFit(psf_fn=psf_fn, rqe=rqe, scmos_cal=variance)
def initFitter(finder, parameters, psf_fn): """ Initialize and return a fftFitC.CFFTFit object. """ # Load variance, scale by gain. # # Offset is in units of ADU. # Variance is in units of ADU*ADU. # Gain is ADU/photo-electron. # RQE is dimensionless, it should be around 1.0. # # This fitter only supports 'MLE' assert (parameters.getAttr("fit_error_model") == 'MLE'), "Only MLE fitting is supported." rqe = None variance = None if parameters.hasAttr("camera_calibration"): [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration(parameters.getAttr("camera_calibration")) variance = variance/(gain*gain) # Set variance in the peak finder, this method also pads the # variance to the correct size. variance = finder.setVariance(variance) # Pad relative quantum efficiency array to the correct size. rqe = finder.padArray(rqe) # Create C fitter object. return fftFitC.CFFTFit(psf_fn = psf_fn, rqe = rqe, scmos_cal = variance)
def initFitter(finder, parameters, pupil_fn): """ Initialize and return a pupilFitC.CPupilFit object. """ # Load variance, scale by gain. # # Offset is in units of ADU. # Variance is in units of ADU*ADU. # Gain is ADU/photo-electron. # RQE is dimensionless, it should be around 1.0. # # This fitter only supports 'MLE' assert (parameters.getAttr("fit_error_model") == 'MLE' ), "Only MLE fitting is supported." rqe = None variance = None if parameters.hasAttr("camera_calibration"): [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration( parameters.getAttr("camera_calibration")) variance = variance / (gain * gain) # Set variance in the peak finder, this method also pads the # variance to the correct size. variance = finder.setVariance(variance) # Pad relative quantum efficiency array to the correct size. rqe = finder.padArray(rqe) # Get fitting Z range. [min_z, max_z] = parameters.getZRange() # Create C fitter object. return pupilFitC.CPupilFit(pupil_fn=pupil_fn, rqe=rqe, scmos_cal=variance)
def initFitter(finder, parameters, spline_fn): """ Initialize and return a cubicFitC.CSplineFit object. """ # Load variance, scale by gain. # # Offset is in units of ADU. # Variance is in units of ADU*ADU. # Gain is ADU/photo-electron. # RQE is dimensionless, it should be around 1.0. # rqe = None variance = None if parameters.hasAttr("camera_calibration"): [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration( parameters.getAttr("camera_calibration")) variance = variance / (gain * gain) # Set variance in the peak finder, this method also pads the # variance to the correct size. variance = finder.setVariance(variance) # Pad relative quantum efficiency array to the correct size. rqe = finder.padArray(rqe) # Create C fitter object. mfitter = None emodel = parameters.getAttr("fit_error_model") if (spline_fn.getType() == "2D"): if (emodel == "MLE"): mfitter = cubicFitC.CSpline2DFit(rqe=rqe, scmos_cal=variance, spline_fn=spline_fn) else: if (emodel == "MLE"): return cubicFitC.CSpline3DFit(rqe=rqe, scmos_cal=variance, spline_fn=spline_fn) elif (emodel == "ALS"): return cubicFitC.CSpline3DFitALS(rqe=rqe, scmos_cal=variance, spline_fn=spline_fn) elif (emodel == "LS"): return cubicFitC.CSpline3DFitLS(rqe=rqe, scmos_cal=variance, spline_fn=spline_fn) elif (emodel == "FWLS"): return cubicFitC.CSpline3DFitFWLS(rqe=rqe, scmos_cal=variance, spline_fn=spline_fn) if mfitter is None: raise Exception("Request error model is not available. " + emodel) return mfitter
def initFitter(finder, parameters, spline_fn): """ Initialize and return a cubicFitC.CSplineFit object. """ # Load variance, scale by gain. # # Offset is in units of ADU. # Variance is in units of ADU*ADU. # Gain is ADU/photo-electron. # RQE is dimensionless, it should be around 1.0. # rqe = None variance = None if parameters.hasAttr("camera_calibration"): [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration(parameters.getAttr("camera_calibration")) variance = variance/(gain*gain) # Set variance in the peak finder, this method also pads the # variance to the correct size. variance = finder.setVariance(variance) # Pad relative quantum efficiency array to the correct size. rqe = finder.padArray(rqe) # Create C fitter object. mfitter = None emodel = parameters.getAttr("fit_error_model") if (spline_fn.getType() == "2D"): if (emodel == "MLE"): mfitter = cubicFitC.CSpline2DFit(rqe = rqe, scmos_cal = variance, spline_fn = spline_fn) else: if (emodel == "MLE"): return cubicFitC.CSpline3DFit(rqe = rqe, scmos_cal = variance, spline_fn = spline_fn) elif (emodel == "ALS"): return cubicFitC.CSpline3DFitALS(rqe = rqe, scmos_cal = variance, spline_fn = spline_fn) elif (emodel == "LS"): return cubicFitC.CSpline3DFitLS(rqe = rqe, scmos_cal = variance, spline_fn = spline_fn) elif (emodel == "FWLS"): return cubicFitC.CSpline3DFitFWLS(rqe = rqe, scmos_cal = variance, spline_fn = spline_fn) if mfitter is None: raise Exception("Request error model is not available. " + emodel) return mfitter
def initFindAndFit(parameters): """ Create and return a fittingMp.MPFinderFitter object. """ # Create PSF objects. psf_objects = initPSFObjects(parameters) # Create peak finder. finder = fittingMp.MPPeakFinderArb(parameters=parameters, psf_objects=psf_objects) # Load sCMOS calibration data. # # Note: Gain is expected to be in units of ADU per photo-electron. # rqes = [] variances = [] for calib_name in mpUtil.getCalibrationAttrs(parameters): [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration(parameters.getAttr(calib_name)) variances.append(variance / (gain * gain)) rqes.append(rqe) # Set variance in the peak finder. This method also pads the variance # to the correct size and performs additional initializations. # variances = finder.setVariances(variances) # Pad the rqes to the correct size. rqes = list(map(lambda x: finder.padArray(x), rqes)) # Create mpFitC.MPFit object. # mfitter = initFitter(finder.margin, parameters, psf_objects, rqes, variances) # Create peak fitter. # fitter = fittingMp.MPPeakFitterArb(mfitter=mfitter, parameters=parameters) # Specify which properties we want (for each channel) from the # analysis. Note that some of these may be duplicates of each # other, for example if the heights are not independent. # properties = [ "background", "error", "height", "iterations", "significance", "sum", "x", "y", "z" ] return fittingMp.MPFinderFitter(peak_finder=finder, peak_fitter=fitter, properties=properties)
def initFindAndFit(parameters): """ Create and return a fittingMp.MPFinderFitter object. """ # Create PSF objects. psf_objects = initPSFObjects(parameters) # Create peak finder. finder = fittingMp.MPPeakFinderArb(parameters = parameters, psf_objects = psf_objects) # Load sCMOS calibration data. # # Note: Gain is expected to be in units of ADU per photo-electron. # rqes = [] variances = [] for calib_name in mpUtil.getCalibrationAttrs(parameters): [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration(parameters.getAttr(calib_name)) variances.append(variance/(gain*gain)) rqes.append(rqe) # Set variance in the peak finder. This method also pads the variance # to the correct size and performs additional initializations. # variances = finder.setVariances(variances) # Pad the rqes to the correct size. rqes = list(map(lambda x: finder.padArray(x), rqes)) # Create mpFitC.MPFit object. # mfitter = initFitter(finder.margin, parameters, psf_objects, rqes, variances) # Create peak fitter. # fitter = fittingMp.MPPeakFitterArb(mfitter = mfitter, parameters = parameters) # Specify which properties we want (for each channel) from the # analysis. Note that some of these may be duplicates of each # other, for example if the heights are not independent. # properties = ["background", "error", "height", "iterations", "significance", "sum", "x", "y", "z"] return fittingMp.MPFinderFitter(peak_finder = finder, peak_fitter = fitter, properties = properties)
def __init__(self, sim_fp, x_size, y_size, i3_data, scmos_cal): Camera.__init__(self, sim_fp, x_size, y_size, i3_data) [self.offset, variance, self.gain] = map(numpy.transpose, analysisIO.loadCMOSCalibration(scmos_cal)) self.std_dev = numpy.sqrt(variance) if (self.offset.shape[0] != x_size) or (self.offset.shape[1] != y_size): raise simbase.SimException( "sCMOS calibration data size does not match the image size.") self.saveJSON({"camera": {"class": "Ideal", "scmos_cal": scmos_cal}})
def test_cal_error_handling(): """ Test calibration file loader error handling. """ cal_file = storm_analysis.getPathOutputTest("calib.npy") offset = numpy.random.uniform(size = cal_size) okay = False numpy.save(cal_file, [offset, offset, offset, 2]) try: [o, v, g, r] = analysisIO.loadCMOSCalibration(cal_file) except analysisIO.AnalysisIOException: okay = True assert okay okay = False numpy.save(cal_file, [offset, offset, offset, offset, 1]) try: [o, v, g, r] = analysisIO.loadCMOSCalibration(cal_file) except analysisIO.AnalysisIOException: okay = True assert okay
def test_cal_error_handling(): """ Test calibration file loader error handling. """ cal_file = storm_analysis.getPathOutputTest("calib.npy") offset = numpy.random.uniform(size=cal_size) okay = False numpy.save(cal_file, [offset, offset, offset, 2]) try: [o, v, g, r] = analysisIO.loadCMOSCalibration(cal_file) except analysisIO.AnalysisIOException: okay = True assert okay okay = False numpy.save(cal_file, [offset, offset, offset, offset, 1]) try: [o, v, g, r] = analysisIO.loadCMOSCalibration(cal_file) except analysisIO.AnalysisIOException: okay = True assert okay
def __init__(self, sim_fp, x_size, y_size, i3_data, scmos_cal): Camera.__init__(self, sim_fp, x_size, y_size, i3_data) # We transpose the calibration data here because the images we process # are the transpose of the images that are saved for the analysis. # [self.offset, variance, self.gain, self.rqe] = map(numpy.transpose, analysisIO.loadCMOSCalibration(scmos_cal)) self.std_dev = numpy.sqrt(variance) if (self.offset.shape[0] != x_size) or (self.offset.shape[1] != y_size): raise simbase.SimException("sCMOS calibration data size does not match the image size.") self.saveJSON({"camera" : {"class" : "SCMOS", "scmos_cal" : scmos_cal}})
def __init__(self, sim_fp, x_size, y_size, i3_data, scmos_cal): Camera.__init__(self, sim_fp, x_size, y_size, i3_data) # We transpose the calibration data here because the images we process # are the transpose of the images that are saved for the analysis. # [self.offset, variance, self.gain, self.rqe] = map(numpy.transpose, analysisIO.loadCMOSCalibration(scmos_cal)) self.std_dev = numpy.sqrt(variance) if (self.offset.shape[0] != x_size) or (self.offset.shape[1] != y_size): raise simbase.SimException( "sCMOS calibration data size does not match the image size.") self.saveJSON({"camera": {"class": "SCMOS", "scmos_cal": scmos_cal}})
def test_cal_v2(): """ Test loading a v2 calibration file. """ cal_file = storm_analysis.getPathOutputTest("calib.npy") offset = numpy.random.uniform(size=cal_size) variance = numpy.random.uniform(size=cal_size) gain = numpy.random.uniform(size=cal_size) rqe = numpy.random.uniform(size=cal_size) numpy.save(cal_file, [offset, variance, gain, rqe, 2]) [o, v, g, r] = analysisIO.loadCMOSCalibration(cal_file) assert (numpy.allclose(offset, o)) assert (numpy.allclose(variance, v)) assert (numpy.allclose(gain, g)) assert (numpy.allclose(rqe, r))
def test_cal_v2(): """ Test loading a v2 calibration file. """ cal_file = storm_analysis.getPathOutputTest("calib.npy") offset = numpy.random.uniform(size = cal_size) variance = numpy.random.uniform(size = cal_size) gain = numpy.random.uniform(size = cal_size) rqe = numpy.random.uniform(size = cal_size) numpy.save(cal_file, [offset, variance, gain, rqe, 2]) [o, v, g, r] = analysisIO.loadCMOSCalibration(cal_file) assert(numpy.allclose(offset, o)) assert(numpy.allclose(variance, v)) assert(numpy.allclose(gain, g)) assert(numpy.allclose(rqe, r))
def resliceCalibration(in_cal, out_cal, xs, ys, xw, yw): """ This follows the same X/Y convention as the image mask and the localizations, Y is the slow axis and X is the fast axis. """ # Load the data & reshape. [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration(in_cal) # Slice out the ROI. xe = xs + xw ye = ys + yw rs_offset = offset[ys:ye,xs:xe] rs_variance = variance[ys:ye,xs:xe] rs_gain = gain[ys:ye,xs:xe] rs_rqe = rqe[ys:ye,xs:xe] # Save sliced calibration. numpy.save(out_cal, [rs_offset, rs_variance, rs_gain, rs_rqe, 2])
def resliceCalibration(in_cal, out_cal, xs, ys, xw, yw): """ This follows the same X/Y convention as the image mask and the localizations, Y is the slow axis and X is the fast axis. """ # Load the data & reshape. [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration(in_cal) # Slice out the ROI. xe = xs + xw ye = ys + yw rs_offset = offset[ys:ye, xs:xe] rs_variance = variance[ys:ye, xs:xe] rs_gain = gain[ys:ye, xs:xe] rs_rqe = rqe[ys:ye, xs:xe] # Save sliced calibration. numpy.save(out_cal, [rs_offset, rs_variance, rs_gain, rs_rqe, 2])
def test_cal_v0(): """ Test loading a v0 calibration file. """ cal_file = storm_analysis.getPathOutputTest("calib.npy") offset = numpy.random.uniform(size = cal_size) variance = numpy.random.uniform(size = cal_size) gain = numpy.random.uniform(size = cal_size) numpy.save(cal_file, [numpy.transpose(offset), numpy.transpose(variance), numpy.transpose(gain)]) [o, v, g, r] = analysisIO.loadCMOSCalibration(cal_file) assert(numpy.allclose(offset, o)) assert(numpy.allclose(variance, v)) assert(numpy.allclose(gain, g)) assert(numpy.allclose(r, numpy.ones(cal_size)))
def initFitter(finder, parameters, psf_fn): """ Initialize and return a fftFitC.CFFTFit object. """ # Load variance, scale by gain. # # Variance is in units of ADU*ADU. # Gain is ADU/photo-electron. # variance = None if parameters.hasAttr("camera_calibration"): [offset, variance, gain] = analysisIO.loadCMOSCalibration( parameters.getAttr("camera_calibration")) variance = variance / (gain * gain) # Set variance in the peak finder, this method also pads the # variance to the correct size. variance = finder.setVariance(variance) # Create C fitter object. return fftFitC.CFFTFit(psf_fn=psf_fn, scmos_cal=variance)
def test_cal_v0(): """ Test loading a v0 calibration file. """ cal_file = storm_analysis.getPathOutputTest("calib.npy") offset = numpy.random.uniform(size=cal_size) variance = numpy.random.uniform(size=cal_size) gain = numpy.random.uniform(size=cal_size) numpy.save(cal_file, [ numpy.transpose(offset), numpy.transpose(variance), numpy.transpose(gain) ]) [o, v, g, r] = analysisIO.loadCMOSCalibration(cal_file) assert (numpy.allclose(offset, o)) assert (numpy.allclose(variance, v)) assert (numpy.allclose(gain, g)) assert (numpy.allclose(r, numpy.ones(cal_size)))
def test_cal_reslice(): """ Test that calibration re-slicing works as expected. """ cal_file = storm_analysis.getPathOutputTest("calib.npy") cal_rs_file = storm_analysis.getPathOutputTest("calib_rs.npy") offset = numpy.random.uniform(size = cal_size) variance = numpy.random.uniform(size = cal_size) gain = numpy.random.uniform(size = cal_size) rqe = numpy.random.uniform(size = cal_size) numpy.save(cal_file, [offset, variance, gain, rqe, 2]) resliceCalibration.resliceCalibration(cal_file, cal_rs_file, 1, 2, 10, 11) [o, v, g, r] = analysisIO.loadCMOSCalibration(cal_rs_file) assert(o.shape == (11,10)) assert(numpy.allclose(offset[2:13,1:11], o)) assert(numpy.allclose(variance[2:13,1:11], v)) assert(numpy.allclose(gain[2:13,1:11], g)) assert(numpy.allclose(rqe[2:13,1:11], r)) assert(analysisIO.isLatestFormat(cal_rs_file))
def test_cal_reslice(): """ Test that calibration re-slicing works as expected. """ cal_file = storm_analysis.getPathOutputTest("calib.npy") cal_rs_file = storm_analysis.getPathOutputTest("calib_rs.npy") offset = numpy.random.uniform(size=cal_size) variance = numpy.random.uniform(size=cal_size) gain = numpy.random.uniform(size=cal_size) rqe = numpy.random.uniform(size=cal_size) numpy.save(cal_file, [offset, variance, gain, rqe, 2]) resliceCalibration.resliceCalibration(cal_file, cal_rs_file, 1, 2, 10, 11) [o, v, g, r] = analysisIO.loadCMOSCalibration(cal_rs_file) assert (o.shape == (11, 10)) assert (numpy.allclose(offset[2:13, 1:11], o)) assert (numpy.allclose(variance[2:13, 1:11], v)) assert (numpy.allclose(gain[2:13, 1:11], g)) assert (numpy.allclose(rqe[2:13, 1:11], r)) assert (analysisIO.isLatestFormat(cal_rs_file))
def initFitter(finder, parameters, spline_fn): """ Initialize and return a cubicFitC.CSplineFit object. """ # Load variance, scale by gain. # # Offset is in units of ADU. # Variance is in units of ADU*ADU. # Gain is ADU/photo-electron. # RQE is dimensionless, it should be around 1.0. # rqe = None variance = None if parameters.hasAttr("camera_calibration"): [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration( parameters.getAttr("camera_calibration")) variance = variance / (gain * gain) # Set variance in the peak finder, this method also pads the # variance to the correct size. variance = finder.setVariance(variance) # Pad relative quantum efficiency array to the correct size. rqe = finder.padArray(rqe) # Create C fitter object. if (spline_fn.getType() == "2D"): return cubicFitC.CSpline2DFit(rqe=rqe, scmos_cal=variance, spline_fn=spline_fn) else: return cubicFitC.CSpline3DFit( als_fit=(parameters.getAttr("anscombe", 0) != 0), rqe=rqe, scmos_cal=variance, spline_fn=spline_fn)
def initFitter(finder, parameters, spline_fn): """ Initialize and return a cubicFitC.CSplineFit object. """ # Load variance, scale by gain. # # Variance is in units of ADU*ADU. # Gain is ADU/photo-electron. # variance = None if parameters.hasAttr("camera_calibration"): [offset, variance, gain] = analysisIO.loadCMOSCalibration( parameters.getAttr("camera_calibration")) variance = variance / (gain * gain) # Set variance in the peak finder, this method also pads the # variance to the correct size. variance = finder.setVariance(variance) # Create C fitter object. if (spline_fn.getType() == "2D"): return cubicFitC.CSpline2DFit(scmos_cal=variance, spline_fn=spline_fn) else: return cubicFitC.CSpline3DFit(scmos_cal=variance, spline_fn=spline_fn)
def initFindAndFit(parameters): """ Return the appropriate type of finder and fitter. """ fmodel = parameters.getAttr("model") emodel = parameters.getAttr("fit_error_model") # Create peak finder. finder = fitting.PeakFinderGaussian(parameters = parameters) # Initialize Z fitting parameters. wx_params = None wy_params = None min_z = None max_z = None if (parameters.getAttr("model", "na") == "Z"): [wx_params, wy_params] = parameters.getWidthParams(for_mu_Zfit = True) [min_z, max_z] = parameters.getZRange() # Check for camera calibration (this function is also used by sCMOS analysis). rqe = None variance = None if parameters.hasAttr("camera_calibration"): # Load variance, scale by gain. # # Offset is in units of ADU. # Variance is in units of ADU*ADU. # Gain is ADU/photo-electron. # RQE is dimensionless, it should be around 1.0. # [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration(parameters.getAttr("camera_calibration")) variance = variance/(gain*gain) # Set variance in the peak finder, this method also pads the # variance to the correct size. variance = finder.setVariance(variance) # Pad relative quantum efficiency array to the correct size. rqe = finder.padArray(rqe) # Create C fitter object. mfitter = None kwds = {'roi_size' : finder.getROISize(), 'rqe' : rqe, 'scmos_cal' : variance, 'wx_params' : wx_params, 'wy_params' : wy_params, 'min_z' : min_z, 'max_z' : max_z} if (fmodel == '2dfixed'): if (emodel == 'MLE'): mfitter = daoFitC.MultiFitter2DFixed(**kwds) elif (emodel == 'ALS'): mfitter = daoFitC.MultiFitter2DFixedALS(**kwds) elif (emodel == 'LS'): mfitter = daoFitC.MultiFitter2DFixedLS(**kwds) elif (emodel == 'DWLS'): mfitter = daoFitC.MultiFitter2DFixedDWLS(**kwds) elif (emodel == 'FWLS'): mfitter = daoFitC.MultiFitter2DFixedFWLS(**kwds) elif (fmodel == '2d'): sigma = parameters.getAttr("sigma") kwds['sigma_range'] = [0.5 * sigma, 5.0 * sigma] if (emodel == 'MLE'): mfitter = daoFitC.MultiFitter2D(**kwds) elif (emodel == 'ALS'): mfitter = daoFitC.MultiFitter2DALS(**kwds) elif (emodel == 'LS'): mfitter = daoFitC.MultiFitter2DLS(**kwds) elif (emodel == 'DWLS'): mfitter = daoFitC.MultiFitter2DDWLS(**kwds) elif (emodel == 'FWLS'): mfitter = daoFitC.MultiFitter2DFWLS(**kwds) elif (fmodel == '3d'): sigma = parameters.getAttr("sigma") kwds['sigma_range'] = [0.5 * sigma, 5.0 * sigma] if (emodel == 'MLE'): mfitter = daoFitC.MultiFitter3D(**kwds) elif (fmodel == 'Z'): if (emodel == 'MLE'): mfitter = daoFitC.MultiFitterZ(**kwds) if mfitter is None: raise Exception("The requested fitting model and/or error model is not available. '" + fmodel + "' '" + emodel + "'") # Create peak fitter. fitter = fitting.PeakFitter(mfitter = mfitter, parameters = parameters) # Specify which properties we want from the analysis. properties = ["background", "error", "height", "iterations", "significance", "sum", "x", "y"] if (fmodel == "2dfixed") or (fmodel == "2d"): properties.append("xsigma") elif (fmodel == "3d"): properties.append("xsigma") properties.append("ysigma") elif (fmodel == "Z"): properties.append("xsigma") properties.append("ysigma") properties.append("z") return fitting.PeakFinderFitter(peak_finder = finder, peak_fitter = fitter, properties = properties)
def initFindAndFit(parameters): """ Return the appropriate type of finder and fitter. """ fmodel = parameters.getAttr("model") # Create peak finder. finder = fitting.PeakFinderGaussian(parameters = parameters) # Initialize Z fitting parameters. wx_params = None wy_params = None min_z = None max_z = None if (parameters.getAttr("model", "na") == "Z"): [wx_params, wy_params] = parameters.getWidthParams(for_mu_Zfit = True) [min_z, max_z] = parameters.getZRange() # Check for camera calibration (this function is also used by sCMOS analysis). rqe = None variance = None if parameters.hasAttr("camera_calibration"): # Load variance, scale by gain. # # Offset is in units of ADU. # Variance is in units of ADU*ADU. # Gain is ADU/photo-electron. # RQE is dimensionless, it should be around 1.0. # [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration(parameters.getAttr("camera_calibration")) variance = variance/(gain*gain) # Set variance in the peak finder, this method also pads the # variance to the correct size. variance = finder.setVariance(variance) # Pad relative quantum efficiency array to the correct size. rqe = finder.padArray(rqe) # Create C fitter object. kwds = {'roi_size' : finder.getROISize(), 'als_fit' : (parameters.getAttr("anscombe", 0) != 0), 'rqe' : rqe, 'scmos_cal' : variance, 'wx_params' : wx_params, 'wy_params' : wy_params, 'min_z' : min_z, 'max_z' : max_z} if (fmodel == '2dfixed'): mfitter = daoFitC.MultiFitter2DFixed(**kwds) elif (fmodel == '2d'): sigma = parameters.getAttr("sigma") kwds['sigma_range'] = [0.5 * sigma, 5.0 * sigma] mfitter = daoFitC.MultiFitter2D(**kwds) elif (fmodel == '3d'): sigma = parameters.getAttr("sigma") kwds['sigma_range'] = [0.5 * sigma, 5.0 * sigma] mfitter = daoFitC.MultiFitter3D(**kwds) elif (fmodel == 'Z'): mfitter = daoFitC.MultiFitterZ(**kwds) else: raise Exception("Unknown fitting model " + fmodel) # Create peak fitter. fitter = fitting.PeakFitter(mfitter = mfitter, parameters = parameters) # Specify which properties we want from the analysis. properties = ["background", "error", "height", "iterations", "significance", "sum", "x", "y"] if (fmodel == "2dfixed") or (fmodel == "2d"): properties.append("xsigma") elif (fmodel == "3d"): properties.append("xsigma") properties.append("ysigma") elif (fmodel == "Z"): properties.append("xsigma") properties.append("ysigma") properties.append("z") return fitting.PeakFinderFitter(peak_finder = finder, peak_fitter = fitter, properties = properties)
def findOffsets(base_name, params_file, background_scale = 4.0, foreground_scale = 1.0, im_slice = None): """ The 'main' function of this module. base_name - The basename for the group of movies. params_file - An analysis XML file containing the details for this experiment. background_scale - Features in the background change on this scale (in pixels) or more slowly. foreground_scale - Features that change on this scale are likely foreground. im_slice - A slice object created for example with numpy.s_ to limit the analysis to a smaller AOI. Notes: 1. This only checks a limited range of offsets between the two channels. 2. This assumes that the movies are longer than just a few frames. """ n_tests = 10 search_range = 5 # Load parameters. parameters = params.ParametersMultiplane().initFromFile(params_file) # Load the movies from each camera. n_channels = 0 movies = [] for ext in mpUtil.getExtAttrs(parameters): movie_name = base_name + parameters.getAttr(ext) movies.append(datareader.inferReader(movie_name)) n_channels += 1 print("Found", n_channels, "movies.") # Load sCMOS calibration data. offsets = [] gains = [] for calib_name in mpUtil.getCalibrationAttrs(parameters): [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration(parameters.getAttr(calib_name)) offsets.append(offset) gains.append(1.0/gain) assert(len(offsets) == n_channels) # Load the plane to plane mapping data & create affine transform objects. mappings = {} with open(parameters.getAttr("mapping"), 'rb') as fp: mappings = pickle.load(fp) atrans = [] for i in range(n_channels-1): xt = mappings["0_" + str(i+1) + "_x"] yt = mappings["0_" + str(i+1) + "_y"] atrans.append(affineTransformC.AffineTransform(xt = xt, yt = yt)) # Create background and foreground variance filters. # # FIXME: Is this right for movies that are not square? # [y_size, x_size] = movies[0].filmSize()[:2] if im_slice is not None: y_size = im_slice[0].stop - im_slice[0].start x_size = im_slice[1].stop - im_slice[1].start psf = dg.drawGaussiansXY((x_size, y_size), numpy.array([0.5*x_size]), numpy.array([0.5*y_size]), sigma = background_scale) psf = psf/numpy.sum(psf) bg_filter = matchedFilterC.MatchedFilter(psf) psf = dg.drawGaussiansXY((x_size, y_size), numpy.array([0.5*x_size]), numpy.array([0.5*y_size]), sigma = foreground_scale) psf = psf/numpy.sum(psf) fg_filter = matchedFilterC.MatchedFilter(psf) var_filter = matchedFilterC.MatchedFilter(psf*psf) # Check background estimation. if False: frame = loadImage(movies[0], 0, offsets[0], gain[0]) frame_bg = estimateBackground(frame, bg_filter, fg_filter, var_filter) with tifffile.TiffWriter("bg_estimate.tif") as tif: tif.save(frame.astype(numpy.float32)) tif.save(frame_bg.astype(numpy.float32)) tif.save((frame - frame_bg).astype(numpy.float32)) votes = numpy.zeros((n_channels - 1, 2*search_range+1)) for i in range(n_tests): print("Test", i) # Load reference frame. ref_frame = loadImage(movies[0], search_range + i, offsets[0], gain[0]) if im_slice is not None: ref_frame = ref_frame[im_slice] ref_frame_bg = estimateBackground(ref_frame, bg_filter, fg_filter, var_filter) ref_frame -= ref_frame_bg # Load test frames and measure correlation. for j in range(n_channels - 1): best_corr = 0.0 best_offset = 0 for k in range(-search_range, search_range + 1): test_frame = loadImage(movies[j+1], search_range + i + k, offsets[j+1], gain[j+1], transform = atrans[j]) if im_slice is not None: test_frame = test_frame[im_slice] test_frame_bg = estimateBackground(test_frame, bg_filter, fg_filter, var_filter) test_frame -= test_frame_bg test_frame_corr = numpy.sum(ref_frame*test_frame)/numpy.sum(test_frame) if (test_frame_corr > best_corr): best_corr = test_frame_corr best_offset = k + search_range votes[j, best_offset] += 1 # Print results. print("Offset votes:") print(votes) frame_offsets = [0] frame_offsets += list(numpy.argmax(votes, axis = 1) - search_range) print("Best offsets:") for i in range(n_channels): print(str(i) + ": " + str(frame_offsets[i])) # Create stacks with optimal offsets. print("Saving image stacks.") for i in range(n_channels): with tifffile.TiffWriter(base_name + "_offsets_ch" + str(i) + ".tif") as tif: for j in range(5): if (i == 0): frame = loadImage(movies[i], search_range + frame_offsets[i] + j, offsets[i], gain[i]) else: frame = loadImage(movies[i], search_range + frame_offsets[i] + j, offsets[i], gain[i], transform = atrans[i-1]) if im_slice is not None: frame = frame[im_slice] frame_bg = estimateBackground(frame, bg_filter, fg_filter, var_filter) frame -= frame_bg tif.save(frame.astype(numpy.float32)) return frame_offsets
def findOffsets(base_name, params_file, background_scale=4.0, foreground_scale=1.0): """ The 'main' function of this module. base_name - The basename for the group of movies. params_file - An analysis XML file containing the details for this experiment. background_scale - Features in the background change on this scale (in pixels) or more slowly. foreground_scale - Features that change on this scale are likely foreground. Notes: 1. This only checks a limited range of offsets between the two channels. 2. This assumes that the movies are longer than just a few frames. """ n_tests = 10 search_range = 5 # Load parameters. parameters = params.ParametersMultiplane().initFromFile(params_file) # Load the movies from each camera. n_channels = 0 movies = [] for ext in mpUtil.getExtAttrs(parameters): movie_name = base_name + parameters.getAttr(ext) movies.append(datareader.inferReader(movie_name)) n_channels += 1 print("Found", n_channels, "movies.") # Load sCMOS calibration data. offsets = [] gains = [] for calib_name in mpUtil.getCalibrationAttrs(parameters): [offset, variance, gain, rqe] = analysisIO.loadCMOSCalibration(parameters.getAttr(calib_name)) offsets.append(offset) gains.append(1.0 / gain) assert (len(offsets) == n_channels) # Load the plane to plane mapping data & create affine transform objects. mappings = {} with open(parameters.getAttr("mapping"), 'rb') as fp: mappings = pickle.load(fp) atrans = [] for i in range(n_channels - 1): xt = mappings["0_" + str(i + 1) + "_x"] yt = mappings["0_" + str(i + 1) + "_y"] atrans.append(affineTransformC.AffineTransform(xt=xt, yt=yt)) # Create background and foreground variance filters. # # FIXME: Is this right for movies that are not square? # [y_size, x_size] = movies[0].filmSize()[:2] psf = dg.drawGaussiansXY((x_size, y_size), numpy.array([0.5 * x_size]), numpy.array([0.5 * y_size]), sigma=background_scale) psf = psf / numpy.sum(psf) bg_filter = matchedFilterC.MatchedFilter(psf) psf = dg.drawGaussiansXY((x_size, y_size), numpy.array([0.5 * x_size]), numpy.array([0.5 * y_size]), sigma=foreground_scale) psf = psf / numpy.sum(psf) fg_filter = matchedFilterC.MatchedFilter(psf) var_filter = matchedFilterC.MatchedFilter(psf * psf) # Check background estimation. if False: frame = loadImage(movies[0], 0, offsets[0], gain[0]) frame_bg = estimateBackground(frame, bg_filter, fg_filter, var_filter) with tifffile.TiffWriter("bg_estimate.tif") as tif: tif.save(frame.astype(numpy.float32)) tif.save(frame_bg.astype(numpy.float32)) tif.save((frame - frame_bg).astype(numpy.float32)) votes = numpy.zeros((n_channels - 1, 2 * search_range + 1)) for i in range(n_tests): print("Test", i) # Load reference frame. ref_frame = loadImage(movies[0], search_range + i, offsets[0], gain[0]) ref_frame_bg = estimateBackground(ref_frame, bg_filter, fg_filter, var_filter) ref_frame -= ref_frame_bg # Load test frames and measure correlation. for j in range(n_channels - 1): best_corr = 0.0 best_offset = 0 for k in range(-search_range, search_range + 1): test_frame = loadImage(movies[j + 1], search_range + i + k, offsets[j + 1], gain[j + 1], transform=atrans[j]) test_frame_bg = estimateBackground(test_frame, bg_filter, fg_filter, var_filter) test_frame -= test_frame_bg test_frame_corr = numpy.sum( ref_frame * test_frame) / numpy.sum(test_frame) if (test_frame_corr > best_corr): best_corr = test_frame_corr best_offset = k + search_range votes[j, best_offset] += 1 # Print results. print("Offset votes:") print(votes) frame_offsets = [0] frame_offsets += list(numpy.argmax(votes, axis=1) - search_range) print("Best offsets:") for i in range(n_channels): print(str(i) + ": " + str(frame_offsets[i])) # Create stacks with optimal offsets. print("Saving image stacks.") for i in range(n_channels): with tifffile.TiffWriter("find_offsets_ch" + str(i) + ".tif") as tif: for j in range(5): if (i == 0): frame = loadImage(movies[i], search_range + frame_offsets[i] + j, offsets[i], gain[i]) else: frame = loadImage(movies[i], search_range + frame_offsets[i] + j, offsets[i], gain[i], transform=atrans[i - 1]) frame_bg = estimateBackground(frame, bg_filter, fg_filter, var_filter) frame -= frame_bg tif.save(frame.astype(numpy.float32))
def initFindAndFit(parameters): """ Return the appropriate type of finder and fitter. """ fmodel = parameters.getAttr("model") # Create peak finder. finder = fitting.PeakFinderGaussian(parameters=parameters) # Initialize Z fitting parameters. wx_params = None wy_params = None min_z = None max_z = None if (parameters.getAttr("model", "na") == "Z"): [wx_params, wy_params] = parameters.getWidthParams(for_mu_Zfit=True) [min_z, max_z] = parameters.getZRange() # Check for camera calibration (this function is also used by sCMOS analysis). variance = None if parameters.hasAttr("camera_calibration"): # Load variance, scale by gain. # # Variance is in units of ADU*ADU. # Gain is ADU/photo-electron. # [offset, variance, gain] = analysisIO.loadCMOSCalibration( parameters.getAttr("camera_calibration")) variance = variance / (gain * gain) # Set variance in the peak finder, this method also pads the # variance to the correct size. variance = finder.setVariance(variance) # Create C fitter object. fitters = { '2dfixed': daoFitC.MultiFitter2DFixed, '2d': daoFitC.MultiFitter2D, '3d': daoFitC.MultiFitter3D, 'Z': daoFitC.MultiFitterZ } mfitter = fitters[fmodel](roi_size=finder.getROISize(), scmos_cal=variance, wx_params=wx_params, wy_params=wy_params, min_z=min_z, max_z=max_z) # Create peak fitter. fitter = fitting.PeakFitter(mfitter=mfitter, parameters=parameters) # Specify which properties we want from the analysis. properties = [ "background", "error", "height", "iterations", "significance", "sum", "x", "y" ] if (fmodel == "2dfixed") or (fmodel == "2d"): properties.append("xsigma") elif (fmodel == "3d"): properties.append("xsigma") properties.append("ysigma") elif (fmodel == "Z"): properties.append("xsigma") properties.append("ysigma") properties.append("z") return fitting.PeakFinderFitter(peak_finder=finder, peak_fitter=fitter, properties=properties)