def OnCreateMask(self, event=None):
        #lx, ly, hx, hy = self.do.GetSliceSelection()
        import numpy as np
        #from scipy import ndimage
        from PYME.IO.image import ImageStack
        from PYME.DSView import ViewIm3D

        #sp = self.image.data.shape[:3]
        #if len(sp)
        self.mask = np.atleast_3d(np.zeros(self.image.data.shape[:3],
                                           'uint16'))
        self.vmax = 0
        self.image.labels = self.mask

        im = ImageStack(self.mask, titleStub='Manual labels')
        im.mdh.copyEntriesFrom(self.image.mdh)

        #im.mdh['Processing.CropROI'] = roi

        if self.dsviewer.mode == 'visGUI':
            mode = 'visGUI'
        else:
            mode = 'lite'

        self.dv = ViewIm3D(im,
                           mode=mode,
                           glCanvas=self.dsviewer.glCanvas,
                           parent=wx.GetTopLevelParent(self.dsviewer))

        self.rois = []

        #set scaling to (0,1)
        for i in range(im.data.shape[3]):
            self.dv.do.Gains[i] = 1.0
    def OnSVMSegment(self, event):
        # import pylab
        #sp = self.image.data.shape[:3]
        #if len(sp)
        lab2 = self.cf.classify(self.image.data[:, :, self.do.zp, 0].squeeze()
                                )  #, self.image.labels[:,:,self.do.zp])
        #self.vmax = 0
        #self.image.labels = self.mask

        im = ImageStack(lab2, titleStub='Segmentation')
        im.mdh.copyEntriesFrom(self.image.mdh)

        #im.mdh['Processing.CropROI'] = roi

        if self.dsviewer.mode == 'visGUI':
            mode = 'visGUI'
        else:
            mode = 'lite'

        self.dv = ViewIm3D(im,
                           mode=mode,
                           glCanvas=self.dsviewer.glCanvas,
                           parent=wx.GetTopLevelParent(self.dsviewer))

        self.rois = []

        #set scaling to (0,10)
        for i in range(im.data.shape[3]):
            self.dv.do.Gains[i] = .1
            self.dv.do.cmaps[i] = matplotlib.cm.labeled

        self.dv.Refresh()
        self.dv.Update()
Beispiel #3
0
    def OnExtractPSF(self, event):
        if (len(self.PSFLocs) > 0):
            from PYME.Analysis.PSFEst import extractImages
            chnum = self.chChannel.GetSelection()

            psfROISize = [int(s) for s in self.tPSFROI.GetValue().split(',')]
            psfBlur = [float(s) for s in self.tPSFBlur.GetValue().split(',')]
            #print psfROISize
            psf, offsets = extractImages.getPSF3D(
                self.image.data[:, :, :, chnum],
                self.PSFLocs,
                psfROISize,
                psfBlur,
                expand_z=self.cbExpandROI.GetValue())

            if self.cbBackgroundCorrect.GetValue():
                #widefield image - do special background subtraction
                psf = extractImages.backgroundCorrectPSFWF(psf)

            from PYME.DSView.dsviewer import ImageStack, ViewIm3D
            from PYME.IO.MetaDataHandler import NestedClassMDHandler

            mdh = NestedClassMDHandler(self.image.mdh)
            self.write_metadata(mdh, 'default')
            mdh['ImageType'] = 'PSF'

            im = ImageStack(data=psf, mdh=mdh, titleStub='Extracted PSF')
            im.defaultExt = '*.tif'  #we want to save as PSF by default

            ViewIm3D(im,
                     mode='psf',
                     parent=wx.GetTopLevelParent(self.dsviewer))
    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 OnMultiplyMask(self, event=None):
        new_image = []
        
        mask = self.mask > 0.5 #generate a binary mask from labels
        
        for chNum in range(self.image.data.shape[3]):
            new_image.append(mask*self.image.data[:,:,:,chNum])

        im = ImageStack(new_image, titleStub='Masked image')
        im.mdh.copyEntriesFrom(self.image.mdh)
            
        if self.dsviewer.mode == 'visGUI':
            mode = 'visGUI'
        else:
            mode = 'lite'

        self.dv = ViewIm3D(im, mode=mode, glCanvas=self.dsviewer.glCanvas, parent=wx.GetTopLevelParent(self.dsviewer))
    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))
Beispiel #8
0
    def OnExtractMultiviewPSF(self, event):
        if (len(self.PSFLocs) > 0):
            from PYME.Analysis.PSFEst import extractImages

            psfROISize = [int(s) for s in self.tPSFROI.GetValue().split(',')]
            psfBlur = [float(s) for s in self.tPSFBlur.GetValue().split(',')]

            psfs = []

            for chnum in range(self.image.data.shape[3]):
                alignZ = (chnum > 0) and self.cbAlignZ.GetValue()
                #always align the first channel

                psf, offsets = extractImages.getPSF3D(
                    self.image.data[:, :, :, chnum],
                    self.PSFLocs,
                    psfROISize,
                    psfBlur,
                    centreZ=alignZ,
                    expand_z=self.cbExpandROI.GetValue())

                if self.cbBackgroundCorrect.GetValue():
                    #widefield image - do special background subtraction
                    psf = extractImages.backgroundCorrectPSFWF(psf)

                psfs.append(psf)

            from PYME.DSView.dsviewer import ImageStack, ViewIm3D
            from PYME.IO.MetaDataHandler import NestedClassMDHandler

            mdh = NestedClassMDHandler(self.image.mdh)
            self.write_metadata(mdh, 'Multiview')
            mdh['ImageType'] = 'PSF'

            im = ImageStack(data=psfs, mdh=mdh, titleStub='Extracted PSF')
            im.defaultExt = '*.tif'  #we want to save as PSF by default
            ViewIm3D(im,
                     mode='psf',
                     parent=wx.GetTopLevelParent(self.dsviewer))
Beispiel #9
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))
Beispiel #10
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))
Beispiel #13
0
    def OnExtractSplitPSF(self, event):
        if (len(self.PSFLocs) > 0):
            from PYME.Analysis.PSFEst import extractImages
            chnum = self.chChannel.GetSelection()

            psfROISize = [int(s) for s in self.tPSFROI.GetValue().split(',')]
            psfBlur = [float(s) for s in self.tPSFBlur.GetValue().split(',')]
            #print psfROISize

            psfs = []
            offsetsAllChannel = []

            #extract first channel (always aligned)
            psf, offsets = extractImages.getPSF3D(self.image.data[:, :, :,
                                                                  0].squeeze(),
                                                  self.PSFLocs,
                                                  psfROISize,
                                                  psfBlur,
                                                  centreZ=True)
            if self.chType.GetSelection() == 0:
                #widefield image - do special background subtraction
                psf = extractImages.backgroundCorrectPSFWF(psf)

            psfs.append(psf)
            offsetsAllChannel.append(offsets)
            alignZ = self.cbAlignZ.GetValue()
            z_offset = offsets[2]

            #extract subsequent channels, aligning if necessary, otherwise offsetting by the calculated offset for the first channel
            for i in range(1, self.image.data.shape[3]):
                psf, offsets = extractImages.getPSF3D(
                    self.image.data[:, :, :, i].squeeze(),
                    self.PSFLocs,
                    psfROISize,
                    psfBlur,
                    centreZ=alignZ,
                    z_offset=z_offset)

                if self.cbBackgroundCorrect.GetValue():
                    #widefield image - do special background subtraction
                    psf = extractImages.backgroundCorrectPSFWF(psf)

                psfs.append(psf)
                offsetsAllChannel.append(offsets)

            psf = numpy.concatenate(psfs, 0)
            offsetsAllChannel = numpy.asarray(offsetsAllChannel)
            offsetsAllChannel -= offsetsAllChannel[0]
            print(offsetsAllChannel)

            #            from pylab import *
            #            import cPickle
            #            imshow(psf.max(2))

            from PYME.DSView.dsviewer import ImageStack, ViewIm3D
            from PYME.IO.MetaDataHandler import NestedClassMDHandler

            mdh = NestedClassMDHandler(self.image.mdh)
            self.write_metadata(mdh, 'Split', offsetsAllChannel[:, 2])
            mdh['ImageType'] = 'PSF'

            im = ImageStack(data=psf, mdh=mdh, titleStub='Extracted PSF')
            im.defaultExt = '*.tif'  #we want to save as PSF by default
            ViewIm3D(im,
                     mode='psf',
                     parent=wx.GetTopLevelParent(self.dsviewer))
Beispiel #14
0
    def OnCalibrateMultiview(self, event):
        """
        CalibrateMultiview loops over all channels described in the metadata and runs CalibrateAstigmatism on each one.
        Results are stored in a library of dictionaries and are saved into a jason astigmatism map file (.am)
        Args:
            event: GUI event

        Returns:
            nothing

        """
        # first make sure the user is calling the right function
        try:
            chanSizeX = self.image.mdh['Multiview.ROISize'][0]
        except KeyError:
            raise KeyError(
                'You are not looking at multiview data, or the metadata is incomplete'
            )

        if len(self.PSFLocs) > 0:
            print(
                'Place cursor on bead in first multiview channel and press Calibrate Multiview Astigmatism'
            )
            self.OnClearTags(event)
            return

        from PYME.Analysis.PSFEst import extractImages
        from PYME.DSView.modules import psfTools
        import scipy.interpolate as terp
        import numpy as np
        from PYME.IO.FileUtils import nameUtils
        import os
        import json

        zrange = np.nan * np.ones(2)

        rsx, rsy, rsz = [int(s) for s in self.tPSFROI.GetValue().split(',')]
        # astigDat = []
        astigLib = {}
        for ii in range(self.numChan):
            # grab PSFs, currently relying on user to pick psf in first channel
            xmin, xmax = [(self.do.xp - rsx + ii * chanSizeX),
                          (self.do.xp + rsx + ii * chanSizeX + 1)]
            # dz returns offset in units of frames, dx dy are in pixels
            dx, dy, dz = extractImages.getIntCenter(
                self.image.data[xmin:xmax,
                                (self.do.yp - rsy):(self.do.yp + rsy + 1), :,
                                0])
            self.PSFLocs.append((self.do.xp + dx, self.do.yp + dy, dz))
            self.view.psfROIs = self.PSFLocs
            self.view.Refresh()

            psfROISize = [int(s) for s in self.tPSFROI.GetValue().split(',')]
            psfBlur = [float(s) for s in self.tPSFBlur.GetValue().split(',')]

            psf = extractImages.getPSF3D(self.image.data[:, :, :, 0],
                                         [self.PSFLocs[ii]], psfROISize,
                                         psfBlur)

            if self.cbBackgroundCorrect.GetValue():
                #widefield image - do special background subtraction
                psf = extractImages.backgroundCorrectPSFWF(psf)

            from PYME.DSView.dsviewer import ImageStack, ViewIm3D

            im = ImageStack(data=psf,
                            mdh=self.image.mdh,
                            titleStub='Extracted PSF, Chan %i' % ii)
            im.defaultExt = '*.psf'  #we want to save as PSF by default
            ViewIm3D(im,
                     mode='psf',
                     parent=wx.GetTopLevelParent(self.dsviewer))

            calibrater = psfTools.PSFTools(self.dsviewer, im)
            astigLib['PSF%i' % ii] = (calibrater.OnCalibrateAstigmatism(
                event, plotIt=False))
            # the next line is only ok if each frame is at a different z position, which it should be
            astigLib['PSF%i' %
                     ii]['z'] += dz * self.image.mdh['voxelsize.z'] * 1.e3

            # -- spline interpolate --
            # find region of dsigma which is monotonic
            dsig = terp.UnivariateSpline(
                astigLib['PSF%i' % ii]['z'],
                astigLib['PSF%i' %
                         ii]['dsigma'])  #, s=1.5*len(astigDat[ii]['z']))

            # mask where the sign is the same as the center
            zvec = np.linspace(astigLib['PSF%i' % ii]['z'].min(),
                               astigLib['PSF%i' % ii]['z'].max(), 1000)
            sgn = np.sign(np.diff(dsig(zvec)))
            halfway = len(sgn) / 2
            notmask = sgn != sgn[halfway]

            # find z range for spline generation
            lowerZ = zvec[np.where(notmask[:halfway])[0].max()]
            upperZ = zvec[(len(sgn) / 2 +
                           np.where(notmask[halfway:])[0].min() - 1)]
            astigLib['PSF%i' % ii]['zrange'] = [lowerZ, upperZ]
            zrange = [
                np.nanmin([lowerZ, zrange[0]]),
                np.nanmax([upperZ, zrange[1]])
            ]

            #lowsubZ , upsubZ = np.absolute(astigDat[ii]['z'] - zvec[lowerZ]), np.absolute(astigDat[ii]['z'] - zvec[upperZ])
            #lowZLoc = np.argmin(lowsubZ)
            #upZLoc = np.argmin(upsubZ)

            #
            #astigLib['sigxTerp%i' % ii] = terp.UnivariateSpline(astigLib['PSF%i' % ii]['z'], astigLib['PSF%i' % ii]['sigmax'],
            #                                                    bbox=[lowerZ, upperZ])
            #astigLib['sigyTerp%i' % ii] = terp.UnivariateSpline(astigLib['PSF%i' % ii]['z'], astigLib['PSF%i' % ii]['sigmay'],
            #                                                    bbox=[lowerZ, upperZ])
            astigLib['PSF%i' % ii]['z'] = astigLib['PSF%i' % ii]['z'].tolist()

        astigLib['zRange'] = np.round(zrange).tolist()
        astigLib['numChan'] = self.numChan

        psfTools.plotAstigCalibration(astigLib)

        # save to json file
        #defFile = os.path.splitext(os.path.split(self.visFr.GetTitle())[-1])[0] + '.am'

        fdialog = wx.FileDialog(
            None,
            'Save Astigmatism Calibration as ...',
            wildcard='AstigMAPism file (*.am)|*.am',
            style=wx.FD_SAVE,
            defaultDir=nameUtils.genShiftFieldDirectoryPath(
            ))  #, defaultFile=defFile)
        succ = fdialog.ShowModal()
        if (succ == wx.ID_OK):
            fpath = fdialog.GetPath()

            fid = open(fpath, 'wb')
            json.dump(astigLib, fid)
            fid.close()