source: trunk/imports/G2img_1TIF.py @ 2687

Last change on this file since 2687 was 2687, checked in by vondreele, 5 years ago

problem if ESD=0 in EvalPSvarDeriv; just return 0.
add 'setdist' to Image controls; shows up in main image data window
add 'setdist' to tiff image importer; not in others as it isn't known
'setdist' is added to variables, etc. in seq image calib, suitable for plotting.

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