def writeHeader(self, hdr, extInts=None, extFloats=None, byteorder='='): Mrc.initHdrArrayFrom(self.fp.hdr, hdr) self.fp.hdr.Num = hdr.Num self.fp.hdr.PixelType = hdr.PixelType self.fp._initWhenHdrArraySet() if extInts is not None or extFloats is not None: if extInts is None: extInts = N.zeros((1, 1)) if extFloats is None: extFloats = N.zeros((1, 1)) self.fp = addExtHdrFromExt(self.fp, hdr.NumIntegers, hdr.NumFloats, extInts, extFloats) self.fp.hdr.NumIntegers = self.fp.extInts.shape[-1] self.fp.hdr.NumFloats = self.fp.extFloats.shape[-1] self.fp.setByteOrder(byteorder) self.fp.writeHeader() if hasattr(self.fp, 'extInts') or hasattr(self.fp, 'extFloats'): self.fp.writeExtHeader(True) self.hdr = self.fp.hdr self.extInts = extInts self.extFloats = extFloats
def writeHeader(self, hdr): Mrc.initHdrArrayFrom(self.fp.hdr, hdr) self.fp.hdr.Num = hdr.Num self.fp.hdr.PixelType = hdr.PixelType self.fp._initWhenHdrArraySet() if self.byteorder == '<': self.hdr.dvid = -16224 # little_indian number if (self.extInts is not None or self.extFloats is not None) or self.byteorder == '<': # old ImageJ assumes that the dv format (byteorder == <) has extended header if self.extInts is None: self.extInts = N.zeros((1,8)) nInts = self.extInts.shape[-1] if self.extFloats is None: self.extFloats = N.zeros((1,32)) nFloats = self.extFloats.shape[-1] self.fp = addExtHdrFromExt(self.fp, nInts, nFloats, self.extInts, self.extFloats) self.fp.hdr.NumIntegers = self.fp.extInts.shape[-1] self.fp.hdr.NumFloats = self.fp.extFloats.shape[-1] self.fp.setByteOrder(self.byteorder) self.fp.writeHeader() if hasattr(self.fp, 'extInts') or hasattr(self.fp, 'extFloats'): self.fp.writeExtHeader(True) self.hdr = self.fp.hdr
def makeHdrFromRdr(rdr): """ rdr: reader object return header """ if hasattr(rdr, 'hdr'): hdr = rdr.hdr else: hdr = Mrc.makeHdrArray() Mrc.init_simple(hdr, Mrc.dtype2MrcMode(rdr.dtype), rdr.shape) hdr.ImgSequence = rdr.imgSequence hdr.NumTimes = rdr.nt hdr.NumWaves = rdr.nw hdr.Num[-1] = rdr.nt * rdr.nw * rdr.nz if len(rdr.wave): if [ 1 for wave in rdr.wave[:rdr.nw] if isinstance(wave, basestring) ]: hdr.wave[:rdr.nw] = 0 else: hdr.wave[:rdr.nw] = rdr.wave[:rdr.nw] hdr.d = rdr.pxlsiz[::-1] if rdr.metadata.has_key('Instrument'): hdr.LensNum = eval( rdr.metadata['Instrument']['Objective']['ID'].split(':')[1]) return hdr
def saveNewMrc(mrc_path, arr, n_tzcyx, cal_xyz, wavelengths=None): """ Write a new Mrc file using numpy ndarray 'arr' and tuples of - dimension sizes (nt, nz, nc, ny, nx) and - float pixel calibrations in microns (cal_x, cal_y, cal_z) """ nt, nz, nc, ny, nx = n_tzcyx if not wavelengths: wavelengths = tuple(900 + n for n in range(5)) arr = numpy.reshape(arr, n_tzcyx) # introduce length 1 dimensions arr = arr.transpose([0, 2, 1, 3, 4]) # Mrc output shape "ZWT" hdr = Mrc.makeHdrArray() mrc_mode = Mrc.dtype2MrcMode(arr.dtype) nslices = nt * nz * nc Mrc.init_simple(hdr, mrc_mode, (nslices, ny, nx)) # set default hdr values hdr.NumTimes = nt hdr.NumWaves = nc hdr.ImgSequence = 2 # write in order "ZWT" hdr.d = cal_xyz hdr.wave = wavelengths # write header & slices f_out = file(mrc_path, 'wb') f_out.write(hdr._array.tostring()) for t in range(nt): for c in range(nc): for z in range(nz): arr_yx_yinverted = arr[t, c, z, ::-1, :] f_out.write(arr_yx_yinverted.copy(order='C')) f_out.close() return DataDoc(mrc_path)
def makeHdr_like(hdrSrc): """ hdrSrc: header of the source return header """ hdr = Mrc.makeHdrArray() init_simple(hdr, hdrSrc.PixelType, hdrSrc.Num[::-1]) Mrc.initHdrArrayFrom(hdr, hdrSrc) hdr.NumTimes = hdrSrc.NumTimes hdr.NumWaves = hdrSrc.NumWaves hdr.NumIntegers = hdrSrc.NumIntegers hdr.NumFloats = hdrSrc.NumFloats return hdr
def doOnSetDim(self): pixelType = Mrc.dtype2MrcMode(self.dtype) num = self.nx, self.ny, self.nz * self.nw * self.nt if not self.hdr: self.hdr = Mrc.makeHdrArray() init_simple(self.hdr, pixelType, num) self.hdr.Num = num self.hdr.NumTimes = self.nt self.hdr.NumWaves = self.nw self.hdr.PixelType = pixelType self.hdr.ImgSequence = self.imgSequence self.hdr.wave[:self.nw] = self.wave[:self.nw] self.hdr.d[:] = self.pxlsiz[::-1] self.writeHeader(self.hdr)
def doOnSetDim(self): pixelType = Mrc.dtype2MrcMode(self.dtype) num = self.nx, self.ny, self.nz * self.nw * self.nt if not self.hdr: self.hdr = Mrc.makeHdrArray() init_simple(self.hdr, pixelType, num) self.hdr.Num = num self.hdr.NumTimes = self.nt self.hdr.NumWaves = self.nw self.hdr.PixelType = pixelType self.hdr.ImgSequence = self.imgSequence self.hdr.wave[:self.nw] = self.wave[:self.nw] self.hdr.d[:] = self.pxlsiz[::-1] #self.makeHdr() #self.setDimFromMrcHdr(hdr) self.writeHeader(self.hdr, extInts=self.extInts, extFloats=self.extFloats)
def makeHdr(self): """ make a Mrc header using the available dimension information to export """ if not self.hdr: hdr = Mrc.makeHdrArray() Mrc.init_simple(hdr, Mrc.dtype2MrcMode(self.dtype), self.shape) hdr.ImgSequence = self.imgSequence hdr.NumTimes = self.nt hdr.NumWaves = self.nw hdr.Num[-1] = self.nt * self.nw * self.nz if len(self.wave): hdr.wave[:self.nw] = self.wave[:self.nw] hdr.d = self.pxlsiz[::-1] if 'Instrument' in self.metadata: hdr.hdr.LensNum = eval(self.metadata['Instrument']['Objective']['ID'].split(':')[1]) self.hdr = hdr
def setMapyx(fn, doc): """ set doc.mapyx from the filename(fn) """ arr = Mrc.bindFile(fn) nz = arr.Mrc.hdr.Num[-1] / (arr.Mrc.hdr.NumTimes * arr.Mrc.hdr.NumWaves * 2) arr = arr.reshape((arr.Mrc.hdr.NumTimes, arr.Mrc.hdr.NumWaves, nz, 2, arr.Mrc.hdr.Num[1], arr.Mrc.hdr.Num[0])) doc.mapyx = arr
def setDimFromMrcHdr(self, hdr, extInts=None, extFloats=None): """ set dimensions using a Mrc header """ #self.writeHeader(hdr, extInts, extFloats, byteorder) self.hdr = makeHdr_like(hdr) self.setPixelSize(*hdr.d[::-1]) nz = hdr.Num[2] // (hdr.NumWaves * hdr.NumTimes) dtype = Mrc.MrcMode2dtype(hdr.PixelType) self.setDim(hdr.Num[0], hdr.Num[1], nz, hdr.NumTimes, hdr.NumWaves, dtype, hdr.wave, hdr.ImgSequence)#, 1, False)
def writeHeader(self, hdr, extInts=None, extFloats=None): Mrc.initHdrArrayFrom(self.fp.hdr, hdr) self.fp.hdr.Num = hdr.Num self.fp.hdr.PixelType = hdr.PixelType self.fp._initWhenHdrArraySet() if self.byteorder == '<': self.hdr.dvid = -16224 # little_indian number if (extInts is not None or extFloats is not None) or self.byteorder == '<': # old ImageJ assumes that the dv format (byteorder == <) has extended header if extInts is None: extInts = N.zeros((1,8)) nInts = extInts.shape[-1] else: nInts = hdr.NumIntegers if extFloats is None: extFloats = N.zeros((1,32)) nFloats = extFloats.shape[-1] else: nFloats = hdr.NumFloats self.fp = addExtHdrFromExt(self.fp, nInts, nFloats, extInts, extFloats) self.fp.hdr.NumIntegers = self.fp.extInts.shape[-1] self.fp.hdr.NumFloats = self.fp.extFloats.shape[-1] self.fp.setByteOrder(self.byteorder) self.fp.writeHeader() if hasattr(self.fp, 'extInts') or hasattr(self.fp, 'extFloats'): self.fp.writeExtHeader(True) self.hdr = self.fp.hdr self.extInts = extInts self.extFloats = extFloats
def makeHdrFromRdr(rdr): """ rdr: reader object return header """ if hasattr(rdr, 'hdr'): hdr = makeHdr_like(rdr.hdr) else: hdr = Mrc.makeHdrArray() Mrc.init_simple(hdr, Mrc.dtype2MrcMode(rdr.dtype), rdr.shape) hdr.ImgSequence = rdr.imgSequence hdr.NumTimes = rdr.nt hdr.NumWaves = rdr.nw hdr.Num[-1] = rdr.nt * rdr.nw * rdr.nz if len(rdr.wave): if [1 for wave in rdr.wave[:rdr.nw] if isinstance(wave, six.string_types)]: hdr.wave[:rdr.nw] = 0 else: hdr.wave[:rdr.nw] = rdr.wave[:rdr.nw] hdr.d = rdr.pxlsiz[::-1] if 'Instrument' in rdr.metadata: hdr.LensNum = eval(rdr.metadata['Instrument']['Objective']['ID'].split(':')[1]) return hdr
def findOTF(fn, ctfdir=None): doesnotwork = """ tempfn = tempfile.mktemp(suffix='.txt', prefix='lensNum') # header does not work on command line! It stops before extended header com = os.system("header %s |sed -n -e '/Lens ID Number\.\.*/ s/Lens ID Number\.\.*//p' |awk '{print $1}' >> %s" % (fn, tempfn)) if com: raise RuntimeError, 'problem in reading header %s' % fn h = open(tempfn) lensNum = h.readline() h.close() print 'lensNum: ', lensNum""" a = Mrc.Mrc2(fn) lensNum = str(a.hdr.LensNum) a.close() return findOTFfromNum(lensNum, ctfdir)
def setDimFromMrcHdr(self, hdr): try: # inside package from ..Priithon import Mrc except ValueError: # Attempted relative import beyond toplevel package from Priithon import Mrc #from Priithon.all import Mrc self.wave = hdr.wave self.nw = hdr.NumWaves self.nt = hdr.NumTimes self.nx = hdr.Num[0] self.ny = hdr.Num[1] self.nz = hdr.Num[2] // (self.nt * self.nw) self.imgSequence = hdr.ImgSequence self.dtype = Mrc.MrcMode2dtype(hdr.PixelType) if self.multipage: self._setSecSize() else: self._setSuffix()
def makeFlatConv(fn, out=None, suffix=''): #, dark=None): """ save a calibration file return output file name """ if not out: out = os.path.extsep.join((os.path.splitext(fn)[0] + suffix, EXT)) #out = fn + EXT h = imgfileIO.load(fn) #mrcIO.MrcReader(fn) h.makeHdr() ntz = h.nz * h.nt hdr = mrcIO.makeHdr_like(h.hdr) hdr.NumTimes = 1 hdr.Num[-1] = h.nw # * 2 hdr.PixelType = Mrc.dtype2MrcMode(N.float32) hdr.type = IDTYPE for w in range(h.nw): if w == 0: hdr.mmm1[0] = 0 hdr.mmm1[1] = 2 else: exec('hdr.mm%i[0] = 0' % (w + 1)) exec('hdr.mm%i[1] = 2' % (w + 1)) #o = imgfileIO.getWriter(out, hdr) o = mrcIO.MrcWriter(out, hdr) for w in range(h.nw): canvas = N.zeros((h.nt, h.nz, h.ny, h.nx), N.float32) #o.writeArr(canvas[0,0], w=w, z=0) # o.writeArr(canvas[0,0], w=w, z=2) #o.writeArr(canvas[0,0], w=w, z=3) for t in range(h.nt): for z in range(h.nz): canvas[t, z] = h.getArr(w=w, t=t, z=z) arr = canvas.reshape(ntz, h.ny, h.nx).mean(axis=0) arr = arr.mean() / arr o.writeArr(arr.astype(N.float32), w=w, z=0) #1) o.close() h.close() return out
def main(): """Collect input filename, create output file, and filter each slice""" input_path = sys.argv[1] if not os.path.exists(input_path): print "Cannot find file: " + input_path sys.exit() else: # Fourier Filter Stripes: copy to new file (data will be overwritten) output_path = addTag(input_path, "FFS") shutil.copy2(input_path, output_path) # NB. Mrc is a special numpy ndarray with extra metadata attached fMrc = Mrc.bindFile(output_path, writable=1) # make a view of the data ndarray that is a flat list of XY slices nplanes = reduce(lambda x, y: x * y, fMrc.shape[:-2]) ny, nx = fMrc.shape[-2:] xy_slices = fMrc.reshape((nplanes, ny, nx)) # filter out stripes from each slice of the whole stack (in-place) for p in range(nplanes): xy_slices[p, :, :] = filter_stripes(xy_slices[p, :, :])
def saveSelection(self, wavelengths = [], timepoints = [], savePath = None): """ Save a wavelength=channel and/or timepoint=frame selection. Basically a duplicate of parts of the alignAndCrop method below, which should now be refactored to use this method instead. Note that a new MRC object is created in the process. """ if not wavelengths: wavelengths = range(self.size[0]) if not timepoints: timepoints = range(self.cropMin[1], self.cropMax[1]) newShape = numpy.array([len(wavelengths), len(timepoints), self.size[2], self.size[3], self.size[4] ], dtype = numpy.int) # make a new header newHeader = Mrc.makeHdrArray() Mrc.initHdrArrayFrom(newHeader, self.imageHeader) newHeader.Num = (self.size[4], self.size[3], self.size[2] * len(timepoints) * len(wavelengths)) newHeader.NumTimes = len(timepoints) newHeader.NumWaves = len(wavelengths) # Size of the extended header -- forced to zero for now. newHeader.next = 0 # Ordering of data in the file; 2 means z/w/t newHeader.ImgSequence = 2 newHeader.PixelType = Mrc.dtype2MrcMode(numpy.float32) if not savePath: outputArray = numpy.empty(newShape, numpy.float32) else: if self.filePath == savePath: # \todo Why do we do this? del self.image.Mrc # update wavelength info to ensure it remains correct # (we could be re-ordering here) for waveIndex, wavelength in enumerate(wavelengths): trueWavelength = self.imageHeader.wave[wavelength] newHeader.wave[waveIndex] = trueWavelength # Write out the header. outputFile = file(savePath, 'wb') outputFile.write(newHeader._array.tostring()) for timepoint in timepoints: for waveIndex, wavelength in enumerate(wavelengths): volume = self.imageArray[wavelength][timepoint] if not savePath: outputArray[timepoint, waveIndex] = volume else: # Write to the file. for i, zSlice in enumerate(volume): outputFile.write(zSlice) if not savePath: # Reorder to WTZYX since that's what the user expects. return outputArray.transpose([1, 0, 2, 3, 4]) else: outputFile.close()
def __init__(self, MRC_path): ## gb, Oct2012 - load an Mrc file here in DataDoc - previously this # Class was initialized with an existing Mrc object. # Note an Mrc object is not just a numpy ndarray of pixels. image = Mrc.bindFile(MRC_path) self.image = image ## Header for the image data, which tells us e.g. what the ordering # of X/Y/Z/time/wavelength is in the MRC file. self.imageHeader = Mrc.implement_hdr(image.Mrc.hdr._array.copy()) ## Location the file is saved on disk. self.filePath = image.Mrc.path ## Number of wavelengths in the array. self.numWavelengths = self.imageHeader.NumWaves numTimepoints = self.imageHeader.NumTimes numX = self.imageHeader.Num[0] numY = self.imageHeader.Num[1] numZ = self.imageHeader.Num[2] // (self.numWavelengths * numTimepoints) ## Size in pixels of the data, since having it as a Numpy array # instead of a tuple (from self.imageArray.shape) is occasionally # handy. self.size = numpy.array([self.numWavelengths, numTimepoints, numZ, numY, numX], dtype = numpy.int) ## 5D array of pixel data, indexed as # self.imageArray[wavelength][time][z][y][x] # In other words, in WTZYX order. In general we try to treat # Z and time as "just another axis", but wavelength is dealt with # specially. self.imageArray = self.getImageArray() ## Datatype of our array. self.dtype = self.imageArray.dtype.type ## Averages for each wavelength, used to provide fill values when # taking slices. self.averages = [] for wavelength in xrange(self.numWavelengths): self.averages.append(self.imageArray[wavelength].mean()) ## Lower boundary of the cropped data. self.cropMin = numpy.array([0, 0, 0, 0, 0], numpy.int32) ## Upper boundary of the cropped data. self.cropMax = numpy.array(self.size, numpy.int32) ## Index of the single pixel that is visible in all different data # views. self.curViewIndex = numpy.array(self.size / 2, numpy.int) # Initial time view is at 0 self.curViewIndex[1] = 0 ## Parameters for transforming different wavelengths so they align # with each other. Order is dx, dy, dz, angle, zoom self.alignParams = numpy.zeros((self.size[0], 5), numpy.float32) # Default zoom to 1.0 self.alignParams[:,4] = 1.0 ## List of functions to call whenever the alignment parameters change. # Each will be passed self.alignParams so it can take whatever # action is necessary. self.alignCallbacks = [] ## gb, Oct2012 # get a list of the true wavelengths so we can tell the user self.channelWaves = self.getChannelWaves()
def alignAndCrop(self, wavelengths = [], timepoints = [], savePath = None): """ Align and Crop the chosen channels/timepoints according to values already set in this DataDoc, and save the new MRC file result. """ if not wavelengths: wavelengths = range(self.size[0]) if not timepoints: timepoints = range(self.cropMin[1], self.cropMax[1]) # Generate the cropped shape of the file. croppedShape = [len(wavelengths)] for min, max in zip(self.cropMin[1:], self.cropMax[1:]): croppedShape.append(max - min) # Reorder to time/wavelength/z/y/x for saving. croppedShape[0], croppedShape[1] = croppedShape[1], croppedShape[0] croppedShape = tuple(croppedShape) newHeader = Mrc.makeHdrArray() Mrc.initHdrArrayFrom(newHeader, self.imageHeader) newHeader.Num = (croppedShape[4], croppedShape[3], croppedShape[2] * len(timepoints) * len(wavelengths)) newHeader.NumTimes = len(timepoints) newHeader.NumWaves = len(wavelengths) # Size of the extended header -- forced to zero for now. newHeader.next = 0 # Ordering of data in the file; 2 means z/w/t newHeader.ImgSequence = 2 newHeader.PixelType = Mrc.dtype2MrcMode(numpy.float32) if not savePath: outputArray = numpy.empty(croppedShape, numpy.float32) else: if self.filePath == savePath: # \todo Why do we do this? del self.image.Mrc # Write out the header. outputFile = file(savePath, 'wb') outputFile.write(newHeader._array.tostring()) # Slices to use to crop out the 3D volume we want to use for each # wave-timepoint pair. volumeSlices = [] for min, max in zip(self.cropMin[2:], self.cropMax[2:]): volumeSlices.append(slice(min, max)) for timepoint in timepoints: for waveIndex, wavelength in enumerate(wavelengths): volume = self.imageArray[wavelength][timepoint] dx, dy, dz, angle, zoom = self.alignParams[wavelength] if dz and self.size[2] == 1: dz = 0 # in 2D files Z translation blanks out the slice! if dx or dy or dz or angle or zoom != 1: # Transform the volume. volume2 = self.transformArray( volume, dx, dy, dz, angle, zoom ) else: volume2 = volume.copy() # no transform # Crop to the desired shape. volume2 = volume2[volumeSlices].astype(numpy.float32) if not savePath: outputArray[timepoint, waveIndex] = volume2 else: # Write to the file. for i, zSlice in enumerate(volume2): outputFile.write(zSlice) if not savePath: # Reorder to WTZYX since that's what the user expects. return outputArray.transpose([1, 0, 2, 3, 4]) else: outputFile.close()