Skip to content

Commit a49ccaa

Browse files
author
Joel Bernier
committed
Merge branch 'imageseries'
This will be a new feature version; imageseries module with ReadGE refactor are functioning and tested. Note that the v0.3.x version will be maintain for the near future to use with older input format.
2 parents 51fc37c + 888daa3 commit a49ccaa

38 files changed

+2304
-1835
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ hexrd.egg-info
1010
*.so
1111
*.*~
1212
*#
13+
.#*

conda.recipe/meta.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ source:
99

1010
build:
1111
number: {{ environ.get('GIT_DESCRIBE_NUMBER', 0) }}
12-
detect_binary_files_with_prefix: true
12+
# detect_binary_files_with_prefix: true
1313
osx_is_app: yes
1414
entry_points:
1515
- hexrd = hexrd.cli:main
@@ -25,6 +25,7 @@ requirements:
2525
- python
2626
- setuptools
2727
run:
28+
- h5py
2829
- dill
2930
- matplotlib
3031
# - nomkl # in case MKL is broken on Linux

docs/source/dev/imageseries.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
imageseries package
2+
===============
3+
The *imageseries* package provides a standard API for accessing image-based data sets. The primary tool in the package is the ImageSeries class. It's interface is analagous to a list of images with associated image metadata. The number of images is given by the len() function. Properties are defined for image shape (shape), data type (dtype) and metadata (metadata). Individual images are accessed by standard subscripting (e.g. image[i]).
4+
5+
The package contains interfaces for loading (load) and saving (save) imageseries. Images can be loaded in three formats: 'array', 'hdf5' and 'frame-cache'. The 'array' format takes the images from a 3D numpy array. With 'hdf5', images are stored in hdf5 file and accessed on demand. The 'frame-cache' is a list of sparse matrices, useful for thresholded images. An imageseries can be saved in 'hdf5' or 'frame-cache' format.
6+
7+
The imageseries package also contains a module for modifying the images (process). The process module provides the ProcessedImageSeries class, which takes a given imageseries and produces a new one by modifying the images. It has certain built-in image operations including transposition, flipping, dark subtraction and restriction to a subset.
8+
9+
10+
Metadata
11+
----------------
12+
13+
The metadata property is generically a dictionary. The actual contents depends on the application. For common hexrd applications in which the specimen is rotated while being exposed to x-rays, the metadata has an 'omega' key with an associated value being an nx2 numpy array where n is the number of frames and the two associated values give the omega (rotation) range for that frame.
14+
15+
Reader Refactor
16+
-------------
17+
While the imageseries package is in itself indpendent of hexrd, it was used as the basis of a refactoring of the reader classes originally found in the detector module. The main reader class was ReadGE. In the refactored code, the reader classes are now in their own module, image_io, but imported into detector to preserve the interface. The image_io module contains a generic OmegaImageSeries class for working with imageseries having omega metadata. The refactored ReadGE class simply uses the OmegaImageSeries class to provide the same methods as the old class. New code should use the OmegaImageSeries (or the standard ImageSeries) class directly.

docs/source/dev/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ Contents:
99

1010
getting_started
1111
releases
12+
imageseries

hexrd/cli/findorientations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def execute(args, parser):
9292
)
9393
if os.path.exists(quats_f) and not (args.force or args.clean):
9494
logger.error(
95-
'%s already exists. Change yml file or specify "force"', quats_f
95+
'%s already exists. Change yml file or specify "force" or "clean"', quats_f
9696
)
9797
sys.exit()
9898
if not os.path.exists(cfg.working_dir):

hexrd/config/imageseries.py

Lines changed: 18 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -2,131 +2,48 @@
22
import os
33

44
from .config import Config
5+
from hexrd import imageseries
56

67

8+
class ImageSeriesConfig(Config):
9+
10+
def _open(self):
11+
self._imser = imageseries.open(self.filename, self.format, **self.args)
712

8-
class FileConfig(Config):
13+
def _meta(self):
14+
pass # to be done later
915

1016

1117
@property
12-
def stem(self):
13-
temp = self._cfg.get('image_series:file:stem')
18+
def filename(self):
19+
temp = self._cfg.get('image_series:filename')
1420
if not os.path.isabs(temp):
1521
temp = os.path.join(self._cfg.working_dir, temp)
1622
return temp
1723

18-
19-
@property
20-
def ids(self):
21-
temp = self._cfg.get('image_series:file:ids')
22-
return temp if isinstance(temp, list) else [temp]
23-
24-
25-
26-
class ImagesConfig(Config):
27-
28-
2924
@property
30-
def start(self):
31-
return self._cfg.get('image_series:images:start', default=0)
32-
25+
def format(self):
26+
return self._cfg.get('image_series:format')
3327

3428
@property
35-
def step(self):
36-
return self._cfg.get('image_series:images:step', default=1)
37-
29+
def args(self):
30+
return self._cfg.get('image_series:args')
3831

3932
@property
40-
def stop(self):
41-
return self._cfg.get('image_series:images:stop', default=None)
42-
33+
def omega(self):
34+
return OmegaConfig(self._cfg)
4335

4436

4537
class OmegaConfig(Config):
4638

47-
48-
@property
49-
def start(self):
50-
return self._cfg.get('image_series:omega:start')
51-
52-
5339
@property
5440
def step(self):
5541
return self._cfg.get('image_series:omega:step')
5642

43+
@property
44+
def start(self):
45+
return self._cfg.get('image_series:omega:start')
5746

5847
@property
5948
def stop(self):
6049
return self._cfg.get('image_series:omega:stop')
61-
62-
63-
64-
class ImageSeriesConfig(Config):
65-
66-
67-
@property
68-
def dark(self):
69-
temp = self._cfg.get(
70-
'image_series:dark', default=None
71-
)
72-
if temp is None or os.path.exists(temp):
73-
return temp
74-
raise IOError(
75-
'"image_series:dark": "%s" does not exist' % temp
76-
)
77-
78-
79-
@property
80-
def file(self):
81-
return FileConfig(self._cfg)
82-
83-
84-
@property
85-
def files(self):
86-
stem = self._cfg.image_series.file.stem
87-
res = []
88-
missing = []
89-
for id in self._cfg.image_series.file.ids:
90-
try:
91-
id = stem % id
92-
except TypeError:
93-
# string interpolation failed, join stem and id:
94-
id = stem + id
95-
temp = glob.glob(id)
96-
if temp:
97-
res.extend(temp)
98-
else:
99-
missing.append(id)
100-
if missing:
101-
raise IOError(
102-
'Image files not found: %s' % (', '.join(missing))
103-
)
104-
return res
105-
106-
107-
@property
108-
def flip(self):
109-
temp = self._cfg.get('image_series:flip', default=None)
110-
if temp is None:
111-
return
112-
temp = temp.lower()
113-
if temp not in ['h', 'v', 'hv', 'vh', 'cw90', 'ccw90']:
114-
raise RuntimeError(
115-
'image_series:flip setting "%s" is not valid' % temp
116-
)
117-
return temp
118-
119-
120-
@property
121-
def images(self):
122-
return ImagesConfig(self._cfg)
123-
124-
125-
@property
126-
def omega(self):
127-
return OmegaConfig(self._cfg)
128-
129-
130-
@property
131-
def n_frames(self):
132-
return (self.omega.stop - self.omega.start)/self.omega.step

hexrd/config/root.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def multiprocessing(self):
8282
if multiproc > ncpus:
8383
logger.warning(
8484
'Resuested %s processes, %d available',
85-
multiproc, ncpus, ncpus
85+
multiproc, ncpus
8686
)
8787
res = ncpus
8888
else:

hexrd/config/tests/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
test_data = {
1010
'existing_path': os.path.abspath('..'),
1111
'nonexistent_path': 'an_unlikely_name_for_a_directory',
12-
'existing_file': __file__,
12+
'existing_file': os.path.abspath(__file__),
1313
'nonexistent_file': 'an_unlikely_name_for_a_file.dat',
1414
'file_stem': 'test_%%05d.dat',
1515
'tempdir': tempfile.gettempdir(),

hexrd/config/tests/test_find_orientations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def get_reference_data(cls):
7070
return reference_data
7171

7272

73-
def test_threshold(self):
73+
def test_gvecs(self):
7474
self.assertFalse(
7575
self.cfgs[0].find_orientations.extract_measured_g_vectors
7676
)

0 commit comments

Comments
 (0)