From f46eefb0cb4bc83409ade6daf285f16356733128 Mon Sep 17 00:00:00 2001 From: Artur Glavic Date: Mon, 29 Sep 2025 15:13:39 +0200 Subject: [PATCH] Start cleaning up with separating numba check from function usage --- libeos/file_reader.py | 34 +++++----------------- libeos/helpers.py | 10 +++++++ libeos/helpers_fallback.py | 26 +++++++++++++++++ libeos/{nb_helpers.py => helpers_numba.py} | 0 libeos/options.py | 31 -------------------- neos.py | 1 - 6 files changed, 43 insertions(+), 59 deletions(-) create mode 100644 libeos/helpers.py create mode 100644 libeos/helpers_fallback.py rename libeos/{nb_helpers.py => helpers_numba.py} (100%) delete mode 120000 neos.py diff --git a/libeos/file_reader.py b/libeos/file_reader.py index 896df13..7c45084 100644 --- a/libeos/file_reader.py +++ b/libeos/file_reader.py @@ -20,11 +20,7 @@ from . import const from .header import Header from .instrument import Detector from .options import ExperimentConfig, IncidentAngle, MonitorType, ReaderConfig - -try: - from . import nb_helpers -except Exception: - nb_helpers = None +from .helpers import merge_frames, extract_walltime, filter_project_x, calculate_derived_properties_focussing # Time zone used to interpret time strings AMOR_LOCAL_TIMEZONE = zoneinfo.ZoneInfo(key='Europe/Zurich') @@ -268,13 +264,7 @@ class AmorData: logging.debug(f' => counting time {self.stopTime/1e9-self.startTime/1e9:8.2f} s') def extract_walltime(self, norm): - if nb_helpers: - self.wallTime_e = nb_helpers.extract_walltime(self.tof_e, self.dataPacket_p, self.dataPacketTime_p) - else: - self.wallTime_e = np.empty(np.shape(self.tof_e)[0], dtype=np.int64) - for i in range(len(self.dataPacket_p)-1): - self.wallTime_e[self.dataPacket_p[i]:self.dataPacket_p[i+1]] = self.dataPacketTime_p[i] - self.wallTime_e[self.dataPacket_p[-1]:] = self.dataPacketTime_p[-1] + self.wallTime_e = extract_walltime(self.tof_e, self.dataPacket_p, self.dataPacketTime_p) self.wallTime_e -= np.int64(self.seriesStartTime) logging.debug(f' wall time from {self.wallTime_e[0]/1e9:6.1f} s to {self.wallTime_e[-1]/1e9:6.1f} s') @@ -351,22 +341,13 @@ class AmorData: # TODO: - handle each neutron pulse individually, - associate with correct monitor also for slow neutrons def merge_time_frames(self): total_offset = self.tofCut + self.tau * (self.ch1TriggerPhase + self.chopperPhase/2)/180 - if nb_helpers: - self.tof_e = nb_helpers.merge_frames(self.tof_e, self.tofCut, self.tau, total_offset) - else: - self.tof_e = np.remainder(self.tof_e-(self.tofCut-self.tau), self.tau)+total_offset # tof shifted to 1 frame + self.tof_e = merge_frames(self.tof_e, self.tofCut, self.tau, total_offset) def filter_project_x(self): pixelLookUp = self.resolve_pixels() - if nb_helpers: - (self.detZ_e, self.detXdist_e, self.delta_e, self.mask_e) = nb_helpers.filter_project_x( - pixelLookUp, self.pixelID_e.astype(np.int64), self.config.yRange[0], self.config.yRange[1] - ) - else: - # resolve pixel ID into y and z indicees, x position and angle - (detY_e, self.detZ_e, self.detXdist_e, self.delta_e) = pixelLookUp[np.int_(self.pixelID_e)-1, :].T - # define mask and filter y range - self.mask_e = (self.config.yRange[0]<=detY_e) & (detY_e<=self.config.yRange[1]) + (self.detZ_e, self.detXdist_e, self.delta_e, self.mask_e) = filter_project_x( + pixelLookUp, self.pixelID_e.astype(np.int64), self.config.yRange[0], self.config.yRange[1] + ) def correct_for_chopper_opening(self): # correct tof for beam size effect at chopper: t_cor = (delta / 180 deg) * tau @@ -378,9 +359,8 @@ class AmorData: def calculate_derived_properties(self): self.lamdaMax = const.lamdaCut+1.e13*self.tau*const.hdm/(self.chopperDetectorDistance+124.) - #if nb_helpers: if False: - self.lamda_e, self.qz_e, self.mask_e = nb_helpers.calculate_derived_properties_focussing( + self.lamda_e, self.qz_e, self.mask_e = calculate_derived_properties_focussing( self.tof_e, self.detXdist_e, self.delta_e, self.mask_e, self.config.lambdaRange[0], self.config.lambdaRange[1], self.nu, self.mu, self.chopperDetectorDistance, const.hdm diff --git a/libeos/helpers.py b/libeos/helpers.py new file mode 100644 index 0000000..ee3486b --- /dev/null +++ b/libeos/helpers.py @@ -0,0 +1,10 @@ +""" +Helper functions used during calculations. Uses numba enhanced functions if available, otherwise numpy based +fallback is imported. +""" + +try: + from .helpers_numba import merge_frames, extract_walltime, filter_project_x, calculate_derived_properties_focussing +except ImportError: + from .helpers_fallback import merge_frames, extract_walltime, filter_project_x, calculate_derived_properties_focussing + diff --git a/libeos/helpers_fallback.py b/libeos/helpers_fallback.py new file mode 100644 index 0000000..14a06b6 --- /dev/null +++ b/libeos/helpers_fallback.py @@ -0,0 +1,26 @@ +""" +Equivalent function as in helpers_numba.py but using just numpy functionality. +""" + +import numpy as np + +def merge_frames(tof_e, tofCut, tau, total_offset): + # tof shifted to 1 frame + return np.remainder(tof_e-(tofCut-tau), tau)+total_offset + +def extract_walltime(tof_e, dataPacket_p, dataPacketTime_p): + output = np.empty(np.shape(tof_e)[0], dtype=np.int64) + for i in range(len(dataPacket_p)-1): + output[dataPacket_p[i]:dataPacket_p[i+1]] = dataPacketTime_p[i] + output[dataPacket_p[-1]:] = dataPacketTime_p[-1] + return output + +def filter_project_x(pixelLookUp, pixelID_e, ymin, ymax): + (detY_e, detZ_e, detXdist_e, delta_e) = pixelLookUp[np.int_(pixelID_e)-1, :].T + # define mask and filter y range + mask_e = (ymin<=detY_e) & (detY_e<=ymax[1]) + return (detY_e, detZ_e, detXdist_e, delta_e, mask_e) + +def calculate_derived_properties_focussing(tof_e, detXdist_e, delta_e, mask_e, + lmin, lmax, nu, mu, chopperDetectorDistance, hdm): + raise NotImplementedError("Only exists in numba implementation so far.") diff --git a/libeos/nb_helpers.py b/libeos/helpers_numba.py similarity index 100% rename from libeos/nb_helpers.py rename to libeos/helpers_numba.py diff --git a/libeos/options.py b/libeos/options.py index 72535e9..0b23e6e 100644 --- a/libeos/options.py +++ b/libeos/options.py @@ -11,37 +11,6 @@ import numpy as np import logging -#class Defaults: - # fileIdentifier - #outputPath = '.' - #rawPath = ['.', path.join('.','raw'), path.join('..','raw'), path.join('..','..','raw')] - #year = datetime.now().year - #normalisationFileIdentifier = [] - #normalisationMethod = 'o' - #monitorType = 'auto' - # subtract - #outputName = "fromEOS" - #outputFormat = ['Rqz.ort'] - #incidentAngle = 'alphaF' - #qResolution = 0.01 - #timeSlize - #scale = [1] - # autoscale - #lambdaRange = [2., 15.] - #thetaRange = [-12., 12.] - #thetaRangeR = [-0.75, 0.75] - #yRange = [11, 41] - #qzRange = [0.005, 0.51] - #chopperSpeed = 500 - #chopperPhase = 0.0 - #chopperPhaseOffset = -9.1 - #muOffset = 0 - #mu = 0 - #nu = 0 - #sampleModel = None - #lowCurrentThreshold = 50 - # - @dataclass class CommandlineParameterConfig: argument: str # default parameter for command line resutign ins "--argument" diff --git a/neos.py b/neos.py deleted file mode 120000 index 6496bc3..0000000 --- a/neos.py +++ /dev/null @@ -1 +0,0 @@ -eos.py \ No newline at end of file