Skip to content

Commit

Permalink
refactor: improve perfomance of CHAP.utils.scanparsers.FMBSAXSWAXSSca…
Browse files Browse the repository at this point in the history
…nParser.get_detector_data_file
  • Loading branch information
keara-soloway committed Oct 16, 2023
1 parent 9c3e3f2 commit ec8eec2
Showing 1 changed file with 24 additions and 20 deletions.
44 changes: 24 additions & 20 deletions CHAP/utils/scanparsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
from pyspec.file.spec import FileSpec
from pyspec.file.tiff import TiffFile

@cache
def get_filespec(spec_file_name):
return FileSpec(spec_file_name)

class ScanParser:
"""Partial implementation of a class representing a SPEC scan and
Expand Down Expand Up @@ -62,7 +59,7 @@ def spec_file(self):
# NB This FileSpec instance is not stored as a private
# attribute because it cannot be pickled (and therefore could
# cause problems for parallel code that uses ScanParsers).
return get_filespec(self.spec_file_name)
return FileSpec(self.spec_file_name)

@property
def scan_path(self):
Expand Down Expand Up @@ -582,6 +579,27 @@ def get_detector_data_path(self):
return os.path.join(self.scan_path, self.scan_title)



@cache
def list_fmb_saxswaxs_detector_files(detector_data_path, detector_prefix):
"""Return a sorted list of all data files for the given detector
in the given directory. This function is cached to improve
performace for carrying our full FAMB SAXS/WAXS data-processing
workflows.
:param detector_data_path: directory in which to look for detector
data files
:type detector_data_path: str
:param detector_prefix: detector name to list files for
:type detector_prefix: str
:return: list of detector filenames
:rtype: list[str]
"""
return sorted(
[f for f in os.listdir(detector_data_path)
if detector_prefix in f
and not f.endswith('.log')])

class FMBSAXSWAXSScanParser(FMBLinearScanParser):
"""Concrete implementation of a class representing a scan taken
with the typical SAXS/WAXS setup at FMB.
Expand All @@ -591,20 +609,8 @@ def get_scan_title(self):
return f'{self.scan_name}_{self.scan_number:03d}'

def get_detector_data_file(self, detector_prefix, scan_step_index:int):
scan_step = self.get_scan_step(scan_step_index)
file_indices = [f'{scan_step[i]:03d}'
for i in range(len(self.spec_scan_shape))
if self.spec_scan_shape[i] != 1]
if len(file_indices) == 0:
file_indices = ['000']
file_name = f'{self.scan_name}_{detector_prefix}_' \
f'{self.scan_number:03d}_{"_".join(file_indices)}.tiff'
file_name_full = os.path.join(self.detector_data_path, file_name)
if os.path.isfile(file_name_full):
return file_name_full
raise RuntimeError(f'{self.scan_title}: could not find detector image '
f'file for detector {detector_prefix} scan step '
f'({scan_step})')
detector_files = list_fmb_saxswaxs_detector_files(self.detector_data_path, detector_prefix)
return os.path.join(self.detector_data_path, detector_files[scan_step_index])

def get_detector_data(self, detector_prefix, scan_step_index:int):
image_file = self.get_detector_data_file(detector_prefix,
Expand Down Expand Up @@ -699,8 +705,6 @@ def get_spec_scan_shape(self):
return (mot_npts,)
if self.spec_macro in ('tseries', 'loopscan'):
return len(np.array(self.spec_scan.data[:,0]))
if self.spec_macro == 'wbsync_ct':
return (1,)
raise RuntimeError(f'{self.scan_title}: cannot determine scan shape '
f'for scans of type {self.spec_macro}')

Expand Down

0 comments on commit ec8eec2

Please sign in to comment.