def configureTest():
    """
    These tests have a lot of setup. This function takes care of this.
    """
    mparams = params.ParametersMultiplane()

    # sCMOS calibration files.
    gain = numpy.ones(im_size)
    offset = numpy.zeros(im_size)
    variance = numpy.ones(im_size)
    rqe = numpy.ones(im_size)

    cal_file = storm_analysis.getPathOutputTest("c1_cal.npy")
    numpy.save(cal_file, [offset, variance, gain, rqe, 2])
    mparams.changeAttr("channel0_cal", cal_file)

    cal_file = storm_analysis.getPathOutputTest("c2_cal.npy")
    numpy.save(cal_file, [offset, variance, gain, rqe, 2])
    mparams.changeAttr("channel1_cal", cal_file)

    mparams.changeAttr("channel0_ext", "_c1.tif")
    mparams.changeAttr("channel1_ext", "_c2.tif")

    mparams.changeAttr("channel0_offset", 0)
    mparams.changeAttr("channel1_offset", 0)

    return mparams
Example #2
0
def analyze(base_name, mlist_name, olist_name, settings_name):
    parameters = params.ParametersMultiplane().initFromFile(settings_name)
    finder = PFPeakFinder(parameters)
    fitter = findPeaksStd.MPPeakFitter(parameters)
    finder_fitter = PFPeakFinderFitter(parameters, finder, fitter)
    reader = PFMovieReader(base_name=base_name,
                           bin_name=olist_name,
                           parameters=parameters)
    stdAnalysis.standardAnalysis(finder_fitter, reader, mlist_name, parameters)
Example #3
0
def analyze(base_name, mlist_name, settings_name):
    parameters = params.ParametersMultiplane().initFromFile(settings_name)
    finder = findPeaksStd.MPPeakFinder(parameters)
    fitter = findPeaksStd.MPPeakFitter(parameters)
    finder_fitter = findPeaksStd.MPFinderFitter(parameters, finder, fitter)
    reader = findPeaksStd.MPMovieReader(base_name = base_name,
                                        parameters = parameters)
    data_writer = findPeaksStd.MPDataWriter(data_file = mlist_name,
                                            parameters = parameters)
    stdAnalysis.standardAnalysis(finder_fitter,
                                 reader,
                                 data_writer,
                                 parameters)
Example #4
0
def splitPeaks(mlist_filename, params_filename):

    parameters = params.ParametersMultiplane().initFromFile(params_filename)

    # Load the plane to plane mapping data.
    mappings = {}
    if parameters.hasAttr("mapping"):
        if os.path.exists(parameters.getAttr("mapping")):
            with open(parameters.getAttr("mapping"), 'rb') as fp:
                mappings = pickle.load(fp)

        else:
            print("No mapping file parameter, nothing to do")

    # Load frame offset information.
    frame_offsets = list(
        map(parameters.getAttr, mpUtilC.getOffsetAttrs(parameters)))
    print(frame_offsets)

    # Load the molecule list.
    ch0_data = readinsight3.loadI3File(mlist_filename)

    # Map to other channels.
    basename = mlist_filename[:-4]
    channel = 1
    m_key = "0_1_"
    while (m_key + "x") in mappings:
        chn_data = ch0_data.copy()

        # Map x.
        tx = mappings[m_key + "x"]
        chn_data['x'] = tx[0] + ch0_data['x'] * tx[1] + ch0_data['y'] * tx[2]

        # Map y.
        ty = mappings[m_key + "y"]
        chn_data['y'] = ty[0] + ch0_data['x'] * ty[1] + ch0_data['y'] * ty[2]

        # Map frame.
        chn_data[
            'fr'] = ch0_data['fr'] - frame_offsets[0] + frame_offsets[channel]

        with writeinsight3.I3Writer(basename + "_ch" + str(channel) +
                                    ".bin") as i3w:
            i3w.addMolecules(chn_data)

        channel += 1
        m_key = "0_" + str(channel) + "_"
def analyze(base_name, mlist_name, settings_name):
    parameters = params.ParametersMultiplane().initFromFile(settings_name)

    # Set to only analyze 1 frame, 1 iteration of peak finding.
    parameters.setAttr("max_frame", "int", 1)
    parameters.setAttr("iterations", "int", 1)

    # Analyze one frame.
    finder = PFPeakFinder(parameters)
    fitter = PFPeakFitter(parameters)
    finder_fitter = findPeaksStd.MPFinderFitter(parameters, finder, fitter)
    reader = findPeaksStd.MPMovieReader(base_name=base_name,
                                        parameters=parameters)
    stdAnalysis.standardAnalysis(finder_fitter, reader, mlist_name, parameters)

    # Evaluate found vs fit parameters.
    hi = utilC.getHeightIndex()
    xi = utilC.getXCenterIndex()
    yi = utilC.getYCenterIndex()

    # First identify peak pairs.
    fi_x = fitted_peaks[:, xi]
    fi_y = fitted_peaks[:, yi]
    fo_x = found_peaks[:, xi]
    fo_y = found_peaks[:, yi]

    dd = utilC.peakToPeakDist(fo_x, fo_y, fi_x, fi_y)
    di = utilC.peakToPeakIndex(fo_x, fo_y, fi_x, fi_y)

    print(numpy.mean(dd), fi_x.size, fo_x.size)

    fo_h = []
    fi_h = []
    for i in range(dd.size):
        if (dd[i] < 2.0):
            fo_h.append(found_peaks[i, hi])
            fi_h.append(fitted_peaks[di[i], hi])

    fi_h = numpy.array(fi_h)
    fo_h = numpy.array(fo_h)

    print(numpy.mean(fi_h), fi_h.size)
    print(numpy.mean(fo_h), fo_h.size)
    print(numpy.mean(fi_h) / numpy.mean(fo_h))
def test_offset_2():
    """
    Movie reading test with non-zero offset.
    """
    # Create XML file and sCMOS calibration files.
    mparams = configureTest()
    xml_file = storm_analysis.getPathOutputTest("mp_analysis.xml")

    mparams.changeAttr("channel1_offset", 1)
    mparams.toXMLFile(xml_file)

    # Create movies.
    mv_file = storm_analysis.getPathOutputTest("mp_c1.tif")
    with tifffile.TiffWriter(mv_file) as tf:
        for i in range(10):
            im = (i + 1) * numpy.ones(im_size, dtype=numpy.int16)
            tf.save(im.astype(numpy.int16))

    mv_file = storm_analysis.getPathOutputTest("mp_c2.tif")
    with tifffile.TiffWriter(mv_file) as tf:
        for i in range(10):
            im = (i + 1) * numpy.ones(im_size, dtype=numpy.int16)
            tf.save(im.astype(numpy.int16))

    # Create and test MPMovieReader
    mpmr = analysis_io.MPMovieReader(
        base_name=os.path.join(storm_analysis.getPathOutputTest(), "mp"),
        parameters=params.ParametersMultiplane().initFromFile(xml_file))
    mpmr.setup(0)

    [mx, my, ml] = mpmr.getFilmSize()
    assert (mx == im_size[1])
    assert (my == im_size[0])
    assert (ml == 9)

    # Check that all of the frames are the same.
    for i in range(ml):
        frames = mpmr.getFrames(i)
        assert (numpy.allclose(frames[0], frames[1] - 1))
    parser.add_argument(
        '--photons',
        dest='photons',
        type=int,
        required=True,
        help="An estimate of the average number of photons in the localization."
    )
    parser.add_argument('--xml',
                        dest='xml',
                        type=str,
                        required=True,
                        help="The name of the settings xml file.")

    args = parser.parse_args()

    parameters = params.ParametersMultiplane().initFromFile(args.xml)
    spline_file_names = []
    for spline_attr in mpUtilC.getSplineAttrs(parameters):
        spline_file_names.append(parameters.getAttr(spline_attr))

    #
    # FIXME: Variances or weights need to be adjusted in x, y based on
    #        the mapping. This won't make much difference for symmetric
    #        PSFs but it is currently incorrect for asymmetric PSFs.
    #
    variances = planeVariances(args.background, args.photons,
                               parameters.getAttr("pixel_size"),
                               spline_file_names)

    weights = {
        "bg": planeWeights(variances[0]),
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))