amor-eos 3.2.7__tar.gz → 3.3.0__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.
Files changed (43) hide show
  1. {amor_eos-3.2.7 → amor_eos-3.3.0}/PKG-INFO +5 -1
  2. amor_eos-3.3.0/README.rst +38 -0
  3. {amor_eos-3.2.7 → amor_eos-3.3.0}/amor_eos.egg-info/PKG-INFO +5 -1
  4. {amor_eos-3.2.7 → amor_eos-3.3.0}/amor_eos.egg-info/SOURCES.txt +1 -0
  5. {amor_eos-3.2.7 → amor_eos-3.3.0}/amor_eos.egg-info/requires.txt +4 -0
  6. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/__init__.py +2 -2
  7. amor_eos-3.3.0/eos/compat.py +44 -0
  8. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/event_data_types.py +7 -0
  9. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/event_handling.py +12 -2
  10. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/file_reader.py +199 -75
  11. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/options.py +3 -3
  12. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/projection.py +9 -8
  13. amor_eos-3.3.0/eos/reduction_kafka.py +203 -0
  14. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/reduction_reflectivity.py +11 -6
  15. {amor_eos-3.2.7 → amor_eos-3.3.0}/setup.cfg +4 -0
  16. {amor_eos-3.2.7 → amor_eos-3.3.0}/tests/test_event_handling.py +12 -6
  17. {amor_eos-3.2.7 → amor_eos-3.3.0}/tests/test_full_analysis.py +28 -0
  18. amor_eos-3.2.7/README.rst +0 -27
  19. amor_eos-3.2.7/eos/reduction_kafka.py +0 -128
  20. {amor_eos-3.2.7 → amor_eos-3.3.0}/LICENSE +0 -0
  21. {amor_eos-3.2.7 → amor_eos-3.3.0}/amor_eos.egg-info/dependency_links.txt +0 -0
  22. {amor_eos-3.2.7 → amor_eos-3.3.0}/amor_eos.egg-info/entry_points.txt +0 -0
  23. {amor_eos-3.2.7 → amor_eos-3.3.0}/amor_eos.egg-info/top_level.txt +0 -0
  24. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/__main__.py +0 -0
  25. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/command_line.py +0 -0
  26. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/const.py +0 -0
  27. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/e2h.py +0 -0
  28. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/event_analysis.py +0 -0
  29. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/header.py +0 -0
  30. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/helpers.py +0 -0
  31. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/helpers_fallback.py +0 -0
  32. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/helpers_numba.py +0 -0
  33. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/instrument.py +0 -0
  34. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/kafka_events.py +0 -0
  35. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/kafka_serializer.py +0 -0
  36. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/logconfig.py +0 -0
  37. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/ls.py +0 -0
  38. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/nicos.py +0 -0
  39. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/nicos_interface.py +0 -0
  40. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/normalization.py +0 -0
  41. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/path_handling.py +0 -0
  42. {amor_eos-3.2.7 → amor_eos-3.3.0}/eos/reduction_e2h.py +0 -0
  43. {amor_eos-3.2.7 → amor_eos-3.3.0}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amor_eos
3
- Version: 3.2.7
3
+ Version: 3.3.0
4
4
  Summary: EOS reflectometry reduction for AMOR instrument
5
5
  Author: Jochen Stahn - Paul Scherrer Institut
6
6
  Author-email: jochen.stahn@psi.ch
@@ -16,6 +16,10 @@ Requires-Dist: numpy
16
16
  Requires-Dist: h5py
17
17
  Requires-Dist: orsopy
18
18
  Requires-Dist: numba
19
+ Requires-Dist: matplotlib
20
+ Requires-Dist: tabulate
21
+ Requires-Dist: ess-streaming-data-types
22
+ Requires-Dist: confluent-kafka
19
23
  Requires-Dist: backports.strenum; python_version < "3.11"
20
24
  Requires-Dist: backports.zoneinfo; python_version < "3.9"
21
25
  Dynamic: license-file
@@ -0,0 +1,38 @@
1
+ *************************************************************
2
+ EOS - The AMOR focusing reflectometry data reduction software
3
+ *************************************************************
4
+
5
+ .. image:: https://img.shields.io/pypi/v/amor-eos.svg
6
+ :target: https://pypi.python.org/pypi/amor-eos/
7
+
8
+
9
+ Software repository for the neutron reflectometer Amor at the Paul Scherrer Institut, Switzerland
10
+
11
+ Reduction of the raw files (.hdf) to reflectivity files in one of the representations of the **ORSO reflectivity file format**:
12
+
13
+ eos --help
14
+
15
+ visualisation of the content of a raw file (.hdf):
16
+
17
+ events2histogram.py
18
+
19
+ :TODO: real readme for final system needed.
20
+
21
+ Installation
22
+ ============
23
+
24
+ Python Environment
25
+ ------------------
26
+
27
+ Create a [virtual python environment](https://docs.python.org/3/library/venv.html) (>3.8) and install the PyPI package:
28
+
29
+ pip install amor-eos
30
+
31
+ Windows Binary
32
+ --------------
33
+
34
+ On Windows you can use the binary eos.exe that you find in the
35
+ [Gitea Releases](https://gitea.psi.ch/sinq-reflectometry/eos/releases/latest) section.
36
+
37
+ Either extract it to the folder where you analyze your data or choose a common location and make sure
38
+ that is in the system PATH to be able to run the program from command line.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amor_eos
3
- Version: 3.2.7
3
+ Version: 3.3.0
4
4
  Summary: EOS reflectometry reduction for AMOR instrument
5
5
  Author: Jochen Stahn - Paul Scherrer Institut
6
6
  Author-email: jochen.stahn@psi.ch
@@ -16,6 +16,10 @@ Requires-Dist: numpy
16
16
  Requires-Dist: h5py
17
17
  Requires-Dist: orsopy
18
18
  Requires-Dist: numba
19
+ Requires-Dist: matplotlib
20
+ Requires-Dist: tabulate
21
+ Requires-Dist: ess-streaming-data-types
22
+ Requires-Dist: confluent-kafka
19
23
  Requires-Dist: backports.strenum; python_version < "3.11"
20
24
  Requires-Dist: backports.zoneinfo; python_version < "3.9"
21
25
  Dynamic: license-file
@@ -11,6 +11,7 @@ amor_eos.egg-info/top_level.txt
11
11
  eos/__init__.py
12
12
  eos/__main__.py
13
13
  eos/command_line.py
14
+ eos/compat.py
14
15
  eos/const.py
15
16
  eos/e2h.py
16
17
  eos/event_analysis.py
@@ -2,6 +2,10 @@ numpy
2
2
  h5py
3
3
  orsopy
4
4
  numba
5
+ matplotlib
6
+ tabulate
7
+ ess-streaming-data-types
8
+ confluent-kafka
5
9
 
6
10
  [:python_version < "3.11"]
7
11
  backports.strenum
@@ -2,5 +2,5 @@
2
2
  Package to handle data redction at AMOR instrument to be used by __main__.py script.
3
3
  """
4
4
 
5
- __version__ = '3.2.7'
6
- __date__ = '2026-03-13'
5
+ __version__ = '3.3.0'
6
+ __date__ = '2026-07-09'
@@ -0,0 +1,44 @@
1
+ """
2
+ Presever compatibility with previous versions of AMOR datafiles.
3
+ """
4
+
5
+ from datetime import datetime
6
+
7
+ # old hdf parameter mappings, key is last date of validity
8
+ legacy_hdf_paths = {
9
+ datetime(2026, 3, 18).timestamp():
10
+ dict(
11
+ title=('entry1/title', str),
12
+ proposal_id=('entry1/proposal_id', str),
13
+ user_name=('entry1/user/name', str),
14
+ user_email=('entry1/user/email', str),
15
+ sample_name=('entry1/sample/name', str),
16
+ source_name=('entry1/Amor/source/name', str),
17
+ sample_model=('entry1/sample/model', str),
18
+ start_time=('entry1/start_time', str),
19
+ start_time_fallback=('entry1/Amor/instrument_control_parameters/start_time', str),
20
+
21
+ chopper_separation=('entry1/Amor/chopper/pair_separation', float),
22
+ detector_distance=('entry1/Amor/detector/transformation/distance', float),
23
+ chopper_distance=('entry1/Amor/chopper/distance', float),
24
+ sample_temperature=('entry1/sample/temperature', float),
25
+ sample_magnetic_field=('entry1/sample/magnetic_field', float),
26
+
27
+ mu=('entry1/Amor/instrument_control_parameters/mu', float, 'mu'),
28
+ nu=('entry1/Amor/instrument_control_parameters/nu', float, 'nu'),
29
+ kap=('entry1/Amor/instrument_control_parameters/kappa', float, 'kappa'),
30
+ kad=('entry1/Amor/instrument_control_parameters/kappa_offset', float, 'kappa_offset'),
31
+ div=('entry1/Amor/instrument_control_parameters/div', float, 'div'),
32
+ ch1_trigger_phase=('entry1/Amor/chopper/ch1_trigger_phase', float, 'ch1_trigger_phase'),
33
+ ch2_trigger_phase=('entry1/Amor/chopper/ch2_trigger_phase', float, 'ch2_trigger_phase'),
34
+ chopper_speed=('entry1/Amor/chopper/rotation_speed', float, 'chopper_phase'),
35
+ chopper_phase=('entry1/Amor/chopper/phase', float, 'chopper_phase'),
36
+ polarization_config_label=('entry1/Amor/polarization/configuration', int, 'polarization_config_label', '/*'),
37
+
38
+ data=('entry1/Amor/detector/data', None), # data group used to load events from
39
+ trigger=('entry1/Amor/chopper/ch2_trigger', float),
40
+ proton_current=('entry1/Amor/detector/proton_current', None),
41
+ ),
42
+ }
43
+ # create a sorted list of validity timestamps for quick comparison
44
+ legacy_cutoffs = list(sorted(legacy_hdf_paths.keys()))
@@ -29,11 +29,17 @@ class AmorTiming:
29
29
  chopperPhase: float
30
30
  tau: float
31
31
 
32
+ @dataclass
33
+ class DA00EventBuffer:
34
+ signal: np.ndarray
35
+ time: np.ndarray
36
+
32
37
  # Structured datatypes used for event streams
33
38
  EVENT_TYPE = np.dtype([('tof', np.float64), ('pixelID', np.uint32), ('mask', np.int32)])
34
39
  PACKET_TYPE = np.dtype([('start_index', np.uint32), ('time', np.int64)])
35
40
  PULSE_TYPE = np.dtype([('time', np.int64), ('monitor', np.float32)])
36
41
  PC_TYPE = np.dtype([('current', np.float32), ('time', np.int64)])
42
+ BM_TYPE = np.dtype([('value', np.int32), ('time', np.int64)])
37
43
  LOG_TYPE = np.dtype([('value', np.float32), ('time', np.int64)])
38
44
 
39
45
  # define the bitmask for individual event filters
@@ -63,6 +69,7 @@ class AmorEventStream:
63
69
  packets: np.recarray # PACKET_TYPE
64
70
  pulses: np.recarray # PULSE_TYPE
65
71
  proton_current: np.recarray # PC_TYPE
72
+ beam_monitor: Optional[np.recarray] = None # BM_TYPE
66
73
  device_logs: Dict[str, np.recarray] = field(default_factory=dict) # LOG_TYPE
67
74
 
68
75
  class EventDatasetProtocol(Protocol):
@@ -91,6 +91,16 @@ class AssociatePulseWithMonitor(EventDataAction):
91
91
  * 2*dataset.timing.tau * 1e-3
92
92
  elif self.monitorType==MonitorType.time:
93
93
  dataset.data.pulses.monitor = 2*dataset.timing.tau
94
+ elif self.monitorType==MonitorType.neutron_monitor:
95
+ if dataset.data.pulses.monitor is None:
96
+ logging.warning(" Neutron monitor was selected for normalization but not presend, "
97
+ "falling back to proton current")
98
+ dataset.data.pulses.monitor = self.get_current_per_pulse(dataset.data.pulses.time,
99
+ dataset.data.proton_current.time,
100
+ dataset.data.proton_current.current) \
101
+ *2*dataset.timing.tau*1e-3
102
+ else:
103
+ dataset.data.pulses.monitor = dataset.data.beam_monitor.value / 1e4
94
104
  else: # pulses
95
105
  dataset.data.pulses.monitor = 1
96
106
 
@@ -184,7 +194,7 @@ class ApplyMask(EventDataAction):
184
194
  fltr = (d.events.mask & (~self.bitmask_filter)) == 0
185
195
  d.events = d.events[fltr]
186
196
  post_filter = d.events.shape[0]
187
- logging.info(f' number of events: total = {pre_filter:7d}, filtered = {post_filter:7d}')
197
+ logging.info(f' number of events: total = {pre_filter:7d}, after filtering = {post_filter:7d}')
188
198
  if d.device_logs == {} or not hasattr(dataset, 'update_info_from_logs'):
189
199
  return
190
200
  # filter pulses and logs to allow update of header information
@@ -201,4 +211,4 @@ class ApplyMask(EventDataAction):
201
211
  d.device_logs[key] = np.recarray(d.pulses.shape, dtype = log.dtype)
202
212
  d.device_logs[key].time = d.pulses.time
203
213
  d.device_logs[key].value = d.pulses[key]
204
- dataset.update_info_from_logs()
214
+ dataset.update_info_from_logs()