Skip to content

Commit

Permalink
developer/API docs for imageseries
Browse files Browse the repository at this point in the history
  • Loading branch information
donald e. boyce committed Mar 5, 2024
1 parent 0c2a6f6 commit d188c2b
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 102 deletions.
28 changes: 26 additions & 2 deletions docs/source/dev/imageseries-load-options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ subtraction and flipping.
**On Write.**

``path``
(required) path to directory containing data group (data set is named
`images`
(required) path to directory containing data group

``dataname``
name of data set, default = "images"

``shuffle``
(default=True) HDF5 write option
Expand All @@ -34,6 +36,11 @@ subtraction and flipping.
(required) path to directory containing data group (data set is named
`images`)

``dataname``
name of data set, default = "images"; note that there is no actual
write option for this.


Frame Cache
++++++++++++++++++++
The format name is ``frame-cache``.
Expand Down Expand Up @@ -154,3 +161,20 @@ Here is an example that describes the GE format:
bytes: 2
signed: false
endian: little
Array
++++++

This loads a 3D numpy array and treats it as an imageseries.

**On Write.**

There is no writer for this format.

**On Open.**

``data``
The 3-dimensional numpy array data.
``metadata``
The metadata dictionary.
5 changes: 3 additions & 2 deletions docs/source/dev/imageseries-overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ format. Possible formats currently are:
``raw-image``
This is for nonstandard or less common image formats that do not load with
`fabio <https://pypi.org/project/fabio/>`. In that case, you can define
your own data format.
your own data format. This ``file`` argument is a YAML file.

``array``
images are stored as a 3D numpy array; used for testing.
images are stored as a 3D numpy array; used for testing. It takes no
``file`` argument, use ``None``.

See also :ref:`keyword-options`.

Expand Down
28 changes: 12 additions & 16 deletions hexrd/imageseries/load/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@


class ArrayImageSeriesAdapter(ImageSeriesAdapter):
"""collection of images in numpy array"""

"""Collection of Images in numpy array
Parameters
----------
fname: None
should be None
data: array (n, m, l)
3-dimensional data array
metadata: dict (optional)
the metadata dictionary
"""
format = 'array'

def __init__(self, fname, **kwargs):
"""Constructor for frame cache image series
*fname* - should be None
*kwargs* - keyword arguments
. 'data' = a 3D array (double/float)
. 'metadata' = a dictionary
"""
data_arr = np.array(kwargs['data'])
if data_arr.ndim < 3:
self._data = np.tile(data_arr, (1, 1, 1))
Expand All @@ -37,10 +39,7 @@ def __init__(self, fname, **kwargs):

@property
def metadata(self):
"""(read-only) Image sequence metadata
Currently returns none
"""
"""Image sequence metadata"""
return self._meta

@property
Expand All @@ -57,8 +56,5 @@ def __getitem__(self, key):
def __iter__(self):
return ImageSeriesIterator(self)

# @memoize
def __len__(self):
return self._nframes

pass # end class
38 changes: 13 additions & 25 deletions hexrd/imageseries/load/hdf5.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,23 @@


class HDF5ImageSeriesAdapter(ImageSeriesAdapter):
"""collection of images in HDF5 format"""
"""Collection of Images in HDF5 Format
Parameters
----------
fname : str or h5py.File object
filename of the HDF5 file, or an open h5py file. Note that this
class will close the h5py.File when finished.
path : str, required
The path to the HDF dataset containing the image data
dataname : str, optional
The name of the HDF dataset containing the 2-d or 3d image data.
The default values is 'images'.
"""

format = 'hdf5'

def __init__(self, fname, **kwargs):
"""
Constructor for HDF% ImageSeries
Parameters
----------
fname : str or h5py.File object
filename of the HDF5 file, or an open h5py file. Note that this
class will close the h5py.File when finished.
**kwargs : Keyword arguments
See below.
Keyword Arguments
-----------------
path : str, required
The path to the HDF dataset containing the image data
dataname : str, optional
The name of the HDF dataset containing the 2-d or 3d image data.
The default values is 'images'.
Returns
-------
None.
"""
if isinstance(fname, h5py.File):
self.__h5name = fname.filename
self.__h5file = fname
Expand Down
1 change: 0 additions & 1 deletion hexrd/imageseries/omega.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ def omegarange_to_frames(self, omin, omax):
class OmegaWedges(object):
"""piecewise linear omega ranges"""
def __init__(self, nframes):
"""Constructor for OmegaWedge"""
self.nframes = nframes
self._wedges = []
#
Expand Down
23 changes: 12 additions & 11 deletions hexrd/imageseries/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,26 @@


class ProcessedImageSeries(ImageSeries):
"""Images series with mapping applied to frames"""
"""imsageseries based on existing one with image processing options
Parameters
----------
imser: ImageSeries
an existing imageseries
oplist: list
list of processing operations; each option is a (key, data) pair,
with key specifying the operation to perform using specified data
frame_list: list of ints or None, default = None
specify subset of frames by list; if None, then all frames are used
"""
FLIP = 'flip'
DARK = 'dark'
RECT = 'rectangle'
ADD = 'add'
GAUSS_LAPLACE = 'gauss_laplace'

def __init__(self, imser, oplist, **kwargs):
"""imsageseries based on existing one with image processing options

*imser* - an existing imageseries
*oplist* - list of processing operations;
a list of pairs (key, data) pairs, with key specifying the
operation to perform using specified data
*keyword args*
'frame_list' - specify subset of frames by list
"""
self._imser = imser
self._meta = copy.deepcopy(imser.metadata)
self._oplist = oplist
Expand Down
97 changes: 60 additions & 37 deletions hexrd/imageseries/save.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@
def write(ims, fname, fmt, **kwargs):
"""write imageseries to file with options
*ims* - an imageseries
*fname* - name of file or an h5py file for writing HDF5
*fmt* - a format string
*kwargs* - options specific to format
Parameters
----------
ims: Imageseries
the imageseries to write
fname: str
the name of the HDF5 file to write
fmt: str
format name of the imageseries
kwargs: dict
options specific to format
"""
wcls = _Registry.getwriter(fmt)
w = wcls(ims, fname, **kwargs)
Expand Down Expand Up @@ -61,7 +67,17 @@ def getwriter(cls, name):


class Writer(object, metaclass=_RegisterWriter):
"""Base class for writers"""
"""Base class for writers
Parameters
----------
ims: Imageseries
the imageseries to write
fname: str
the name of the HDF5 file to write
kwargs: dict
options specific to format
"""
fmt = None

def __init__(self, ims, fname, **kwargs):
Expand Down Expand Up @@ -98,21 +114,29 @@ def opts(self):
return self._opts

class WriteH5(Writer):
"""Write imageseries in HDF5 file
Parameters
----------
ims: Imageseries
the imageseries to write
fname: str
the name of the HDF5 file to write
path: str, required
the path in HDF5 file
gzip: int 0-9
0 turns off compression, default=1
chunk_rows: int
number of rows per chunk; default is all
shuffle: bool
shuffle HDF5 data
"""
fmt = 'hdf5'
dflt_gzip = 1
dflt_chrows = 0
dflt_shuffle = True

def __init__(self, ims, fname, **kwargs):
"""Write imageseries in HDF5 file
Required Args:
path - the path in HDF5 file
Options:
gzip - 0-9; 0 turns off compression; 4 is default
chunk_rows - number of rows per chunk; default is all
"""
Writer.__init__(self, ims, fname, **kwargs)
self._path = self._opts['path']

Expand Down Expand Up @@ -173,32 +197,31 @@ def h5opts(self):


class WriteFrameCache(Writer):
"""info from yml file"""
"""write frame cache imageseries
The default write option is to save image data and metadata all
in a single npz file. The original option was to have a YAML file
as the primary file and a specified cache file for the images; this
method is deprecated.
Parameters
----------
ims: Imageseries instance
the imageseries to write
fname: str or Path
name of file to write;
threshold: float
threshold value for image, at or below which values are zeroed
cache_file: str or Path, optional
name of the npz file to save the image data, if not given in the
`fname` argument; for YAML format (deprecated), this is required
max_workers: int, optional
The max number of worker threads for multithreading. Defaults to
the number of CPUs.
"""
fmt = 'frame-cache'

def __init__(self, ims, fname, **kwargs):
"""write yml file with frame cache info
The default write option is to save image data and metadata all
in a single npz file. The original option was to have a YAML file
as the primary file and a specified cache file for the images; this
method is deprecated.
Parameters
----------
ims: Imageseries instance
the imageseries to write
fname: str or Path
name of file to write;
threshold: float
threshold value for image, at or below which values are zeroed
cache_file: str or Path, optional
name of the npz file to save the image data, if not given in the
`fname` argument; for YAML format (deprecated), this is required
max_workers: int, optional
The max number of worker threads for multithreading. Defaults to
the number of CPUs.
"""
Writer.__init__(self, ims, fname, **kwargs)
self._thresh = self._opts['threshold']
self._cache, self.cachename = self._set_cache()
Expand Down
19 changes: 11 additions & 8 deletions hexrd/imageseries/stats.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""aggregate statistics for imageseries
"""Aggregate Statistics for Imageseries
The functions here operate on the frames of an imageseries and return a
single aggregate image. For each function, there is a corresponding iterable
Expand All @@ -8,15 +8,18 @@
For example:
# Using the standard function call
img = stats.average(ims)
.. code-block:: python
# Using the iterable with 10 chunks
for img in stats.average_iter(ims, 10):
# update progress bar
pass
# Using the standard function call
img = stats.average(ims)
NOTE:
# Using the iterable with 10 chunks
for img in stats.average_iter(ims, 10):
# update progress bar
pass
NOTES
-----
* Perhaps we should rename min -> minimum and max -> maximum to avoid
conflicting with the python built-ins
"""
Expand Down

0 comments on commit d188c2b

Please sign in to comment.