Skip to content

Commit ab7edd1

Browse files
author
Peter Ercius ncem-gauss jupyter
committed
Add dectris reader
1 parent 6d0b5b2 commit ab7edd1

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

ncempy/io/dectris.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
"""
2+
This module provides an interface to Dectris Arina data sets
3+
"""
4+
5+
class fileDECTRIS:
6+
""" Class to represent Dectris Arina data sets
7+
8+
Attributes
9+
----------
10+
raw_shape : list
11+
The shape of the raw data. This is three-dimensional: [num_frames, frameY, frameX].
12+
data_shape : list
13+
The four-dimensional shape of the dataset. It is always assumed that the
14+
num_frames**0.5 = num_frames (i.e. region of interest is square).
15+
file_hdl : h5py.File
16+
The h5py file handle which provides direct access to the underlying hdf5 file structure.
17+
data_type : numpy.dtype
18+
The data type of the values in the data set.
19+
"""
20+
def __init__(self, filename, verbose=False):
21+
""" Initialize a data set by opening the master file and determining the file size
22+
23+
Parameters
24+
----------
25+
filename : str or pathlib.Path or file object
26+
The HDF5 master file to open.
27+
verbose : bool, default False
28+
If True, prints out debugging information
29+
"""
30+
31+
self._verbose = verbose
32+
self.raw_shape = [0, 0, 0] # shape of data on disk
33+
self.data_shape = [0, 0, 0, 0] # the shape of the final 4D dataset
34+
self.file_hdl = None
35+
self.data_dtype = None
36+
37+
# Pixels to remove automatically
38+
self.bad_pixels = ((49, 75), (93,118), (95,119), (108, 57))
39+
self.bad_pixel_value = None
40+
41+
if hasattr(filename, 'read'):
42+
try:
43+
self.file_path = Path(filename.name)
44+
self.file_name = self.file_path.name
45+
except AttributeError:
46+
self.file_path = None
47+
self.file_name = None
48+
else:
49+
# check filename type, change to pathlib.Path
50+
if isinstance(filename, str):
51+
filename = Path(filename)
52+
elif isinstance(filename, Path):
53+
pass
54+
else:
55+
raise TypeError('Filename is supposed to be a string or pathlib.Path or file object')
56+
self.file_path = filename
57+
self.file_name = self.file_path.name
58+
59+
# Try opening the file
60+
try:
61+
self.file_hdl = h5py.File(filename, 'r')
62+
assert self.file_hdl['/entry/data']
63+
except:
64+
print('Error opening file: "{}"'.format(filename))
65+
raise
66+
67+
# if this is a HDF5 file
68+
if self.file_hdl:
69+
# Find the initial shape of the data set
70+
for v in self.file_hdl['/entry/data'].values():
71+
self.raw_shape[0] = self.raw_shape[0] + v.shape[0]
72+
self.raw_shape[1] = v.shape[1]
73+
self.raw_shape[2] = v.shape[2]
74+
self.data_dtype = v.dtype
75+
76+
def __del__(self):
77+
""" Destructor for EMD file object.
78+
79+
"""
80+
# close the file
81+
# if(not self.file_hdl.closed):
82+
self.file_hdl.close()
83+
84+
def __enter__(self):
85+
"""Implement python's with statement for context managers.
86+
87+
"""
88+
return self
89+
90+
def __exit__(self, exception_type, exception_value, traceback):
91+
"""Implement python's with statement fr context managers.
92+
and close the file via __del__()
93+
"""
94+
self.__del__()
95+
return None
96+
97+
def get_dataset(self, remove_bad_pixels=False):
98+
""" Read the data from the HDF5 files
99+
100+
Parameters
101+
----------
102+
remove_bad_pixels : bool, default False
103+
If True, remove_bad_pixels function is called after the data is loaded.
104+
105+
"""
106+
# Pre allocate space
107+
data = np.zeros(self.raw_shape, dtype=self.data_dtype)
108+
# Read in the data in all linked files
109+
ii = 0
110+
for v in self.file_hdl['/entry/data'].values():
111+
data[ii:ii+v.shape[0]] = v[:]
112+
ii += v.shape[0]
113+
114+
# Reshape assuming square
115+
shape_square = int((data.shape[0])**0.5)
116+
assert data.shape[0] == shape_square**2
117+
self.data_shape = (shape_square, shape_square,
118+
data.shape[1], data.shape[2])
119+
data = data.reshape(data_shape)
120+
if remove_bad_pixels:
121+
self.remove_bad_pixels()
122+
return data
123+
124+
def remove_bad_pixels(self, data, value=0, bad_pixels=None):
125+
""" Some pixels are known to be very high or very low. This function will replace the
126+
pixel values.
127+
128+
Parameters
129+
----------
130+
data : numpy.ndarray
131+
The 4D-STEM data set
132+
value : int or float
133+
The value to replace the bad pixels by.
134+
bad_pixels : numpy.ndarray
135+
A m by 2 ndarray where m is the number of bad pixels and the locations
136+
are specified in order for frame axis 2 and 3.
137+
138+
"""
139+
if bad_pixels:
140+
self.bad_pixels = bad_pixels
141+
for bad in self.bad_pixels:
142+
data[:, :, bad[0], bad[1]] = value

0 commit comments

Comments
 (0)