source: trunk/imports/G2img_1TIF.py @ 2065

Last change on this file since 2065 was 2065, checked in by toby, 7 years ago

Allow reading of multiple images from single file

  • Property svn:eol-style set to native
File size: 11.6 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2014-12-27 11:14:59 -0600 (Sat, 27 Dec 2014) $
4# $Author: $
5# $Revision: $
6# $URL: $
7# $Id: $
8########### SVN repository information ###################
9'''
10*Module G2img_TIF: .tif image file*
11--------------------------------------
12
13Routine to read an image in Tagged-image file (TIF) format as well as a variety
14of slightly incorrect pseudo-TIF formats used at instruments around the world.
15
16'''
17
18import sys
19import struct as st
20import os.path as ospath
21import GSASIIIO as G2IO
22import GSASIIpath
23import numpy as np
24DEBUG = False
25GSASIIpath.SetVersionNumber("$Revision: $")
26class TIF_ReaderClass(G2IO.ImportImage):
27    '''Routine to read an image in Tagged-image file (TIF) format as well as a variety
28    of slightly incorrect pseudo-TIF formats
29    '''
30    def __init__(self):
31        super(self.__class__,self).__init__( # fancy way to self-reference
32            extensionlist=('.tif','.tiff'),
33            strictExtension=False,
34            formatName = 'TIF image',
35            longFormatName = 'Various .tif and pseudo-TIF formats'
36            )
37
38    def ContentsValidator(self, filepointer):
39        '''Does the header match the required TIF header?
40        '''
41        tag = filepointer.read(2)
42        if tag == 'II' and int(st.unpack('<h',filepointer.read(2))[0]) == 42: #little endian
43            pass
44        elif tag == 'MM' and int(st.unpack('>h',filepointer.read(2))[0]) == 42: #big endian
45            pass
46        else:
47            return False # header not found; not valid TIF
48        return True
49   
50    def Reader(self,filename,filepointer, ParentFrame=None, **unused):
51        '''Read the TIF file using Bob's routine
52        '''
53       
54        self.Comments,self.Data,self.Npix,self.Image = GetTifData(filename)
55        if self.Npix == 0:
56            print("GetTifData failed to read "+str(filename)+" Trying SciPy")
57            import scipy.misc
58            self.Image = scipy.misc.imread(filename,flatten=True)
59            self.Npix = self.Image.size
60            if ParentFrame:
61                self.Comments = ['no metadata']
62                self.Data = {'wavelength': 0.1, 'pixelSize': [200, 200], 'distance': 100.0}
63                self.Data['size'] = list(self.Image.shape)
64                self.Data['center'] = [int(i/2) for i in self.Image.shape]
65                G2IO.EditImageParms(ParentFrame,self.Data,self.Comments,self.Image,filename)
66        if self.Npix == 0:
67            return False
68        self.LoadImage(ParentFrame,filename)
69        return True
70
71def GetTifData(filename):
72    '''Read an image in a pseudo-tif format,
73    as produced by a wide variety of software, almost always
74    incorrectly in some way.
75    '''
76    import struct as st
77    import array as ar
78    import ReadMarCCDFrame as rmf
79    image = None
80    File = open(filename,'rb')
81    dataType = 5
82    center = [None,None]
83    wavelength = None
84    distance = None
85    try:
86        Meta = open(filename+'.metadata','Ur')
87        head = Meta.readlines()
88        for line in head:
89            line = line.strip()
90            if 'dataType=' in line:
91                dataType = int(line.split('=')[1])
92        Meta.close()
93    except IOError:
94        print 'no metadata file found - will try to read file anyway'
95        head = ['no metadata file found',]
96       
97    tag = File.read(2)
98    byteOrd = '<'
99    if tag == 'II' and int(st.unpack('<h',File.read(2))[0]) == 42:     #little endian
100        IFD = int(st.unpack(byteOrd+'i',File.read(4))[0])
101    elif tag == 'MM' and int(st.unpack('>h',File.read(2))[0]) == 42:   #big endian
102        byteOrd = '>'
103        IFD = int(st.unpack(byteOrd+'i',File.read(4))[0])       
104    else:
105        lines = ['not a detector tiff file',]
106        return lines,0,0,0
107    File.seek(IFD)                                                  #get number of directory entries
108    NED = int(st.unpack(byteOrd+'h',File.read(2))[0])
109    IFD = {}
110    nSlice = 1
111    for ied in range(NED):
112        Tag,Type = st.unpack(byteOrd+'Hh',File.read(4))
113        nVal = st.unpack(byteOrd+'i',File.read(4))[0]
114        if DEBUG: print 'Try:',Tag,Type,nVal
115        if Type == 1:
116            Value = st.unpack(byteOrd+nVal*'b',File.read(nVal))
117        elif Type == 2:
118            Value = st.unpack(byteOrd+'i',File.read(4))
119        elif Type == 3:
120            Value = st.unpack(byteOrd+nVal*'h',File.read(nVal*2))
121            x = st.unpack(byteOrd+nVal*'h',File.read(nVal*2))
122        elif Type == 4:
123            if Tag in [273,279]:
124                nSlice = nVal
125                nVal = 1
126            Value = st.unpack(byteOrd+nVal*'i',File.read(nVal*4))
127        elif Type == 5:
128            Value = st.unpack(byteOrd+nVal*'i',File.read(nVal*4))
129        elif Type == 11:
130            Value = st.unpack(byteOrd+nVal*'f',File.read(nVal*4))
131        IFD[Tag] = [Type,nVal,Value]
132        if DEBUG: print Tag,IFD[Tag]
133    sizexy = [IFD[256][2][0],IFD[257][2][0]]
134    [nx,ny] = sizexy
135    Npix = nx*ny
136    if 34710 in IFD:
137        print 'Read MAR CCD tiff file: ',filename
138        marFrame = rmf.marFrame(File,byteOrd,IFD)
139        image = np.flipud(np.array(np.asarray(marFrame.image),dtype=np.int32))
140        tifType = marFrame.filetitle
141        pixy = [marFrame.pixelsizeX/1000.0,marFrame.pixelsizeY/1000.0]
142        head = marFrame.outputHead()
143# extract resonable wavelength from header
144        wavelength = marFrame.sourceWavelength*1e-5
145        wavelength = (marFrame.opticsWavelength > 0) and marFrame.opticsWavelength*1e-5 or wavelength
146        wavelength = (wavelength <= 0) and None or wavelength
147# extract resonable distance from header
148        distance = (marFrame.startXtalToDetector+marFrame.endXtalToDetector)*5e-4
149        distance = (distance <= 0) and marFrame.xtalToDetector*1e-3 or distance
150        distance = (distance <= 0) and None or distance
151# extract resonable center from header
152        center = [marFrame.beamX*marFrame.pixelsizeX*1e-9,marFrame.beamY*marFrame.pixelsizeY*1e-9]
153        center = (center[0] != 0 and center[1] != 0) and center or [None,None]
154#print head,tifType,pixy
155    elif nSlice > 1:    #CheMin multislice tif file!
156        try:
157            import Image as Im
158        except ImportError:
159            try:
160                from PIL import Image as Im
161            except ImportError:
162                print "PIL/pillow Image module not present. This TIF cannot be read without this"
163                #raise Exception("PIL/pillow Image module not found")
164                lines = ['not a detector tiff file',]
165                return lines,0,0,0
166        tifType = 'CheMin'
167        pixy = [40,40]
168        image = np.flipud(np.array(Im.open(filename)))*10.
169        distance = 18.0
170        center = [pixy[0]*sizexy[0]/2000,0]     #the CheMin beam stop is here
171        wavelength = 1.78892
172    elif 272 in IFD:
173        ifd = IFD[272]
174        File.seek(ifd[2][0])
175        S = File.read(ifd[1])
176        if 'PILATUS' in S:
177            tifType = 'Pilatus'
178            dataType = 0
179            pixy = [172,172]
180            File.seek(4096)
181            print 'Read Pilatus tiff file: ',filename
182            image = ar.array('L',File.read(4*Npix))
183            image = np.array(np.asarray(image),dtype=np.int32)
184        else:
185            if IFD[258][2][0] == 16:
186                tifType = 'GE'
187                pixy = [200,200]
188                File.seek(8)
189                print 'Read GE-detector tiff file: ',filename
190                image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
191            elif IFD[258][2][0] == 32:
192                tifType = 'CHESS'
193                pixy = [200,200]
194                File.seek(8)
195                print 'Read CHESS-detector tiff file: ',filename
196                image = np.array(ar.array('L',File.read(4*Npix)),dtype=np.int32)
197    elif 270 in IFD:
198        File.seek(IFD[270][2][0])
199        S = File.read(IFD[273][2][0]-IFD[270][2][0])
200        if 'ImageJ' in S:
201            tifType = 'ImageJ'
202            dataType = 0
203            pixy = [200,200]*IFD[277][2][0]
204            File.seek(IFD[273][2][0])
205            print 'Read ImageJ tiff file: ',filename
206            image = ar.array('H',File.read(2*Npix))
207            if '>' in byteOrd:
208                image.byteswap()
209            image = np.array(np.asarray(image,dtype='H'),dtype=np.int32)           
210    elif 262 in IFD and IFD[262][2][0] > 4:
211        tifType = 'DND'
212        pixy = [158,158]
213        File.seek(512)
214        print 'Read DND SAX/WAX-detector tiff file: ',filename
215        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
216    elif sizexy == [1536,1536]:
217        tifType = 'APS Gold'
218        pixy = [150,150]
219        File.seek(64)
220        print 'Read Gold tiff file:',filename
221        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
222    elif sizexy == [2048,2048] or sizexy == [1024,1024] or sizexy == [3072,3072]:
223        if IFD[273][2][0] == 8:
224            if IFD[258][2][0] == 32:
225                tifType = 'PE'
226                pixy = [200,200]
227                File.seek(8)
228                print 'Read APS PE-detector tiff file: ',filename
229                if dataType == 5:
230                    image = np.array(ar.array('f',File.read(4*Npix)),dtype=np.float32)
231                else:
232                    image = np.array(ar.array('I',File.read(4*Npix)),dtype=np.int32)
233            elif IFD[258][2][0] == 16: 
234                tifType = 'MedOptics D1'
235                pixy = [46.9,46.9]
236                File.seek(8)
237                print 'Read MedOptics D1 tiff file: ',filename
238                image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
239                 
240        elif IFD[273][2][0] == 4096:
241            if sizexy[0] == 3072:
242                pixy =  [73,73]
243                tifType = 'MAR225'           
244            else:
245                pixy = [158,158]
246                tifType = 'MAR325'           
247            File.seek(4096)
248            print 'Read MAR CCD tiff file: ',filename
249            image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
250        elif IFD[273][2][0] == 512:
251            tiftype = '11-ID-C'
252            pixy = [200,200]
253            File.seek(512)
254            print 'Read 11-ID-C tiff file: ',filename
255            image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
256                   
257    elif sizexy == [4096,4096]:
258        if IFD[273][2][0] == 8:
259            if IFD[258][2][0] == 16:
260                tifType = 'scanCCD'
261                pixy = [9,9]
262                File.seek(8)
263                print 'Read APS scanCCD tiff file: ',filename
264                image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
265        elif IFD[273][2][0] == 4096:
266            tifType = 'Rayonix'
267            pixy = [73.242,73.242]
268            File.seek(4096)
269            print 'Read Rayonix MX300HE tiff file: ',filename
270            image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
271#    elif sizexy == [960,960]:
272#        tiftype = 'PE-BE'
273#        pixy = (200,200)
274#        File.seek(8)
275#        if not imageOnly:
276#            print 'Read Gold tiff file:',filename
277#        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
278           
279    if image is None:
280        lines = ['not a known detector tiff file',]
281        return lines,0,0,0
282       
283    if sizexy[1]*sizexy[0] != image.size: # test is resize is allowed
284        lines = ['not a known detector tiff file',]
285        return lines,0,0,0
286       
287    image = np.reshape(image,(sizexy[1],sizexy[0]))
288    center = (not center[0]) and [pixy[0]*sizexy[0]/2000,pixy[1]*sizexy[1]/2000] or center
289    wavelength = (not wavelength) and 0.10 or wavelength
290    distance = (not distance) and 100.0 or distance
291    data = {'pixelSize':pixy,'wavelength':wavelength,'distance':distance,'center':center,'size':sizexy}
292    File.close()   
293    return head,data,Npix,image
Note: See TracBrowser for help on using the repository browser.