From e9ba48db943645bddd72867f38d14834af178052 Mon Sep 17 00:00:00 2001 From: Artur Glavic Date: Tue, 24 Sep 2024 14:15:47 +0200 Subject: [PATCH 1/6] Minor cleanup and proper orso SampleModel class use --- libeos/file_reader.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libeos/file_reader.py b/libeos/file_reader.py index 355f5bd..e7b7dbd 100644 --- a/libeos/file_reader.py +++ b/libeos/file_reader.py @@ -9,6 +9,7 @@ import h5py import numpy as np import scipy as sp from orsopy import fileio +from orsopy.fileio.model_language import SampleModel from . import const from .header import Header @@ -44,6 +45,8 @@ class AmorData: tofCut: float start_date: str + seriesStartTime = None + #------------------------------------------------------------------------------------------------- def __init__(self, header: Header, reader_config: ReaderConfig, config: ExperimentConfig, short_notation:str, norm=False): @@ -205,12 +208,10 @@ class AmorData: pulseTime = np.sort(self.dataPacketTime_p) pulseTime = pulseTime[np.abs(pulseTime[:]-np.roll(pulseTime, 1)[:])>5] - try: - self.seriesStartTime - except: - self.seriesStartTime = pulseTime[0] + if self.seriesStartTime is None: + self.seriesStartTime = float(pulseTime[0]) pulseTime -= self.seriesStartTime - stopTime = pulseTime[-1] + self.stopTime = float(pulseTime[-1]) # fill in missing pulse times # TODO: check for real end time @@ -227,7 +228,7 @@ class AmorData: def associate_pulse_with_current(self): if self.monitorType == 'protonCharge': self.currentTime -= self.seriesStartTime - currentInterpolator = sp.interpolate.interp1d(self.currentTime, self.current, kind='previous', bounds_error=False) + currentInterpolator = sp.interpolate.interp1d(self.currentTime, self.current, kind='previous', bounds_error=False, fill_value='extrapolate') charge = np.array(currentInterpolator(self.pulseTimeS) * 2*self.tau *1e-3, dtype=float) # filter low-current pulses charge = np.where(charge > 2*self.tau * 1e-1, charge, 0) @@ -241,7 +242,7 @@ class AmorData: if self.monitorType == 'protonCharge': # associate each pulse with a proton current self.currentTime -= self.seriesStartTime - currentInterpolator = sp.interpolate.interp1d(self.currentTime, self.current, kind='previous', bounds_error=False, fill_value=0) + currentInterpolator = sp.interpolate.interp1d(self.currentTime, self.current, kind='previous', bounds_error=False, fill_value='extrapolate') charge = np.array(currentInterpolator(self.pulseTimeS) * 2*self.tau *1e-3, dtype=float) # TODO: activate the following filter AND remove the respective events : # remove events (wallTime, tof and pixelID) from stream for pulses with too low monitor signal @@ -440,7 +441,7 @@ class AmorData: ) self.header.sample = fileio.Sample( name=sampleName, - model=model, + model=SampleModel(stack=model), sample_parameters=None, ) self.header.measurement_scheme = 'angle- and energy-dispersive' From af569e538ed52273062128d4cc57afc739750b09 Mon Sep 17 00:00:00 2001 From: Artur Glavic Date: Tue, 24 Sep 2024 14:19:32 +0200 Subject: [PATCH 2/6] Readability improvement --- libeos/reduction.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libeos/reduction.py b/libeos/reduction.py index a7ff8d5..340ab35 100644 --- a/libeos/reduction.py +++ b/libeos/reduction.py @@ -80,8 +80,8 @@ class AmorReduction: self.file_reader, self.norm_lz, self.normAngle, lamda_e, detZ_e) monitor = self.file_reader.monitor if monitor>1 : - ref_lz *= 1/monitor - err_lz *= 1/monitor + ref_lz /= monitor + err_lz /= monitor try: ref_lz *= self.reduction_config.scale[i] err_lz *= self.reduction_config.scale[i] @@ -93,7 +93,7 @@ class AmorReduction: headerRqz.data_set = f'Nr {i} : mu = {self.file_reader.mu:6.3f} deg' if qz_lz[0,int(np.shape(qz_lz)[1]/2)] < 0: - # assuming a 'measurement from below' + # assuming a 'measurement from below' when center of detector at negative qz qz_lz *= -1 # projection on qz-grid From 128a8da3588b5aa570ad3ae61b0f8ab57db59b2f Mon Sep 17 00:00:00 2001 From: Artur Glavic Date: Tue, 24 Sep 2024 14:29:12 +0200 Subject: [PATCH 3/6] Fix use of class method with wrong object instead of instance method, --- libeos/command_line.py | 1 - libeos/options.py | 95 +++++++++++++++++++++--------------------- libeos/reduction.py | 6 +-- 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/libeos/command_line.py b/libeos/command_line.py index 22152f7..4d51ab8 100644 --- a/libeos/command_line.py +++ b/libeos/command_line.py @@ -1,5 +1,4 @@ import argparse -from datetime import date from .logconfig import update_loglevel from .options import ReaderConfig, EOSConfig, ExperimentConfig, OutputConfig, ReductionConfig, Defaults diff --git a/libeos/options.py b/libeos/options.py index 3ab191b..5819094 100644 --- a/libeos/options.py +++ b/libeos/options.py @@ -5,6 +5,7 @@ from dataclasses import dataclass, field from typing import Optional, Tuple from datetime import datetime +import logging class Defaults: # fileIdentifier @@ -99,64 +100,64 @@ class EOSConfig: base = 'python eos.py' inpt = '' - if self.reader_config.year: - inpt += f' -Y {self.reader_config.year}' + if self.reader.year: + inpt += f' -Y {self.reader.year}' else: inpt += f' -Y {datetime.now().year}' - if self.reader_config.dataPath != '.': - inpt += f' --dataPath {self.reader_config.dataPath}' - #if self.reader_config.raw != '.': - # inpt = f' --rawd {self.reader_config.raw}' - if self.reduction_config.subtract: - inpt += f' -subtract {self.reduction_config.subtract}' - if self.reduction_config.normalisationFileIdentifier: - inpt += f' -n {" ".join(self.reduction_config.normalisationFileIdentifier)}' - if self.reduction_config.fileIdentifier: - inpt += f' -f {" ".join(self.reduction_config.fileIdentifier)}' + if self.reader.dataPath != '.': + inpt += f' --dataPath {self.reader.dataPath}' + #if self.reader.raw != '.': + # inpt = f' --rawd {self.reader.raw}' + if self.reduction.subtract: + inpt += f' -subtract {self.reduction.subtract}' + if self.reduction.normalisationFileIdentifier: + inpt += f' -n {" ".join(self.reduction.normalisationFileIdentifier)}' + if self.reduction.fileIdentifier: + inpt += f' -f {" ".join(self.reduction.fileIdentifier)}' otpt = '' - if self.reduction_config.qResolution: - otpt += f' -r {self.reduction_config.qResolution}' - if self.output_config.outputName: - otpt += f' -o {self.output_config.outputName}' - if self.output_config.outputFormats != ['Rqz.ort']: - otpt += f' -of {" ".join(self.output_config.outputFormats)}' + if self.reduction.qResolution: + otpt += f' -r {self.reduction.qResolution}' + if self.output.outputName: + otpt += f' -o {self.output.outputName}' + if self.output.outputFormats != ['Rqz.ort']: + otpt += f' -of {" ".join(self.output.outputFormats)}' mask = '' - if self.experiment_config.yRange != Defaults.yRange: - mask += f' -y {" ".join(str(ii) for ii in self.experiment_config.yRange)}' - if self.experiment_config.lambdaRange!= Defaults.lambdaRange: - mask += f' -l {" ".join(str(ff) for ff in self.experiment_config.lambdaRange)}' - if self.reduction_config.thetaRange != Defaults.thetaRange: - mask += f' -T {" ".join(str(ff) for ff in self.reduction_config.thetaRange)}' - elif self.reduction_config.thetaRangeR != Defaults.thetaRangeR: - mask += f' -t {" ".join(str(ff) for ff in self.reduction_config.thetaRangeR)}' - if self.experiment_config.qzRange!= Defaults.qzRange: - mask += f' -q {" ".join(str(ff) for ff in self.experiment_config.qzRange)}' + if self.experiment.yRange != Defaults.yRange: + mask += f' -y {" ".join(str(ii) for ii in self.experiment.yRange)}' + if self.experiment.lambdaRange!= Defaults.lambdaRange: + mask += f' -l {" ".join(str(ff) for ff in self.experiment.lambdaRange)}' + if self.reduction.thetaRange != Defaults.thetaRange: + mask += f' -T {" ".join(str(ff) for ff in self.reduction.thetaRange)}' + elif self.reduction.thetaRangeR != Defaults.thetaRangeR: + mask += f' -t {" ".join(str(ff) for ff in self.reduction.thetaRangeR)}' + if self.experiment.qzRange!= Defaults.qzRange: + mask += f' -q {" ".join(str(ff) for ff in self.experiment.qzRange)}' para = '' - if self.experiment_config.chopperPhase != Defaults.chopperPhase: - para += f' --chopperPhase {self.experiment_config.chopperPhase}' - if self.experiment_config.chopperPhaseOffset != Defaults.chopperPhaseOffset: - para += f' --chopperPhaseOffset {self.experiment_config.chopperPhaseOffset}' - if self.experiment_config.mu: - para += f' --mu {self.experiment_config.mu}' - elif self.experiment_config.muOffset: - para += f' --muOffset {self.experiment_config.muOffset}' - if self.experiment_config.nu: - para += f' --nu {self.experiment_config.nu}' + if self.experiment.chopperPhase != Defaults.chopperPhase: + para += f' --chopperPhase {self.experiment.chopperPhase}' + if self.experiment.chopperPhaseOffset != Defaults.chopperPhaseOffset: + para += f' --chopperPhaseOffset {self.experiment.chopperPhaseOffset}' + if self.experiment.mu: + para += f' --mu {self.experiment.mu}' + elif self.experiment.muOffset: + para += f' --muOffset {self.experiment.muOffset}' + if self.experiment.nu: + para += f' --nu {self.experiment.nu}' modl = '' - if self.experiment_config.sampleModel: - modl += f" --sampleModel '{self.experiment_config.sampleModel}'" + if self.experiment.sampleModel: + modl += f" --sampleModel '{self.experiment.sampleModel}'" acts = '' - if self.reduction_config.autoscale: - acts += f' --autoscale {" ".join(str(ff) for ff in self.reduction_config.autoscale)}' - if self.reduction_config.scale != Defaults.scale: - acts += f' --scale {self.reduction_config.scale}' - if self.reduction_config.timeSlize: - acts += f' --timeSlize {" ".join(str(ff) for ff in self.reduction_config.timeSlize)}' + if self.reduction.autoscale: + acts += f' --autoscale {" ".join(str(ff) for ff in self.reduction.autoscale)}' + if self.reduction.scale != Defaults.scale: + acts += f' --scale {self.reduction.scale}' + if self.reduction.timeSlize: + acts += f' --timeSlize {" ".join(str(ff) for ff in self.reduction.timeSlize)}' mlst = base + inpt + otpt if mask: @@ -179,7 +180,7 @@ class EOSConfig: if modl: mlst += ' ' + modl - print(mlst) + logging.debug(f'Argument list build in EOSConfig.call_string: {mlst}') return mlst diff --git a/libeos/reduction.py b/libeos/reduction.py index 340ab35..e1b27a7 100644 --- a/libeos/reduction.py +++ b/libeos/reduction.py @@ -18,9 +18,9 @@ class AmorReduction: self.reduction_config = config.reduction self.output_config = config.output self.grid = Grid(config.reduction.qResolution, config.experiment.qzRange) - self.header = Header() - self.header.reduction.call = EOSConfig.call_string(self) + self.header = Header() + self.header.reduction.call = config.call_string() def reduce(self): if not os.path.exists(f'{self.reader_config.dataPath}'): @@ -221,7 +221,7 @@ class AmorReduction: self.datasetsRqz.append(orso_data) # reset normal logging behavior logging.StreamHandler.terminator = "\n" - logging.warning(f' time slize {ti:4d}, done') + logging.warning(f' time slizing, done') def save_Rqz(self): fname = os.path.join(self.reader_config.dataPath, f'{self.output_config.outputName}.Rqz.ort') From a7e88db4253401348ef6d4e005009f5213169437 Mon Sep 17 00:00:00 2001 From: Artur Glavic Date: Tue, 24 Sep 2024 14:51:27 +0200 Subject: [PATCH 4/6] Update test cases and make old datafile work --- libeos/file_reader.py | 7 +++++-- tests/test_full_analysis.py | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/libeos/file_reader.py b/libeos/file_reader.py index e7b7dbd..8217533 100644 --- a/libeos/file_reader.py +++ b/libeos/file_reader.py @@ -352,11 +352,14 @@ class AmorData: self.pixelID_e = np.array(self.hdf['/entry1/Amor/detector/data/event_id'][:], dtype=int) self.dataPacket_p = np.array(self.hdf['/entry1/Amor/detector/data/event_index'][:], dtype=np.uint64) #self.dataPacketTime_p = np.array(self.hdf['/entry1/Amor/detector/data/event_time_zero'][:], dtype=np.uint64)/1e9 - self.dataPacketTime_p = np.array(self.hdf['/entry1/Amor/detector/data/event_time_zero'][:], dtype=int) + self.dataPacketTime_p = np.array(self.hdf['/entry1/Amor/detector/data/event_time_zero'][:], dtype=float) try: self.currentTime = np.array(self.hdf['entry1/Amor/detector/proton_current/time'][:], dtype=int) self.current = np.array(self.hdf['entry1/Amor/detector/proton_current/value'][:,0], dtype=float) - self.monitorType = 'protonCharge' + if len(self.current)>0: + self.monitorType = 'protonCharge' + else: + self.monitorType = 'countingTime' except(KeyError, IndexError): self.monitorType = 'countingTime' diff --git a/tests/test_full_analysis.py b/tests/test_full_analysis.py index 44a6878..9eff6d0 100644 --- a/tests/test_full_analysis.py +++ b/tests/test_full_analysis.py @@ -6,6 +6,8 @@ from libeos import options, reduction, logconfig logconfig.setup_logging() logconfig.update_loglevel(True, False) +# TODO: add test for new features like proton charge normalization + class FullAmorTest(TestCase): @classmethod def setUpClass(cls): @@ -19,7 +21,9 @@ class FullAmorTest(TestCase): self.pr.enable() self.reader_config = options.ReaderConfig( year=2023, - dataPath=os.path.join('..', "test_data")) + dataPath=os.path.join('..', "test_data"), + raw=(os.path.join('..', "test_data"),) + ) def tearDown(self): self.pr.disable() @@ -37,14 +41,16 @@ class FullAmorTest(TestCase): yRange=(11., 41.), lambdaRange=(2., 15.), qzRange=(0.005, 0.30), - offSpecular=False, + incidentAngle=options.Defaults.incidentAngle, mu=0, nu=0, muOffset=0.0, sampleModel='air | 10 H2O | D2O' ) reduction_config = options.ReductionConfig( + normalisationMethod=options.Defaults.normalisationMethod, qResolution=0.01, + qzRange=options.Defaults.qzRange, thetaRange=(-12., 12.), thetaRangeR=(-12., 12.), fileIdentifier=["610"], @@ -72,19 +78,21 @@ class FullAmorTest(TestCase): yRange=(11., 41.), lambdaRange=(2., 15.), qzRange=(0.005, 0.30), - offSpecular=False, + incidentAngle=options.Defaults.incidentAngle, mu=0, nu=0, muOffset=0.0 ) reduction_config = options.ReductionConfig( qResolution=0.01, + qzRange=options.Defaults.qzRange, + normalisationMethod=options.Defaults.normalisationMethod, thetaRange=(-12., 12.), thetaRangeR=(-12., 12.), fileIdentifier=["610", "611", "608,612-613", "609"], scale=[1], normalisationFileIdentifier=["614"], - autoscale=(0.005, 0.008) + autoscale=(True, True) ) output_config = options.OutputConfig( outputFormats=["Rqz.ort"], From ec2f98d2bd016f2b6b762f3ed64be95e4d72c19a Mon Sep 17 00:00:00 2001 From: Artur Glavic Date: Wed, 25 Sep 2024 10:45:50 +0200 Subject: [PATCH 5/6] fix fill_value for interpolation --- libeos/file_reader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libeos/file_reader.py b/libeos/file_reader.py index 8217533..7a61e5f 100644 --- a/libeos/file_reader.py +++ b/libeos/file_reader.py @@ -228,7 +228,7 @@ class AmorData: def associate_pulse_with_current(self): if self.monitorType == 'protonCharge': self.currentTime -= self.seriesStartTime - currentInterpolator = sp.interpolate.interp1d(self.currentTime, self.current, kind='previous', bounds_error=False, fill_value='extrapolate') + currentInterpolator = sp.interpolate.interp1d(self.currentTime, self.current, kind='previous', bounds_error=False, fill_value=0) charge = np.array(currentInterpolator(self.pulseTimeS) * 2*self.tau *1e-3, dtype=float) # filter low-current pulses charge = np.where(charge > 2*self.tau * 1e-1, charge, 0) @@ -242,7 +242,7 @@ class AmorData: if self.monitorType == 'protonCharge': # associate each pulse with a proton current self.currentTime -= self.seriesStartTime - currentInterpolator = sp.interpolate.interp1d(self.currentTime, self.current, kind='previous', bounds_error=False, fill_value='extrapolate') + currentInterpolator = sp.interpolate.interp1d(self.currentTime, self.current, kind='previous', bounds_error=False, fill_value=0) charge = np.array(currentInterpolator(self.pulseTimeS) * 2*self.tau *1e-3, dtype=float) # TODO: activate the following filter AND remove the respective events : # remove events (wallTime, tof and pixelID) from stream for pulses with too low monitor signal From 26fdfd64d6a6ffe5593663b01ab3d3f98bfc4e46 Mon Sep 17 00:00:00 2001 From: Artur Glavic Date: Wed, 25 Sep 2024 10:54:47 +0200 Subject: [PATCH 6/6] update version information --- libeos/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libeos/__init__.py b/libeos/__init__.py index 1099066..9d8cfca 100644 --- a/libeos/__init__.py +++ b/libeos/__init__.py @@ -2,5 +2,5 @@ Package to handle data redction at AMOR instrument to be used by eos.py script. """ -__version__ = '2.0' -__date__ = '2024-03-04' +__version__ = '2.1' +__date__ = '2024-08-25'