source: trunk/imports/G2img_1TIF.py @ 2299

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

fix typo in GetTifData?

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 12.5 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2016-05-27 22:38:04 +0000 (Fri, 27 May 2016) $
4# $Author: vondreele $
5# $Revision: 2299 $
6# $URL: trunk/imports/G2img_1TIF.py $
7# $Id: G2img_1TIF.py 2299 2016-05-27 22:38:04Z 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 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: 2299 $")
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            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            except:
108                print('error reading metadata: '+line)
109        Meta.close()
110    except IOError:
111        print 'no metadata file found - will try to read file anyway'
112        head = ['no metadata file found',]
113       
114    tag = File.read(2)
115    byteOrd = '<'
116    if tag == 'II' and int(st.unpack('<h',File.read(2))[0]) == 42:     #little endian
117        IFD = int(st.unpack(byteOrd+'i',File.read(4))[0])
118    elif tag == 'MM' and int(st.unpack('>h',File.read(2))[0]) == 42:   #big endian
119        byteOrd = '>'
120        IFD = int(st.unpack(byteOrd+'i',File.read(4))[0])       
121    else:
122        lines = ['not a detector tiff file',]
123        return lines,0,0,0
124    File.seek(IFD)                                                  #get number of directory entries
125    NED = int(st.unpack(byteOrd+'h',File.read(2))[0])
126    IFD = {}
127    nSlice = 1
128    for ied in range(NED):
129        Tag,Type = st.unpack(byteOrd+'Hh',File.read(4))
130        nVal = st.unpack(byteOrd+'i',File.read(4))[0]
131        if DEBUG: print 'Try:',Tag,Type,nVal
132        if Type == 1:
133            Value = st.unpack(byteOrd+nVal*'b',File.read(nVal))
134        elif Type == 2:
135            Value = st.unpack(byteOrd+'i',File.read(4))
136        elif Type == 3:
137            Value = st.unpack(byteOrd+nVal*'h',File.read(nVal*2))
138            x = st.unpack(byteOrd+nVal*'h',File.read(nVal*2))
139        elif Type == 4:
140            if Tag in [273,279]:
141                nSlice = nVal
142                nVal = 1
143            Value = st.unpack(byteOrd+nVal*'i',File.read(nVal*4))
144        elif Type == 5:
145            Value = st.unpack(byteOrd+nVal*'i',File.read(nVal*4))
146        elif Type == 11:
147            Value = st.unpack(byteOrd+nVal*'f',File.read(nVal*4))
148        IFD[Tag] = [Type,nVal,Value]
149        if DEBUG: print Tag,IFD[Tag]
150    sizexy = [IFD[256][2][0],IFD[257][2][0]]
151    [nx,ny] = sizexy
152    Npix = nx*ny
153    if 34710 in IFD:
154        print 'Read MAR CCD tiff file: ',filename
155        marFrame = rmf.marFrame(File,byteOrd,IFD)
156        image = np.flipud(np.array(np.asarray(marFrame.image),dtype=np.int32))
157        tifType = marFrame.filetitle
158        pixy = [marFrame.pixelsizeX/1000.0,marFrame.pixelsizeY/1000.0]
159        head = marFrame.outputHead()
160# extract resonable wavelength from header
161        wavelength = marFrame.sourceWavelength*1e-5
162        wavelength = (marFrame.opticsWavelength > 0) and marFrame.opticsWavelength*1e-5 or wavelength
163        wavelength = (wavelength <= 0) and None or wavelength
164# extract resonable distance from header
165        distance = (marFrame.startXtalToDetector+marFrame.endXtalToDetector)*5e-4
166        distance = (distance <= 0) and marFrame.xtalToDetector*1e-3 or distance
167        distance = (distance <= 0) and None or distance
168# extract resonable center from header
169        center = [marFrame.beamX*marFrame.pixelsizeX*1e-9,marFrame.beamY*marFrame.pixelsizeY*1e-9]
170        center = (center[0] != 0 and center[1] != 0) and center or [None,None]
171#print head,tifType,pixy
172    elif nSlice > 1:    #CheMin multislice tif file!
173        try:
174            import Image as Im
175        except ImportError:
176            try:
177                from PIL import Image as Im
178            except ImportError:
179                print "PIL/pillow Image module not present. This TIF cannot be read without this"
180                #raise Exception("PIL/pillow Image module not found")
181                lines = ['not a detector tiff file',]
182                return lines,0,0,0
183        tifType = 'CheMin'
184        pixy = [40,40]
185        image = np.flipud(np.array(Im.open(filename)))*10.
186        distance = 18.0
187        center = [pixy[0]*sizexy[0]/2000,0]     #the CheMin beam stop is here
188        wavelength = 1.78892
189    elif 272 in IFD:
190        ifd = IFD[272]
191        File.seek(ifd[2][0])
192        S = File.read(ifd[1])
193        if 'PILATUS' in S:
194            tifType = 'Pilatus'
195            dataType = 0
196            pixy = [172,172]
197            File.seek(4096)
198            print 'Read Pilatus tiff file: ',filename
199            image = ar.array('L',File.read(4*Npix))
200            image = np.array(np.asarray(image),dtype=np.int32)
201        else:
202            if IFD[258][2][0] == 16:
203                tifType = 'GE'
204                pixy = [200,200]
205                File.seek(8)
206                print 'Read GE-detector tiff file: ',filename
207                image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
208            elif IFD[258][2][0] == 32:
209                tifType = 'CHESS'
210                pixy = [200,200]
211                File.seek(8)
212                print 'Read CHESS-detector tiff file: ',filename
213                image = np.array(ar.array('L',File.read(4*Npix)),dtype=np.int32)
214    elif 270 in IFD:
215        File.seek(IFD[270][2][0])
216        S = File.read(IFD[273][2][0]-IFD[270][2][0])
217        if 'ImageJ' in S:
218            tifType = 'ImageJ'
219            dataType = 0
220            pixy = [200,200]*IFD[277][2][0]
221            File.seek(IFD[273][2][0])
222            print 'Read ImageJ tiff file: ',filename
223            image = ar.array('H',File.read(2*Npix))
224            if '>' in byteOrd:
225                image.byteswap()
226            image = np.array(np.asarray(image,dtype='H'),dtype=np.int32)           
227    elif 262 in IFD and IFD[262][2][0] > 4:
228        tifType = 'DND'
229        pixy = [158,158]
230        File.seek(512)
231        print 'Read DND SAX/WAX-detector tiff file: ',filename
232        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
233    elif sizexy == [1536,1536]:
234        tifType = 'APS Gold'
235        pixy = [150,150]
236        File.seek(64)
237        print 'Read Gold tiff file:',filename
238        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
239    elif sizexy == [2048,2048] or sizexy == [1024,1024] or sizexy == [3072,3072]:
240        if IFD[273][2][0] == 8:
241            if IFD[258][2][0] == 32:
242                tifType = 'PE'
243                pixy = [200,200]
244                File.seek(8)
245                print 'Read APS PE-detector tiff file: ',filename
246                if dataType == 5:
247                    image = np.array(ar.array('f',File.read(4*Npix)),dtype=np.int32)
248                else:
249                    image = np.array(ar.array('I',File.read(4*Npix)),dtype=np.int32)
250            elif IFD[258][2][0] == 16: 
251                tifType = 'MedOptics D1'
252                pixy = [46.9,46.9]
253                File.seek(8)
254                print 'Read MedOptics D1 tiff file: ',filename
255                image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
256                 
257        elif IFD[273][2][0] == 4096:
258            if sizexy[0] == 3072:
259                pixy =  [73,73]
260                tifType = 'MAR225'           
261            else:
262                pixy = [158,158]
263                tifType = 'MAR325'           
264            File.seek(4096)
265            print 'Read MAR CCD tiff file: ',filename
266            image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
267        elif IFD[273][2][0] == 512:
268            tiftype = '11-ID-C'
269            pixy = [200,200]
270            File.seek(512)
271            print 'Read 11-ID-C tiff file: ',filename
272            image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
273                   
274    elif sizexy == [4096,4096]:
275        if IFD[273][2][0] == 8:
276            if IFD[258][2][0] == 16:
277                tifType = 'scanCCD'
278                pixy = [9,9]
279                File.seek(8)
280                print 'Read APS scanCCD tiff file: ',filename
281                image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
282        elif IFD[273][2][0] == 4096:
283            tifType = 'Rayonix'
284            pixy = [73.242,73.242]
285            File.seek(4096)
286            print 'Read Rayonix MX300HE tiff file: ',filename
287            image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
288#    elif sizexy == [960,960]:
289#        tiftype = 'PE-BE'
290#        pixy = (200,200)
291#        File.seek(8)
292#        if not imageOnly:
293#            print 'Read Gold tiff file:',filename
294#        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
295           
296    if image is None:
297        lines = ['not a known detector tiff file',]
298        return lines,0,0,0
299       
300    if sizexy[1]*sizexy[0] != image.size: # test is resize is allowed
301        lines = ['not a known detector tiff file',]
302        return lines,0,0,0
303       
304    image = np.reshape(image,(sizexy[1],sizexy[0]))
305    center = (not center[0]) and [pixy[0]*sizexy[0]/2000,pixy[1]*sizexy[1]/2000] or center
306    wavelength = (not wavelength) and 0.10 or wavelength
307    distance = (not distance) and 100.0 or distance
308    data = {'pixelSize':pixy,'wavelength':wavelength,'distance':distance,'center':center,'size':sizexy}
309    File.close()   
310    return head,data,Npix,image
Note: See TracBrowser for help on using the repository browser.