amor-eos 3.3.4__tar.gz → 3.3.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {amor_eos-3.3.4 → amor_eos-3.3.5}/PKG-INFO +1 -1
- {amor_eos-3.3.4 → amor_eos-3.3.5}/amor_eos.egg-info/PKG-INFO +1 -1
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/__init__.py +2 -2
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/event_analysis.py +11 -4
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/event_data_types.py +1 -1
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/event_handling.py +23 -16
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/file_reader.py +18 -5
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/options.py +10 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/projection.py +74 -3
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/reduction_e2h.py +11 -4
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/reduction_reflectivity.py +11 -8
- {amor_eos-3.3.4 → amor_eos-3.3.5}/tests/test_event_handling.py +50 -11
- {amor_eos-3.3.4 → amor_eos-3.3.5}/LICENSE +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/README.rst +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/amor_eos.egg-info/SOURCES.txt +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/amor_eos.egg-info/dependency_links.txt +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/amor_eos.egg-info/entry_points.txt +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/amor_eos.egg-info/requires.txt +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/amor_eos.egg-info/top_level.txt +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/__main__.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/command_line.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/compat.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/const.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/e2h.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/header.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/helpers.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/helpers_fallback.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/helpers_numba.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/instrument.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/kafka_events.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/kafka_serializer.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/logconfig.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/ls.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/nicos.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/nicos_interface.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/normalization.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/path_handling.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/eos/reduction_kafka.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/pyproject.toml +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/setup.cfg +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/tests/test_full_analysis.py +0 -0
- {amor_eos-3.3.4 → amor_eos-3.3.5}/tests/test_full_analysis_v2.py +0 -0
|
@@ -19,7 +19,7 @@ class ExtractWalltime(EventDataAction):
|
|
|
19
19
|
wallTime = extract_walltime(dataset.data.events.tof,
|
|
20
20
|
dataset.data.packets.start_index,
|
|
21
21
|
dataset.data.packets.time)
|
|
22
|
-
logging.debug(f'
|
|
22
|
+
logging.debug(f' expending event stream by wallTime')
|
|
23
23
|
new_events = append_fields(dataset.data.events, [('wallTime', wallTime.dtype)])
|
|
24
24
|
new_events.wallTime = wallTime
|
|
25
25
|
dataset.data.events = new_events
|
|
@@ -156,12 +156,14 @@ class FilterQzRange(EventDataAction):
|
|
|
156
156
|
|
|
157
157
|
class FilterByLog(EventDataAction):
|
|
158
158
|
|
|
159
|
-
def __init__(self, filter_string, remove_switchpulse=False):
|
|
159
|
+
def __init__(self, filter_string, remove_switchpulse=False, pre_switch=0, post_switch=0):
|
|
160
160
|
if filter_string.startswith('!'):
|
|
161
161
|
filter_string = filter_string[1:]
|
|
162
162
|
remove_switchpulse = True
|
|
163
163
|
self.filter_string = filter_string
|
|
164
164
|
self.remove_switchpulse = remove_switchpulse
|
|
165
|
+
self.pre_switch = pre_switch
|
|
166
|
+
self.post_switch = post_switch
|
|
165
167
|
|
|
166
168
|
def perform_action(self, dataset: EventDatasetProtocol) -> None:
|
|
167
169
|
filter_variable = None
|
|
@@ -184,8 +186,13 @@ class FilterByLog(EventDataAction):
|
|
|
184
186
|
add_log_to_pulses(filter_variable, dataset)
|
|
185
187
|
fltr_pulses = eval(self.filter_string, {filter_variable: dataset.data.pulses[filter_variable]})
|
|
186
188
|
if self.remove_switchpulse:
|
|
187
|
-
switched = fltr_pulses[:-1]
|
|
188
|
-
fltr_pulses[:-1] &=
|
|
189
|
+
switched = np.logical_xor(fltr_pulses[:-1], fltr_pulses[1:])
|
|
190
|
+
fltr_pulses[:-1] &= np.logical_not(switched)
|
|
191
|
+
for i in range(self.pre_switch):
|
|
192
|
+
fltr_pulses[:-2-i] &= np.logical_not(switched[1+i:])
|
|
193
|
+
for i in range(self.post_switch):
|
|
194
|
+
fltr_pulses[1+i:-1] &= np.logical_not(switched[:-1-i])
|
|
195
|
+
dataset.data.pulses.mask += EVENT_BITMASKS[filter_variable]*np.logical_not(fltr_pulses)
|
|
189
196
|
goodTimeS = dataset.data.pulses.time[fltr_pulses]
|
|
190
197
|
filter_e = np.logical_not(np.isin(dataset.data.events.wallTime, goodTimeS))
|
|
191
198
|
dataset.data.events.mask += EVENT_BITMASKS[filter_variable]*filter_e
|
|
@@ -37,7 +37,7 @@ class DA00EventBuffer:
|
|
|
37
37
|
# Structured datatypes used for event streams
|
|
38
38
|
EVENT_TYPE = np.dtype([('tof', np.float64), ('pixelID', np.uint32), ('mask', np.int32)])
|
|
39
39
|
PACKET_TYPE = np.dtype([('start_index', np.uint32), ('time', np.int64)])
|
|
40
|
-
PULSE_TYPE = np.dtype([('time', np.int64), ('monitor', np.float32)])
|
|
40
|
+
PULSE_TYPE = np.dtype([('time', np.int64), ('monitor', np.float32), ('mask', np.int32)])
|
|
41
41
|
PC_TYPE = np.dtype([('current', np.float32), ('time', np.int64)])
|
|
42
42
|
BM_TYPE = np.dtype([('value', np.int32), ('time', np.int64)])
|
|
43
43
|
LOG_TYPE = np.dtype([('value', np.float32), ('time', np.int64)])
|
|
@@ -134,6 +134,7 @@ class FilterMonitorThreshold(EventDataAction):
|
|
|
134
134
|
raise ValueError(
|
|
135
135
|
"FilterMonitorThreshold requires walltTime to be extracted, please run ExtractWalltime first")
|
|
136
136
|
low_current_filter = dataset.data.pulses.monitor>2*dataset.timing.tau*self.lowCurrentThreshold*1e-3
|
|
137
|
+
dataset.data.pulses.mask[np.logical_not(low_current_filter)] = EVENT_BITMASKS['MonitorThreshold']
|
|
137
138
|
dataset.data.pulses.monitor[np.logical_not(low_current_filter)] = 0.
|
|
138
139
|
goodTimeS = dataset.data.pulses.time[low_current_filter]
|
|
139
140
|
filter_e = np.logical_not(np.isin(dataset.data.events.wallTime, goodTimeS))
|
|
@@ -197,19 +198,25 @@ class ApplyMask(EventDataAction):
|
|
|
197
198
|
logging.info(f' number of events: total = {pre_filter:7d}, after filtering = {post_filter:7d}')
|
|
198
199
|
if d.device_logs == {} or not hasattr(dataset, 'update_info_from_logs'):
|
|
199
200
|
return
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
201
|
+
# filter pulses, not all masks apply to pulses
|
|
202
|
+
pre_filter_pulses = d.pulses.shape[0]
|
|
203
|
+
# make sure all log variables are associated with pulses
|
|
204
|
+
for key, log in d.device_logs.items():
|
|
205
|
+
if not key in d.pulses.dtype.names:
|
|
206
|
+
from .helpers import add_log_to_pulses
|
|
207
|
+
# interpolate the parameter values for all existing pulses
|
|
208
|
+
add_log_to_pulses(key, dataset)
|
|
209
|
+
if self.bitmask_filter is None:
|
|
210
|
+
d.pulses = d.pulses[d.pulses.mask==0]
|
|
211
|
+
else:
|
|
212
|
+
# remove the provided bitmask_filter bits from the events
|
|
213
|
+
# this means that all bits that are set in bitmask_filter will NOT be used to filter events
|
|
214
|
+
fltr = (d.pulses.mask & (~self.bitmask_filter)) == 0
|
|
215
|
+
d.pulses = d.pulses[fltr]
|
|
216
|
+
post_filter_pulses = d.pulses.shape[0]
|
|
217
|
+
logging.info(f' number of pulses: total = {pre_filter_pulses:7d}, after filtering = {post_filter_pulses:7d}')
|
|
218
|
+
for key, log in d.device_logs.items():
|
|
219
|
+
d.device_logs[key] = np.recarray(d.pulses.shape, dtype = log.dtype)
|
|
220
|
+
d.device_logs[key].time = d.pulses.time
|
|
221
|
+
d.device_logs[key].value = d.pulses[key]
|
|
222
|
+
dataset.update_info_from_logs()
|
|
@@ -527,11 +527,11 @@ class AmorEventData(AmorHeader):
|
|
|
527
527
|
pulseTimeS = self._beam_monitor.time
|
|
528
528
|
elif self.correctTimeFallback:
|
|
529
529
|
logging.critical(
|
|
530
|
-
' No chopper trigger data or monitor time available, using event
|
|
530
|
+
' No chopper trigger data or monitor time available, using event stream and packet times instead!')
|
|
531
531
|
data_group = self.hdf[self.hdf_paths['data'][0]]
|
|
532
532
|
startTime = np.array(data_group['event_time_zero'][0], dtype=np.int64)
|
|
533
533
|
stopTime = np.array(data_group['event_time_zero'][-1], dtype=np.int64)
|
|
534
|
-
pulseTimeS = np.arange(startTime, stopTime, self.timing.tau*1e9, dtype=np.int64)
|
|
534
|
+
pulseTimeS = np.arange(startTime, stopTime+self.timing.tau*1e9, self.timing.tau*1e9, dtype=np.int64)
|
|
535
535
|
# find times that are closest to the next packet time and correct them to fit exactly
|
|
536
536
|
all_times = np.unique(packets.time)
|
|
537
537
|
all_times.sort()
|
|
@@ -549,6 +549,7 @@ class AmorEventData(AmorHeader):
|
|
|
549
549
|
pulses = np.recarray(pulseTimeS.shape, dtype=PULSE_TYPE)
|
|
550
550
|
pulses.time = pulseTimeS
|
|
551
551
|
pulses.monitor = 1. # default is monitor pulses as it requires no calculation
|
|
552
|
+
pulses.mask = 0
|
|
552
553
|
# apply filter in case the events were filtered
|
|
553
554
|
if (self.first_index>0 or not self.EOF):
|
|
554
555
|
pulses = pulses[(pulses.time>=packets.time[0])&(pulses.time<=packets.time[-1])]
|
|
@@ -604,8 +605,9 @@ class AmorEventData(AmorHeader):
|
|
|
604
605
|
output = np.recarray(a1.shape[0]+a2.shape[0], dtype=new_fields)
|
|
605
606
|
for field in new_fields.fields.keys():
|
|
606
607
|
output[field] = np.concatenate([a1[field], a2[field]])
|
|
607
|
-
logging.warning("Missing data when combining datasets
|
|
608
|
-
f"{tuple(a1.dtype.fields.keys())}
|
|
608
|
+
logging.warning(" Missing data when combining datasets,\n"
|
|
609
|
+
f" {tuple(a1.dtype.fields.keys())} \n"
|
|
610
|
+
f" !={tuple(a2.dtype.fields.keys())}")
|
|
609
611
|
return output
|
|
610
612
|
|
|
611
613
|
def append(self, other):
|
|
@@ -625,7 +627,15 @@ class AmorEventData(AmorHeader):
|
|
|
625
627
|
else:
|
|
626
628
|
new_device_logs = {}
|
|
627
629
|
for key, slog in self.data.device_logs.items():
|
|
628
|
-
|
|
630
|
+
try:
|
|
631
|
+
olog = other.data.device_logs[key]
|
|
632
|
+
except KeyError:
|
|
633
|
+
if getattr(other.experiment, 'end_date', None) is None:
|
|
634
|
+
logging.warning(f" Device logs for '{key}' not found in dataset to be added, "
|
|
635
|
+
f"ignoring key as file is not finalized")
|
|
636
|
+
continue
|
|
637
|
+
else:
|
|
638
|
+
raise KeyError(f"Device logs for '{key}' not found in dataset to be added")
|
|
629
639
|
new_device_logs[key] = np.recarray(slog.shape[0]+olog.shape[0],
|
|
630
640
|
dtype = slog.dtype)
|
|
631
641
|
new_device_logs[key].time = np.concatenate([slog.time, olog.time])
|
|
@@ -664,4 +674,7 @@ class AmorEventData(AmorHeader):
|
|
|
664
674
|
output.data = AmorEventStream(self.data.events[event_filter], self.data.packets,
|
|
665
675
|
self.data.pulses[pulse_filter], self.data.proton_current,
|
|
666
676
|
self.data.beam_monitor)
|
|
677
|
+
for key, value in self.data.device_logs.items():
|
|
678
|
+
output.data.device_logs[key] = value[pulse_filter]
|
|
679
|
+
output.update_info_from_logs()
|
|
667
680
|
return output
|
|
@@ -499,6 +499,15 @@ class ReflectivityReductionConfig(ArgParsable):
|
|
|
499
499
|
},
|
|
500
500
|
)
|
|
501
501
|
|
|
502
|
+
flipperMaxDelay: int = field(
|
|
503
|
+
default=4,
|
|
504
|
+
metadata={
|
|
505
|
+
'short': 'fmd',
|
|
506
|
+
'group': 'data manicure',
|
|
507
|
+
'help': 'Remove all neutron pulses that are within flipperMaxDelay of a change in spin state',
|
|
508
|
+
},
|
|
509
|
+
)
|
|
510
|
+
|
|
502
511
|
class OutputFomatOption(StrEnum):
|
|
503
512
|
Rqz_ort = "Rqz.ort"
|
|
504
513
|
Rqz_orb = "Rqz.orb"
|
|
@@ -640,6 +649,7 @@ class E2HPlotSelection(StrEnum):
|
|
|
640
649
|
YZ = 'Iyz'
|
|
641
650
|
LT = 'Ilt'
|
|
642
651
|
YT = 'Iyt'
|
|
652
|
+
Z = 'Iz'
|
|
643
653
|
TZ = 'Itz'
|
|
644
654
|
Q = 'Iq'
|
|
645
655
|
L = 'Il'
|
|
@@ -237,7 +237,7 @@ class LZProjection(ProjectionInterface):
|
|
|
237
237
|
|
|
238
238
|
def normalize_no_footprint(self, norm: LZNormalisation):
|
|
239
239
|
norm_lz = norm.norm
|
|
240
|
-
ref_lz = (self.data.I/norm_lz)
|
|
240
|
+
ref_lz = (self.data.I/np.where(norm_lz>0, norm_lz, np.nan))
|
|
241
241
|
ref_lz *= norm.monitor/self.monitor
|
|
242
242
|
ref_lz[np.logical_not(self.data.mask)] = np.nan
|
|
243
243
|
self.data.norm = norm_lz
|
|
@@ -249,8 +249,8 @@ class LZProjection(ProjectionInterface):
|
|
|
249
249
|
def scale(self, factor: float):
|
|
250
250
|
if not self.is_normalized:
|
|
251
251
|
raise ValueError("Dataset needs to be normalized, first")
|
|
252
|
-
self.data.ref
|
|
253
|
-
self.data.err
|
|
252
|
+
self.data.ref *= factor
|
|
253
|
+
self.data.err *= factor
|
|
254
254
|
self.norm_monitor *= factor
|
|
255
255
|
|
|
256
256
|
def project_on_qz(self):
|
|
@@ -636,6 +636,77 @@ class TofZProjection(ProjectionInterface):
|
|
|
636
636
|
art.remove()
|
|
637
637
|
plt.draw()
|
|
638
638
|
|
|
639
|
+
class FltrZProjection(ProjectionInterface):
|
|
640
|
+
z: np.ndarray
|
|
641
|
+
tau: float
|
|
642
|
+
foldback: bool
|
|
643
|
+
l_range: Tuple[float, float]
|
|
644
|
+
|
|
645
|
+
data: np.recarray
|
|
646
|
+
_dtype = np.dtype([
|
|
647
|
+
('cts', np.float64),
|
|
648
|
+
('I', np.float64),
|
|
649
|
+
('err', np.float64),
|
|
650
|
+
])
|
|
651
|
+
|
|
652
|
+
def __init__(self, tau, foldback=False, l_range=(0., 15.0)):
|
|
653
|
+
self.l_range = l_range
|
|
654
|
+
self.tau = tau
|
|
655
|
+
self.z = np.arange(Detector.nBlades*Detector.nWires+1)-0.5
|
|
656
|
+
self.foldback = foldback
|
|
657
|
+
self.data = np.zeros(self.z.shape[0]-1, dtype=self._dtype).view(np.recarray)
|
|
658
|
+
self.monitor = 0.
|
|
659
|
+
|
|
660
|
+
def project(self, dataset: EventDatasetProtocol, monitor: float):
|
|
661
|
+
detYi, detZi, detX, delta = Detector.pixelLookUp[dataset.data.events.pixelID-1].T
|
|
662
|
+
|
|
663
|
+
fltr = dataset.data.events.lamda>=self.l_range[0]
|
|
664
|
+
fltr &= dataset.data.events.lamda<=self.l_range[1]
|
|
665
|
+
|
|
666
|
+
cts , *_ = np.histogram(detZi[fltr], bins=self.z)
|
|
667
|
+
self.data.cts += cts
|
|
668
|
+
self.monitor += monitor
|
|
669
|
+
|
|
670
|
+
self.data.I = self.data.cts / self.monitor
|
|
671
|
+
self.data.err = np.sqrt(self.data.cts) / self.monitor
|
|
672
|
+
|
|
673
|
+
def clear(self):
|
|
674
|
+
self.data[:] = 0
|
|
675
|
+
self.monitor = 0.
|
|
676
|
+
|
|
677
|
+
def plot(self, **kwargs):
|
|
678
|
+
from matplotlib import pyplot as plt
|
|
679
|
+
|
|
680
|
+
Z = (self.z[1:]+self.z[:-1])/2.
|
|
681
|
+
self._graph = plt.errorbar(Z, self.data.I, yerr=self.data.err, **kwargs)
|
|
682
|
+
ez, eI = self.find_lower_edge()
|
|
683
|
+
plt.plot([ez], [eI], 'ro')
|
|
684
|
+
plt.text(ez, 0., f'{ez:.1f}', ha='center', va='bottom')
|
|
685
|
+
|
|
686
|
+
plt.xlabel('Z')
|
|
687
|
+
plt.xlim(self.z[-1], self.z[0])
|
|
688
|
+
plt.title('Vertical Pixel w/ filter')
|
|
689
|
+
|
|
690
|
+
def update_plot(self):
|
|
691
|
+
"""
|
|
692
|
+
Inline update of previous plot by just updating the data.
|
|
693
|
+
"""
|
|
694
|
+
from matplotlib.colors import LogNorm
|
|
695
|
+
self._graph.set_array(self.data.I)
|
|
696
|
+
|
|
697
|
+
def find_lower_edge(self):
|
|
698
|
+
Imax = self.data.I.max()
|
|
699
|
+
next_pix = np.where(self.data.I>Imax/2.)[0][-1]
|
|
700
|
+
I_next = self.data.I[next_pix]
|
|
701
|
+
I_prev = self.data.I[next_pix+1]
|
|
702
|
+
|
|
703
|
+
Z = (self.z[1:]+self.z[:-1])/2.
|
|
704
|
+
nxt_prev_ratio = (Imax/2.-I_prev)/(I_next - Imax/2.)
|
|
705
|
+
z = Z[next_pix+1] + nxt_prev_ratio*(Z[next_pix]-Z[next_pix+1])
|
|
706
|
+
print(I_next - Imax/2., Imax/2.-I_prev, )
|
|
707
|
+
return z, Imax/2.
|
|
708
|
+
|
|
709
|
+
|
|
639
710
|
class TofProjection(ProjectionInterface):
|
|
640
711
|
tof: np.ndarray
|
|
641
712
|
|
|
@@ -19,10 +19,11 @@ from .normalization import LZNormalisation
|
|
|
19
19
|
from .options import E2HConfig, E2HPlotArguments, IncidentAngle, MonitorType, E2HPlotSelection
|
|
20
20
|
from . import event_handling as eh
|
|
21
21
|
from .path_handling import PathResolver
|
|
22
|
-
from .projection import CombinedProjection, LProjection, LZProjection, ProjectionInterface,
|
|
23
|
-
|
|
22
|
+
from .projection import CombinedProjection, FltrZProjection, LProjection, LZProjection, ProjectionInterface, \
|
|
23
|
+
ReflectivityProjector, \
|
|
24
|
+
TofProjection, TofZProjection, TProjection, YTProjection, YZProjection
|
|
24
25
|
|
|
25
|
-
NEEDS_LAMDA = (E2HPlotSelection.All, E2HPlotSelection.LT, E2HPlotSelection.Q, E2HPlotSelection.L)
|
|
26
|
+
NEEDS_LAMDA = (E2HPlotSelection.All, E2HPlotSelection.LT, E2HPlotSelection.Q, E2HPlotSelection.L, E2HPlotSelection.Z)
|
|
26
27
|
|
|
27
28
|
class E2HReduction:
|
|
28
29
|
config: E2HConfig
|
|
@@ -97,7 +98,8 @@ class E2HReduction:
|
|
|
97
98
|
self.event_actions |= eh.ApplyMask()
|
|
98
99
|
|
|
99
100
|
# plot dependant options
|
|
100
|
-
if self.config.reduction.plot in [E2HPlotSelection.All, E2HPlotSelection.LT,
|
|
101
|
+
if self.config.reduction.plot in [E2HPlotSelection.All, E2HPlotSelection.LT,
|
|
102
|
+
E2HPlotSelection.Q, E2HPlotSelection.Z]:
|
|
101
103
|
self.grid = LZGrid(0.05, [0.0, 0.25], lambda_overwrite=self.config.experiment.lambdaRange)
|
|
102
104
|
self.grid.dldl = 0.01
|
|
103
105
|
|
|
@@ -195,6 +197,11 @@ class E2HReduction:
|
|
|
195
197
|
if self.config.reduction.plot==E2HPlotSelection.TZ:
|
|
196
198
|
self.projection = TofZProjection(last_file_header.timing.tau, foldback=not self.config.reduction.fast)
|
|
197
199
|
|
|
200
|
+
if self.config.reduction.plot==E2HPlotSelection.Z:
|
|
201
|
+
self.projection = FltrZProjection(last_file_header.timing.tau,
|
|
202
|
+
foldback=not self.config.reduction.fast,
|
|
203
|
+
l_range=self.config.experiment.lambdaRange)
|
|
204
|
+
|
|
198
205
|
if self.config.reduction.plot==E2HPlotSelection.ToF:
|
|
199
206
|
self.projection = TofProjection(last_file_header.timing.tau, foldback=not self.config.reduction.fast)
|
|
200
207
|
|
|
@@ -125,6 +125,8 @@ class ReflectivityReduction:
|
|
|
125
125
|
_sampleName = 'unknown'
|
|
126
126
|
_mu = int(self.dataset.geometry.mu * 3)
|
|
127
127
|
self.config.output.outputName = f'{_sampleName}_{_mu:03}_{_date}'
|
|
128
|
+
elif self.config.output.outputName.endswith('.Rqz.ort'):
|
|
129
|
+
self.config.output.outputName = self.config.output.outputName[:-len('.Rqz.ort')]
|
|
128
130
|
|
|
129
131
|
logging.warning('output:')
|
|
130
132
|
|
|
@@ -145,9 +147,10 @@ class ReflectivityReduction:
|
|
|
145
147
|
logging.warning('input:')
|
|
146
148
|
file_list = self.path_resolver.resolve(short_notation)
|
|
147
149
|
|
|
148
|
-
self.header.measurement_data_files = []
|
|
149
150
|
|
|
150
151
|
self.dataset = AmorEventData(file_list[0])
|
|
152
|
+
self.header.measurement_data_files = [
|
|
153
|
+
fileio.File( file=os.path.basename(file_list[0]), timestamp=self.dataset.fileDate)]
|
|
151
154
|
if self.config.experiment.monitorType==MonitorType.auto:
|
|
152
155
|
if self.dataset.data.proton_current.current.sum()>1:
|
|
153
156
|
self.config.experiment.monitorType = MonitorType.proton_charge
|
|
@@ -169,10 +172,8 @@ class ReflectivityReduction:
|
|
|
169
172
|
di = AmorEventData(fi)
|
|
170
173
|
self.dataevent_actions(di)
|
|
171
174
|
self.dataset.append(di)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
self.header.measurement_data_files.append(fileio.File( file=os.path.basename(fileName),
|
|
175
|
-
timestamp=self.dataset.fileDate))
|
|
175
|
+
self.header.measurement_data_files.append(fileio.File( file=os.path.basename(fi),
|
|
176
|
+
timestamp=di.fileDate))
|
|
176
177
|
|
|
177
178
|
if 'polarization_config_label' in self.dataset.data.device_logs:
|
|
178
179
|
pols = np.unique(self.dataset.data.device_logs['polarization_config_label'].value)
|
|
@@ -185,7 +186,9 @@ class ReflectivityReduction:
|
|
|
185
186
|
for pi in pols:
|
|
186
187
|
plabel = const.polarizationLabels[pi]
|
|
187
188
|
pol_filter = FilterByLog(f'polarization_config_label=={pi}',
|
|
188
|
-
remove_switchpulse=True
|
|
189
|
+
remove_switchpulse=True,
|
|
190
|
+
pre_switch=self.config.reduction.flipperMaxDelay
|
|
191
|
+
) | ApplyMask()
|
|
189
192
|
logging.info(f' filter {plabel} using polarization_config_label=={pi}')
|
|
190
193
|
pol_filter(self.dataset)
|
|
191
194
|
self.dataset.update_header(self.header)
|
|
@@ -238,7 +241,7 @@ class ReflectivityReduction:
|
|
|
238
241
|
logging.warning(
|
|
239
242
|
f'backgroung file {self.sFileName} not compatible with q_z scale ({len(self.sq_q)} vs. {len(result.Q)})')
|
|
240
243
|
|
|
241
|
-
if not self.config.reduction.is_default('scale'):
|
|
244
|
+
if self.config.reduction.autoscale and not self.config.reduction.is_default('scale'):
|
|
242
245
|
try:
|
|
243
246
|
scale = self.config.reduction.scale[i]
|
|
244
247
|
except IndexError:
|
|
@@ -366,7 +369,7 @@ class ReflectivityReduction:
|
|
|
366
369
|
self.last_result = result
|
|
367
370
|
# reset normal logging behavior
|
|
368
371
|
#logging.StreamHandler.terminator = "\n"
|
|
369
|
-
logging.info(f' done
|
|
372
|
+
logging.info(f' done {min(time+interval, pulseTimeS[-1]):5.0f}')
|
|
370
373
|
|
|
371
374
|
def save_Rqz(self):
|
|
372
375
|
fname = os.path.join(self.config.output.outputPath, f'{self.config.output.outputName}.Rqz.ort')
|
|
@@ -53,6 +53,7 @@ class MockEventData:
|
|
|
53
53
|
pulses = np.recarray((packets.shape[0],), dtype=PULSE_TYPE)
|
|
54
54
|
pulses.monitor = 1.0
|
|
55
55
|
pulses.time = packets.time
|
|
56
|
+
pulses.mask = 0
|
|
56
57
|
|
|
57
58
|
# proton current information with independent timing
|
|
58
59
|
proton_current = np.recarray((50,), dtype=PC_TYPE)
|
|
@@ -552,27 +553,65 @@ class TestSimpleActions(TestCase):
|
|
|
552
553
|
|
|
553
554
|
self._extract_walltime()
|
|
554
555
|
|
|
555
|
-
test_log = np.recarray(shape=(
|
|
556
|
-
|
|
557
|
-
test_log.time =
|
|
558
|
-
test_log.value =
|
|
556
|
+
test_log = np.recarray(shape=(self.d.data.pulses.shape[0],),
|
|
557
|
+
dtype=np.dtype([('value', np.int32), ('time', np.int64)]))
|
|
558
|
+
test_log.time = self.d.data.pulses.time
|
|
559
|
+
test_log.value = 0
|
|
560
|
+
test_log.value[10:-10] = 1
|
|
559
561
|
self.d.data.device_logs['test_log'] = test_log
|
|
560
562
|
action.perform_action(self.d)
|
|
561
|
-
self.assertEqual(self.d.data.pulses.shape[0]
|
|
563
|
+
self.assertEqual(20, self.d.data.pulses.shape[0])
|
|
562
564
|
|
|
563
565
|
def test_filter_by_log_switchpulse(self):
|
|
564
566
|
action = FilterByLog("!test_log==0") | ApplyMask()
|
|
565
567
|
self._extract_walltime()
|
|
566
568
|
|
|
567
|
-
test_log = np.recarray(shape=(
|
|
568
|
-
|
|
569
|
-
test_log.time =
|
|
570
|
-
test_log.value =
|
|
569
|
+
test_log = np.recarray(shape=(self.d.data.pulses.shape[0],),
|
|
570
|
+
dtype=np.dtype([('value', np.int32), ('time', np.int64)]))
|
|
571
|
+
test_log.time = self.d.data.pulses.time
|
|
572
|
+
test_log.value = 0
|
|
573
|
+
test_log.value[10:-10] = 1
|
|
571
574
|
self.d.data.device_logs['test_log'] = test_log
|
|
572
575
|
self.d.data.device_logs['check_log'] = test_log.copy()
|
|
573
576
|
action.perform_action(self.d)
|
|
574
|
-
self.assertEqual(self.d.data.pulses.shape[0]
|
|
577
|
+
self.assertEqual(19, self.d.data.pulses.shape[0])
|
|
575
578
|
np.testing.assert_array_equal(
|
|
576
579
|
self.d.data.device_logs['test_log'],
|
|
577
580
|
self.d.data.device_logs['check_log'],
|
|
578
|
-
)
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
def test_filter_by_log_preswitch(self):
|
|
584
|
+
action = FilterByLog("!test_log==0", pre_switch=2) | ApplyMask()
|
|
585
|
+
self._extract_walltime()
|
|
586
|
+
|
|
587
|
+
test_log = np.recarray(shape=(self.d.data.pulses.shape[0],),
|
|
588
|
+
dtype=np.dtype([('value', np.int32), ('time', np.int64)]))
|
|
589
|
+
test_log.time = self.d.data.pulses.time
|
|
590
|
+
test_log.value = 0
|
|
591
|
+
test_log.value[10:-10] = 1
|
|
592
|
+
self.d.data.device_logs['test_log'] = test_log
|
|
593
|
+
self.d.data.device_logs['check_log'] = test_log.copy()
|
|
594
|
+
action.perform_action(self.d)
|
|
595
|
+
self.assertEqual(17, self.d.data.pulses.shape[0])
|
|
596
|
+
np.testing.assert_array_equal(
|
|
597
|
+
self.d.data.device_logs['test_log'],
|
|
598
|
+
self.d.data.device_logs['check_log'],
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
def test_filter_by_log_postswitch(self):
|
|
602
|
+
action = FilterByLog("!test_log==0", post_switch=2) | ApplyMask()
|
|
603
|
+
self._extract_walltime()
|
|
604
|
+
|
|
605
|
+
test_log = np.recarray(shape=(self.d.data.pulses.shape[0],),
|
|
606
|
+
dtype=np.dtype([('value', np.int32), ('time', np.int64)]))
|
|
607
|
+
test_log.time = self.d.data.pulses.time
|
|
608
|
+
test_log.value = 0
|
|
609
|
+
test_log.value[10:-10] = 1
|
|
610
|
+
self.d.data.device_logs['test_log'] = test_log
|
|
611
|
+
self.d.data.device_logs['check_log'] = test_log.copy()
|
|
612
|
+
action.perform_action(self.d)
|
|
613
|
+
self.assertEqual(17, self.d.data.pulses.shape[0])
|
|
614
|
+
np.testing.assert_array_equal(
|
|
615
|
+
self.d.data.device_logs['test_log'],
|
|
616
|
+
self.d.data.device_logs['check_log'],
|
|
617
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|