Beispiel #1
0
    def _loadBioformats(self, filename):
        #from PYME.IO.FileUtils import readTiff
        from PYME.IO.DataSources import BioformatsDataSource

        try:
            import bioformats
        except ImportError:
            logger.exception(
                'Error importing bioformats - is the python-bioformats module installed?'
            )
            raise

        #mdfn = self.FindAndParseMetadata(filename)
        print("Bioformats:loading data")
        self.dataSource = BioformatsDataSource.DataSource(filename, None)
        self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.BareBones)

        print("Bioformats:loading metadata")
        OMEXML = bioformats.get_omexml_metadata(filename).encode('utf8')
        print("Bioformats:parsing metadata")
        OMEmd = MetaDataHandler.OMEXMLMDHandler(OMEXML)
        self.mdh.copyEntriesFrom(OMEmd)
        print("Bioformats:done")

        print(self.dataSource.shape)
        self.dataSource = BufferedDataSource.DataSource(
            self.dataSource, min(self.dataSource.getNumSlices(), 50))
        self.data = self.dataSource  #this will get replaced with a wrapped version

        print(self.data.shape)

        #from PYME.ParallelTasks.relativeFiles import getRelFilename
        self.seriesName = getRelFilename(filename)

        self.mode = 'default'
Beispiel #2
0
    def Export(self,
               data,
               outFile,
               xslice,
               yslice,
               zslice,
               metadata=None,
               events=None,
               origName=None,
               progressCallback=None):
        from PYME.contrib.gohlke import tifffile
        from PYME.IO import dataWrap

        def _bool_to_uint8(data):
            if data.dtype == 'bool':
                return data.astype('uint8')
            else:
                return data

        if data.nbytes > 2e9:
            warnings.warn(
                'Data is larger than 2GB, generated TIFF may not read in all software'
            )

        if data.nbytes > 4e9:
            raise RuntimeError(
                'TIFF has a maximum file size of 4GB, crop data or save as HDF'
            )

        dw = dataWrap.ListWrap([
            numpy.atleast_3d(
                _bool_to_uint8(data[xslice, yslice, zslice, i].squeeze()))
            for i in range(data.shape[3])
        ])
        #xmd = None
        if not metadata is None:
            xmd = MetaDataHandler.OMEXMLMDHandler(mdToCopy=metadata)
            if not origName is None:
                xmd.setEntry('cropping.originalFile', origName)

            xmd.setEntry('cropping.xslice', xslice.indices(data.shape[0]))
            xmd.setEntry('cropping.yslice', yslice.indices(data.shape[1]))
            xmd.setEntry('cropping.zslice', zslice.indices(data.shape[2]))

            description = xmd.getXML(dw)
        else:
            description = None

        tifffile.imsave_f(outFile, dw, description=description)

        if progressCallback:
            try:
                progressCallback(100, 100)
            except:
                pass
Beispiel #3
0
    def Export(self,
               data,
               outFile,
               xslice,
               yslice,
               zslice,
               metadata=None,
               events=None,
               origName=None,
               progressCallback=None):
        from PYME.contrib.gohlke import tifffile
        from PYME.IO import dataWrap

        def _bool_to_uint8(data):
            if data.dtype == 'bool':
                return data.astype('uint8')
            else:
                return data

        dw = dataWrap.ListWrap([
            numpy.atleast_3d(
                _bool_to_uint8(data[xslice, yslice, zslice, i].squeeze()))
            for i in range(data.shape[3])
        ])
        #xmd = None
        if not metadata is None:
            xmd = MetaDataHandler.OMEXMLMDHandler(mdToCopy=metadata)
            if not origName is None:
                xmd.setEntry('cropping.originalFile', origName)

            xmd.setEntry('cropping.xslice', xslice.indices(data.shape[0]))
            xmd.setEntry('cropping.yslice', yslice.indices(data.shape[1]))
            xmd.setEntry('cropping.zslice', zslice.indices(data.shape[2]))

            description = xmd.getXML(dw)
        else:
            description = None

        tifffile.imsave_f(outFile, dw, description=description)

        if progressCallback:
            try:
                progressCallback(100, 100)
            except:
                pass
Beispiel #4
0
    def _findAndParseMetadata(self, filename):
        """Try and find and load a .xml or .md metadata file that might be ascociated
        with a given image filename. See the relevant metadatahandler classes
        for details."""
        import xml.parsers.expat
        from PYME.IO import unifiedIO

        if not self.mdh is None:
            return  #we already have metadata (probably passed in on command line)

        mdf = None
        xmlfn = os.path.splitext(filename)[0] + '.xml'
        xmlfnmc = os.path.splitext(filename)[0].split('__')[0] + '.xml'
        if os.path.exists(xmlfn):
            try:
                self.mdh = MetaDataHandler.NestedClassMDHandler(
                    MetaData.TIRFDefault)
                self.mdh.copyEntriesFrom(MetaDataHandler.XMLMDHandler(xmlfn))
                mdf = xmlfn
            except xml.parsers.expat.ExpatError:
                #fix for bug in which PYME .md was written with a .xml extension
                self.mdh = MetaDataHandler.NestedClassMDHandler(
                    MetaData.BareBones)
                self.mdh.copyEntriesFrom(
                    MetaDataHandler.SimpleMDHandler(xmlfn))
                mdf = xmlfn

        elif os.path.exists(
                xmlfnmc):  #this is a single colour channel of a pair
            self.mdh = MetaDataHandler.NestedClassMDHandler(
                MetaData.TIRFDefault)
            self.mdh.copyEntriesFrom(MetaDataHandler.XMLMDHandler(xmlfnmc))
            mdf = xmlfnmc
        else:
            self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.BareBones)

            #check for simple metadata (python code with an .md extension which
            #fills a dictionary called md)
            mdfn = os.path.splitext(filename)[0] + '.md'
            jsonfn = os.path.splitext(filename)[0] + '.json'
            if os.path.exists(mdfn):
                self.mdh.copyEntriesFrom(MetaDataHandler.SimpleMDHandler(mdfn))
                mdf = mdfn
            elif os.path.exists(jsonfn):
                import json
                with open(jsonfn, 'r') as f:
                    mdd = json.load(f)
                    self.mdh.update(mdd)
            elif filename.endswith('.lsm'):
                #read lsm metadata
                from PYME.contrib.gohlke.tifffile import TIFFfile
                tf = TIFFfile(filename)
                lsm_info = tf[0].cz_lsm_scan_information
                self.mdh['voxelsize.x'] = lsm_info['line_spacing']
                self.mdh['voxelsize.y'] = lsm_info['line_spacing']
                self.mdh['voxelsize.z'] = lsm_info['plane_spacing']

                def lsm_pop(basename, dic):
                    for k, v in dic.items():
                        if isinstance(v, list):
                            #print k, v
                            for i, l_i in enumerate(v):
                                #print i, l_i, basename
                                lsm_pop(
                                    basename + k + '.' + k[:-1] + '%i.' % i,
                                    l_i)

                        else:
                            self.mdh[basename + k] = v

                lsm_pop('LSM.', lsm_info)

            elif filename.endswith('.tif'):
                #look for OME data...
                from PYME.contrib.gohlke.tifffile import TIFFfile
                tf = TIFFfile(filename)

                if tf.is_ome:
                    try:
                        omemdh = MetaDataHandler.OMEXMLMDHandler(
                            tf.pages[0].tags['image_description'].value)

                        self.mdh.copyEntriesFrom(omemdh)
                    except IndexError:
                        pass

            elif filename.endswith('.dcimg'):  #Bewersdorf lab Biplane
                # FIXME load seriesXX.json for seriesXX_chunkXX.dcimg files more elegantly
                jsonfn = filename[:-22] + '.json'

                import json
                try:
                    mdd = json.loads(unifiedIO.read(jsonfn))
                    self.mdh.update(mdd)

                except IOError:
                    pass

            elif filename.endswith('.dbl'):  #Bewersdorf lab STED
                mdfn = filename[:-4] + '.txt'
                entrydict = {}

                try:  #try to read in extra metadata if possible
                    with unifiedIO.openFile(mdfn, 'r') as mf:
                        for line in mf:
                            s = line.split(':')
                            if len(s) == 2:
                                entrydict[s[0]] = s[1]

                except IOError:
                    pass


#                vx, vy = entrydict['Pixel size (um)'].split('x')
#                self.mdh['voxelsize.x'] = float(vx)
#                self.mdh['voxelsize.y'] = float(vy)
#                self.mdh['voxelsize.z'] = 0.2 #FIXME for stacks ...
#
#                sx, sy = entrydict['Image format'].split('x')
#                self.mdh['Camera.ROIWidth'] = int(sx)
#                self.mdh['Camera.ROIHeight'] = int(sy)
#
#                self.mdh['NumImages'] = int(entrydict['# Images'])

                with unifiedIO.openFile(filename) as df:
                    s = df.read(8)
                    Z, X, Y, T = numpy.fromstring(s, '>u2')
                    s = df.read(16)
                    depth, width, height, elapsed = numpy.fromstring(s, '<f4')

                    self.mdh['voxelsize.x'] = width / X
                    self.mdh['voxelsize.y'] = height / Y
                    self.mdh['voxelsize.z'] = depth

                    self.mdh['Camera.ROIWidth'] = X
                    self.mdh['Camera.ROIHeight'] = Y
                    self.mdh['NumImages'] = Z * T

                def _sanitise_key(key):
                    k = key.replace('#', 'Num')
                    k = k.replace('(%)', '')
                    k = k.replace('(', '')
                    k = k.replace(')', '')
                    k = k.replace('.', '')
                    k = k.replace('/', '')
                    k = k.replace('?', '')
                    k = k.replace(' ', '')
                    if not k[0].isalpha():
                        k = 's' + k
                    return k

                for k, v in entrydict.items():
                    self.mdh['STED.%s' % _sanitise_key(k)] = v

            #else: #try bioformats
            #    OMEXML = bioformats.get_omexml_metadata(filename).encode('utf8')
            #    OMEmd = MetaDataHandler.OMEXMLMDHandler(OMEXML)
            #    self.mdh.copyEntriesFrom(OMEmd)

        if self.haveGUI and not ('voxelsize.x' in self.mdh.keys()
                                 and 'voxelsize.y' in self.mdh.keys()):
            from PYME.DSView.voxSizeDialog import VoxSizeDialog

            dlg = VoxSizeDialog(None)
            dlg.ShowModal()

            self.mdh.setEntry('voxelsize.x', dlg.GetVoxX())
            self.mdh.setEntry('voxelsize.y', dlg.GetVoxY())
            self.mdh.setEntry('voxelsize.z', dlg.GetVoxZ())

        return mdf
Beispiel #5
0
    def _loadBioformats(self, filename):
        try:
            import bioformats
        except ImportError:
            logger.exception(
                'Error importing bioformats - is the python-bioformats module installed?'
            )
            raise

        from PYME.IO.DataSources import BioformatsDataSource
        series_num = None

        if '?' in filename:
            #we have a query string to pick the series
            from six.moves import urllib
            filename, query = filename.split('?')

            try:
                series_num = int(urllib.parse.parse_qs(query)['series'][0])
            except KeyError:
                pass

        #mdfn = self.FindAndParseMetadata(filename)
        print("Bioformats:loading data")
        bioformats_file = BioformatsDataSource.BioformatsFile(filename)
        if series_num is None and bioformats_file.series_count > 1:
            print('File has multiple series, need to pick one.')

            if self.haveGUI:
                import wx
                dlg = wx.SingleChoiceDialog(None, 'Series', 'Select a series',
                                            bioformats_file.series_names)
                if dlg.ShowModal() == wx.ID_OK:
                    series_num = dlg.GetSelection()
            else:
                logger.warning('No GUI, using 0th series.')

        self.dataSource = BioformatsDataSource.DataSource(bioformats_file,
                                                          series=series_num)
        self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.BareBones)

        # NOTE: We are triple-loading metadata. BioformatsDataSource.BioformatsFile.rdr has metadata (hard to access),
        # BioformatsDataSource.BioformatsFile has metadata, and now we are loading the same metadata again here.
        print("Bioformats:loading metadata")
        OMEXML = bioformats.get_omexml_metadata(filename).encode('utf8')
        print("Bioformats:parsing metadata")
        OMEmd = MetaDataHandler.OMEXMLMDHandler(OMEXML)
        self.mdh.copyEntriesFrom(OMEmd)
        print("Bioformats:done")

        #fix voxelsizes if not specified in OME metadata
        if self.haveGUI and ((self.mdh['voxelsize.x'] < 0) or
                             (self.mdh['voxelsize.y'] < 0)):
            from PYME.DSView.voxSizeDialog import VoxSizeDialog

            dlg = VoxSizeDialog(None)
            dlg.ShowModal()

            self.mdh.setEntry('voxelsize.x', dlg.GetVoxX())
            self.mdh.setEntry('voxelsize.y', dlg.GetVoxY())
            self.mdh.setEntry('voxelsize.z', dlg.GetVoxZ())

            dlg.Destroy()

        print(self.dataSource.shape)
        self.dataSource = BufferedDataSource.DataSource(
            self.dataSource, min(self.dataSource.getNumSlices(), 50))
        self.data = self.dataSource  #this will get replaced with a wrapped version

        print(self.data.shape)

        #from PYME.ParallelTasks.relativeFiles import getRelFilename
        self.seriesName = getRelFilename(filename)

        self.mode = 'default'