Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
Help
Special pages
SBGrid Resources
SBGrid Consortium
SBGrid Data Bank
Software Webinars
PyMOL Webinar
PyMOL Wiki
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Tiff2ccp4
(section)
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
= The Code = <source lang="python"> # # tiff2ccp4.py -- convert a TIFF stack to a CCP4 map # # Author: Jason Vertrees # Date : 2011-09-16 # # Notes : To get help, type "python tiff2ccp4.py -h" # import struct import sys import string # key = field_type # value = # bytes for that field field_types = { 1 : 1, 2 : 1, 3 : 2, 4 : 4, 5 : 8, 6 : 1, 7 : 1, 8 : 2, 9 : 4, 10: 8, 11: 4, 12: 8 } field_fmt = { 1 : "B", 2 : "c", 3 : "H", 4 : "I", 5 : "II", 6 : "i", 7 : "B", 8 : "h", 9 : "i", 10: "ii", 11: "f", 12: "d" } tag_types = { "NewSubfileType" : 254, "ImageWidth" : 256, # # cols (number of pixels per scanline) "ImageLength" : 257, # # rows (number of scanlines) "BitsPerSample" : 258, "PhotometricInterpretation" : 262, "ImageDescription" : 270, "StripOffsets" : 273, "SamplesPerPixel" : 277, "RowsPerStrip" : 278, "StripByteCounts" : 279, "XResolution" : 282, "YResolution" : 283, "ZResolution" : 284, "ResolutionUnit" : 296, } class TIFFStack: def __init__(self,filename): self._filename = filename self._f = open(self._filename, 'rb') self._file_size = self.get_file_size() # read and store the file header self._header = self.get_header() # read all IFDs and store self._IFDs = self.get_IFDs() def __str__(self): s = "" s += "[TIFFStack]\n" s += "Filename : %s\n" % self._filename s += "File size : %s\n" % self._file_size s += "Header : %s\n" % self._header s += "IFDs : %s\n" % self._IFDs return s def get_file_size(self): """ file size in bytes """ if not self._f: print "Invalid: Must have open file handle." return -1 # less typing f = self._f # get file size curP = f.tell() f.seek(0,2) sz = f.tell() # return to previous location f.seek(curP) return sz def get_header(self): return TIFFHeader(self._f) def get_IFDs(self): return IFD_Store(self._f, self._header) def get_data(self): f = self._f # bits per sample bps = 258 # StripOffsets offset = 273 # byte counts per strip byte_count = 279 sample_format = 339 data = [] ifds = self._IFDs._store for curIFD in ifds: curOffset = curIFD[offset]._val curLength = curIFD[byte_count]._val curBPS = curIFD[bps]._val bytesPerSample = curBPS / 8.0 fld = self.get_field_fmt(curIFD) # use "B" for now; support 16-bit later using tag 339 (SampleFormat) unpackStr = self._header._e_flg + fld * int(curLength/bytesPerSample) f.seek(curOffset) data.extend(struct.unpack(unpackStr, f.read(curLength))) return data def get_field_fmt(self,ifd): """ Determines the Python struct code given BitsPerSample and SampleFormat from the IFD """ bits_per_sample, sample_fmt = 258, 339 bps = ifd[bits_per_sample]._val fmt = None if sample_fmt in ifd.keys(): fmt = ifd[sample_fmt]._val else: fmt = 1 if bps==8: # 1-byte unsigned int if fmt==1: return "B" # 1-byte signed elif fmt==2: return "b" elif bps==16: # 2-byte unsigned if fmt==1: return "H" elif fmt==2: return "h" def get_size(self): fX, fY = 256, 257 x = self._IFDs._store[0][fX]._val y = self._IFDs._store[0][fY]._val z = len(self._IFDs._store) return x, y, z def get_axes_scale(self): # for now return 1,1,1 def asCCP4(self,filename,dimX=-1,dimY=-1,dimZ=-1): data = self.get_data() # pixels size x,y,z nX, nY, nZ = self.get_size() # dimension scaling if -1 in (dimX,dimY,dimZ): dimX, dimY, dimZ = self.get_axes_scale() dimX *= nX dimY *= nY dimZ *= nZ m, avg, M = min(data), sum(data)/len(data), max(data) outFile = open(filename, 'wb') outFile.write(struct.pack('i',nX)) # col outFile.write(struct.pack('i',nY)) # row outFile.write(struct.pack('i',nZ)) # section outFile.write(struct.pack('i',2)) # mode = 2 outFile.write(struct.pack('i',1)) # number of first col outFile.write(struct.pack('i',1)) # '' row outFile.write(struct.pack('i',1)) # '' section outFile.write(struct.pack('i',nX)) # nIntervals outFile.write(struct.pack('i',nY)) # outFile.write(struct.pack('i',nZ)) # outFile.write(struct.pack('f',dimX)) # length in X outFile.write(struct.pack('f',dimY)) # length in Y outFile.write(struct.pack('f',dimZ)) # length in Z outFile.write(struct.pack('f',90.)) # alpha outFile.write(struct.pack('f',90.)) # beta outFile.write(struct.pack('f',90.)) # gamma outFile.write(struct.pack('i',1)) # axis cols outFile.write(struct.pack('i',2)) # axis rows outFile.write(struct.pack('i',3)) # axis section outFile.write(struct.pack('f', m)) # min density outFile.write(struct.pack('f', avg)) # max density outFile.write(struct.pack('f', M)) # mean density outFile.write(struct.pack('i',0)) # space gp ? # header info; blank for us for x in range(24,257): outFile.write(struct.pack('i',0)) # assume constant data in file norm = 255. bps = tag_types["BitsPerSample"] max_bits = self._IFDs._store[0][bps]._val norm = float(2**max_bits-1.) # read/write data for x in data: outFile.write(struct.pack('f', x/norm)) outFile.close() class TIFFHeader: def __init__(self,fileHandle): self._endian, self._e_flg = self.get_endian(fileHandle) self._magic_number = self.get_magic_number(fileHandle) self._first_IFD = self.get_first_IFDOffset(fileHandle) def __str__(self): s = "\n" s += " [TIFF Header]\n" s += " Endian : %s\n" % self._endian s += " Endian Flag : %s\n" % self._e_flg s += " Magic Number : %s\n" % self._magic_number s += " IFD[0] Offset : %s" % self._first_IFD return s # for struct.unpackx def _1byte(self,n=1): return self._e_flg + "C"*n def _2byte(self,n=1): return self._e_flg + "H"*n def _4byte(self,n=1): return self._e_flg + "I"*n def _IFDbyte(self,n=1): return self._e_flg + "HHII"*n def get_endian(self,fileHandle): f = fileHandle f.seek(0) code = struct.unpack("cc", f.read(2)) code = "".join(code) flg = "" if code=="II": flg = "<" elif code=="MM": flg = ">" else: print "This file is not a valid TIFF (bad endian tag)." flg = "?" return code,flg def get_magic_number(self,fileHandle): f = fileHandle f.seek(2) # read the magic number idx = 0 if self._endian == "II": idx = 1 _42 = struct.unpack(self._2byte(), f.read(2))[0] if _42!=42: print "Error: Improperly formatted TIFF file (bad magic number)." return None return _42 def get_first_IFDOffset(self,fileHandle): f=fileHandle f.seek(4) off = struct.unpack(self._4byte(), f.read(4))[0] return off class IFD_Store: def __init__(self,fileHandle,fileHeader): self._f = fileHandle self._header = fileHeader self._first_offset = self._header._first_IFD # array of IFDs self._store = self.read_ifds() def __str__(self): s = "\n" s += " [IFD_Store]\n" s += " First Offset : %d\n" % self._first_offset s += " Store :\n" for st in self._store: s += "\n\n IFD Store =>\n" for k in st: s += " %s => %s" % (k,st[k]) return s def read_ifds(self): f = self._f pos = self._first_offset ifds = [] while pos!=0: ifds.append({}) # get number of IFD_Entries f.seek(pos) # read number of IFDs num_entries = struct.unpack(self._header._2byte(), f.read(2)) num_entries = num_entries[0] # read all into IFD[x] for x in range(num_entries): # pull the current record from file curParams = struct.unpack(self._header._IFDbyte(), f.read(12)) # format the data if necessary if (self._header._e_flg==">" and sys.byteorder=="little") and \ curParams[0] not in (270,50838,50839): scale = 32 - (8 * field_types[curParams[1]]) scaledData = curParams[3] >> scale else: scaledData = curParams[3] ifds[-1][curParams[0]] = IFDEntry(curParams[0], curParams[1], curParams[2], scaledData) # read next offset pos = struct.unpack(self._header._4byte(), f.read(4))[0] return ifds class IFDEntry: def __init__(self,theTag=None,theType=None,theCount=None,theValue=None): self._tag = theTag self._type = theType self._count = theCount self._val = theValue def __str__(self): s = "\n" s += " [IFD_Entry]\n" s += " Tag : %s\n" % self._tag s += " Type : %s\n" % self._type s += " Count : %s\n" % self._count s += " Val/Off: %s\n" % self._val return s if __name__=="__main__": """ Running, python tiff2ccp4.py will convert all TIFF stacks in the current directory to CCP4 maps. """ import argparse from string import split parser = argparse.ArgumentParser(description="Convert a TIFF Stack to a CCP4 Map") parser.add_argument("input", type=str, help="input file name (usually .tif, .tiff)") parser.add_argument("output", type=str, help="output file name (usually .ccp4)") parser.add_argument('-x',"--x", help="length of x-dimension",default=-1.,type=float) parser.add_argument('-y',"--y", help="length of y-dimension",default=-1.,type=float) parser.add_argument('-z',"--z", help="length of z-dimension",default=-1.,type=float) args = parser.parse_args() s = TIFFStack(args.input) s.asCCP4(args.output, args.x, args.y, args.z) </source> [[Category:Script_Library]] [[Category:System_Scripts]] [[Category:ThirdParty_Scripts]]
Summary:
Please note that all contributions to PyMOL Wiki are considered to be released under the GNU Free Documentation License 1.2 (see
PyMOL Wiki:Copyrights
for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Search
Search
Editing
Tiff2ccp4
(section)
Add topic