Skip to content

Commit 13aa04d

Browse files
authored
Merge pull request #104 from scipp/lower-bounds
Fix lower bounds nightly build
2 parents 483e755 + 273506d commit 13aa04d

6 files changed

Lines changed: 131 additions & 134 deletions

File tree

pyproject.toml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,20 @@ requires-python = ">=3.11"
2929
# IMPORTANT:
3030
# Run 'tox -e deps' after making changes here. This will update requirement files.
3131
# Make sure to list one dependency per line.
32-
dependencies = ["plopp", "scipp", "scipy", "lazy-loader"]
32+
dependencies = [
33+
"plopp>=23.10.0",
34+
"scipp>=24.11.0",
35+
"scipy>=1.12.0",
36+
"lazy-loader>=0.3",
37+
]
3338

3439
dynamic = ["version"]
3540

3641
[project.optional-dependencies]
37-
test = ["pytest", "scippneutron"]
42+
test = [
43+
"pytest>=8.0",
44+
"scippneutron>=24.12.0",
45+
]
3846

3947
[project.urls]
4048
"Bug Tracker" = "https://github.com/scipp/tof/issues"

tests/__init__.py

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/common.py

Lines changed: 0 additions & 73 deletions
This file was deleted.

tests/conftest.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright (c) 2025 Scipp contributors (https://github.com/scipp)
3+
4+
import numpy as np
5+
import pytest
6+
import scipp as sc
7+
8+
import tof
9+
10+
11+
@pytest.fixture
12+
def make_chopper():
13+
def _make_chopper(topen, tclose, f, phase, distance, name):
14+
two_pi = 2.0 * np.pi * sc.units.rad
15+
aopen = two_pi * sc.concat(topen, dim='cutout').to(unit='s') * f
16+
aclose = two_pi * sc.concat(tclose, dim='cutout').to(unit='s') * f
17+
return tof.Chopper(
18+
frequency=f,
19+
open=aopen,
20+
close=aclose,
21+
phase=phase,
22+
distance=distance,
23+
name=name,
24+
)
25+
26+
return _make_chopper
27+
28+
29+
@pytest.fixture
30+
def make_source():
31+
def _make_source(arrival_times, distance, pulses=1, frequency=None):
32+
# Arrival times are distance * m_over_h * wavelength
33+
return tof.Source.from_neutrons(
34+
birth_times=sc.array(
35+
dims=['event'], values=[0.0] * len(arrival_times), unit='s'
36+
),
37+
wavelengths=arrival_times.to(unit='s') / (distance * tof.utils.m_over_h),
38+
pulses=pulses,
39+
frequency=frequency,
40+
)
41+
42+
return _make_source
43+
44+
45+
@pytest.fixture
46+
def dummy_chopper():
47+
return tof.Chopper(
48+
frequency=sc.scalar(1.0, unit="Hz"),
49+
open=sc.array(dims=['cutout'], values=[0.0], unit='deg'),
50+
close=sc.array(dims=['cutout'], values=[1.0], unit='deg'),
51+
phase=sc.scalar(0.0, unit="deg"),
52+
distance=sc.scalar(1.0, unit="m"),
53+
name='dummy_chopper',
54+
)
55+
56+
57+
@pytest.fixture
58+
def dummy_detector():
59+
return tof.Detector(
60+
distance=sc.scalar(1.0, unit="m"),
61+
name='dummy_detector',
62+
)
63+
64+
65+
@pytest.fixture
66+
def dummy_source():
67+
return tof.Source.from_neutrons(
68+
birth_times=sc.array(dims=['event'], values=[0.0], unit='s'),
69+
wavelengths=sc.array(dims=['event'], values=[1.0], unit='angstrom'),
70+
)

tests/model_test.py

Lines changed: 48 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,13 @@
1111

1212
import tof
1313

14-
from .common import (
15-
dummy_chopper,
16-
dummy_detector,
17-
dummy_source,
18-
make_chopper,
19-
make_source,
20-
)
21-
2214
Hz = sc.Unit('Hz')
2315
deg = sc.Unit('deg')
2416
meter = sc.Unit('m')
2517
ms = sc.Unit('ms')
2618

2719

28-
def test_one_chopper_one_opening():
20+
def test_one_chopper_one_opening(make_chopper, make_source):
2921
# Make a chopper open from 10-20 ms. Assume zero phase.
3022
topen = 10.0 * ms
3123
tclose = 20.0 * ms
@@ -79,7 +71,7 @@ def test_one_chopper_one_opening():
7971
)
8072

8173

82-
def test_two_choppers_one_opening():
74+
def test_two_choppers_one_opening(make_chopper, make_source):
8375
# Make a first chopper open from 5-16 ms. Assume zero phase.
8476
topen = 5.0 * ms
8577
tclose = 16.0 * ms
@@ -166,7 +158,7 @@ def test_two_choppers_one_opening():
166158
)
167159

168160

169-
def test_two_choppers_one_and_two_openings():
161+
def test_two_choppers_one_and_two_openings(make_chopper, make_source):
170162
topen = 5.0 * ms
171163
tclose = 16.0 * ms
172164
chopper1 = make_chopper(
@@ -224,7 +216,7 @@ def test_two_choppers_one_and_two_openings():
224216
)
225217

226218

227-
def test_neutron_conservation():
219+
def test_neutron_conservation(make_chopper):
228220
N = 100_000
229221
source = tof.Source(facility='ess', neutrons=N)
230222

@@ -266,20 +258,22 @@ def test_neutron_conservation():
266258
assert det.sum().value + det.masks['blocked_by_others'].sum().value == N
267259

268260

269-
def test_add_chopper_and_detector():
270-
chopper = dummy_chopper()
271-
detector = dummy_detector()
272-
model = tof.Model(source=dummy_source())
261+
def test_add_chopper_and_detector(dummy_chopper, dummy_detector, dummy_source):
262+
chopper = dummy_chopper
263+
detector = dummy_detector
264+
model = tof.Model(source=dummy_source)
273265
model.add(chopper)
274266
assert 'dummy_chopper' in model.choppers
275267
model.add(detector)
276268
assert 'dummy_detector' in model.detectors
277269

278270

279-
def test_add_components_with_same_name_raises():
280-
chopper = dummy_chopper()
281-
detector = dummy_detector()
282-
model = tof.Model(source=dummy_source())
271+
def test_add_components_with_same_name_raises(
272+
dummy_chopper, dummy_detector, dummy_source
273+
):
274+
chopper = dummy_chopper
275+
detector = dummy_detector
276+
model = tof.Model(source=dummy_source)
283277
model.add(chopper)
284278
with pytest.raises(
285279
KeyError, match='Component with name dummy_chopper already exists'
@@ -297,76 +291,78 @@ def test_add_components_with_same_name_raises():
297291
model.add(detector2)
298292

299293

300-
def test_create_model_with_duplicate_component_names_raises():
301-
chopper = dummy_chopper()
302-
detector = dummy_detector()
294+
def test_create_model_with_duplicate_component_names_raises(
295+
dummy_chopper, dummy_detector, dummy_source
296+
):
297+
chopper = dummy_chopper
298+
detector = dummy_detector
303299
with pytest.raises(
304300
ValueError, match="More than one component named 'dummy_chopper' found"
305301
):
306-
tof.Model(source=dummy_source(), choppers=[chopper, chopper])
302+
tof.Model(source=dummy_source, choppers=[chopper, chopper])
307303
with pytest.raises(
308304
ValueError, match="More than one component named 'dummy_detector' found"
309305
):
310-
tof.Model(source=dummy_source(), detectors=[detector, detector])
306+
tof.Model(source=dummy_source, detectors=[detector, detector])
311307

312308

313-
def test_iter():
314-
chopper = dummy_chopper()
315-
detector = dummy_detector()
316-
model = tof.Model(source=dummy_source())
309+
def test_iter(dummy_chopper, dummy_detector, dummy_source):
310+
chopper = dummy_chopper
311+
detector = dummy_detector
312+
model = tof.Model(source=dummy_source)
317313
model.add(chopper)
318314
assert 'dummy_chopper' in model.choppers
319315
model.add(detector)
320316
assert 'dummy_detector' in model.detectors
321317

322318

323-
def test_remove():
324-
chopper = dummy_chopper()
325-
detector = dummy_detector()
326-
model = tof.Model(source=dummy_source(), choppers=[chopper], detectors=[detector])
319+
def test_remove(dummy_chopper, dummy_detector, dummy_source):
320+
chopper = dummy_chopper
321+
detector = dummy_detector
322+
model = tof.Model(source=dummy_source, choppers=[chopper], detectors=[detector])
327323
del model['dummy_chopper']
328324
assert 'dummy_chopper' not in model
329325
assert 'dummy_detector' in model
330326
del model['dummy_detector']
331327
assert 'dummy_detector' not in model
332328

333329

334-
def test_getitem():
335-
chopper = dummy_chopper()
336-
detector = dummy_detector()
337-
model = tof.Model(source=dummy_source(), choppers=[chopper], detectors=[detector])
330+
def test_getitem(dummy_chopper, dummy_detector, dummy_source):
331+
chopper = dummy_chopper
332+
detector = dummy_detector
333+
model = tof.Model(source=dummy_source, choppers=[chopper], detectors=[detector])
338334
assert model['dummy_chopper'] is chopper
339335
assert model['dummy_detector'] is detector
340336
with pytest.raises(KeyError, match='No component with name foo'):
341337
model['foo']
342338

343339

344-
def test_input_can_be_single_component():
345-
chopper = dummy_chopper()
346-
detector = dummy_detector()
347-
model = tof.Model(source=dummy_source(), choppers=chopper, detectors=detector)
340+
def test_input_can_be_single_component(dummy_chopper, dummy_detector, dummy_source):
341+
chopper = dummy_chopper
342+
detector = dummy_detector
343+
model = tof.Model(source=dummy_source, choppers=chopper, detectors=detector)
348344
assert 'dummy_chopper' in model.choppers
349345
assert 'dummy_detector' in model.detectors
350346

351347

352-
def test_bad_input_type_raises():
353-
chopper = dummy_chopper()
354-
detector = dummy_detector()
348+
def test_bad_input_type_raises(dummy_chopper, dummy_detector, dummy_source):
349+
chopper = dummy_chopper
350+
detector = dummy_detector
355351
with pytest.raises(TypeError, match='Invalid input type'):
356-
_ = tof.Model(source=dummy_source(), choppers='bad chopper')
352+
_ = tof.Model(source=dummy_source, choppers='bad chopper')
357353
with pytest.raises(TypeError, match='Invalid input type'):
358-
_ = tof.Model(source=dummy_source(), choppers=[chopper], detectors='abc')
354+
_ = tof.Model(source=dummy_source, choppers=[chopper], detectors='abc')
359355
with pytest.raises(TypeError, match='Invalid input type'):
360-
_ = tof.Model(source=dummy_source(), choppers=[chopper, 'bad chopper'])
356+
_ = tof.Model(source=dummy_source, choppers=[chopper, 'bad chopper'])
361357
with pytest.raises(TypeError, match='Invalid input type'):
362-
_ = tof.Model(source=dummy_source(), detectors=(1234, detector))
358+
_ = tof.Model(source=dummy_source, detectors=(1234, detector))
363359
with pytest.raises(TypeError, match='Invalid input type'):
364-
_ = tof.Model(source=dummy_source(), choppers=[detector])
360+
_ = tof.Model(source=dummy_source, choppers=[detector])
365361
with pytest.raises(TypeError, match='Invalid input type'):
366-
_ = tof.Model(source=dummy_source(), detectors=[chopper])
362+
_ = tof.Model(source=dummy_source, detectors=[chopper])
367363

368364

369-
def test_model_repr_does_not_raise():
365+
def test_model_repr_does_not_raise(make_chopper, make_source):
370366
N = 10_000
371367
source = tof.Source(facility='ess', neutrons=N)
372368
chopper1 = make_chopper(
@@ -392,7 +388,7 @@ def test_model_repr_does_not_raise():
392388
assert repr(model) is not None
393389

394390

395-
def test_component_distance():
391+
def test_component_distance(make_chopper, make_source):
396392
# Make a chopper open from 10-20 ms. Assume zero phase.
397393
topen = 10.0 * ms
398394
tclose = 20.0 * ms

0 commit comments

Comments
 (0)