source: trunk/imports/G2img_1TIF.py @ 3018

Last change on this file since 3018 was 3018, checked in by toby, 4 years ago

put user-defined seq ref var labels into table

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