source: trunk/imports/G2img_1TIF.py @ 2086

Last change on this file since 2086 was 2086, checked in by toby, 6 years ago

17-BM autoint fixes and improvements; remove atmdata.dat (not used)

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