Exemplo n.º 1
0
def convertToMultiFit(i3data, x_size, y_size, frame, nm_per_pixel, inverted=False):
    """
    Create a 3D-DAOSTORM, sCMOS or Spliner analysis compatible peak array from I3 data.

    Notes:
      (1) This uses the non-drift corrected positions.
      (2) This sets the initial fitting error to zero and the status to RUNNING.
    """
    i3data = maskData(i3data, (i3data['fr'] == frame))

    peaks = numpy.zeros((i3data.size, utilC.getNPeakPar()))
    
    peaks[:,utilC.getBackgroundIndex()] = i3data['bg']
    peaks[:,utilC.getHeightIndex()] = i3data['h']
    peaks[:,utilC.getZCenterIndex()] = i3data['z'] * 0.001

    if inverted:
        peaks[:,utilC.getXCenterIndex()] = y_size - i3data['x']
        peaks[:,utilC.getYCenterIndex()] = x_size - i3data['y']
        ax = i3data['ax']
        ww = i3data['w']
        peaks[:,utilC.getYWidthIndex()] = 0.5*numpy.sqrt(ww*ww/ax)/nm_per_pixel
        peaks[:,utilC.getXWidthIndex()] = 0.5*numpy.sqrt(ww*ww*ax)/nm_per_pixel
    else:
        peaks[:,utilC.getYCenterIndex()] = i3data['x'] - 1
        peaks[:,utilC.getXCenterIndex()] = i3data['y'] - 1
        ax = i3data['ax']
        ww = i3data['w']
        peaks[:,utilC.getXWidthIndex()] = 0.5*numpy.sqrt(ww*ww/ax)/nm_per_pixel
        peaks[:,utilC.getYWidthIndex()] = 0.5*numpy.sqrt(ww*ww*ax)/nm_per_pixel

    return peaks
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
    def __init__(self, parameters):

        # Initialized from parameters.
        self.find_max_radius = parameters.getAttr("find_max_radius", 5)     # Radius (in pixels) over which the maxima is maximal.
        self.iterations = parameters.getAttr("iterations")                  # Maximum number of cycles of peak finding, fitting and subtraction to perform.
        self.sigma = parameters.getAttr("sigma")                            # Peak sigma (in pixels).
        self.threshold = parameters.getAttr("threshold")                    # Peak minimum threshold (height, in camera units).
        self.z_value = parameters.getAttr("z_value", 0.0)                   # The starting z value to use for peak fitting.

        # Other member variables.
        self.background = None                                              # Current estimate of the image background.
        self.image = None                                                   # The original image.
        self.margin = PeakFinderFitter.margin                               # Size of the unanalyzed "edge" around the image.
        self.neighborhood = PeakFinder.unconverged_dist * self.sigma        # Radius for marking neighbors as unconverged.
        self.new_peak_radius = PeakFinder.new_peak_dist                     # Minimum allowed distance between new peaks and current peaks.
        self.parameters = parameters                                        # Keep access to the parameters object.
        self.peak_locations = None                                          # Initial peak locations, as explained below.
        self.peak_mask = None                                               # Mask for limiting peak identification to a particular AOI.
        self.taken = None                                                   # Spots in the image where a peak has already been added.

        
        #
        # This is for is you already know where your want fitting to happen, as
        # for example in a bead calibration movie and you just want to use the
        # approximate locations as inputs for fitting.
        #
        # peak_locations is a text file with the peak x, y, height and background
        # values as white spaced columns (x and y positions are in pixels as
        # determined using visualizer).
        #
        # 1.0 2.0 1000.0 100.0
        # 10.0 5.0 2000.0 200.0
        # ...
        #
        if parameters.hasAttr("peak_locations"):
            print("Using peak starting locations specified in", parameters.getAttr("peak_locations"))

            # Only do one cycle of peak finding as we'll always return the same locations.
            if (self.iterations != 1):
                print("WARNING: setting number of iterations to 1!")
                self.iterations = 1

            # Load peak x,y locations.
            peak_locs = numpy.loadtxt(parameters.getAttr("peak_locations"), ndmin = 2)
            print(peak_locs.shape)

            # Create peak array.
            self.peak_locations = numpy.zeros((peak_locs.shape[0],
                                               utilC.getNPeakPar()))
            self.peak_locations[:,utilC.getXCenterIndex()] = peak_locs[:,1] + self.margin
            self.peak_locations[:,utilC.getYCenterIndex()] = peak_locs[:,0] + self.margin
            self.peak_locations[:,utilC.getHeightIndex()] = peak_locs[:,2]
            self.peak_locations[:,utilC.getBackgroundIndex()] = peak_locs[:,3]

            self.peak_locations[:,utilC.getXWidthIndex()] = numpy.ones(peak_locs.shape[0]) * self.sigma
            self.peak_locations[:,utilC.getYWidthIndex()] = numpy.ones(peak_locs.shape[0]) * self.sigma
Exemplo n.º 8
0
def convertToMultiFit(i3data,
                      x_size,
                      y_size,
                      frame,
                      nm_per_pixel,
                      inverted=False):
    """
    Create a 3D-DAOSTORM, sCMOS or Spliner analysis compatible peak array from I3 data.

    Notes:
      (1) This uses the non-drift corrected positions.
      (2) This sets the initial fitting error to zero and the status to RUNNING.
    """
    i3data = maskData(i3data, (i3data['fr'] == frame))

    peaks = numpy.zeros((i3data.size, utilC.getNPeakPar()))

    peaks[:, utilC.getBackgroundIndex()] = i3data['bg']
    peaks[:, utilC.getHeightIndex()] = i3data['h']
    peaks[:, utilC.getZCenterIndex()] = i3data['z'] * 0.001

    if inverted:
        peaks[:, utilC.getXCenterIndex()] = y_size - i3data['x']
        peaks[:, utilC.getYCenterIndex()] = x_size - i3data['y']
        ax = i3data['ax']
        ww = i3data['w']
        peaks[:, utilC.getYWidthIndex()] = 0.5 * numpy.sqrt(
            ww * ww / ax) / nm_per_pixel
        peaks[:, utilC.getXWidthIndex()] = 0.5 * numpy.sqrt(
            ww * ww * ax) / nm_per_pixel
    else:
        peaks[:, utilC.getYCenterIndex()] = i3data['x'] - 1
        peaks[:, utilC.getXCenterIndex()] = i3data['y'] - 1
        ax = i3data['ax']
        ww = i3data['w']
        peaks[:, utilC.getXWidthIndex()] = 0.5 * numpy.sqrt(
            ww * ww / ax) / nm_per_pixel
        peaks[:, utilC.getYWidthIndex()] = 0.5 * numpy.sqrt(
            ww * ww * ax) / nm_per_pixel

    return peaks
Exemplo n.º 9
0
    def getPeaks(self, threshold, margin):
        """
        Extract peaks from the deconvolved image and create
        an array that can be used by a peak fitter.
        
        FIXME: Need to compensate for up-sampling parameter in x,y.
        """

        fx = self.getXVector()

        # Get area, position, height.
        fd_peaks = fdUtil.getPeaks(fx, threshold, margin)
        num_peaks = fd_peaks.shape[0]

        peaks = numpy.zeros((num_peaks, utilC.getNPeakPar()))

        peaks[:, utilC.getXWidthIndex()] = numpy.ones(num_peaks)
        peaks[:, utilC.getYWidthIndex()] = numpy.ones(num_peaks)

        peaks[:, utilC.getXCenterIndex()] = fd_peaks[:, 2]
        peaks[:, utilC.getYCenterIndex()] = fd_peaks[:, 1]

        # Calculate height.
        #
        # FIXME: Typically the starting value for the peak height will be
        #        under-estimated unless a large enough number of FISTA
        #        iterations is performed to completely de-convolve the image.
        #
        h_index = utilC.getHeightIndex()
        #peaks[:,h_index] = fd_peaks[:,0]
        for i in range(num_peaks):
            peaks[i, h_index] = fd_peaks[i, 0] * self.psf_heights[int(
                round(fd_peaks[i, 3]))]

        # Calculate z (0.0 - 1.0).
        if (fx.shape[2] > 1):
            peaks[:, utilC.getZCenterIndex()] = fd_peaks[:, 3] / (
                float(fx.shape[2]) - 1.0)

        # Background term calculation.
        bg_index = utilC.getBackgroundIndex()
        for i in range(num_peaks):
            ix = int(round(fd_peaks[i, 1]))
            iy = int(round(fd_peaks[i, 2]))
            peaks[i, bg_index] = self.background[ix, iy]

        return peaks
Exemplo n.º 10
0
    def getPeaks(self, threshold, margin):

        fx = self.getXVector()

        # Get area, position, height.
        fd_peaks = fdUtil.getPeaks(fx, threshold, margin)
        num_peaks = fd_peaks.shape[0]

        peaks = numpy.zeros((num_peaks, utilC.getNResultsPar()))

        peaks[:, utilC.getXWidthIndex()] = numpy.ones(num_peaks)
        peaks[:, utilC.getYWidthIndex()] = numpy.ones(num_peaks)

        peaks[:, utilC.getXCenterIndex()] = fd_peaks[:, 2]
        peaks[:, utilC.getYCenterIndex()] = fd_peaks[:, 1]

        # Calculate height.
        #
        # FIXME: Typically the starting value for the peak height will be
        #        under-estimated unless a large enough number of FISTA
        #        iterations is performed to completely de-convolve the image.
        #
        h_index = utilC.getHeightIndex()
        #peaks[:,h_index] = fd_peaks[:,0]
        for i in range(num_peaks):
            peaks[i, h_index] = fd_peaks[i, 0] * self.psf_heights[int(
                round(fd_peaks[i, 3]))]

        # Calculate z (0.0 - 1.0).
        peaks[:,
              utilC.getZCenterIndex()] = fd_peaks[:, 3] / (float(fx.shape[2]) -
                                                           1.0)

        # Background term calculation.
        bg_index = utilC.getBackgroundIndex()
        for i in range(num_peaks):
            ix = int(round(fd_peaks[i, 1]))
            iy = int(round(fd_peaks[i, 2]))
            peaks[i, bg_index] = self.background[ix, iy]

        return peaks
Exemplo n.º 11
0
    def __init__(self, parameters):

        # Member variables.
        self.background = None  # Current estimate of the image background.
        self.image = None  # The original image.
        self.iterations = parameters.iterations  # Maximum number of cycles of peak finding, fitting and subtraction to perform.
        self.margin = PeakFinderFitter.margin  # Size of the unanalyzed "edge" around the image.
        self.neighborhood = PeakFinder.unconverged_dist * parameters.sigma  # Radius for marking neighbors as unconverged.
        self.new_peak_radius = PeakFinder.new_peak_dist  # Minimum allowed distance between new peaks and current peaks.
        self.parameters = parameters  # Keep access to the parameters object.
        self.peak_locations = None  # Initial peak locations, as explained below.
        self.peak_mask = None  # Mask for limiting peak identification to a particular AOI.
        self.sigma = parameters.sigma  # Peak sigma (in pixels).
        self.taken = None  # Spots in the image where a peak has already been added.
        self.threshold = parameters.threshold  # Peak minimum threshold (height, in camera units).
        self.z_value = 0.0  # The starting z value to use for peak fitting.

        # Radius (in pixels) over which the maxima is maximal.
        if hasattr(parameters, "find_max_radius"):
            self.find_max_radius = float(parameters.find_max_radius)
        else:
            self.find_max_radius = 5

        #
        # This is for is you already know where your want fitting to happen, as
        # for example in a bead calibration movie and you just want to use the
        # approximate locations as inputs for fitting.
        #
        # peak_locations is a text file with the peak x, y, height and background
        # values as white spaced columns (x and y positions are in pixels as
        # determined using visualizer).
        #
        # 1.0 2.0 1000.0 100.0
        # 10.0 5.0 2000.0 200.0
        # ...
        #
        if hasattr(parameters, "peak_locations"):
            print("Using peak starting locations specified in",
                  parameters.peak_locations)

            # Only do one cycle of peak finding as we'll always return the same locations.
            if (self.iterations != 1):
                print("WARNING: setting number of iterations to 1!")
                self.iterations = 1

            # Load peak x,y locations.
            peak_locs = numpy.loadtxt(parameters.peak_locations, ndmin=2)
            print(peak_locs.shape)

            # Create peak array.
            self.peak_locations = numpy.zeros(
                (peak_locs.shape[0], util_c.getNResultsPar()))
            self.peak_locations[:, util_c.getXCenterIndex(
            )] = peak_locs[:, 1] + self.margin
            self.peak_locations[:, util_c.getYCenterIndex(
            )] = peak_locs[:, 0] + self.margin
            self.peak_locations[:, util_c.getHeightIndex()] = peak_locs[:, 2]
            self.peak_locations[:, util_c.getBackgroundIndex()] = peak_locs[:,
                                                                            3]

            self.peak_locations[:, util_c.getXWidthIndex()] = numpy.ones(
                peak_locs.shape[0]) * self.sigma
            self.peak_locations[:, util_c.getYWidthIndex()] = numpy.ones(
                peak_locs.shape[0]) * self.sigma