示例#1
0
    def execute(self, namespace):

        inp = namespace[self.inputName]

        # generate LineProfileHandler from tables
        handler = LineProfileHandler()
        handler._load_profiles_from_list(inp)

        fit_class = profile_fitters.ensemble_fitters[self.fit_type]
        self.fitter = fit_class(handler)

        if self.hold_ensemble_parameter_constant:
            self.fitter.fit_profiles(self.ensemble_parameter_guess)
        else:
            self.fitter.ensemble_fit(self.ensemble_parameter_guess)

        res = tabular.RecArraySource(self.fitter.results)

        # propagate metadata, if present
        res.mdh = MetaDataHandler.NestedClassMDHandler(
            getattr(inp, 'mdh', None))

        res.mdh['EnsembleFitProfiles.FitType'] = self.fit_type
        res.mdh[
            'EnsembleFitProfiles.EnsembleParameterGuess'] = self.ensemble_parameter_guess
        res.mdh[
            'EnsembleFitProfiles.HoldEnsembleParamConstant'] = self.hold_ensemble_parameter_constant

        namespace[self.outputName] = res
    def execute(self, namespace):
        #from PYME.localization.FitFactories import DumbellFitR
        from PYME.IO import MetaDataHandler
        img = namespace[self.inputImage]

        md = MetaDataHandler.NestedClassMDHandler()
        #set metadata entries needed for fitting to suitable defaults
        md['Camera.ADOffset'] = img.data[:, :, 0].min()
        md['Camera.TrueEMGain'] = 1.0
        md['Camera.ElectronsPerCount'] = 1.0
        md['Camera.ReadNoise'] = 1.0
        md['Camera.NoiseFactor'] = 1.0

        #copy across the entries from the real image, replacing the defaults
        #if necessary
        md.copyEntriesFrom(img.mdh)

        inp = namespace[self.inputPositions]

        res = np.zeros(len(inp['x']), dtype=[('r%d' % r, 'f4') for r in self.radii])

        ff_t = -1

        aggFunc = getattr(self, '_get_%s' % self.mode)

        ps = img.pixelSize
        print('pixel size: %s' % ps)
        for x, y, t, i in zip(inp['x'], inp['y'], inp['t'], range(len(inp['x']))):
            for r in self.radii:
                res[i]['r%d' % r] = aggFunc(img.data, np.round(x / ps), np.round(y / ps), t, r)

        res = tabular.RecArraySource(res)
        res.mdh = md

        namespace[self.outputName] = res
示例#3
0
    def execute(self, namespace):
        from PYME.IO.FileUtils import readSpeckle
        from PYME.IO import MetaDataHandler
        import os

        fileInfo = {'SEP': os.sep}

        seriesLength = 100000

        mdh = MetaDataHandler.NestedClassMDHandler()
        mdh['voxelsize.x'] = .001  # default pixel size - FIXME
        mdh['voxelsize.y'] = .001

        #use a default sensor size of 512
        #this gets over-ridden below if we supply an image
        clip_region = [
            self.edgeRejectionPixels, self.edgeRejectionPixels,
            512 - self.edgeRejectionPixels, 512 - self.edgeRejectionPixels
        ]

        if not self.inputImage == '':
            inp = namespace[self.inputImage]
            mdh.update(inp.mdh)
            seriesLength = inp.data.shape[2]

            clip_region = [
                self.edgeRejectionPixels, self.edgeRejectionPixels,
                inp.data.shape[0] - self.edgeRejectionPixels,
                inp.data.shape[1] - self.edgeRejectionPixels
            ]

            try:
                fileInfo['DIRNAME'], fileInfo['IMAGENAME'] = os.path.split(
                    inp.filename)
                fileInfo['IMAGESTUB'] = fileInfo['IMAGENAME'].split('MM')[0]
            except:
                pass

        speckleFN = self.speckleFilename.format(**fileInfo)

        specks = readSpeckle.readSpeckles(speckleFN)
        traces = readSpeckle.gen_traces_from_speckles(
            specks,
            leadFrames=self.leadFrames,
            followFrames=self.followFrames,
            seriesLength=seriesLength,
            clipRegion=clip_region)

        #turn this into an inputFilter object
        inp = tabular.RecArraySource(traces)

        #create a mapping to covert the co-ordinates in pixels to co-ordinates in nm
        vs = mdh.voxelsize_nm
        map = tabular.MappingFilter(inp,
                                    x='x_pixels*%3.2f' % vs.x,
                                    y='y_pixels*%3.2f' % vs.y)

        map.mdh = mdh

        namespace[self.outputName] = map
示例#4
0
    def execute(self, namespace):
        import PYME.Analysis.points.spherical_harmonics as spharm
        from PYME.IO import MetaDataHandler

        inp = namespace[self.input_name]

        modes, coefficients, centre = spharm.sphere_expansion_clean(
            inp['x'],
            inp['y'],
            inp['z'] * self.z_scale,
            mmax=self.max_m_mode,
            centre_points=True,
            nIters=self.n_iterations,
            tol_init=self.init_tolerance)

        mdh = MetaDataHandler.NestedClassMDHandler()
        try:
            mdh.copyEntriesFrom(namespace[self.input_name].mdh)
        except AttributeError:
            pass

        mdh['Processing.SphericalHarmonicShell.ZScale'] = self.z_scale
        mdh['Processing.SphericalHarmonicShell.MaxMMode'] = self.max_m_mode
        mdh['Processing.SphericalHarmonicShell.NIterations'] = self.n_iterations
        mdh['Processing.SphericalHarmonicShell.InitTolerance'] = self.init_tolerance
        mdh['Processing.SphericalHarmonicShell.Centre'] = centre

        output_dtype = [('modes', '<2i4'), ('coefficients', '<f4')]
        out = np.zeros(len(coefficients), dtype=output_dtype)
        out['modes'] = modes
        out['coefficients'] = coefficients
        out = tabular.RecArraySource(out)
        out.mdh = mdh

        namespace[self.output_name] = out
    def execute(self, namespace):
        from PYME.Analysis.points import cluster_morphology as cmorph
        import numpy as np

        inp = namespace[self.inputName]

        # make sure labeling scheme is consistent with what pyme conventions
        if np.min(inp[self.labelKey]) < 0:
            raise UserWarning(
                'This module expects 0-label for unclustered points, and no negative labels'
            )

        labels = inp[self.labelKey].astype(np.int)
        I = np.argsort(labels)
        I = I[labels[I] > 0]

        x_vals, y_vals, z_vals = inp['x'][I], inp['y'][I], inp['z'][I]
        labels = labels[I]
        maxLabel = labels[-1]

        #find the unique labels, and their separation in the sorted list of points
        unique_labels, counts = np.unique(labels, return_counts=True)

        #allocate memory to store results in
        measurements = np.zeros(maxLabel, cmorph.measurement_dtype)

        # loop over labels, recalling that input is now sorted, and we know how many points are in each label.
        # Note that missing labels result in zeroed entries (i.e. the initial values are not changed).
        # Missing values can be filtered out later, if desired, by filtering on the 'counts' column, but having a dense
        # array where index == label number makes any postprocessing in which we might want to find the data
        # corresponding to a particular label MUCH easier and faster.
        indi = 0
        for label_num, ct in zip(unique_labels, counts):
            indf = indi + ct

            # create x,y,z arrays for this cluster, and calculate center of mass
            x, y, z = x_vals[indi:indf], y_vals[indi:indf], z_vals[indi:indf]

            cluster_index = label_num - 1  # we ignore the unclustered points, and start labeling at 1
            cmorph.measure_3d(x, y, z, output=measurements[cluster_index])

            indi = indf

        meas = tabular.RecArraySource(measurements)

        try:
            meas.mdh = namespace[self.inputName].mdh
        except AttributeError:
            pass

        namespace[self.outputName] = meas
    def OnSave(self, event):
        filename = wx.SaveFileSelector(
            "Save data as ...",
            'HDF (*.hdf)|*.hdf|Comma separated text (*.csv)|*.csv')
        if not filename == '':
            if isinstance(self.data, tabular.TabularBase):
                data = self.data
            else:
                data = tabular.RecArraySource(self.data)

            if filename.endswith('.hdf'):
                data.to_hdf(filename)
            else:
                data.to_csv(filename)
示例#7
0
    def test_thickness(self,
                       ensemble_parameter={'psf_fwhm': np.arange(35, 105, 5)},
                       annulus_thicknesses=None,
                       outdir=None):
        from PYME.IO import tabular
        import matplotlib.pyplot as plt
        psfs = ensemble_parameter['psf_fwhm']
        num_psfs = len(psfs)
        num_annuli = len(annulus_thicknesses)

        mmse = np.zeros((num_psfs, num_annuli))
        diameters = np.zeros_like(mmse)
        for pi in range(num_psfs):
            for ai in range(num_annuli):
                self.annulus_thickness = annulus_thicknesses[ai]
                mmse[pi, ai] = self.fit_profiles_mean(psfs[pi])

                if outdir is not None:
                    res = tabular.RecArraySource(self.results)
                    res.to_hdf(outdir +
                               'ensemble_fit_results_psf%f_annulus%f.hdf' %
                               (psfs[pi], self.annulus_thickness))

                    plt.figure()
                    diameter_bins = np.arange(0, 200, 10)
                    mean_diameter = np.mean(res['fitResults']['diameter'])
                    diameters[pi, ai] = mean_diameter
                    plt.hist(res['fitResults']['diameter'],
                             bins=diameter_bins,
                             color='gray')
                    plt.xlabel('Tubule Diameter [nm]', size=26)
                    plt.ylabel('Counts', size=26)
                    plt.title(
                        'mean = %.1f +- %f.1 nm' %
                        (mean_diameter, np.std(res['fitResults']['diameter'])))
                    plt.tight_layout()
                    plt.savefig(outdir +
                                'diameter_histogram_psf%f_annulus%f.pdf' %
                                (psfs[pi], self.annulus_thickness))
        return mmse, diameters
示例#8
0
    def execute(self, namespace):

        inp = namespace[self.inputName]

        # generate LineProfileHandler from tables
        handler = LineProfileHandler()
        handler._load_profiles_from_list(inp)

        fit_class = profile_fitters.non_ensemble_fitters[self.fit_type]
        self.fitter = fit_class(handler)

        self.fitter.fit_profiles()

        res = tabular.RecArraySource(self.fitter.results)

        # propagate metadata, if present
        res.mdh = MetaDataHandler.NestedClassMDHandler(
            getattr(inp, 'mdh', None))

        res.mdh['FitProfiles.FitType'] = self.fit_type

        namespace[self.outputName] = res
    def execute(self, namespace):
        from PYME.IO.image import ImageStack

        series = namespace[self.input_series]
        positions = namespace[self.input_positions]

        ox_nm, oy_nm, oz = series.origin
        vs_nm = np.array([series.voxelsize_nm.x, series.voxelsize_nm.y])
        roi_half_nm = (self.roi_half_size + 1) * vs_nm
        x_max, y_max = (series.data.shape[:2] * vs_nm) - roi_half_nm
        
        edge_filtered = tabular.ResultsFilter(positions, 
                                              x=[ox_nm + roi_half_nm[0], x_max],
                                              y=[oy_nm + roi_half_nm[1], y_max])
        n_filtered = len(positions) - len(edge_filtered)
        if n_filtered > 0:
            logger.error('%d positions too close to edge, filtering.' % n_filtered)

        extracted = FitPoints(fitModule='ROIExtractNR', 
                              roiHalfSize=self.roi_half_size, 
                              channel=0).apply_simple(inputImage=series,
                                                      inputPositions=edge_filtered)
        
        # get roi edge position. FFBase._get_roi rounds before extracting
        relative_positions = edge_filtered.to_recarray()
        x_edge = np.round(edge_filtered['x'] / series.voxelsize_nm.x) - self.roi_half_size
        y_edge = np.round(edge_filtered['y'] / series.voxelsize_nm.y) - self.roi_half_size
        # subtract off ofset to ROI edge 
        relative_positions['x'] = edge_filtered['x'] - (x_edge * series.voxelsize_nm.x)
        relative_positions['y'] = edge_filtered['y'] - (y_edge * series.voxelsize_nm.y)
        relative_positions['fitResults_x0'] = relative_positions['x']
        relative_positions['fitResults_y0'] = relative_positions['y']
        relative_positions = tabular.RecArraySource(relative_positions)
        relative_positions.mdh = MetaDataHandler.NestedClassMDHandler(positions.mdh)
        relative_positions.mdh['ExtractROIs.RoiHalfSize'] = self.roi_half_size

        namespace[self.output_rois] = ImageStack(data=np.moveaxis(extracted['data'], 0, 2), 
                                                 mdh=series.mdh)
        namespace[self.output_relative_positions] = relative_positions
示例#10
0
    def execute(self, namespace):

        inp = namespace[self.inputName]

        # generate LineProfileHandler from tables
        handler = LineProfileHandler()
        handler._load_profiles_from_list(inp)

        fit_class = profile_fitters.ensemble_fitters[self.fit_type]
        fitter = fit_class(handler)

        results = fitter.ensemble_test(self.ensemble_test_values)
        res = tabular.RecArraySource(results)

        # propagate metadata, if present
        res.mdh = MetaDataHandler.NestedClassMDHandler(
            getattr(inp, 'mdh', None))

        res.mdh['TestEnsembleParameters.FitType'] = self.fit_type
        res.mdh[
            'TestEnsembleParameters.EnsembleTestValues'] = self.ensemble_test_values

        namespace[self.outputName] = res
示例#11
0
    def execute(self, namespace):
        from PYME.Analysis.points import twoColour
        from PYME.Analysis.points import multiview
        from PYME.IO.MetaDataHandler import NestedClassMDHandler

        inp = namespace[self.input_name]

        try:  # make sure we're looking at multiview data
            n_chan = inp.mdh['Multiview.NumROIs']
        except AttributeError:
            raise AttributeError('multiview metadata is missing or incomplete')

        # sort in frame order
        I = inp['tIndex'].argsort()
        x_sort, y_sort = inp['x'][I], inp['y'][I]
        chan_sort = inp['multiviewChannel'][I]

        clump_id, keep = multiview.pair_molecules(
            inp['tIndex'][I],
            x_sort,
            y_sort,
            chan_sort,
            self.search_radius_nm * np.ones_like(x_sort),
            appear_in=np.arange(n_chan),
            n_frame_sep=inp['tIndex'].max(),
            pix_size_nm=1e3 * inp.mdh['voxelsize.x'])

        # only look at the clumps which showed up in all channels
        x = x_sort[keep]
        y = y_sort[keep]
        chan = chan_sort[keep]
        clump_id = clump_id[keep]

        # Generate raw shift vectors (map of displacements between channels) for each channel
        mol_list = np.unique(clump_id)
        n_mols = len(mol_list)

        dx = np.zeros((n_chan - 1, n_mols))
        dy = np.zeros_like(dx)
        dx_err = np.zeros_like(dx)
        dy_err = np.zeros_like(dx)
        x_clump, y_clump, x_std, y_std, x_shifted, y_shifted = [], [], [], [], [], []

        shift_map_dtype = [
            ('mx', '<f4'),
            ('mx2', '<f4'),
            ('mx3', '<f4'),  # x terms
            ('my', '<f4'),
            ('my2', '<f4'),
            ('my3', '<f4'),  # y terms
            ('mxy', '<f4'),
            ('mx2y', '<f4'),
            ('mxy2', '<f4'),  # cross terms
            ('x0', '<f4')
        ]  # 0th order shift

        shift_maps = np.zeros(2 * (n_chan - 1), dtype=shift_map_dtype)
        mdh = NestedClassMDHandler(inp.mdh)
        mdh['Multiview.shift_map.legend'] = {}

        for ii in range(n_chan):
            chan_mask = (chan == ii)
            x_chan = np.zeros(n_mols)
            y_chan = np.zeros(n_mols)
            x_chan_std = np.zeros(n_mols)
            y_chan_std = np.zeros(n_mols)

            for ind in range(n_mols):
                # merge clumps within channels
                clump_mask = np.where(
                    np.logical_and(chan_mask, clump_id == mol_list[ind]))
                x_chan[ind] = x[clump_mask].mean()
                y_chan[ind] = y[clump_mask].mean()
                x_chan_std[ind] = x[clump_mask].std()
                y_chan_std[ind] = y[clump_mask].std()

            x_clump.append(x_chan)
            y_clump.append(y_chan)
            x_std.append(x_chan_std)
            y_std.append(y_chan_std)

            if ii > 0:
                dx[ii - 1, :] = x_clump[0] - x_clump[ii]
                dy[ii - 1, :] = y_clump[0] - y_clump[ii]
                dx_err[ii - 1, :] = np.sqrt(x_std[ii]**2 + x_std[0]**2)
                dy_err[ii - 1, :] = np.sqrt(y_std[ii]**2 + y_std[0]**2)
                # generate shiftmap between ii-th channel and the 0th channel
                dxx, dyy, spx, spy, good = twoColour.genShiftVectorFieldQ(
                    x_clump[0], y_clump[0], dx[ii - 1, :], dy[ii - 1, :],
                    dx_err[ii - 1, :], dy_err[ii - 1, :])
                # store shiftmaps in structured array
                mdh['Multiview.shift_map.legend']['Chan0%s.X' %
                                                  ii] = 2 * (ii - 1)
                mdh['Multiview.shift_map.legend']['Chan0%s.Y' %
                                                  ii] = 2 * (ii - 1) + 1
                for ki in range(len(shift_map_dtype)):
                    k = shift_map_dtype[ki][0]
                    shift_maps[2 * (ii - 1)][k] = spx.__getattribute__(k)
                    shift_maps[2 * (ii - 1) + 1][k] = spy.__getattribute__(k)

                # shift_maps['Chan0%s.X' % ii], shift_maps['Chan0%s.Y' % ii] = spx.__dict__, spy.__dict__

        mdh['Multiview.shift_map.model'] = '.'.join(
            [spx.__class__.__module__, spx.__class__.__name__])

        namespace[self.output_name] = tabular.RecArraySource(shift_maps)
        namespace[self.output_name].mdh = mdh
示例#12
0
    def execute(self, namespace):
        from PYME.Analysis.points import surfit
        data_source = namespace[self.input]

        # arrange point data in the format we expect
        points = np.vstack([
            data_source['x'].astype('f'), data_source['y'].astype('f'),
            data_source['z'].astype('f')
        ])

        # do the actual fitting - this fits one surface for every point in the dataset
        results = surfit.fit_quad_surfaces_Pr(
            points.T,
            self.fit_influence_radius,
            fitPos=(not self.constrain_surface_to_point))

        # calculate a radius of curvature from our polynomials
        raw_fits = tabular.MappingFilter(tabular.RecArraySource(results))
        raw_fits.setMapping('r_curve', '1./(np.abs(A) + np.abs(B) + 1e-6)'
                            )  # cap max at 1e6 instead of inf
        raw_fits.mdh = data_source.mdh
        namespace[self.output_fits_raw] = raw_fits

        # filter surfaces and throw out patches with normals that don't point approx. the same way as their neighbors
        results = surfit.filter_quad_results(results, points.T,
                                             self.fit_influence_radius,
                                             self.alignment_threshold)

        # again, add radius of curvature calculation with lazy evaluation
        filtered_fits = tabular.MappingFilter(
            tabular.RecArraySource(results.view(surfit.SURF_PATCH_DTYPE_FLAT)))
        filtered_fits.setMapping('r_curve',
                                 '1./(np.abs(A) + np.abs(B) + 1e-6)')
        filtered_fits.mdh = data_source.mdh
        namespace[self.output_fits_filtered] = filtered_fits

        # reconstruct the surface by generating an augmented point data set for each surface, adding virtual
        # localizations spread evenly across each surface patch. Note this is done on the filtered fits.
        if self.limit_reconstruction_to_support_hull:
            xs, ys, zs, xn, yn, zn, N, j = surfit.reconstruct_quad_surfaces_Pr_region_cropped(
                results,
                self.reconstruction_radius,
                points.T,
                fit_radius=self.fit_influence_radius,
                step=self.reconstruction_point_spacing)
        else:
            xs, ys, zs, xn, yn, zn, N, j = surfit.reconstruct_quad_surfaces_Pr(
                results,
                self.reconstruction_radius,
                step=self.reconstruction_point_spacing)

        j = j.astype(int)
        try:
            # duck-type probe; note we assume surface was fit to single-color data
            probe = np.ones_like(xs) * data_source['probe'][0]
        except KeyError:
            probe = np.zeros_like(xs)
        # construct a new datasource with our augmented points
        reconstruction = tabular.MappingFilter({
            'x':
            xs,
            'y':
            ys,
            'z':
            zs,
            'xn':
            xn,
            'yn':
            yn,
            'zn':
            zn,
            'probe':
            probe,
            'n_points_fit':
            N,
            'patch_id':
            j,
            'r_curve':
            filtered_fits['r_curve'][j]
        })
        reconstruction.mdh = data_source.mdh
        namespace[self.output_surface_reconstruction] = reconstruction
示例#13
0
    def OnMeasure(self, event):
        from PYME.Analysis.points import objectMeasure

        pipeline = self.visFr.pipeline

        chans = pipeline.colourFilter.getColourChans()

        # If we're not using objectIDs from an image, look for other clustering labels
        # TODO - rather than trying a few pre-set objectID alternatives, make this a dialog instead
        # - look for objectID and carry on if present
        # - if not present, display a dialog "No objectID found - did you segment objects? Either cancel,
        # segment, and come back, or choose an alternative column to use as an ID.
        keys = ['objectID', 'dbscanClumpID', 'clumpIndex']
        key = 'objectID'

        for k in keys:
            try:
                ids = set(pipeline.mapping[k].astype('i'))
                key = k
                break
            except (KeyError):
                continue
        # ids = set(pipeline.mapping['objectID'].astype('i'))

        pipeline.objectMeasures = {}

        if len(chans) == 0:
            pipeline.objectMeasures[
                'Everything'] = objectMeasure.measureObjectsByID(
                    pipeline.colourFilter, 10, ids, key)

            from PYME.ui import recArrayView
            f = recArrayView.ArrayFrame(pipeline.objectMeasures['Everything'],
                                        parent=self.visFr,
                                        title='Object Measurements')
            f.Show()

        else:
            curChan = pipeline.colourFilter.currentColour

            chanNames = chans[:]

            #            if 'Sample.Labelling' in metadata.getEntryNames():
            #                lab = metadata.getEntry('Sample.Labelling')
            #
            #                for i in range(len(lab)):
            #                    if lab[i][0] in chanNames:
            #                        chanNames[chanNames.index(lab[i][0])] = lab[i][1]

            for ch, i in zip(chans, range(len(chans))):
                pipeline.colourFilter.setColour(ch)
                #fitDecayChan(colourFilter, metadata, chanNames[i], i)
                pipeline.objectMeasures[
                    chanNames[i]] = objectMeasure.measureObjectsByID(
                        pipeline.colourFilter, 10, ids, key)

            pipeline.colourFilter.setColour(curChan)

            from PYME.ui import recArrayView
            from PYME.IO import tabular
            from PYME.recipes.tablefilters import AggregateMeasurements

            om = {
                k: tabular.RecArraySource(v)
                for k, v in pipeline.objectMeasures.items()
            }

            args = {}
            for i, name in enumerate(chanNames):
                args['inputMeasurements%d' % (i + 1)] = name
                args['suffix%d' % (i + 1)] = ('_' + name)

            args['outputName'] = 'aggregated'

            agg = AggregateMeasurements(**args)
            agg.execute(om)

            f = recArrayView.ArrayFrame(om['aggregated'],
                                        parent=self.visFr,
                                        title='Object Measurements')
            f.Show()
示例#14
0
def histfitting(colourFilter,
                metadata,
                cluster_idxs,
                fit_order,
                num_bins,
                blink_on_label,
                blink_off_label,
                to_json=False,
                log_bins=False,
                n_on_bins=1,
                n_off_bins=1,
                fixed_on_max=-1,
                fixed_off_max=-1):
    import matplotlib as plt
    from PYME.IO import tabular
    # for best number of bins, find number of different on duration times, set as number of bins
    # should probably include this as an option in traits ui, I.E. do you want to manually set num bins or set to
    #       max number of unique states (blink duration, time to next blink, etc)

    N = fit_order
    """
    should add traits thing where this line can be used or set to 1

    """
    frame_duration = metadata.getEntry('Camera.IntegrationTime')

    on_times = colourFilter[blink_on_label].astype('f')  #* frame_duration
    on_times = [np.int(i) for i in on_times]
    # print('is it being loaded correctly 1?', on_times)
    """
    setting up binning for histogram(s)
    this might not be correct, check again
    """
    #    max_on = np.max(on_times) + frame_duration

    # if fixed_on_max == -1:
    #     fixed_on_max = on_times.max()

    # if log_bins:
    #     binning = np.logspace(0.5, fixed_on_max + 1, num=n_on_bins)
    # else:
    binning = np.arange(frame_duration, max(on_times), 1)
    print('max on time', max(on_times))
    # if len(binning) < 20
    # binning = np.linspace(0, 30, 30)

    vals, bin_edges = np.histogram(
        on_times, bins=binning)  #here, take 2-ed vals = vals[2:]
    np.set_printoptions(threshold=100000, suppress=True)
    # print('on y hist', len(vals), vals)

    logonbins = np.logspace(0, 1.49136169383, num=max(on_times))

    logvals, logbinedges = np.histogram(on_times, bins=logonbins)
    np.set_printoptions(threshold=100000, suppress=True)
    print('log scale on vals', logvals)
    # logoff_vals, log_bin_edges_off = np.histogram()

    bin_edges *= frame_duration
    """
    clip vectors here
    """
    y_hist = vals
    bin_starts = bin_edges[:-1]
    x_hist = bin_starts
    max_xaxis = max(bin_edges)

    off_times = colourFilter[blink_off_label].astype('f')
    # print('is it being loaded right 2?', off_times)
    # min_off = min(off_times)
    #    max_off = max(off_times) + frame_duratio
    logoffbins = np.logspace(0, 4.92471852852, num=30)
    logoff_vals, log_bin_edges_off = np.histogram(off_times, bins=logoffbins)
    print('log scale off vals', logoff_vals)

    if fixed_off_max == -1:
        fixed_off_max = off_times.max()

    # if log_bins:
    # binning_off = np.logspace(frame_duration, fixed_off_max + 1, num=30)

    # binning_off = np.logspace(-.60205999132, 4.92471852852, num=30)
    #
    # print(binning_off)
    # else:
    binning_off = np.arange(0.5, fixed_off_max + 1, n_off_bins)

    vals_off, bin_edges_off = np.histogram(off_times, bins=binning_off)
    """
    brute force print statement for getting sims going before retreat
    """
    np.set_printoptions(threshold=100000, suppress=True)
    # print('off y hist vals', len(vals_off), vals_off)
    bin_edges_off *= frame_duration

    y_hist_off = vals_off
    bin_starts_off = bin_edges_off[:-1]
    x_hist_off = bin_starts_off
    max_xaxis_off = max(bin_edges_off)

    # getting start params from integrated fit
    vals = np.array(vals)
    on_t_in_t = [i * frame_duration for i in on_times]
    off_t_in_t = [i * frame_duration for i in off_times]
    if N == 1:
        res_fxn = tfoef
        fit_fxn = sefm
        # print('what is going wrong here?')
        # print(max(vals), vals)
        # print(on_times, frame_duration)
        # print(np.mean(on_t_in_t))

        start_params = [max(vals), 1.0 / np.mean(on_t_in_t)]
        # start_params = [40417, 5.608, 0]
        start_params_off = [max(vals_off), 1.0 / np.mean(off_t_in_t)]
        fit_eqn = 'A*e^(-B*x)'

    if N == 2:
        res_fxn = tsoef
        fit_fxn = defm
        start_params = [(np.max(vals), 1.0 / np.mean(on_t_in_t), np.max(vals),
                         5.0 / np.mean(on_t_in_t))]
        start_params_off = [(np.max(vals_off), 1.0 / np.mean(off_t_in_t),
                             np.max(vals_off), 5.0 / np.mean(off_t_in_t))]
        fit_eqn = 'A*e^(-B*x) + C*e^(-D*x)'

    params = start_params
    fit_results = FitModel_N(res_fxn, params, x_hist[1:], y_hist[1:])
    #
    # plt.figure()
    # plt.plot(x_hist_off[1:], y_hist[1:])
    fit_results_off = FitModel_N(res_fxn, start_params_off, x_hist_off[1:],
                                 y_hist_off[1:])

    cov = np.linalg.inv(np.matmul(
        fit_results.jac.T, fit_results.jac)) * np.mean(
            (fit_results.fun * fit_results.fun).sum())
    # print('test 1', fit_results_off.jac.T)
    # print('test 2', fit_results_off.jac)
    # print(np.matmul(fit_results_off.jac.T, fit_results_off.jac))
    # print(np.linalg.inv(np.matmul(fit_results_off.jac.T, fit_results_off.jac)))
    cov_off = np.linalg.inv(
        np.matmul(fit_results_off.jac.T, fit_results_off.jac)) * np.mean(
            (fit_results_off.fun * fit_results_off.fun).sum())

    fitErrors_on = np.sqrt(np.diag(cov))
    fitErrors_off = np.sqrt(np.diag(cov_off))
    # fitErrors_off = 1.1

    x_on_fit = np.linspace(0, max_xaxis, 100)
    y_on_fit = fit_fxn(x_on_fit, *fit_results.x)

    x_off_fit = np.linspace(0, max_xaxis_off, 100)
    y_off_fit = fit_fxn(x_off_fit, *fit_results_off.x)

    on_hist_datasource = np.rec.fromarrays((y_hist, bin_edges[1:]),
                                           dtype=[('y_hist', '<f4'),
                                                  ('x_hist', '<f4')])
    off_hist_datasource = np.rec.fromarrays((y_hist_off, bin_edges_off[1:]),
                                            dtype=[('y_hist', '<f4'),
                                                   ('x_hist', '<f4')])

    filt_on = tabular.RecArraySource(on_hist_datasource.view(np.recarray))
    filt_off = tabular.RecArraySource(off_hist_datasource.view(np.recarray))
    """
    trying to get relevant files into metadata
    """

    if USE_GUI:
        plt.figure()
        plt.bar(bin_starts,
                vals,
                width=bin_starts[1] - bin_starts[0],
                alpha=.4)
        # plt.scatter(x_hist[1:], y_hist[1:])
        plt.plot(x_on_fit, y_on_fit)
        # plt.xscale('')
        xx = max(plt.xlim())
        yy = max(plt.ylim())

        if N == 1:
            plt.text(xx * .3, yy * .5,
                     r'$y = Ae ^{-Bx} + C$')  #, transform=plt.gca())
            plt.text(
                xx * .3, yy * .45,
                'A= %5.2f +/- %5.2f' % (fit_results.x[0], fitErrors_on[0]))
            plt.text(
                xx * .3, yy * .40,
                'B= %5.2f +/- %5.2f' % (fit_results.x[1], fitErrors_on[1]))
            # plt.text(xx * .3, yy * .35, 'C= %5.2f +/- %5.2f' % (fit_results.x[2], fitErrors_on[2]))
        elif N == 2:
            plt.text(xx * .3, yy * .6, r'$y =  Ae^{-B*x} + C e^{-D*x}$')
            plt.text(
                xx * .3, yy * .55,
                'A= %5.2f +/- %5.2f' % (fit_results.x[0], fitErrors_on[0]))
            plt.text(
                xx * .3, yy * .5,
                'B= %5.2f +/- %5.2f' % (fit_results.x[1], fitErrors_on[1]))
            plt.text(
                xx * .3, yy * .45,
                'C= %5.2f +/- %5.2f' % (fit_results.x[2], fitErrors_on[2]))
            plt.text(
                xx * .3, yy * .4,
                'D= %5.2f +/- %5.2f' % (fit_results.x[3], fitErrors_on[3]))
        #            plt.text(xx * .3, yy * .35, 'E= %5.2f +/- %5.2f' % (fit_results.x[4], fitErrors_on[2]))

        plt.ylabel('Events')
        plt.xlabel('Blink duration')
        plt.title('Blink On Duration')

        fig, ax = plt.subplots(1, 1)
        ax.scatter(x_hist, y_hist - fit_fxn(x_hist, *fit_results.x))
        ax.set_ylabel('Residual')
        ax.set_xlabel('Blink duration')
        ax.set_title('Blink On Duration residuals')

        # now, this is getting hists & fits for time to next blink values
        plt.figure()
        plt.bar(bin_starts_off,
                vals_off,
                width=bin_starts_off[1] - bin_starts_off[0],
                alpha=.4)
        # plt.scatter(x_hist_off[1:], y_hist_off[1:])
        plt.plot(x_off_fit, y_off_fit)
        xx2 = max(plt.xlim())
        yy2 = max(plt.ylim())
        if N == 1:
            plt.text(xx2 * .3, yy2 * .6, r'$y = Ae ^{-Bx} + C$')
            plt.text(
                xx2 * .3, yy2 * .55, 'A= %5.2f +/- %5.2f' %
                (fit_results_off.x[0], fitErrors_off[0]))
            plt.text(
                xx2 * .3, yy2 * .50, 'B= %5.2f +/- %5.2f' %
                (fit_results_off.x[1], fitErrors_off[1]))
            # plt.text(xx2 * .3, yy2 * .35, 'C= %5.2f +/- %5.2f' % (fit_results_off.x[2], fitErrors_off[2]))
        elif N == 2:
            plt.text(xx2 * .3, yy2 * .6, r'$y =  Ae^{-B*x} + C e^{-D*x}$')
            plt.text(
                xx2 * .3, yy2 * .55, 'A= %5.2f +/- %5.2f' %
                (fit_results_off.x[0], fitErrors_off[0]))
            plt.text(
                xx2 * .3, yy2 * .5, 'B= %5.2f +/- %5.2f' %
                (fit_results_off.x[1], fitErrors_off[1]))
            plt.text(
                xx2 * .3, yy2 * .45, 'C= %5.2f +/- %5.2f' %
                (fit_results_off.x[2], fitErrors_off[2]))
            plt.text(
                xx2 * .3, yy2 * .4, 'D= %5.2f +/- %5.2f' %
                (fit_results_off.x[3], fitErrors_off[3]))
        #            plt.text(xx2 * .3, yy2 * .35, 'E= %5.2f +/- %5.2f' % (fit_results_off.x[4], fitErrors_off[2]))

        plt.ylabel('Events')
        plt.xlabel('Time to next blink')
        plt.title('Time to next blink in the same cluster')

        fig, ax = plt.subplots(1, 1)
        ax.scatter(x_hist_off,
                   y_hist_off - fit_fxn(x_hist_off, *fit_results_off.x))
        ax.set_ylabel('Residual')
        ax.set_xlabel('Time to next blink')
        ax.set_title('Time to next blink residuals')

    if to_json == True:
        import io
        import time
        import json
        try:
            to_unicode = unicode
        except NameError:
            to_unicode = str

        # Generate dye kinetics structure for JSON file
        dk = {}
        dk['plog'] = [0, 0]
        if log_bins:
            dk['tlog'] = [1, 1]
        else:
            dk['tlog'] = [0, 0]
        dk['tmin'] = [bin_edges[0], bin_edges_off[0]]
        dk['tmax'] = [bin_edges[-1], bin_edges_off[-1]]
        dk['off'] = y_hist_off.tolist()
        dk['on'] = y_hist.tolist()

        # Write JSON file
        timestr = time.strftime("%Y%m%d-%H%M%S")
        with io.open('empirical_histograms_' + timestr + '.json',
                     'w',
                     encoding='utf8') as outfile:
            str_ = '{"dk": ' + json.dumps(dk) + '}'
            outfile.write(to_unicode(str_))

    params_on = fit_results.x
    params_off = fit_results_off.x
    return filt_on, filt_off, params_on, params_off, fitErrors_on, fitErrors_off, fit_eqn
示例#15
0
def g_histfitting(colourFilter, metadata, cluster_ids, blink_ids,
                  N_bins):  #geometric and negative binomial fitting
    from PYME.IO import tabular
    # N_bins =
    # frame_duration = metadata.getEntry('Camera.IntegrationTime')
    # frame_duration = metadata.getEntry('Camera.CycleTime')
    """
    Important to note: blinks per cluster does nto exist as callable value in pipeline, have to create in this fxn call
    data from pipeline needed: dbscabcluster, blink id?
    """
    # I = np.argsort(colourFilter[cluster_ids])
    # print(pl['dbscanClustered'][I])
    # bpc = np.zeros_like(np.unique(colourFilter[cluster_ids]))# blinks per cluster
    # cid = np.arange(1, max(colourFilter[cluster_ids])+1, 1)
    # print('cid vec', cid)
    # print('just before loop', len(np.unique(colourFilter[cluster_ids])))
    # for i in range(1, len(np.unique(colourFilter[cluster_ids])) + 1):
    #     nblinks = len(colourFilter[blink_ids][I][colourFilter[cluster_ids] == i])
    #     bpc[i-1] = nblinks
    # print(i, nblinks)

    _, bpc_2 = np.unique(colourFilter[cluster_ids], return_counts=True)
    print('any points where bps = 0?', np.where(bpc_2 == 0))

    plt.hist(bpc_2, bins=20)
    plt.figure()
    # plt.hist(bpc, bins=20)
    # binning = np.linspace(1, np.max(bpc_2), np.max(bpc_2))
    vals, bin_edges = np.histogram(bpc_2, bins=np.max(bpc_2) / 5, density=True)
    print('hist stuff', vals, bin_edges)
    # x_data = on_times
    y_hist = vals
    bin_starts = bin_edges[:-1]
    bin_ends = bin_edges[1:]
    x_hist = (bin_starts + bin_ends) / 2
    params_on = np.array([.1])
    geofit = FitModel_N(grff, params_on, x_hist, y_hist)

    # print('p value from geo fit', geofit.x)
    # plt.figure()
    # plt.plot(np.linspace(min(x_hist), max(x_hist), 100), gfm(np.linspace(min(x_hist), max(x_hist), 100), geofit.x))

    # nb_params = np.array([2.0, geofit.x[0]])
    # print('nb_params: ', nb_params)
    # nbfit = FitModel_N(nbrff, nb_params, x_hist, y_hist)
    # N = nbfit.x[0]
    # p = nbfit.x[1]
    x_fit = np.linspace(min(bin_edges), max(bin_edges), max(bin_edges) * 10)
    y_fit = gfm(x_fit, geofit.x)
    #
    hist_datasource = np.rec.fromarrays((y_hist, x_hist),
                                        dtype=[('y_hist', '<f4'),
                                               ('x_hist', '<f4')])
    #
    hist_data = tabular.RecArraySource(hist_datasource.view(np.recarray))
    # filt_off = tabular.recArrayInput(off_hist_datasource.view(np.recarray))
    """
    have fit for both N and p simultaneously, also want to make one that fits based on p as found in geo fit
    maybe make a button to determine which one?
    """
    geo_cov = np.linalg.inv(np.matmul(geofit.jac.T, geofit.jac)) * np.mean(
        (geofit.fun * geofit.fun).sum())
    # nb_cov = np.linalg.inv(np.matmul(nbfit.jac.T, nbfit.jac)) * np.mean(
    #     (nbfit.fun * nbfit.fun).sum())
    fitErrors_geo = np.sqrt(np.diag(geo_cov))
    # fitErrors_nb = np.sqrt(np.diag(nb_cov))

    # print('bpc', len(bpc), max(bpc), min(bpc), len(np.unique(bpc)), bpc)
    if USE_GUI:
        plt.bar(bin_starts,
                vals,
                width=bin_starts[1] - bin_starts[0],
                alpha=.4)
        plt.plot(x_fit, y_fit)
        plt.xlim([0, 200])
        xx3 = max(plt.xlim())
        yy3 = max(plt.ylim())
        cv = min(plt.xlim())
        # r'$y = Ae ^{-Bx} + C$'
        r'$y = p(1-p)^{x}$'
        plt.text(((xx3 - cv) * .3) + cv, yy3 * .7, r'$y = p(1-p)^{x}$')
        plt.text(((xx3 - cv) * .3) + cv, yy3 * .6,
                 'p= %5.2f +/- %5.2f' % (geofit.x, fitErrors_geo))

        # plt.text(xx3 * .3, yy3 * .45, 'p= %5.2f' % (geofit.x))
        plt.title(r'$mE0s3.2-CAAX$')
        plt.xlabel('Number of blinks per molecule')
        plt.ylabel('Probability')

        # negative binomial fitting
        # plt.figure()
        # plt.bar(bin_starts, vals, width=bin_starts[1] - bin_starts[0], alpha=.4)
        # plt.plot(x_fit, nbmf(x_fit, N, p))
        # xx4 = max(plt.xlim())
        # yy4 = max(plt.ylim())
        # cv2 = min(plt.xlim())
        # plt.text(((xx4-cv2)*.1) + cv2, yy4 * .9, 'Number of molecules N = %5.2f, off probability = %5.2f' % (N, p))
        # plt.title('Negative Binomial fit for both N and p')
        # plt.text(xx2 * .3, yy2 * .45, )
    """
    hist_data = hist_data
    params_geo = geofit.x
    params_nb = nbfit.x
    fitErrors_geo =
    fitErrors_nb =
    fit_eqn_geo =
    fit_eqn_nb =
    """
    return hist_data, geofit.x, fitErrors_geo,  #, fit_eqn_geo, fit_eqn_nb
    def execute(self, namespace):
        from scipy.ndimage import center_of_mass
        from PYME.IO.MetaDataHandler import DictMDHandler
        from PYME.IO import tabular

        chan0 = namespace[self.input_chan0]
        mdh = DictMDHandler()
        mdh.copyEntriesFrom(chan0.mdh)
        vx, vy, vz = chan0.voxelsize
        chan0 = np.stack([
            chan0.data[:, :, t, 0].squeeze()
            for t in range(chan0.data.shape[2])
        ],
                         axis=2)
        mask0 = namespace[self.input_mask0]
        mask0 = np.stack([
            mask0.data[:, :, t, 0].squeeze()
            for t in range(mask0.data.shape[2])
        ],
                         axis=2)
        mask0 = mask0 > 0
        chan1 = namespace[self.input_chan1]
        chan1 = np.stack([
            chan1.data[:, :, t, 0].squeeze()
            for t in range(chan1.data.shape[2])
        ],
                         axis=2)
        mask1 = namespace[self.input_mask1]
        mask1 = np.stack([
            mask1.data[:, :, t, 0].squeeze()
            for t in range(mask1.data.shape[2])
        ],
                         axis=2)
        mask1 = mask1 > 0

        com0 = center_of_mass(chan0, mask0)  # [px]
        com1 = center_of_mass(chan1, mask1)
        ox = vx * (com0[0] - com1[0])  # [nm]
        oy = vy * (com0[1] - com1[1])
        oz = vz * (com0[2] - com1[2])
        offset = np.sqrt((ox**2) + (oy**2) + (oz**2))

        n0 = mask0.sum()
        n1 = mask1.sum()
        n_total = n0 + n1
        mask_both = mask0 * mask1
        intensity_overlap = (mask_both * (chan0 + chan1)).sum()
        intensity0 = (chan0 * mask0).sum()
        intensity1 = (chan1 * mask1).sum()
        intensity_total = intensity0 + intensity1
        n_overlapping = np.sum(mask0 * mask1)

        out = np.empty((1, ), dtype=self._dtype)
        out[0]['offset'] = offset
        out[0]['com0'] = com0
        out[0]['com1'] = com1
        out[0]['n_overlapping'] = n_overlapping
        out[0]['n_0'] = n0
        out[0]['n_1'] = n1
        out[0]['n_total'] = n_total
        out[0]['fractional_volume_overlap'] = n_overlapping / n_total
        out[0][
            'fractional_intensity_overlap'] = intensity_overlap / intensity_total
        out[0]['intensity_total'] = intensity_total
        out[0]['intensity0'] = intensity0
        out[0]['intensity1'] = intensity1

        out = tabular.RecArraySource(out)
        out.mdh = mdh
        namespace[self.output_name] = out