source: trunk/imports/G2img_HDF5.py @ 3360

Last change on this file since 3360 was 3360, checked in by vondreele, 4 years ago

fix HDF5 importer to read CHESS version hdf5 files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 5.8 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2018-04-27 13:59:50 +0000 (Fri, 27 Apr 2018) $
4# $Author: vondreele $
5# $Revision: 3360 $
6# $URL: trunk/imports/G2img_HDF5.py $
7# $Id: G2img_HDF5.py 3360 2018-04-27 13:59:50Z vondreele $
8########### SVN repository information ###################
9'''
10*Module G2img_HDF5: summed HDF5 image file*
11-------------------------------------------
12
13Reads all images found in a HDF5 file.
14
15'''
16
17from __future__ import division, print_function
18try:
19    import h5py
20except ImportError:
21    h5py = None
22import GSASIIobj as G2obj
23import GSASIIpath
24GSASIIpath.SetVersionNumber("$Revision: 3360 $")
25
26class HDF5_Reader(G2obj.ImportImage):
27    '''Routine to read a HD5 image, typically from APS Sector 6.
28    B. Frosik/SDM.
29    '''
30    dsetlist = []
31    buffer = {}
32    init = False
33
34    def __init__(self):
35        if h5py is None:
36            self.UseReader = False
37            print('HDF5 Reader skipped because h5py library is not installed')
38            import os,sys
39            os.path.split(sys.executable)[0]
40            conda = os.path.join(os.path.split(sys.executable)[0],'conda')
41            if os.path.exists(conda):
42                print('To fix this use command:\n\t'+conda+' install h5py hdf5')
43        super(self.__class__,self).__init__( # fancy way to self-reference
44            extensionlist=('.hdf5','.hd5','.h5','.hdf'),strictExtension=True,
45            formatName = 'HDF5 image',longFormatName = 'HDF5 image file')
46
47    def ContentsValidator(self, filename):
48        '''Test if valid by seeing if the HDF5 library recognizes the file.
49        '''
50        try:
51            fp = h5py.File(filename, 'r')
52            fp.close()
53            return True
54        except IOError:
55            return False               
56
57    def Reader(self, filename, ParentFrame=None, **kwarg):
58        '''Scan file structure using :meth:`visit` and map out locations of image(s)
59        then read one image using :meth:`readDataset`. Save map of file structure in
60        buffer arg, if used.
61        '''
62        imagenum = kwarg.get('blocknum')
63        if imagenum is None: imagenum = 1
64        self.buffer = kwarg.get('buffer',{})
65        try:
66            fp = h5py.File(filename, 'r')
67            if not self.buffer.get('init'):
68                self.buffer['init'] = True
69                self.Comments = self.visit(fp)
70                if imagenum > len(self.buffer['imagemap']):
71                    self.errors = 'No valid images found in file'
72                    return False
73               
74            self.Data,self.Npix,self.Image = self.readDataset(fp,imagenum)
75            if self.Npix == 0:
76                self.errors = 'No valid images found in file'
77                return False
78            self.LoadImage(ParentFrame,filename,imagenum)
79            self.repeatcount = imagenum
80            self.repeat = imagenum < len(self.buffer['imagemap'])
81            if GSASIIpath.GetConfigValue('debug'): print('Read image #'+str(imagenum)+' from file '+filename)
82            return True
83        except IOError:
84            print ('cannot open file '+ filename)
85            return False
86        finally:
87            fp.close()
88
89    def visit(self, fp):
90        '''Recursively visit each node in an HDF5 file. For nodes
91        ending in 'data' look at dimensions of contents. If the shape is
92        length 2 or 4 assume an image and index in self.buffer['imagemap']
93        ''' 
94        datakeywords = ['data','images']
95        head = []
96        def func(name, dset):
97            if not hasattr(dset,'shape'): return # not array, can't be image
98            if isinstance(dset, h5py.Dataset):
99                if len(dset.shape) < 2:
100                    head.append('%s: %s'%(dset.name,str(dset[()][0])))
101                for datakeyword in datakeywords:
102                    if dset.name.endswith(datakeyword):
103                        dims = dset.shape
104                        if len(dims) == 4:
105                            self.buffer['imagemap'] += [(dset.name,i) for i in range(dims[1])]
106                        elif len(dims) == 3:
107                            self.buffer['imagemap'] += [(dset.name,i) for i in range(dims[0])]
108                        elif len(dims) == 2:
109                            self.buffer['imagemap'] += [(dset.name,None)]
110                        else:
111                            print('Skipping entry '+str(dset.name)+'. Shape is '+str(dims))
112        self.buffer['imagemap'] = []
113        fp.visititems(func)
114        return head
115       
116    def readDataset(self,fp,imagenum=1):
117        '''Read a specified image number from a file
118        '''
119        name,num = self.buffer['imagemap'][imagenum-1] # look up in map
120        dset = fp[name]
121        if num is None:
122            image = dset[()]
123        elif len(dset.shape) == 4:
124            image = dset[0,num,...]
125        elif len(dset.shape) == 3:
126            image = dset[num,...]
127        else:
128            msg = 'Unexpected image dimensions '+name
129            print(msg)
130            raise Exception(msg)
131        sizexy = list(image.shape) 
132        Npix = sizexy[0]*sizexy[1]
133        data = {'pixelSize':[200.,200.],'wavelength':0.15,'distance':1000.,
134                'center':[sizexy[0]*0.1,sizexy[1]*0.1],'size':sizexy}
135        for item in self.Comments:
136            name,val = item.split(':',1)
137            if 'wavelength' in name and 'spread' not in name:
138                try:
139                    data['wavelength'] = float(val)
140                except ValueError:
141                    pass
142            elif 'distance' in name:
143                data['distance'] = float(val)
144            elif 'x_pixel_size' in name:
145                data['pixelSize'][0] = float(val)*1000.
146            elif 'y_pixel_size' in name:
147                data['pixelSize'][1] = float(val)*1000.
148            elif 'beam_center_x' in name: 
149                data['center'][0] = float(val)
150            elif 'beam_center_y' in name: 
151                data['center'][1] = float(val)               
152        return data,Npix,image.T
Note: See TracBrowser for help on using the repository browser.