From 3327d7d890e4db397452acfcbca717abea382a89 Mon Sep 17 00:00:00 2001 From: Artur Glavic Date: Mon, 24 Aug 2026 11:26:27 +0200 Subject: [PATCH] Add correction of pulse times from packet times if no chopper or monitor triggers exist --- eos/__main__.py | 3 ++- eos/event_handling.py | 2 +- eos/file_reader.py | 18 +++++++++++++++++- eos/options.py | 8 ++++++++ eos/reduction_reflectivity.py | 3 +++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/eos/__main__.py b/eos/__main__.py index c3fff27..5eefbfe 100644 --- a/eos/__main__.py +++ b/eos/__main__.py @@ -8,6 +8,7 @@ Author: Jochen Stahn (algorithms, python draft), import logging # need to do absolute import here as pyinstaller requires it +from eos import __version__ from eos.options import ReflectivityConfig, ReaderConfig, ExperimentConfig, ReflectivityReductionConfig, ReflectivityOutputConfig from eos.command_line import commandLineArgs from eos.logconfig import setup_logging, update_loglevel, setup_logfile @@ -29,7 +30,7 @@ def main(): if output_config.logFile: setup_logfile() - logging.warning('######## eos - data reduction for Amor ########') + logging.warning(f'######## eos ({__version__}) - data reduction for Amor ########') # only import heavy module if sufficient command line parameters were provided from eos.reduction_reflectivity import ReflectivityReduction diff --git a/eos/event_handling.py b/eos/event_handling.py index bcd42c8..76169f4 100644 --- a/eos/event_handling.py +++ b/eos/event_handling.py @@ -184,7 +184,7 @@ class ApplyMask(EventDataAction): # only run this calculation if debug level is actually active filtered_by_mask = {} for key, value in EVENT_BITMASKS.items(): - filtered_by_mask[key] = ((d.events.mask & value)!=0).sum() + filtered_by_mask[key] = int(((d.events.mask & value)!=0).sum()) logging.debug(f" Removed by filters: {filtered_by_mask}") if self.bitmask_filter is None: d.events = d.events[d.events.mask==0] diff --git a/eos/file_reader.py b/eos/file_reader.py index 5871d6a..1678d75 100644 --- a/eos/file_reader.py +++ b/eos/file_reader.py @@ -379,6 +379,7 @@ class AmorEventData(AmorHeader): data: AmorEventStream eventStartTime: np.int64 + correctTimeFallback:bool = True def __init__(self, fileName:Union[str, h5py.File, BinaryIO], first_index:int=0, max_events:int=100_000_000): if type(fileName) is str: @@ -523,8 +524,23 @@ class AmorEventData(AmorHeader): logging.critical(' No chopper trigger data available, using first monitor time!') startTime = np.array(self._beam_monitor.time[0], dtype=np.int64) pulseTimeS = self._beam_monitor.time + elif self.correctTimeFallback: + logging.critical( + ' No chopper trigger data or monitor time available, using event stearm and packet times instead!') + data_group = self.hdf[self.hdf_paths['data'][0]] + startTime = np.array(data_group['event_time_zero'][0], dtype=np.int64) + stopTime = np.array(data_group['event_time_zero'][-1], dtype=np.int64) + pulseTimeS = np.arange(startTime, stopTime, self.timing.tau*1e9, dtype=np.int64) + # find times that are closest to the next packet time and correct them to fit exactly + all_times = np.unique(packets.time) + all_times.sort() + tauhalf = self.timing.tau*5e8 + for ti in all_times: + idx = np.where((pulseTimeS+tauhalf)>=ti)[0][0] + # to keep approximate tau spacing, correct all times after the current packet + pulseTimeS[idx:] -= (pulseTimeS[idx]-ti) else: - logging.critical(' No chopper trigger data available, using event steram instead, pulse filtering will fail!') + logging.critical(' No chopper trigger data or monitor time available, using event steram instead, pulse filtering will fail!') data_group = self.hdf[self.hdf_paths['data'][0]] startTime = np.array(data_group['event_time_zero'][0], dtype=np.int64) stopTime = np.array(data_group['event_time_zero'][-2], dtype=np.int64) diff --git a/eos/options.py b/eos/options.py index 7e9bd46..5a9aebd 100644 --- a/eos/options.py +++ b/eos/options.py @@ -490,6 +490,14 @@ class ReflectivityReductionConfig(ArgParsable): }, ) + correctTimeFallback: bool = field( + default=True, + metadata={ + 'group': 'data manicure', + 'help': 'if falleng back to event stream for pulse time estimation, correct exact values ' + 'to recover filtering options (slower)', + }, + ) class OutputFomatOption(StrEnum): Rqz_ort = "Rqz.ort" diff --git a/eos/reduction_reflectivity.py b/eos/reduction_reflectivity.py index 72c9a2f..484fff8 100644 --- a/eos/reduction_reflectivity.py +++ b/eos/reduction_reflectivity.py @@ -82,6 +82,9 @@ class ReflectivityReduction: self.grid = LZGrid(self.config.reduction.qResolution, self.config.reduction.qzRange) + # transfer option to data reader + AmorEventData.correctTimeFallback = self.config.reduction.correctTimeFallback + def reduce(self): if not os.path.exists(f'{self.config.output.outputPath}'): logging.debug(f'Creating destination path {self.config.output.outputPath}')