Esempio n. 1
0
    def peakFinder(self, no_bg_image):

        # Mask the image so that peaks are only found in the AOI.
        masked_image = no_bg_image * self.peak_mask
        
        # Identify local maxima in the masked image.
        [new_peaks, self.taken] = utilC.findLocalMaxima(masked_image,
                                                        self.taken,
                                                        self.cur_threshold,
                                                        self.find_max_radius,
                                                        self.margin)

        # Fill in initial values for peak height, background and sigma.
        new_peaks = utilC.initializePeaks(new_peaks,         # The new peaks.
                                          self.image,        # The original image.
                                          self.background,   # The current estimate of the background.
                                          self.sigma,        # The starting sigma value.
                                          self.z_value)      # The starting z value.
            
        return new_peaks
Esempio n. 2
0
    def peakFinder(self, no_bg_image):

        # Mask the image so that peaks are only found in the AOI.
        masked_image = no_bg_image * self.peak_mask

        # Identify local maxima in the masked image.
        [new_peaks,
         self.taken] = util_c.findLocalMaxima(masked_image, self.taken,
                                              self.cur_threshold,
                                              self.find_max_radius,
                                              self.margin)

        # Fill in initial values for peak height, background and sigma.
        new_peaks = util_c.initializePeaks(
            new_peaks,  # The new peaks.
            self.image,  # The original image.
            self.background,  # The current estimate of the background.
            self.sigma,  # The starting sigma value.
            self.z_value)  # The starting z value.

        return new_peaks
Esempio n. 3
0
    def peakFinder(self, image):

        # Calculate convolved image, this is where the background subtraction happens.
        smooth_image = self.smoother.smoothImage(image, self.sigma)

        # Mask the image so that peaks are only found in the AOI.
        masked_image = smooth_image * self.peak_mask

        # Identify local maxima in the masked image.
        [new_peaks,
         self.taken] = utilC.findLocalMaxima(masked_image, self.taken,
                                             self.cur_threshold,
                                             self.find_max_radius, self.margin)

        # Fill in initial values for peak height, background and sigma.
        new_peaks = utilC.initializePeaks(
            new_peaks,  # The new peaks.
            self.image,  # The original image.
            self.background,  # The current estimate of the background.
            self.sigma,  # The starting sigma value.
            self.z_value)  # The starting z value.

        return new_peaks
Esempio n. 4
0
    def peakFinder(self, image):

        # Calculate convolved image, this is where the background subtraction happens.
        smooth_image = self.smoother.smoothImage(image, self.sigma)

        # Mask the image so that peaks are only found in the AOI.
        masked_image = smooth_image * self.peak_mask

        # Identify local maxima in the masked image.
        [new_peaks, self.taken] = utilC.findLocalMaxima(
            masked_image, self.taken, self.cur_threshold, self.find_max_radius, self.margin
        )

        # Fill in initial values for peak height, background and sigma.
        new_peaks = utilC.initializePeaks(
            new_peaks,  # The new peaks.
            self.image,  # The original image.
            self.background,  # The current estimate of the background.
            self.sigma,  # The starting sigma value.
            self.z_value,
        )  # The starting z value.

        return new_peaks
Esempio n. 5
0
    def peakFinder(self, no_bg_image):
        """
        This method does the actual peak finding.
        
        Override this if you want to change the peak finding behaviour.
        """
        # Mask the image so that peaks are only found in the AOI.
        masked_image = no_bg_image * self.peak_mask

        # Identify local maxima in the masked image.
        [new_peaks,
         self.taken] = utilC.findLocalMaxima(masked_image, self.taken,
                                             self.cur_threshold,
                                             self.find_max_radius, self.margin)

        # Fill in initial values for peak height, background and sigma.
        new_peaks = utilC.initializePeaks(
            new_peaks,  # The new peaks.
            self.image,  # The original image.
            self.background,  # The current estimate of the background.
            self.sigma,  # The starting sigma value.
            self.z_value)  # The starting z value.

        return new_peaks
Esempio n. 6
0
    def peakFinder(self, no_bg_image):

        all_new_peaks = None

        save_convolution = False
        if save_convolution:
            print("making image")
            tif = tifffile.TiffWriter("image.tif")
            tif.save(self.image.astype(numpy.uint16) + 100)
            tif.save(no_bg_image.astype(numpy.uint16) + 100)
            tif.save(self.background.astype(numpy.uint16) + 100)
            
        #
        # Find peaks in image convolved with the PSF at different z values.
        #
        for i in range(len(self.mfilter)):

            height_rescale = self.height_rescale[i]
            mfilter = self.mfilter[i]
            taken = self.taken[i]
            z_value = self.z_value[i]

            # Smooth image with gaussian filter.
            smooth_image = mfilter.convolve(no_bg_image)

            if save_convolution:
                tif.save(smooth_image.astype(numpy.uint16) + 100)

            # Mask the image so that peaks are only found in the AOI.
            masked_image = smooth_image * self.peak_mask
        
            # Identify local maxima in the masked image.
            [new_peaks, taken] = utilC.findLocalMaxima(masked_image,
                                                       taken,
                                                       self.cur_threshold,
                                                       self.find_max_radius,
                                                       self.margin)

            #
            # Fill in initial values for peak height, background and sigma.
            #
            # FIXME: We just add the smoothed image and the background together
            #        as a hack so that we can still use the initializePeaks()
            #        function.
            #
            new_peaks = utilC.initializePeaks(new_peaks,                      # The new peaks.
                                              smooth_image + self.background, # Smooth image + background.
                                              self.background,                # The current estimate of the background.
                                              self.sigma,                     # The starting sigma value.
                                              z_value)                        # The starting z value.

            # Correct initial peak heights.
            h_index = utilC.getHeightIndex()
            new_peaks[:,h_index] = new_peaks[:,h_index] * height_rescale
            
            if all_new_peaks is None:
                all_new_peaks = new_peaks
            else:
                all_new_peaks = numpy.append(all_new_peaks, new_peaks, axis = 0)

        if save_convolution:
            tif.close()
                
        #
        # Remove the dimmer of two peaks with similar x,y values but different z values.
        #
        if (len(self.mfilter) > 1):

            if False:
                print("before", all_new_peaks.shape)
                for i in range(all_new_peaks.shape[0]):
                    print(all_new_peaks[i,:])
                print("")
            
            all_new_peaks = utilC.removeClosePeaks(all_new_peaks,                                               
                                                   self.find_max_radius,
                                                   self.find_max_radius)

            if False:
                print("after", all_new_peaks.shape)
                for i in range(all_new_peaks.shape[0]):
                    print(all_new_peaks[i,:])
                print("")
                
        return all_new_peaks
    def peakFinder(self, no_bg_image):

        all_new_peaks = None

        save_convolution = False
        if save_convolution:
            print("making image")
            tif = tifffile.TiffWriter("image.tif")
            tif.save(self.image.astype(numpy.uint16) + 100)
            tif.save(no_bg_image.astype(numpy.uint16) + 100)
            tif.save(self.background.astype(numpy.uint16) + 100)
            
        #
        # Find peaks in image convolved with the PSF at different z values.
        #
        for i in range(len(self.mfilter)):

            height_rescale = self.height_rescale[i]
            mfilter = self.mfilter[i]
            taken = self.taken[i]
            z_value = self.z_value[i]

            # Smooth image with gaussian filter.
            smooth_image = mfilter.convolve(no_bg_image)

            if save_convolution:
                tif.save(smooth_image.astype(numpy.uint16) + 100)

            # Mask the image so that peaks are only found in the AOI.
            masked_image = smooth_image * self.peak_mask
        
            # Identify local maxima in the masked image.
            [new_peaks, taken] = utilC.findLocalMaxima(masked_image,
                                                       taken,
                                                       self.cur_threshold,
                                                       self.find_max_radius,
                                                       self.margin)

            #
            # Fill in initial values for peak height, background and sigma.
            #
            # FIXME: We just add the smoothed image and the background together
            #        as a hack so that we can still use the initializePeaks()
            #        function.
            #
            new_peaks = utilC.initializePeaks(new_peaks,                      # The new peaks.
                                              smooth_image + self.background, # Smooth image + background.
                                              self.background,                # The current estimate of the background.
                                              self.sigma,                     # The starting sigma value.
                                              z_value)                        # The starting z value.

            # Correct initial peak heights.
            h_index = utilC.getHeightIndex()
            new_peaks[:,h_index] = new_peaks[:,h_index] * height_rescale
            
            if all_new_peaks is None:
                all_new_peaks = new_peaks
            else:
                all_new_peaks = numpy.append(all_new_peaks, new_peaks, axis = 0)

        if save_convolution:
            tif.close()
                
        #
        # Remove the dimmer of two peaks with similar x,y values but different z values.
        #
        if (len(self.mfilter) > 1):

            if False:
                print("before", all_new_peaks.shape)
                for i in range(all_new_peaks.shape[0]):
                    print(all_new_peaks[i,:])
                print("")
            
            all_new_peaks = utilC.removeClosePeaks(all_new_peaks,                                               
                                                   self.find_max_radius,
                                                   self.find_max_radius)

            if False:
                print("after", all_new_peaks.shape)
                for i in range(all_new_peaks.shape[0]):
                    print(all_new_peaks[i,:])
                print("")
                
        return all_new_peaks
    def peakFinder(self, fit_images):
        """
        This method does the actual peak finding. 

        We are assuming that Poisson statistics applies, so if we have
        a good estimate of the background and foreground then we can
        predict the significance of a foreground value with reasonable
        accuracy.
        """
        #
        # Calculate (estimated) background variance for each plane.
        #
        # The estimated background and variance should both be > 0.0,
        # or there is going to be trouble.
        #
        bg_variances = []

        # Save fit images for debugging purposes.
        if self.check_mode:
            with tifffile.TiffWriter("fit_images.tif") as tf:
                for fi in fit_images:
                    tf.save(numpy.transpose(fi.astype(numpy.float32)))

        # Iterate over z values.
        for i in range(len(self.vfilters)):
            bg_variance = numpy.zeros(fit_images[0].shape)

            # Iterate over channels / planes.
            for j in range(len(self.vfilters[i])):

                # Convolve fit image + background with the appropriate variance filter.
                #
                # I believe that this is correct, the variance of the weighted average
                # of a (independent) Poisson processes is calculated using the square of
                # the weights.
                #
                conv_var = self.vfilters[i][j].convolve(fit_images[j] +
                                                        self.backgrounds[j])

                # Transform variance to the channel 0 frame.
                if self.atrans[j] is None:
                    bg_variance += conv_var
                else:
                    bg_variance += self.atrans[j].transform(conv_var)

            bg_variances.append(bg_variance + self.variances[i])

        # Check for problematic values.
        if self.check_mode:
            for bg in bg_variances:
                mask = (bg <= 0.0)
                if (numpy.sum(mask) > 0):
                    print(
                        "Warning! 0.0 / negative values detected in background variance."
                    )

        # Save results if needed for debugging purposes.
        if self.check_mode:
            with tifffile.TiffWriter("variances.tif") as tf:
                for bg in bg_variances:
                    tf.save(numpy.transpose(bg.astype(numpy.float32)))

        #
        # Calculate foreground for each z plane.
        #
        fg_averages = [
        ]  # This is the average foreground across all the planes for each z value.
        foregrounds = []  # This is the foreground for each plane and z value.

        # Iterate over z values.
        for i in range(len(self.mfilters)):
            foreground = numpy.zeros(fit_images[0].shape)
            foregrounds.append([])

            # Iterate over channels / planes.
            for j in range(len(self.mfilters[i])):

                # Convolve image / background with the appropriate PSF.
                conv_fg = self.mfilters[i][j].convolve(self.images[j] -
                                                       fit_images[j] -
                                                       self.backgrounds[j])

                # Store convolved image in foregrounds.
                foregrounds[i].append(conv_fg)

                # Transform image to the channel 0 frame.
                if self.atrans[j] is None:
                    foreground += conv_fg
                else:
                    foreground += self.atrans[j].transform(conv_fg)

            fg_averages.append(foreground)

        # Normalize average foreground by background standard deviation.
        fg_bg_ratios = []
        for i in range(len(fg_averages)):
            fg_bg_ratios.append(fg_averages[i] / numpy.sqrt(bg_variances[i]))

        # Save results if needed for debugging purposes.
        if self.check_mode:
            with tifffile.TiffWriter("foregrounds.tif") as tf:
                for fg in fg_averages:
                    tf.save(numpy.transpose(fg.astype(numpy.float32)))

            with tifffile.TiffWriter("fg_bg_ratio.tif") as tf:
                for fg_bg_ratio in fg_bg_ratios:
                    tf.save(numpy.transpose(fg_bg_ratio.astype(numpy.float32)))

        #
        # At each z value, find peaks in foreground image normalized
        # by the background standard deviation.
        #
        all_new_peaks = None
        zero_array = numpy.zeros(fg_bg_ratios[0].shape)
        for i in range(len(self.mfilters)):

            #
            # Mask the image so that peaks are only found in the AOI. Ideally the
            # this mask should probably be adjusted to limit analysis to only
            # the regions of the image where there is data from every channel / plane.
            #
            masked_image = fg_bg_ratios[i] * self.peak_mask

            # Identify local maxima in the masked image.
            [new_peaks,
             taken] = utilC.findLocalMaxima(masked_image, self.taken[i],
                                            self.cur_threshold,
                                            self.find_max_radius, self.margin)

            #
            # Initialize peaks with normalized height value. We'll split these
            # later into peaks for each plane, and at that point the height,
            # background and z values will be corrected.
            #
            # Note: Sigma is irrelevant for fitting, but it needs to be some non-zero number.
            #
            new_peaks = utilC.initializePeaks(
                new_peaks,  # The new peaks.
                masked_image,  # Use SNR as height, corrected later for fitting.
                zero_array,  # Zero for now, corrected later for fitting.
                self.sigma,  # The starting sigma value.
                i)  # Index of the z-plane, the actual z value is added later.

            # Add to all peaks accumulator.
            if all_new_peaks is None:
                all_new_peaks = new_peaks
            else:
                all_new_peaks = numpy.append(all_new_peaks, new_peaks, axis=0)

        #
        # If there are multiple peaks with similar x,y but in different
        # planes, use the one with the highest normalized value.
        #
        # FIXME: If the planes are far enough apart in z we should allow
        #        peaks with a similar x,y.
        #
        if (len(self.mfilters) > 1):
            all_new_peaks = utilC.removeClosePeaks(all_new_peaks,
                                                   self.find_max_radius,
                                                   self.find_max_radius)

        #
        # Split into a peak/localization for each image plane.
        #
        # Note that the peaks array is expected to have all the peaks
        # for the first plane first, then all the peaks for the second
        # plane, etc.. With the same number of peaks per plane.
        #
        # This is how you would access the same peak in different channels:
        #
        # ch0) all_new_peaks[0 * n_peaks + peak_number]
        # ch1) all_new_peaks[1 * n_peaks + peak_number]
        # etc..
        #
        all_new_peaks = self.mpu.splitPeaks(all_new_peaks)

        #
        # Remove peaks with members in one or more channels that are
        # outside of the image.
        #
        all_new_peaks = self.mpu.filterPeaks(
            all_new_peaks, self.mpu.badPeakMask(all_new_peaks))

        # Initialize background values.
        mpUtilC.initializeBackground(all_new_peaks, self.backgrounds)

        # Need to do this before z initialization as we are using the
        # z value to index into the foregrounds array.
        mpUtilC.initializeHeight(all_new_peaks, foregrounds,
                                 self.height_rescale)

        # Replace z index with the z value used as the initial guess
        # for fitting.
        mpUtilC.initializeZ(all_new_peaks, self.z_values)

        if False:
            pp = 3
            if (all_new_peaks.shape[0] > pp):
                for i in range(pp):
                    print("Peak", i)
                    self.mpu.prettyPrintPeak(all_new_peaks, i)
                    print("")

        return all_new_peaks