restage 0.4.0__tar.gz → 0.4.1__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 (33) hide show
  1. {restage-0.4.0/src/restage.egg-info → restage-0.4.1}/PKG-INFO +1 -1
  2. {restage-0.4.0 → restage-0.4.1}/src/restage/bifrost_choppers.py +6 -5
  3. {restage-0.4.0 → restage-0.4.1}/src/restage/cache.py +2 -1
  4. {restage-0.4.0 → restage-0.4.1}/src/restage/energy.py +11 -6
  5. {restage-0.4.0 → restage-0.4.1}/src/restage/instr.py +4 -18
  6. {restage-0.4.0 → restage-0.4.1/src/restage.egg-info}/PKG-INFO +1 -1
  7. {restage-0.4.0 → restage-0.4.1}/test/test_energy.py +36 -28
  8. {restage-0.4.0 → restage-0.4.1}/test/test_single.py +7 -0
  9. {restage-0.4.0 → restage-0.4.1}/.github/workflows/pip.yml +0 -0
  10. {restage-0.4.0 → restage-0.4.1}/.github/workflows/wheels.yml +0 -0
  11. {restage-0.4.0 → restage-0.4.1}/.gitignore +0 -0
  12. {restage-0.4.0 → restage-0.4.1}/README.md +0 -0
  13. {restage-0.4.0 → restage-0.4.1}/pyproject.toml +0 -0
  14. {restage-0.4.0 → restage-0.4.1}/setup.cfg +0 -0
  15. {restage-0.4.0 → restage-0.4.1}/src/restage/__init__.py +0 -0
  16. {restage-0.4.0 → restage-0.4.1}/src/restage/cspec_choppers.py +0 -0
  17. {restage-0.4.0 → restage-0.4.1}/src/restage/database.py +0 -0
  18. {restage-0.4.0 → restage-0.4.1}/src/restage/emulate.py +0 -0
  19. {restage-0.4.0 → restage-0.4.1}/src/restage/mcpl.py +0 -0
  20. {restage-0.4.0 → restage-0.4.1}/src/restage/range.py +0 -0
  21. {restage-0.4.0 → restage-0.4.1}/src/restage/run.py +0 -0
  22. {restage-0.4.0 → restage-0.4.1}/src/restage/scan.py +0 -0
  23. {restage-0.4.0 → restage-0.4.1}/src/restage/splitrun.py +0 -0
  24. {restage-0.4.0 → restage-0.4.1}/src/restage/tables.py +0 -0
  25. {restage-0.4.0 → restage-0.4.1}/src/restage.egg-info/SOURCES.txt +0 -0
  26. {restage-0.4.0 → restage-0.4.1}/src/restage.egg-info/dependency_links.txt +0 -0
  27. {restage-0.4.0 → restage-0.4.1}/src/restage.egg-info/entry_points.txt +0 -0
  28. {restage-0.4.0 → restage-0.4.1}/src/restage.egg-info/requires.txt +0 -0
  29. {restage-0.4.0 → restage-0.4.1}/src/restage.egg-info/top_level.txt +0 -0
  30. {restage-0.4.0 → restage-0.4.1}/test/test_cache.py +0 -0
  31. {restage-0.4.0 → restage-0.4.1}/test/test_database.py +0 -0
  32. {restage-0.4.0 → restage-0.4.1}/test/test_range.py +0 -0
  33. {restage-0.4.0 → restage-0.4.1}/test/test_scan.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: restage
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Author-email: Gregory Tucker <gregory.tucker@ess.eu>
5
5
  License: BSD-3-Clause
6
6
  Classifier: License :: OSI Approved :: BSD License
@@ -82,9 +82,7 @@ def bandwidth_chopper_speeds_phases(energy_minimum: float):
82
82
  return SOURCE_FREQUENCY, phase, -SOURCE_FREQUENCY, phase
83
83
 
84
84
 
85
- def calculate(order: float, time: float, energy: float, names: list[str] | None = None):
86
- if names is None or len(names) != 6:
87
- names = ['ps1', 'ps2', 'fo1', 'fo2', 'bw1', 'bw2']
85
+ def calculate(order: float, time: float, energy: float, names: tuple[str, ...]):
88
86
  a, b, c, d, e, f = names
89
87
  s, p = 'speed', 'phase'
90
88
  r = dict()
@@ -94,9 +92,12 @@ def calculate(order: float, time: float, energy: float, names: list[str] | None
94
92
  return r
95
93
 
96
94
 
97
- def main(order: float, time: float, energy: float, names: list[str] | None = None):
95
+ def main(order: float, time: float, energy: float, names: tuple[str, ...] | None = None):
98
96
  if names is None or len(names) != 6:
99
- names = ['ps1', 'ps2', 'fo1', 'fo2', 'bw1', 'bw2']
97
+ # names = ('ps1', 'ps2', 'fo1', 'fo2', 'bw1', 'bw2')
98
+ names = ('pulse_shaping_chopper_1', 'pulse_shaping_chopper_2',
99
+ 'frame_overlap_chopper_1', 'frame_overlap_chopper_2',
100
+ 'bandwidth_chopper_1', 'bandwidth_chopper_2')
100
101
  rep = calculate(order, time, energy, names)
101
102
  print(' '.join([f'{k}={v}' for k, v in rep.items()]))
102
103
 
@@ -2,7 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  from mccode_antlr.instr import Instr
4
4
  from .tables import InstrEntry, SimulationTableEntry, SimulationEntry
5
- from mccode_antlr.compiler.c import CBinaryTarget
6
5
 
7
6
 
8
7
  def setup_database(named: str):
@@ -54,6 +53,8 @@ def _compile_instr(entry: InstrEntry, instr: Instr, config: dict | None = None,
54
53
  generator = MCSTAS_GENERATOR
55
54
 
56
55
  output = directory_under_module_data_path('bin')
56
+ # TODO consider adding `dump_source=True` _and_ putting the resulting file into
57
+ # the cache in order to make debugging future problems a tiny bit easier.
57
58
  binary_path = compile_instrument(instr, target, output, generator=generator, config=config)
58
59
  entry.mccode_version = __version__
59
60
  entry.binary_path = str(binary_path)
@@ -10,13 +10,15 @@ def get_and_remove(d: dict, k: str, default=None):
10
10
  return default
11
11
 
12
12
 
13
- def one_generic_energy_to_chopper_parameters(calculate_choppers, time: float, order: int, parameters: dict):
13
+ def one_generic_energy_to_chopper_parameters(
14
+ calculate_choppers, chopper_names: tuple[str, ...],
15
+ time: float, order: int, parameters: dict):
14
16
  if any(x in parameters for x in ('ei', 'wavelength', 'lambda', 'energy', 'e')):
15
17
  ei = get_and_remove(parameters, 'ei', get_and_remove(parameters, 'energy', get_and_remove(parameters, 'e')))
16
18
  if ei is None:
17
19
  wavelength = get_and_remove(parameters, 'wavelength', get_and_remove(parameters, 'lambda'))
18
20
  ei = _wavelength_angstrom_to_energy_mev(wavelength)
19
- choppers = calculate_choppers(order, time, ei)
21
+ choppers = calculate_choppers(order, time, ei, names=chopper_names)
20
22
  parameters.update(choppers)
21
23
  return parameters
22
24
 
@@ -24,25 +26,28 @@ def one_generic_energy_to_chopper_parameters(calculate_choppers, time: float, or
24
26
  def bifrost_translate_energy_to_chopper_parameters(parameters: dict):
25
27
  from itertools import product
26
28
  from .bifrost_choppers import calculate
27
- for name in product([a+b for a, b in product(('ps', 'fo', 'bw'), ('1', '2'))], ('speed', 'phase')):
29
+ choppers = tuple(f'{a}_chopper_{b}' for a, b in product(['pulse_shaping', 'frame_overlap', 'bandwidth'], [1, 2]))
30
+ # names = [a+b for a, b in product(('ps', 'fo', 'bw'), ('1', '2'))]
31
+ for name in product(choppers, ('speed', 'phase')):
28
32
  name = ''.join(name)
29
33
  if name not in parameters:
30
34
  parameters[name] = 0
31
35
  order = get_and_remove(parameters, 'order', 14)
32
36
  time = get_and_remove(parameters, 'time', get_and_remove(parameters, 't', 170/180/(2 * 15 * 14)))
33
- return one_generic_energy_to_chopper_parameters(calculate, time, order, parameters)
37
+ return one_generic_energy_to_chopper_parameters(calculate, choppers, time, order, parameters)
34
38
 
35
39
 
36
40
  def cspec_translate_energy_to_chopper_parameters(parameters: dict):
37
41
  from itertools import product
38
42
  from .cspec_choppers import calculate
39
- for name in product(('bw1', 'bw2', 'bw3', 's', 'p', 'm1', 'm2'), ('speed', 'phase')):
43
+ choppers = ('bw1', 'bw2', 'bw3', 's', 'p', 'm1', 'm2')
44
+ for name in product(choppers, ('speed', 'phase')):
40
45
  name = ''.join(name)
41
46
  if name not in parameters:
42
47
  parameters[name] = 0
43
48
  time = get_and_remove(parameters, 'time', 0.004)
44
49
  order = get_and_remove(parameters, 'order', 16)
45
- return one_generic_energy_to_chopper_parameters(calculate, time, order, parameters)
50
+ return one_generic_energy_to_chopper_parameters(calculate, choppers, time, order, parameters)
46
51
 
47
52
 
48
53
  def no_op_translate_energy_to_chopper_parameters(parameters: dict):
@@ -6,10 +6,9 @@ from __future__ import annotations
6
6
  from pathlib import Path
7
7
  from typing import Union
8
8
  from mccode_antlr.instr import Instr
9
- from mccode_antlr.reader import Registry
10
9
 
11
10
 
12
- def load_instr(filepath: Union[str, Path], extra_registries: list[Registry] | None = None) -> Instr:
11
+ def load_instr(filepath: Union[str, Path]) -> Instr:
13
12
  """Loads an Instr object from a .instr file or a HDF5 file"""
14
13
  from mccode_antlr.io import load_hdf5
15
14
  from mccode_antlr.loader import load_mcstas_instr
@@ -19,23 +18,10 @@ def load_instr(filepath: Union[str, Path], extra_registries: list[Registry] | No
19
18
  if not filepath.exists() or not filepath.is_file():
20
19
  raise ValueError('The provided filepath does not exist or is not a file')
21
20
 
22
- # FIXME this hack should be removed ASAP
23
- if extra_registries is None:
24
- from mccode_antlr.reader import GitHubRegistry
25
- mcpl_input_once_registry = GitHubRegistry(
26
- name='mcpl_input_once',
27
- url='https://github.com/g5t/mccode-mcpl-input-once',
28
- version='main',
29
- filename='pooch-registry.txt'
30
- )
31
- extra_registries = [mcpl_input_once_registry]
32
-
33
21
  if filepath.suffix == '.instr':
34
- return load_mcstas_instr(filepath, registries=extra_registries)
22
+ return load_mcstas_instr(filepath)
35
23
 
36
- instr = load_hdf5(filepath)
37
- instr.registries += tuple(extra_registries)
38
- return instr
24
+ return load_hdf5(filepath)
39
25
 
40
26
 
41
27
  def collect_parameter_dict(instr: Instr, kwargs: dict, strict: bool = True) -> dict:
@@ -60,7 +46,7 @@ def collect_parameter_dict(instr: Instr, kwargs: dict, strict: bool = True) -> d
60
46
  for k, v in kwargs.items():
61
47
  if k not in parameters:
62
48
  if strict:
63
- raise ValueError(f"Parameter {k} is not a valid parameter name")
49
+ raise ValueError(f"Parameter {k} is not a valid parameter name. Valid names are: {', '.join(parameters)}")
64
50
  continue
65
51
  if not isinstance(v, Value):
66
52
  expected_type = parameters[k].data_type
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: restage
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Author-email: Gregory Tucker <gregory.tucker@ess.eu>
5
5
  License: BSD-3-Clause
6
6
  Classifier: License :: OSI Approved :: BSD License
@@ -1,20 +1,31 @@
1
1
  import unittest
2
2
 
3
+
4
+ def parameters(names: tuple[str, ...]):
5
+ from itertools import product
6
+ return tuple(x + y for x, y in product(names, ('speed', 'phase')))
7
+
8
+
9
+ CHOPPER_NAMES = ('pulse_shaping', 'frame_overlap', 'bandwidth')
10
+ CHOPPERS = tuple(f'{name}_chopper_{no}' for name in CHOPPER_NAMES for no in (1, 2))
11
+ OLD_CHOPPERS = tuple(f'{name}{no}' for name in ('ps', 'fo', 'bw') for no in (1, 2))
12
+
13
+
3
14
  class BIFROSTEnergyTestCase(unittest.TestCase):
4
15
  def setUp(self):
5
16
  from mccode_antlr.loader import parse_mcstas_instr
6
17
  instr = f"""DEFINE INSTRUMENT this_IS_NOT_BIFROST(
7
- ps1speed, ps1phase, ps2speed, ps2phase, fo1speed, fo1phase, bw1speed, bw1phase, bw2speed, bw2phase
18
+ pulse_shaping_chopper_1speed, pulse_shaping_chopper_1phase, pulse_shaping_chopper_2speed, pulse_shaping_chopper_2phase, frame_overlap_chopper_1speed, frame_overlap_chopper_1phase, bandwidth_chopper_1speed, bandwidth_chopper_1phase, bandwidth_chopper_2speed, bandwidth_chopper_2phase
8
19
  )
9
20
  TRACE
10
21
  COMPONENT origin = Arm() AT (0, 0, 0) ABSOLUTE
11
- COMPONENT ps1 = DiskChopper(theta_0=170, radius=0.35, nu=ps1speed, phase=ps1phase) AT (0, 0, 1) RELATIVE PREVIOUS
12
- COMPONENT ps2 = DiskChopper(theta_0=170, radius=0.35, nu=ps2speed, phase=ps2phase) AT (0, 0, 0.02) RELATIVE ps1
13
- COMPONENT fo1 = DiskChopper(theta_0=110, radius=0.35, nu=fo1speed, phase=fo1phase) AT (0, 0, 12) RELATIVE ps2
14
- COMPONENT fo2 = DiskChopper(theta_0=115, radius=0.35, nu=fo1speed, phase=fo1phase) AT (0, 0, 4) RELATIVE fo1
15
- COMPONENT bw1 = DiskChopper(theta_0=110, radius=0.35, nu=bw1speed, phase=bw1phase) AT (0, 0, 80) RELATIVE fo2
16
- COMPONENT bw2 = DiskChopper(theta_0=115, radius=0.35, nu=bw2speed, phase=bw2phase) AT (0, 0, 0.02) RELATIVE bw1
17
- COMPONENT sample = Arm() AT (0, 0, 80) RELATIVE bw2
22
+ COMPONENT pulse_shaping_chopper_1 = DiskChopper(theta_0=170, radius=0.35, nu=pulse_shaping_chopper_1speed, phase=pulse_shaping_chopper_1phase) AT (0, 0, 1) RELATIVE PREVIOUS
23
+ COMPONENT pulse_shaping_chopper_2 = DiskChopper(theta_0=170, radius=0.35, nu=pulse_shaping_chopper_2speed, phase=pulse_shaping_chopper_2phase) AT (0, 0, 0.02) RELATIVE pulse_shaping_chopper_1
24
+ COMPONENT frame_overlap_chopper_1 = DiskChopper(theta_0=110, radius=0.35, nu=frame_overlap_chopper_1speed, phase=frame_overlap_chopper_1phase) AT (0, 0, 12) RELATIVE pulse_shaping_chopper_2
25
+ COMPONENT frame_overlap_chopper_2 = DiskChopper(theta_0=115, radius=0.35, nu=frame_overlap_chopper_1speed, phase=frame_overlap_chopper_1phase) AT (0, 0, 4) RELATIVE frame_overlap_chopper_1
26
+ COMPONENT bandwidth_chopper_1 = DiskChopper(theta_0=110, radius=0.35, nu=bandwidth_chopper_1speed, phase=bandwidth_chopper_1phase) AT (0, 0, 80) RELATIVE frame_overlap_chopper_2
27
+ COMPONENT bandwidth_chopper_2 = DiskChopper(theta_0=115, radius=0.35, nu=bandwidth_chopper_2speed, phase=bandwidth_chopper_2phase) AT (0, 0, 0.02) RELATIVE bandwidth_chopper_1
28
+ COMPONENT sample = Arm() AT (0, 0, 80) RELATIVE bandwidth_chopper_2
18
29
  END
19
30
  """
20
31
  self.instr = parse_mcstas_instr(instr)
@@ -46,8 +57,8 @@ class BIFROSTEnergyTestCase(unittest.TestCase):
46
57
  e = y * 0.5 + 1.7
47
58
  self.assertAlmostEqual(x, e)
48
59
 
49
- parameters = dict(order=order, time=time, ei=ei)
50
- npts, names, points = parameters_to_scan(parameters, grid=True)
60
+ scan_parameters = dict(order=order, time=time, ei=ei)
61
+ npts, names, points = parameters_to_scan(scan_parameters, grid=True)
51
62
  self.assertEqual(npts, 47*11)
52
63
  self.assertEqual(names, ['order', 'time', 'ei'])
53
64
  all_points = list(points)
@@ -68,7 +79,7 @@ class BIFROSTEnergyTestCase(unittest.TestCase):
68
79
  from restage.energy import energy_to_chopper_translator
69
80
  from restage.energy import bifrost_translate_energy_to_chopper_parameters
70
81
  from restage.range import MRange, Singular, parameters_to_scan
71
- from itertools import product
82
+
72
83
 
73
84
  translator = energy_to_chopper_translator(self.instr.name)
74
85
  self.assertEqual(translator, bifrost_translate_energy_to_chopper_parameters)
@@ -76,36 +87,33 @@ class BIFROSTEnergyTestCase(unittest.TestCase):
76
87
  order = Singular(14, 1)
77
88
  time = MRange(0.0001, 0.002248, 0.0002)
78
89
  ei = MRange(1.7, 24.7, 0.5)
79
- parameters = dict(order=order, time=time, ei=ei)
90
+ scan_parameters = dict(order=order, time=time, ei=ei)
80
91
 
81
- spts, names, points = parameters_to_scan(parameters, grid=True)
92
+ spts, names, points = parameters_to_scan(scan_parameters, grid=True)
82
93
 
83
94
  self.assertEqual(47*11, spts)
84
95
  self.assertEqual(names, ['order', 'time', 'ei'])
85
96
 
86
- chopper_pars = [x + y for x, y in product(('ps1', 'ps2', 'fo1', 'fo2', 'bw1', 'bw2'), ('speed', 'phase'))]
87
-
97
+ chopper_parameters = parameters(CHOPPERS)
88
98
  for point in points:
89
99
  kv = {k: v for k, v in zip(names, point)}
90
100
  translated = translator(kv)
91
- for x in chopper_pars:
92
- self.assertTrue(''.join(x) in translated)
101
+ for x in chopper_parameters:
102
+ self.assertTrue(x in translated)
93
103
 
94
- self.assertEqual(len(translated), len(chopper_pars))
95
- self.assertAlmostEqual(translated['bw1speed'], 14.0)
96
- self.assertAlmostEqual(translated['bw2speed'], -14.0)
97
- self.assertAlmostEqual(translated['fo1speed'], 14.0)
98
- self.assertAlmostEqual(translated['fo1speed'], 14.0)
99
- self.assertAlmostEqual(translated['ps1speed'], 14*14.0)
100
- self.assertAlmostEqual(translated['ps2speed'], 14*14.0)
104
+ self.assertEqual(len(translated), len(chopper_parameters))
105
+ self.assertAlmostEqual(translated['bandwidth_chopper_1speed'], 14.0)
106
+ self.assertAlmostEqual(translated['bandwidth_chopper_2speed'], -14.0)
107
+ self.assertAlmostEqual(translated['frame_overlap_chopper_1speed'], 14.0)
108
+ self.assertAlmostEqual(translated['frame_overlap_chopper_1speed'], 14.0)
109
+ self.assertAlmostEqual(translated['pulse_shaping_chopper_1speed'], 14*14.0)
110
+ self.assertAlmostEqual(translated['pulse_shaping_chopper_2speed'], 14*14.0)
101
111
 
102
112
  def test_calculations(self):
103
113
  from itertools import product
104
114
  from chopcal import bifrost as mcstas_bifrost_calculation
105
115
  from restage.energy import bifrost_translate_energy_to_chopper_parameters
106
116
 
107
- pars = [x+y for x, y in product(('ps1', 'ps2', 'fo1', 'fo2', 'bw1', 'bw2'), ('speed', 'phase'))]
108
-
109
117
  shortest_time = 0.0001 # this is approximately twice the opening time of the pulse shaping choppers at 15*14 Hz
110
118
  # Normal operation Shortest full-height pulse Shorter pulses reduce height
111
119
  # /-----\ /\
@@ -129,8 +137,8 @@ class BIFROSTEnergyTestCase(unittest.TestCase):
129
137
  kv = {'order': order, 'time': time, 'ei': energy}
130
138
  translated = bifrost_translate_energy_to_chopper_parameters(kv)
131
139
  from_mcstas = mcstas_bifrost_calculation(energy, 0., time)
132
- for x in pars:
133
- self.assertAlmostEqual(from_mcstas[x], translated[x])
140
+ for o, x in zip(parameters(OLD_CHOPPERS), parameters(CHOPPERS)):
141
+ self.assertAlmostEqual(from_mcstas[o], translated[x])
134
142
 
135
143
 
136
144
  if __name__ == '__main__':
@@ -218,6 +218,13 @@ class SplitRunTestCase(unittest.TestCase):
218
218
  shutil.rmtree(self.dir)
219
219
 
220
220
  def test_simple_scan(self):
221
+ """This test requires MCPL shared libraries to work
222
+
223
+ For some unexplored reason, MCPL shared libraries are not found in their
224
+ default installed location, /usr/local/lib64/libmcpl.so; so this test must
225
+ be invoked with that location specified, e.g.,
226
+ $ LD_LIBRARY_PATH=/usr/local/lib64 pytest test/test_single.py -k test_simple_scan
227
+ """
221
228
  # Scanning a1 and a2 with a2=2*a1 should produce approximately the same intensity for all points
222
229
  # as long as a1 is between the limits of min_a1 and max_a1
223
230
  from restage.splitrun import splitrun
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