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'
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
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
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
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'