source: trunk/imports/G2img_1TIF.py @ 2829

Last change on this file since 2829 was 2829, checked in by vondreele, 6 years ago

update tif reader ti include 4 different versions of LCLS tif images

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 15.7 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2017-05-12 02:46:48 +0000 (Fri, 12 May 2017) $
4# $Author: vondreele $
5# $Revision: 2829 $
6# $URL: trunk/imports/G2img_1TIF.py $
7# $Id: G2img_1TIF.py 2829 2017-05-12 02:46:48Z vondreele $
8########### SVN repository information ###################
9'''
10*Module G2img_1TIF: Tagged-image File images*
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.
15Note that the name ``G2img_1TIF`` is used so that this file will
16sort to the top of the image formats and thus show up first in the menu.
17(It is the most common, alas).
18
19'''
20
21import struct as st
22import GSASIIobj as G2obj
23import GSASIIpath
24import numpy as np
25import time
26DEBUG = False
27GSASIIpath.SetVersionNumber("$Revision: 2829 $")
28class TIF_ReaderClass(G2obj.ImportImage):
29    '''Reads TIF files using a routine (:func:`GetTifData`) that looks
30    for files that can be identified from known instruments and will
31    correct for slightly incorrect TIF usage. If that routine fails,
32    it will be read with a standard TIF reader, which can handle compression
33    and other things less commonly used at beamlines.
34    '''
35    def __init__(self):
36        super(self.__class__,self).__init__( # fancy way to self-reference
37            extensionlist=('.tif','.tiff'),
38            strictExtension=False,
39            formatName = 'TIF image',
40            longFormatName = 'Various .tif and pseudo-TIF formats'
41            )
42
43    def ContentsValidator(self, filepointer):
44        '''Does the header match the required TIF header?
45        '''
46        tag = filepointer.read(2)
47        if tag == 'II' and int(st.unpack('<h',filepointer.read(2))[0]) == 42: #little endian
48            pass
49        elif tag == 'MM' and int(st.unpack('>h',filepointer.read(2))[0]) == 42: #big endian
50            pass
51        else:
52            return False # header not found; not valid TIF
53        return True
54   
55    def Reader(self,filename,filepointer, ParentFrame=None, **unused):
56        '''Read the TIF file using :func:`GetTifData`. If that fails,
57        use :func:`scipy.misc.imread` and give the user a chance to
58        edit the likely wrong default image parameters.
59        '''
60        self.Comments,self.Data,self.Npix,self.Image = GetTifData(filename)
61        if self.Npix == 0:
62            print("GetTifData failed to read "+str(filename)+" Trying SciPy")
63            import scipy.misc
64            self.Image = scipy.misc.imread(filename,flatten=True)
65            self.Npix = self.Image.size
66            if ParentFrame:
67                self.SciPy = True
68                self.Comments = ['no metadata']
69                self.Data = {'wavelength': 0.1, 'pixelSize': [200, 200], 'distance': 100.0}
70                self.Data['size'] = list(self.Image.shape)
71                self.Data['center'] = [int(i/2) for i in self.Image.shape]
72        if self.Npix == 0:
73            return False
74        self.LoadImage(ParentFrame,filename)
75        return True
76
77def GetTifData(filename):
78    '''Read an image in a pseudo-tif format,
79    as produced by a wide variety of software, almost always
80    incorrectly in some way.
81    '''
82    import struct as st
83    import array as ar
84    import ReadMarCCDFrame as rmf
85    image = None
86    File = open(filename,'rb')
87    dataType = 5
88    center = [None,None]
89    wavelength = None
90    distance = None
91    polarization = None
92    try:
93        Meta = open(filename+'.metadata','Ur')
94        head = Meta.readlines()
95        for line in head:
96            line = line.strip()
97            try:
98                if '=' not in line: continue
99                keyword = line.split('=')[0].strip()
100                if 'dataType' == keyword:
101                    dataType = int(line.split('=')[1])
102                elif 'wavelength' == keyword.lower():
103                    wavelength = float(line.split('=')[1])
104                elif 'distance' == keyword.lower():
105                    distance = float(line.split('=')[1])
106                elif 'polarization' == keyword.lower():
107                    polarization = float(line.split('=')[1])
108            except:
109                print('error reading metadata: '+line)
110        Meta.close()
111    except IOError:
112        print 'no metadata file found - will try to read file anyway'
113        head = ['no metadata file found',]
114       
115    tag = File.read(2)
116    byteOrd = '<'
117    if tag == 'II' and int(st.unpack('<h',File.read(2))[0]) == 42:     #little endian
118        IFD = int(st.unpack(byteOrd+'i',File.read(4))[0])
119    elif tag == 'MM' and int(st.unpack('>h',File.read(2))[0]) == 42:   #big endian
120        byteOrd = '>'
121        IFD = int(st.unpack(byteOrd+'i',File.read(4))[0])       
122    else:
123        lines = ['not a detector tiff file',]
124        return lines,0,0,0
125    File.seek(IFD)                                                  #get number of directory entries
126    NED = int(st.unpack(byteOrd+'h',File.read(2))[0])
127    IFD = {}
128    nSlice = 1
129    for ied in range(NED):
130        Tag,Type = st.unpack(byteOrd+'Hh',File.read(4))
131        nVal = st.unpack(byteOrd+'i',File.read(4))[0]
132        if DEBUG: print 'Try:',Tag,Type,nVal
133        if Type == 1:
134            Value = st.unpack(byteOrd+nVal*'b',File.read(nVal))
135        elif Type == 2:
136            Value = st.unpack(byteOrd+'i',File.read(4))
137        elif Type == 3:
138            Value = st.unpack(byteOrd+nVal*'h',File.read(nVal*2))
139            st.unpack(byteOrd+nVal*'h',File.read(nVal*2))
140        elif Type == 4:
141            if Tag in [273,279]:
142                nSlice = nVal
143                nVal = 1
144            Value = st.unpack(byteOrd+nVal*'i',File.read(nVal*4))
145        elif Type == 5:
146            Value = st.unpack(byteOrd+nVal*'i',File.read(nVal*4))
147        elif Type == 11:
148            Value = st.unpack(byteOrd+nVal*'f',File.read(nVal*4))
149        IFD[Tag] = [Type,nVal,Value]
150        if DEBUG: print Tag,IFD[Tag]
151    sizexy = [IFD[256][2][0],IFD[257][2][0]]
152    [nx,ny] = sizexy
153    Npix = nx*ny
154    time0 = time.time()
155    if 34710 in IFD:
156        print 'Read MAR CCD tiff file: ',filename
157        marFrame = rmf.marFrame(File,byteOrd,IFD)
158        image = np.flipud(np.array(np.asarray(marFrame.image),dtype=np.int32))
159        tifType = marFrame.filetitle
160        pixy = [marFrame.pixelsizeX/1000.0,marFrame.pixelsizeY/1000.0]
161        head = marFrame.outputHead()
162# extract resonable wavelength from header
163        wavelength = marFrame.sourceWavelength*1e-5
164        wavelength = (marFrame.opticsWavelength > 0) and marFrame.opticsWavelength*1e-5 or wavelength
165        wavelength = (wavelength <= 0) and None or wavelength
166# extract resonable distance from header
167        distance = (marFrame.startXtalToDetector+marFrame.endXtalToDetector)*5e-4
168        distance = (distance <= marFrame.startXtalToDetector*5e-4) and marFrame.xtalToDetector*1e-3 or distance
169        distance = (distance <= 0) and None or distance
170# extract resonable center from header
171        center = [marFrame.beamX*marFrame.pixelsizeX*1e-9,marFrame.beamY*marFrame.pixelsizeY*1e-9]
172        center = (center[0] != 0 and center[1] != 0) and center or [None,None]
173#print head,tifType,pixy
174    elif nSlice > 1:    #CheMin multislice tif file!
175        try:
176            import Image as Im
177        except ImportError:
178            try:
179                from PIL import Image as Im
180            except ImportError:
181                print "PIL/pillow Image module not present. This TIF cannot be read without this"
182                #raise Exception("PIL/pillow Image module not found")
183                lines = ['not a detector tiff file',]
184                return lines,0,0,0
185        tifType = 'CheMin'
186        pixy = [40,40]
187        image = np.flipud(np.array(Im.open(filename)))*10.
188        distance = 18.0
189        center = [pixy[0]*sizexy[0]/2000,0]     #the CheMin beam stop is here
190        wavelength = 1.78892
191    elif 272 in IFD:
192        ifd = IFD[272]
193        File.seek(ifd[2][0])
194        S = File.read(ifd[1])
195        if 'PILATUS' in S:
196            tifType = 'Pilatus'
197            dataType = 0
198            pixy = [172,172]
199            File.seek(4096)
200            print 'Read Pilatus tiff file: ',filename
201            image = ar.array('I',File.read(4*Npix))
202            image = np.array(np.asarray(image),dtype=np.int32)
203        else:
204            if IFD[258][2][0] == 16:
205                tifType = 'GE'
206                pixy = [200,200]
207                File.seek(8)
208                print 'Read GE-detector tiff file: ',filename
209                image = np.array(np.frombuffer(File.read(2*Npix),dtype=np.uint16),dtype=np.int32)
210#                image = np.fromfile(File,dtype=np.int16,count=2*Npix)[:Npix]
211#                image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
212            elif IFD[258][2][0] == 32:
213                tifType = 'CHESS'
214                pixy = [200,200]
215                File.seek(8)
216                print 'Read CHESS-detector tiff file: ',filename
217                image = np.array(ar.array('I',File.read(4*Npix)),dtype=np.int32)
218    elif 270 in IFD:
219        File.seek(IFD[270][2][0])
220        S = File.read(IFD[273][2][0]-IFD[270][2][0])
221        if 'ImageJ' in S:
222            tifType = 'ImageJ'
223            dataType = 0
224            pixy = [200,200]*IFD[277][2][0]
225            File.seek(IFD[273][2][0])
226            print 'Read ImageJ tiff file: ',filename
227#            image = ar.array('H',File.read(2*Npix))
228#            image = File.read(2*Npix,dtype=np.uint16)
229            image = File.read(4*Npix)
230#            if '>' in byteOrd:
231#                image.byteswap()
232            image = np.array(np.frombuffer(image,dtype=np.int),dtype=np.int32)
233#            image = np.array(np.frombuffer(image),dtype=np.int32)
234#            image = np.array(np.asarray(image,dtype='H'),dtype=np.int32)           
235    elif 262 in IFD and IFD[262][2][0] > 4:
236        tifType = 'DND'
237        pixy = [158,158]
238        File.seek(512)
239        print 'Read DND SAX/WAX-detector tiff file: ',filename
240        image = np.array(np.frombuffer(File.read(2*Npix),dtype=np.uint16),dtype=np.int32)
241#        image = np.fromfile(File,dtype=np.int16,count=2*Npix)[:Npix]
242#        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
243    elif sizexy == [1536,1536]:
244        tifType = 'APS Gold'
245        pixy = [150,150]
246        File.seek(64)
247        print 'Read Gold tiff file:',filename
248        image = np.array(np.frombuffer(File.read(2*Npix),dtype=np.uint16),dtype=np.int32)
249#        image = np.fromfile(File,dtype=np.int16,count=2*Npix)[:Npix]
250#        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
251    elif sizexy == [2048,2048] or sizexy == [1024,1024] or sizexy == [3072,3072]:
252        if IFD[273][2][0] == 8:
253            if IFD[258][2][0] == 32:
254                tifType = 'PE'
255                pixy = [200,200]
256                File.seek(8)
257                print 'Read APS PE-detector tiff file: ',filename
258                if dataType == 5:
259                    image = np.array(np.frombuffer(File.read(4*Npix),dtype=np.float32),dtype=np.int32)  #fastest
260#                    image = np.fromfile(File,dtype=np.float32,count=4*Npix)[:Npix]
261#                    image = np.array(ar.array('f',File.read(4*Npix)),dtype=np.int32)
262                else:
263                    image = np.array(np.frombuffer(File.read(4*Npix),dtype=np.int),dtype=np.int32)
264#                    image = np.fromfile(File,dtype=np.int,count=4*Npix)[:Npix]
265#                    image = np.array(ar.array('I',File.read(4*Npix)),dtype=np.int32)
266            elif IFD[258][2][0] == 16: 
267                tifType = 'MedOptics D1'
268                pixy = [46.9,46.9]
269                File.seek(8)
270                print 'Read MedOptics D1 tiff file: ',filename
271                image = np.array(np.frombuffer(File.read(2*Npix),dtype=np.uint16),dtype=np.int32)
272#                image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
273                 
274        elif IFD[273][2][0] == 4096:
275            if sizexy[0] == 3072:
276                pixy =  [73,73]
277                tifType = 'MAR225'           
278            else:
279                pixy = [158,158]
280                tifType = 'MAR325'           
281            File.seek(4096)
282            print 'Read MAR CCD tiff file: ',filename
283            image = np.array(np.frombuffer(File.read(2*Npix),dtype=np.uint16),dtype=np.int32)
284#            image = np.fromfile(File,dtype=np.int16,count=2*Npix)[:Npix]
285#            image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
286        elif IFD[273][2][0] == 512:
287            tifType = '11-ID-C'
288            pixy = [200,200]
289            File.seek(512)
290            print 'Read 11-ID-C tiff file: ',filename
291            image = np.array(np.frombuffer(File.read(2*Npix),dtype=np.uint16),dtype=np.int32)
292#            image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
293                   
294    elif sizexy == [4096,4096]:
295        if IFD[273][2][0] == 8:
296            if IFD[258][2][0] == 16:
297                tifType = 'scanCCD'
298                pixy = [9,9]
299                File.seek(8)
300                print 'Read APS scanCCD tiff file: ',filename
301                image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
302            elif IFD[258][2][0] == 32:
303                tifType = 'PE4k'
304                pixy = [100,100]
305                File.seek(8)
306                print 'Read PE 4Kx4K tiff file: ',filename
307                image = np.array(np.frombuffer(File.read(4*Npix),dtype=np.float32)/2.**4,dtype=np.int32)
308#                image = np.fromfile(File,dtype=np.uint,count=4*Npix)[:Npix]
309#                if np.max(image) > 2**31:
310#                    image = np.array(image-2**30,dtype=np.int32)
311#                else:
312#                    image = np.array(image,dtype=np.int32)
313#                arry = ar.array('I',File.read(4*Npix))
314#                image = np.array(arry)/2**16           
315        elif IFD[273][2][0] == 4096:
316            tifType = 'Rayonix'
317            pixy = [73.242,73.242]
318            File.seek(4096)
319            print 'Read Rayonix MX300HE tiff file: ',filename
320            image = np.array(np.frombuffer(File.read(2*Npix),dtype=np.uint16),dtype=np.int32)
321#            image = np.fromfile(File,dtype=np.int16,count=2*Npix)[:Npix]
322#            image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
323    elif sizexy == [391,380]:
324        pixy = [109.92,109.92]
325        File.seek(8)
326        image = np.array(np.frombuffer(File.read(2*Npix),dtype=np.int16),dtype=np.int32)
327    elif sizexy == [380,391]:
328        File.seek(110)
329        pixy = [109.92,109.92]
330        image = np.array(np.frombuffer(File.read(Npix),dtype=np.uint8),dtype=np.int32)
331    elif sizexy ==  [825,830]:
332        pixy = [109.92,109.92]
333        File.seek(8)
334        image = np.array(np.frombuffer(File.read(Npix),dtype=np.uint8),dtype=np.int32)
335    elif sizexy ==  [1800,1800]:
336        pixy = [109.92,109.92]
337        File.seek(110)
338        image = np.array(np.frombuffer(File.read(Npix),dtype=np.uint8),dtype=np.int32)
339#    elif sizexy == [960,960]:
340#        tiftype = 'PE-BE'
341#        pixy = (200,200)
342#        File.seek(8)
343#        if not imageOnly:
344#            print 'Read Gold tiff file:',filename
345#        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
346           
347    if image is None:
348        lines = ['not a known detector tiff file',]
349        return lines,0,0,0
350       
351    if sizexy[1]*sizexy[0] != image.size: # test is resize is allowed
352        lines = ['not a known detector tiff file',]
353        return lines,0,0,0
354    print 'image read time: %.3f'%(time.time()-time0)
355    image = np.reshape(image,(sizexy[1],sizexy[0]))
356    center = (not center[0]) and [pixy[0]*sizexy[0]/2000,pixy[1]*sizexy[1]/2000] or center
357    wavelength = (not wavelength) and 0.10 or wavelength
358    distance = (not distance) and 100.0 or distance
359    polarization = (not polarization) and 0.99 or polarization
360    data = {'pixelSize':pixy,'wavelength':wavelength,'distance':distance,'center':center,'size':sizexy,
361            'setdist':distance,'PolaVal':[polarization,False]}
362    File.close()   
363    return head,data,Npix,image
Note: See TracBrowser for help on using the repository browser.