def OnPlotProfile(self, event=None):
        from PYME.Analysis.profile_extraction import extract_profile

        lx, ly, hx, hy = self.do.GetSliceSelection()

        w = int(self.do.selectionWidth)

        try:
            names = self.image.mdh.getEntry('ChannelNames')
        except:
            names = ['Channel %d' % d for d in range(self.image.data.shape[3])]

        try:
            voxx = self.image.mdh.getEntry('voxelsize.x')
        except:
            voxx = 1

        plots = []

        n_chans = self.image.data_xyztc.shape[4]
        for chanNum in range(n_chans):
            img = self.image.data_xyztc[:, :, self.do.zp, self.do.tp,
                                        chanNum].squeeze()

            p = extract_profile(img, lx, ly, hx, hy, w)

            plots.append(p.reshape(-1, 1, 1, 1))

        #plt.legend(names)

        t = np.arange(p.size)

        im = ImageStack(plots, titleStub='New Profile')
        im.xvals = t * voxx

        if not voxx == 1:
            im.xlabel = 'Distance [um]'
        else:
            im.xlabel = 'Distance [pixels]'

        im.ylabel = 'Intensity'
        im.defaultExt = '.txt'

        im.mdh['voxelsize.x'] = voxx
        im.mdh['ChannelNames'] = names
        im.mdh['Profile.XValues'] = im.xvals
        im.mdh['Profile.XLabel'] = im.xlabel
        im.mdh['Profile.YLabel'] = im.ylabel
        im.mdh['Profile.StartX'] = lx
        im.mdh['Profile.StartY'] = ly
        im.mdh['Profile.EndX'] = hx
        im.mdh['Profile.EndY'] = hy
        im.mdh['Profile.Width'] = 2 * w + 1

        im.mdh['OriginalImage'] = self.image.filename

        ViewIm3D(im, mode='graph', parent=wx.GetTopLevelParent(self.dsviewer))
    def OnPlotWavyProfile(self, event=None):
        #lx, ly, hx, hy = self.do.GetSliceSelection()
        pts = np.array(self.do.selection_trace)

        w = int(np.floor(0.5 * self.do.selectionWidth))

        try:
            names = self.image.mdh.getEntry('ChannelNames')
        except:
            names = ['Channel %d' % d for d in range(self.image.data.shape[3])]

        try:
            voxx = self.image.mdh.getEntry('voxelsize.x')
        except:
            voxx = 1

        plots = []
        t = np.arange(np.ceil(len(pts)))

        n_chans = self.image.data_xyztc.shape[4]

        for chanNum in range(n_chans):
            p = ndimage.map_coordinates(
                self.image.data_xyztc[:, :, self.do.zp, self.do.tp,
                                      chanNum].squeeze(), pts.T)

            plots.append(p.reshape(-1, 1, 1, 1))

        #plt.legend(names)

        im = ImageStack(plots, titleStub='New Profile')
        im.xvals = t * voxx

        if not voxx == 1:
            im.xlabel = 'Distance [um]'
        else:
            im.xlabel = 'Distance [pixels]'

        im.ylabel = 'Intensity'
        im.defaultExt = '.txt'

        im.mdh['voxelsize.x'] = voxx
        im.mdh['ChannelNames'] = names
        im.mdh['Profile.XValues'] = im.xvals
        im.mdh['Profile.XLabel'] = im.xlabel
        im.mdh['Profile.YLabel'] = im.ylabel
        #im.mdh['Profile.StartX'] = lx
        #im.mdh['Profile.StartY'] = ly
        #im.mdh['Profile.EndX'] = hx
        #im.mdh['Profile.EndY'] = hy
        #im.mdh['Profile.Width'] = 2*w + 1

        im.mdh['OriginalImage'] = self.image.filename

        ViewIm3D(im, mode='graph')
    def OnPlotProfile(self, event=None):
        try:
            names = self.image.mdh.getEntry('ChannelNames')
        except:
            names = ['Channel %d' % d for d in range(self.image.data.shape[3])]

        #print lx, hx, ly, hy

        #pylab.figure()
        plots = []

        for chanNum in range(self.image.data.shape[3]):

            tmin = self.do.Offs[chanNum]
            tmax = tmin + 1. / self.do.Gains[chanNum]

            d = self.image.data[:, :, :, chanNum].squeeze()

            trange = np.linspace(tmin, tmax)

            p = np.array([ndimage.label(d > t)[1] for t in trange])

            plots.append(p.reshape(-1, 1, 1))

        #pylab.legend(names)

        im = ImageStack(plots, titleStub='New Threshold Range')
        im.xvals = trange

        im.xlabel = 'Threshold'

        im.ylabel = 'Num Objects'
        im.defaultExt = '.txt'

        #im.mdh['voxelsize.x'] = voxx
        im.mdh['ChannelNames'] = names

        im.mdh['Profile.XValues'] = im.xvals
        im.mdh['Profile.XLabel'] = im.xlabel
        im.mdh['Profile.YLabel'] = im.ylabel

        im.mdh['OriginalImage'] = self.image.filename

        ViewIm3D(im, mode='graph', parent=wx.GetTopLevelParent(self.dsviewer))
Esempio n. 4
0
    def OnBinProperty(self, event=None):
        # these are the defaults
        avProperty = 'nPhotons'
        byProperty = 'x'
        binwidth = 100

        # traitsui dialog to set the event properties etc
        pChoice = propertyChoice()
        pChoice.add_channels(sorted(self.pipeline.keys()))
        # select defaults if these event properties exist
        if avProperty in pChoice.clist:
            pChoice.EventProperty = avProperty
        if byProperty in pChoice.clist:
            pChoice.BinByProperty = byProperty

        if pChoice.configure_traits(kind='modal'):
            avProperty = pChoice.EventProperty
            byProperty = pChoice.BinByProperty
            binwidth = pChoice.BinWidth
        else:
            return

        avp = self.pipeline[avProperty]
        byp = self.pipeline[byProperty]

        bypmin = byp.min()
        bypmax = byp.max()
        nbins = int((bypmax - bypmin) / binwidth)
        bins = bypmin + np.arange(nbins + 1) * binwidth

        binctrs = 0.5 * (bins[0:-1] + bins[1:])

        avbin, abins = np.histogram(byp, bins=bins, weights=avp)
        bybin, bybins = np.histogram(byp, bins=bins)

        good = bybin > 0
        bad = bybin <= 0

        avmean = np.zeros_like(avbin, dtype='float64')
        avmean[good] = avbin[good] / bybin[good]
        avmean[bad] = np.nan

        # direct matplotlib plotting scrapped for ImageStack approach
        # which allows saving of data
        #plt.figure()
        #plt.plot(binctrs, avmean)
        #plt.xlabel(byProperty)
        #plt.ylabel('mean of %s' % avProperty)

        plots = []
        plots.append(avmean.reshape(-1, 1, 1))

        im = ImageStack(plots, titleStub='mean of %s' % avProperty)
        im.xvals = binctrs
        im.xlabel = byProperty

        im.ylabel = 'mean of %s' % avProperty
        im.defaultExt = '*.txt'

        im.mdh['voxelsize.x'] = binwidth
        im.mdh['ChannelNames'] = [avProperty]
        im.mdh['Profile.XValues'] = im.xvals
        im.mdh['Profile.XLabel'] = im.xlabel
        im.mdh['Profile.YLabel'] = im.ylabel

        im.mdh['OriginalImage'] = self.pipeline.filename

        ViewIm3D(im, mode='graph', parent=wx.GetTopLevelParent(self.visFr))
Esempio n. 5
0
    def OnColoc(self, event=None, restrict_z=False, coloc_vs_z = False):
        from PYME.Analysis.Colocalisation import correlationCoeffs, edtColoc
        from scipy import interpolate
        voxelsize = self.image.voxelsize_nm
        
        names = self.image.names
            
        if not getattr(self.image, 'labels', None) is None:
            have_mask = True
            
            mask = (self.image.labels > 0.5).squeeze()
        else:
            have_mask = False
            mask = None
        
        if not restrict_z:
            dlg = ColocSettingsDialog(self.dsviewer, voxelsize[0], names, have_mask=have_mask)
        else:
            dlg = ColocSettingsDialog(self.dsviewer, voxelsize[0], names, have_mask=have_mask, z_size=self.image.data.shape[2])
        dlg.ShowModal()
        
        bins = dlg.GetBins()
        chans = dlg.GetChans()
        use_mask = dlg.GetUseMask()

        zs, ze = (0, self.image.data.shape[2])
        if (self.image.data.shape[2] > 1) and restrict_z:
            zs, ze = dlg.GetZrange()
            
        zs,ze = (0,1)
        if self.image.data.shape[2] > 1:
            zs,ze = dlg.GetZrange()
        dlg.Destroy()
        
        print('Use mask: %s' % use_mask)
        
        if not use_mask:
            mask=None
        

        #assume we have exactly 2 channels #FIXME - add a selector
        #grab image data
        imA = self.image.data[:,:,zs:ze,chans[0]].squeeze()
        imB = self.image.data[:,:,zs:ze,chans[1]].squeeze()

        #assume threshold is half the colour bounds - good if using threshold mode
        tA = self.do.Offs[chans[0]] + .5/self.do.Gains[chans[0]] #plt.mean(self.ivps[0].clim)
        tB = self.do.Offs[chans[1]] + .5/self.do.Gains[chans[1]] #plt.mean(self.ivps[0].clim)
        
        nameA = names[chans[0]]
        nameB = names[chans[1]]

        voxelsize = voxelsize[:imA.ndim] #trunctate to number of dimensions

        print('Calculating Pearson and Manders coefficients ...')        
        pearson = correlationCoeffs.pearson(imA, imB, roi_mask=mask)
        MA, MB = correlationCoeffs.thresholdedManders(imA, imB, tA, tB, roi_mask=mask)

        if coloc_vs_z:
            MAzs, MBzs = ([],[])
            FAzs, FBzs = ([],[])
            if self.image.data.shape[2] > 1:
                for z in range(self.image.data.shape[2]):
                    imAz = self.image.data[:,:,z,chans[0]].squeeze()
                    imBz = self.image.data[:,:,z,chans[1]].squeeze()
                    MAz, MBz = correlationCoeffs.thresholdedManders(imAz, imBz, tA, tB)
                    FAz, FBz = correlationCoeffs.maskFractions(imAz, imBz, tA, tB)
                    MAzs.append(MAz)
                    MBzs.append(MBz)
                    FAzs.append(FAz)
                    FBzs.append(FBz)

                print("M(A->B) %s" % MAzs)
                print("M(B->A) %s" % MBzs)
                print("Species A: %s, Species B: %s" %(nameA,nameB))
    
                plt.figure()
                plt.subplot(211)
                if 'filename' in self.image.__dict__:
                    plt.title(self.image.filename)
                # nameB with nameA
                cAB, = plt.plot(MAzs,'o', label = '%s with %s' %(nameB,nameA))
                # nameA with nameB
                cBA, = plt.plot(MBzs,'*', label = '%s with %s' %(nameA,nameB))
                plt.legend([cBA,cAB])
                plt.xlabel('z slice level')
                plt.ylabel('Manders coloc fraction')
                plt.ylim(0,None)
    
                plt.subplot(212)
                if 'filename' in self.image.__dict__:
                    plt.title(self.image.filename)
                # nameB with nameA
                fA, = plt.plot(FAzs,'o', label = '%s mask fraction' %(nameA))
                # nameA with nameB
                fB, = plt.plot(FBzs,'*', label = '%s mask fraction' %(nameB))
                plt.legend([fA,fB])
                plt.xlabel('z slice level')
                plt.ylabel('Mask fraction')
                plt.ylim(0,None)
                plt.show()

        print('Performing distance transform ...')
        #bnA, bmA, binsA = edtColoc.imageDensityAtDistance(imB, imA > tA, voxelsize, bins, roi_mask=mask)
        #bnAA, bmAA, binsA = edtColoc.imageDensityAtDistance(imA, imA > tA, voxelsize, bins, roi_mask=mask)
        
        bins_, enrichment_BA, enclosed_BA, enclosed_area_A = edtColoc.image_enrichment_and_fraction_at_distance(imB, imA > tA, voxelsize,
                                                                                               bins, roi_mask=mask)
        bins_, enrichment_AA, enclosed_AA, _ = edtColoc.image_enrichment_and_fraction_at_distance(imA, imA > tA, voxelsize,
                                                                                               bins, roi_mask=mask)
        
        print('Performing distance transform (reversed) ...')
        #bnB, bmB, binsB = edtColoc.imageDensityAtDistance(imA, imB > tB, voxelsize, bins, roi_mask=mask)
        #bnBB, bmBB, binsB = edtColoc.imageDensityAtDistance(imB, imB > tB, voxelsize, bins, roi_mask=mask)

        bins_, enrichment_AB, enclosed_AB, enclosed_area_B = edtColoc.image_enrichment_and_fraction_at_distance(imA, imB > tB, voxelsize,
                                                                                               bins, roi_mask=mask)
        bins_, enrichment_BB, enclosed_BB, _ = edtColoc.image_enrichment_and_fraction_at_distance(imB, imB > tB, voxelsize,
                                                                                               bins, roi_mask=mask)
        
        #print binsB, bmB
        
        plots = []
        pnames = []
        
        
        # B from mA
        ####################
        plots_ = {}


        #plots_['Frac. %s from mask(%s)' % (nameB, nameA)] =
        plots.append(enclosed_BA.reshape(-1, 1, 1))
        pnames.append('Frac. %s from mask(%s)' % (nameB, nameA))

        plots.append(enrichment_BA.reshape(-1, 1, 1))
        pnames.append('Enrichment of %s at distance from mask(%s)' % (nameB, nameA))
        
            
        edtColoc.plot_image_dist_coloc_figure(bins_, enrichment_BA, enrichment_AA, enclosed_BA, enclosed_AA, enclosed_area_A, pearson, MA, MB, nameA, nameB)

        plots.append(enclosed_AB.reshape(-1, 1, 1))
        pnames.append('Frac. %s from mask(%s)' % (nameA, nameB))

        plots.append(enrichment_AB.reshape(-1, 1, 1))
        pnames.append('Enrichment of %s at distance from mask(%s)' % (nameA, nameB))

        edtColoc.plot_image_dist_coloc_figure(bins_, enrichment_AB, enrichment_BB, enclosed_AB, enclosed_BB, enclosed_area_B, pearson,
                                              MA, MB, nameB, nameA)
        
        plt.show()
        
        im = ImageStack(plots, titleStub='Radial Distribution')
        im.xvals = bins[:-1]


        im.xlabel = 'Distance [nm]'

        im.ylabel = 'Fraction'
        im.defaultExt = '.txt'

        im.mdh['voxelsize.x'] = (bins[1] - bins[0])*1e-3
        im.mdh['ChannelNames'] = pnames
        im.mdh['Profile.XValues'] = im.xvals
        im.mdh['Profile.XLabel'] = im.xlabel
        im.mdh['Profile.YLabel'] = im.ylabel
        
        im.mdh['Colocalisation.Channels'] = names
        im.mdh['Colocalisation.Thresholds'] = [tA, tB]
        im.mdh['Colocalisation.Pearson'] = pearson
        im.mdh['Colocalisation.Manders'] = [MA, MB]
        try:
            im.mdh['Colocalisation.ThresholdMode'] = self.do.ThreshMode
        except:
            pass

        im.mdh['OriginalImage'] = self.image.filename

        ViewIm3D(im, mode='graph')
    def OnPlotAxialProfile(self, event=None):
        lx, ly, hx, hy = self.do.GetSliceSelection()

        try:
            names = self.image.mdh.getEntry('ChannelNames')
        except:
            names = ['Channel %d' % d for d in range(self.image.data.shape[3])]

        plots = []
        t = np.arange(self.image.data.shape[2])

        try:
            stack = (self.image.mdh['AcquisitionType'] == 'Stack')
        except:
            stack = False

        if stack:
            dt = self.image.mdh['voxelsize.z']
        else:
            try:
                dt = self.image.mdh['Camera.CycleTime']
            except:
                dt = 1

        for chanNum in range(self.image.data.shape[3]):
            plots.append(np.zeros((len(t), 1, 1)))

        dlg = wx.ProgressDialog('Extracting Axial Profile', 'Progress',
                                max(len(t) - 1, 1))
        for i in t:
            for chanNum in range(self.image.data.shape[3]):
                plots[chanNum][i] = self.image.data[lx:hx, ly:hy, i,
                                                    chanNum].mean()
                if (i % 10) == 0:
                    dlg.Update(i, '%d of %d frames' % (i, t.size))

        dlg.Destroy()

        #plt.legend(names)

        #TODO: Is this really sensible???
        # fix so that we can even plot stacks of depth 1 (i.e. data that is not really a stack)
        # works by replicating the single plane twice simulating a stack of depth 2
        if len(t) == 1:
            t = np.arange(2)
            plots2 = []
            for chanNum in range(self.image.data.shape[3]):
                plots2.append(np.zeros((len(t), 1, 1)))
                for j in range(2):
                    plots2[chanNum][j] = plots[chanNum][0]
            plots = plots2

        im = ImageStack(plots, titleStub='New Profile')
        im.xvals = t * dt

        if stack:
            im.xlabel = 'Position [um]'
        elif not dt == 1:
            im.xlabel = 'Time [s]'
        else:
            im.xlabel = 'Time [frames]'

        im.ylabel = 'Intensity'
        im.defaultExt = '.txt'

        im.mdh['voxelsize.x'] = dt
        im.mdh['ChannelNames'] = names
        im.mdh['Profile.XValues'] = im.xvals
        im.mdh['Profile.XLabel'] = im.xlabel
        im.mdh['Profile.YLabel'] = im.ylabel
        im.mdh['Profile.X1'] = lx
        im.mdh['Profile.Y1'] = ly
        im.mdh['Profile.X2'] = hx
        im.mdh['Profile.Y2'] = hy

        im.mdh['OriginalImage'] = self.image.filename

        im.parent = self.image

        ViewIm3D(im, mode='graph')
    def _OnPlotProfile(self, event=None):
        lx, ly, hx, hy = self.do.GetSliceSelection()

        w = int(np.floor(0.5 * self.do.selectionWidth))

        try:
            names = self.image.mdh.getEntry('ChannelNames')
        except:
            names = ['Channel %d' % d for d in range(self.image.data.shape[3])]

        try:
            voxx = self.image.mdh.getEntry('voxelsize.x')
        except:
            voxx = 1

        Dx = hx - lx
        Dy = hy - ly

        l = np.sqrt((Dx**2 + Dy**2))

        dx = Dx / l
        dy = Dy / l

        if Dx == 0 and Dy == 0:  #special case - profile is orthogonal to current plane
            d_x = w
            d_y = w
        else:
            d_x = w * abs(dy)
            d_y = w * abs(dx)

        #print lx, hx, ly, hy

        #plt.figure()
        plots = []
        t = np.arange(np.ceil(l))

        for chanNum in range(self.image.data.shape[3]):

            x_0 = min(lx, hx)
            y_0 = min(ly, hy)

            d__x = abs(d_x) + 1
            d__y = abs(d_y) + 1

            print((dx, dy, d__x, d__y, w))

            if (self.do.slice == self.do.SLICE_XY):
                ims = self.image.data[(min(lx, hx) - d__x):(max(lx, hx) +
                                                            d__x + 1),
                                      (min(ly, hy) - d__y):(max(ly, hy) +
                                                            d__y + 1),
                                      self.do.zp, chanNum].squeeze()

            splf = ndimage.spline_filter(ims)

            p = np.zeros(len(t))

            x_c = t * dx + lx - x_0
            y_c = t * dy + ly - y_0

            print((splf.shape))

            for i in range(-w, w + 1):
                #print np.vstack([x_c + d__x +i*dy, y_c + d__y + i*dx])
                p += ndimage.map_coordinates(
                    splf,
                    np.vstack([x_c + d__x + i * dy, y_c + d__y - i * dx]),
                    prefilter=False)

            p = p / (2 * w + 1)

            plots.append(p.reshape(-1, 1, 1))

        #plt.legend(names)

        im = ImageStack(plots, titleStub='New Profile')
        im.xvals = t * voxx

        if not voxx == 1:
            im.xlabel = 'Distance [um]'
        else:
            im.xlabel = 'Distance [pixels]'

        im.ylabel = 'Intensity'
        im.defaultExt = '.txt'

        im.mdh['voxelsize.x'] = voxx
        im.mdh['ChannelNames'] = names
        im.mdh['Profile.XValues'] = im.xvals
        im.mdh['Profile.XLabel'] = im.xlabel
        im.mdh['Profile.YLabel'] = im.ylabel
        im.mdh['Profile.StartX'] = lx
        im.mdh['Profile.StartY'] = ly
        im.mdh['Profile.EndX'] = hx
        im.mdh['Profile.EndY'] = hy
        im.mdh['Profile.Width'] = 2 * w + 1

        im.mdh['OriginalImage'] = self.image.filename

        ViewIm3D(im, mode='graph', parent=wx.GetTopLevelParent(self.dsviewer))