From 4491d5b02d6c547055bfff527174432c380808ee Mon Sep 17 00:00:00 2001 From: "donald e. boyce" Date: Wed, 24 Jan 2024 10:14:41 -0500 Subject: [PATCH] cleans up rawimage _get_length() and __get_item__() functions --- hexrd/imageseries/load/rawimage.py | 63 ++++++++++++------------------ 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/hexrd/imageseries/load/rawimage.py b/hexrd/imageseries/load/rawimage.py index ca3d45c90..4c21b5fe4 100644 --- a/hexrd/imageseries/load/rawimage.py +++ b/hexrd/imageseries/load/rawimage.py @@ -1,6 +1,5 @@ -""" Adapter class for raw image reader -""" -import warnings +""" Adapter class for raw image reader""" +import os import numpy as np import yaml @@ -17,8 +16,10 @@ class RawImageSeriesAdapter(ImageSeriesAdapter): def __init__(self, fname, **kwargs): """Image data in custom format - *fname* - filename of the data file - *kwargs* - keyword arguments (none required) + Parameters + ---------- + fname: string or Path + name of input YAML file describing the format """ self.fname = fname with open(fname, "r") as f: @@ -27,14 +28,15 @@ def __init__(self, fname, **kwargs): self.fname = y['filename'] self.dtype = self._get_dtype(y['scalar']) self._shape = tuple((int(si) for si in y['shape'].split())) - self.framesize = self._shape[0]*self._shape[1] + self._frame_size = self._shape[0] * self._shape[1] + self._frame_bytes = self._frame_size * self.dtype.itemsize self.skipbytes = y['skip'] self._len = self._get_length() self._meta = dict() self.kwargs = kwargs - # Prepare to read - self.iframe = -1 + # Open file for reading. + self.f = open(self.fname, "r") def _get_dtype(self, scalar): numtype = scalar['type'] @@ -51,19 +53,18 @@ def _get_dtype(self, scalar): def _get_length(self): """Read file and determine length""" - iframe = 0 - with open(self.fname, "r") as f: - _ = np.fromfile(f, np.byte, count=self.skipbytes) - # now keep reading frames until EOF - moreframes = True - while moreframes: - _ = np.fromfile(f, self.dtype, count=self.framesize) - if len(_) == self.framesize: - iframe += 1 - else: - moreframes = False - - return iframe + nbytes = os.path.getsize(self.fname) + if nbytes % self._frame_bytes == self.skipbytes: + nframes = (nbytes - self.skipbytes) // self._frame_bytes + else: + msg = ( + f"Total number of bytes ({nbytes}) does not work with " + f"skipbytes ({self.skipbytes}) and " + f"_frame_size ({self._frame_size}). Check the skipbytes value." + ) + raise ValueError(msg) + + return nframes @staticmethod def typechars(numtype, bytes_=4, signed=False, little=True): @@ -103,23 +104,9 @@ def __iter__(self): return ImageSeriesIterator(self) def __getitem__(self, key): - if self.iframe < 0: - self.f = open(self.fname, "r") - _ = np.fromfile(self.f, np.byte, count=self.skipbytes) - self.iframe = 0 - if key == 0: - self.f.seek(0, 0) - _ = np.fromfile(self.f, np.byte, count=self.skipbytes) #dcp fix to make sure bytes are properly skipped - self.iframe = 0 - if key != self.iframe: - msg = "frame %d not available, series must be read in sequence!" - raise ValueError(msg % key) - frame = np.fromfile(self.f, self.dtype, count=self.framesize) - self.iframe += 1 - if self.iframe == len(self): - self.iframe = -1 - self.f.close() - + count = key * self._frame_bytes + self.skipbytes + self.f.seek(count, 0) + frame = np.fromfile(self.f, self.dtype, count=self._frame_size) return frame.reshape(self.shape) @property