From f07a06370f557d30d01b8d5c9c6517f569c579fb Mon Sep 17 00:00:00 2001 From: Artur Glavic Date: Thu, 26 Feb 2026 10:15:25 +0100 Subject: [PATCH] React to both yz and toz stop commands --- eos/event_analysis.py | 56 +++++++++++++++++++++++++++++++++++ eos/event_handling.py | 2 ++ eos/options.py | 9 ++++++ eos/reduction_reflectivity.py | 2 ++ 4 files changed, 69 insertions(+) diff --git a/eos/event_analysis.py b/eos/event_analysis.py index e80ed64..0552572 100644 --- a/eos/event_analysis.py +++ b/eos/event_analysis.py @@ -125,3 +125,59 @@ class FilterQzRange(EventDataAction): raise ValueError("FilterQzRange requires dataset with qz values per events, perform WavelengthAndQ first") d.events.mask += EVENT_BITMASKS["qRange"]*((self.qzRange[0]>d.events.qz) | (d.events.qz>self.qzRange[1])) + + +class FilterByLog(EventDataAction): + + def __init__(self, filter_string): + self.filter_string = filter_string + + def perform_action(self, dataset: EventDatasetProtocol) -> None: + filter_variable = None + # go through existing keys in reverse order of their length to insure a name containing another is used + existing_keys = list(dataset.data.device_logs.keys()) + existing_keys.sort(key=lambda x: -len(x)) + for key in existing_keys: + if key in self.filter_string: + filter_variable = key + break + if filter_variable is None: + logging.warning(f' could not find suitable parameter to filter on in {self.filter_string}, ' + f'available parameters are: {list(sorted(existing_keys))}') + return + logging.debug(f' using parameter {filter_variable} to apply filter {self.filter_string}') + if not filter_variable in EVENT_BITMASKS: + EVENT_BITMASKS[filter_variable] = max(EVENT_BITMASKS.values())*2 + if not filter_variable in dataset.data.pulses.dtype.names: + # interpolate the parameter values for all existing pulses + self.add_log_to_pulses(filter_variable, dataset) + fltr_pulses = eval(self.filter_string, {filter_variable: dataset.data.pulses[filter_variable]}) + goodTimeS = dataset.data.pulses.time[fltr_pulses] + filter_e = np.logical_not(np.isin(dataset.data.events.wallTime, goodTimeS)) + dataset.data.events.mask += EVENT_BITMASKS[filter_variable]*filter_e + + + def add_log_to_pulses(self, key, dataset: EventDatasetProtocol): + """ + Add a log value for each pulse to the pulses array. + """ + # TODO: perform some interpolation for the pulse where a change occured + pulses = dataset.data.pulses + log_data = dataset.data.device_logs[key] + if log_data.time[0]>0: + logTimeS = np.hstack([[0], log_data.time, [pulses.time[-1]+1]]) + logValues = np.hstack([[log_data.value[0]], log_data.value]) + else: + logTimeS = np.hstack([log_data.time, [pulses.time[-1]+1]]) + logValues = log_data.value + pulseLogS = np.zeros(pulses.time.shape[0], dtype=log_data.value.dtype) + j = 0 + for i, ti in enumerate(pulses.time): + # find the last current item that was before this pulse + while ti>=logTimeS[j+1]: + j += 1 + pulseLogS[i] = logValues[j] + pulses = append_fields(pulses, [(key, pulseLogS.dtype)]) + pulses[key] = pulseLogS + dataset.data.pulses = pulses + diff --git a/eos/event_handling.py b/eos/event_handling.py index ccd39db..7a610fe 100644 --- a/eos/event_handling.py +++ b/eos/event_handling.py @@ -71,6 +71,8 @@ class CorrectSeriesTime(EventDataAction): dataset.data.pulses.time -= self.seriesStartTime dataset.data.events.wallTime -= self.seriesStartTime dataset.data.proton_current.time -= self.seriesStartTime + for value in dataset.data.device_logs.values(): + value.time -= self.seriesStartTime start, stop = dataset.data.events.wallTime[0], dataset.data.events.wallTime[-1] logging.debug(f' wall time from {start/1e9:6.1f} s to {stop/1e9:6.1f} s, ' f'series time = {self.seriesStartTime/1e9:6.1f}') diff --git a/eos/options.py b/eos/options.py index c0ab3e7..1d66432 100644 --- a/eos/options.py +++ b/eos/options.py @@ -471,6 +471,15 @@ class ReflectivityReductionConfig(ArgParsable): }, ) + logfilter: List[str] = field( + default_factory=lambda: [], + metadata={ + 'short': 'lf', + 'group': 'region of interest', + 'help': 'filter using comparison to a log values, multpiple allowd (example "sample_temperature<150")', + }, + ) + class OutputFomatOption(StrEnum): Rqz_ort = "Rqz.ort" diff --git a/eos/reduction_reflectivity.py b/eos/reduction_reflectivity.py index 2b58f36..4a9756e 100644 --- a/eos/reduction_reflectivity.py +++ b/eos/reduction_reflectivity.py @@ -70,6 +70,8 @@ class ReflectivityReduction: self.dataevent_actions |= ea.CalculateQ(self.config.experiment.incidentAngle) if not self.config.reduction.is_default('qzRange'): self.dataevent_actions |= ea.FilterQzRange(self.config.reduction.qzRange) + for lf in self.config.reduction.logfilter: + self.dataevent_actions |= ea.FilterByLog(lf) self.dataevent_actions |= eh.ApplyMask() self.grid = LZGrid(self.config.reduction.qResolution, self.config.reduction.qzRange)