Skip to content

Commit cebc1cf

Browse files
authored
Merge pull request #486 from munechika-koyo/feature/raysect-0.9-compat
feat: Migrate to `raysect` v0.9
2 parents 36fde32 + 5810951 commit cebc1cf

11 files changed

Lines changed: 87 additions & 50 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@ on:
77
jobs:
88
tests:
99
name: Run tests
10-
runs-on: ubuntu-22.04 # Needed for Python 3.7 compatibility
10+
runs-on: ubuntu-latest
1111
strategy:
1212
fail-fast: false
1313
matrix:
14-
numpy-version: ["oldest-supported-numpy", "'numpy<2'"]
15-
python-version: ["3.7", "3.8", "3.9", "3.10"]
14+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
1615
steps:
1716
- name: Checkout code
1817
uses: actions/checkout@v2
@@ -23,9 +22,9 @@ jobs:
2322
with:
2423
python-version: ${{ matrix.python-version }}
2524
- name: Install Python dependencies
26-
run: python -m pip install --prefer-binary cython~=3.0 ${{ matrix.numpy-version }} scipy matplotlib "pyopencl[pocl]>=2022.2.4"
25+
run: python -m pip install --prefer-binary setuptools cython~=3.1 numpy>=2 scipy matplotlib "pyopencl[pocl]>=2022.2.4"
2726
- name: Install Raysect from pypi
28-
run: pip install raysect==0.8.1.*
27+
run: pip install raysect==0.9.*
2928
- name: Build cherab
3029
run: dev/build.sh
3130
- name: Run tests

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ New:
1111
* Add Function6D framework. (#478)
1212
* Add e_field attribute to Plasma object for electric field vector. (#465)
1313
* Add Integrator2D base class for integration of two-dimensional functions. (#472)
14+
* Support Raysect 0.9. (#486)
15+
* Test against Python 3.9, 3.10, 3.11, 3.12, 3.13 and latest released Numpy. Drop Python 3.7, 3.8 and older Numpy from tests. (#486)
1416

1517
Release 1.5.0 (27 Aug 2024)
1618
-------------------
@@ -137,7 +139,7 @@ API changes:
137139

138140
New:
139141
* Merged cherab-openadas package into the core cherab package to simplify installation.
140-
* Beam object uses a cone primitive instead of a cylinder for the bounding volume of divergent beams.
142+
* Beam object uses a cone primitive instead of a cylinder for the bounding volume of divergent beams.
141143
* Added Clamp functions.
142144
* Added ThermalCXRate.
143145
* Added optimised ray transfer grid calculation tools.
@@ -165,7 +167,7 @@ New:
165167

166168
Bug fixes:
167169
* Improved handling on non c-order arrays in various methods.
168-
* Numerous minor bug fixes (see commit history)
170+
* Numerous minor bug fixes (see commit history)
169171

170172

171173
Release 1.0.1 (1 Oct 2018)

cherab/core/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.6.0.dev1
1+
1.6.0.dev2

cherab/core/model/laser/profile.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ def generate_segmented_cylinder(radius, length):
738738
Generates a segmented cylindrical laser geometry
739739
740740
Approximates a long cylinder with a cylindrical segments to optimize
741-
targetted and importance sampling. The height of a cylinder segments is roughly
741+
targeted and importance sampling. The height of a cylinder segments is roughly
742742
2 * cylinder radius.
743743
744744
:return: List of cylinders

cherab/tools/observers/bolometry.py

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,17 @@
1818
# under the Licence.
1919

2020
from enum import Enum
21+
from warnings import warn
2122
import functools
2223
import numpy as np
2324

2425
from raysect.core import Node, translate, rotate_basis, Point3D, Vector3D, Ray as CoreRay, Primitive, World
25-
from raysect.core.math.sampler import TargettedHemisphereSampler, RectangleSampler3D
26+
from raysect.core.math.sampler import TargetedHemisphereSampler, RectangleSampler3D
2627
from raysect.primitive import Box, Cylinder, Subtract, Union
2728
from raysect.optical.observer import PowerPipeline0D, RadiancePipeline0D, \
28-
SpectralPowerPipeline0D, SpectralRadiancePipeline0D, SightLine, TargettedPixel
29+
SpectralPowerPipeline0D, SpectralRadiancePipeline0D, SightLine, TargetedPixel
2930
from raysect.optical.observer import PowerPipeline2D, RadiancePipeline2D, \
30-
SpectralPowerPipeline2D, SpectralRadiancePipeline2D, TargettedCCDArray
31+
SpectralPowerPipeline2D, SpectralRadiancePipeline2D, TargetedCCDArray
3132
from raysect.optical.material.material import NullMaterial
3233
from raysect.optical.material import AbsorbingSurface
3334

@@ -213,7 +214,7 @@ class BolometerSlit(Node):
213214
larger than the slit dx and dy, which can cause partial occlusion of
214215
nearby primitives. It also relies on no rays being launched with directions
215216
outside the solid angle of the aperture's bounding sphere: depending on the
216-
foil-slit distance and slit size, and also the foil's targetted_path_prob,
217+
foil-slit distance and slit size, and also the foil's targeted_path_prob,
217218
this may not be guaranteed. Supplying a proper mesh geometry for the camera
218219
is recommended instead of using a CSG aperture.
219220
@@ -351,7 +352,7 @@ def curvature_radius(self):
351352
return self._curvature_radius
352353

353354

354-
class BolometerFoil(TargettedPixel):
355+
class BolometerFoil(TargetedPixel):
355356
"""
356357
A rectangular foil bolometer detector.
357358
@@ -447,7 +448,7 @@ def __init__(self, detector_id, centre_point, basis_x, dx, basis_y, dy, slit,
447448
translation = translate(centre_point.x, centre_point.y, centre_point.z)
448449
rotation = rotate_basis(normal_vec, basis_y)
449450

450-
super().__init__([slit.target], targetted_path_prob=1.0,
451+
super().__init__([slit.target], targeted_path_prob=1.0,
451452
pixel_samples=1000, x_width=dx, y_width=dy, spectral_bins=1, quiet=True,
452453
parent=parent, transform=translation * rotation, name=detector_id)
453454

@@ -516,6 +517,24 @@ def accumulate(self, value):
516517
# Discard any samples from previous accumulate behaviour
517518
pipeline.value.clear()
518519

520+
@property
521+
def targetted_path_prob(self):
522+
warn(
523+
"The 'targetted_path_prob' property is deprecated, use 'targeted_path_prob' instead.",
524+
DeprecationWarning,
525+
stacklevel=2
526+
)
527+
return self._targeted_path_prob
528+
529+
@targetted_path_prob.setter
530+
def targetted_path_prob(self, value):
531+
warn(
532+
"The 'targetted_path_prob' property is deprecated, use 'targeted_path_prob' instead.",
533+
DeprecationWarning,
534+
stacklevel=2
535+
)
536+
self.targeted_path_prob = value
537+
519538
def as_sightline(self):
520539
"""
521540
Constructs a SightLine observer for this bolometer.
@@ -661,8 +680,8 @@ def calculate_etendue(self, ray_count=10000, batches=10, max_distance=1e999):
661680
# generate bounding sphere and convert to local coordinate system
662681
sphere = target.bounding_sphere()
663682
spheres = [(sphere.centre.transform(self.to_local()), sphere.radius, 1.0)]
664-
# instance targetted pixel sampler to sample directions
665-
targetted_sampler = TargettedHemisphereSampler(spheres)
683+
# instance targeted pixel sampler to sample directions
684+
targeted_sampler = TargetedHemisphereSampler(spheres)
666685
# instance rectangle pixel sampler to sample origins
667686
point_sampler = RectangleSampler3D(width=self.x_width, height=self.y_width)
668687

@@ -671,8 +690,8 @@ def etendue_single_run(_):
671690
origins = point_sampler(samples=ray_count)
672691
passed = 0.0
673692
for origin in origins:
674-
# obtain targetted vector sample
675-
direction, pdf = targetted_sampler(origin, pdf=True)
693+
# obtain targeted vector sample
694+
direction, pdf = targeted_sampler(origin, pdf=True)
676695
path_weight = R_2_PI * direction.z / pdf
677696
# Transform to world space
678697
origin = origin.transform(detector_transform)
@@ -701,7 +720,7 @@ def etendue_single_run(_):
701720
return etendue, etendue_error
702721

703722

704-
class BolometerIRVB(TargettedCCDArray):
723+
class BolometerIRVB(TargetedCCDArray):
705724
"""
706725
A rectangular infra red video bolometer (IRVB).
707726
@@ -784,7 +803,7 @@ def __init__(self, name, width, pixels, slit, transform, parent=None,
784803
self._accumulate = None # Will be set after pipeline is created.
785804

786805
super().__init__([slit.target], pixels=pixels, width=width,
787-
targetted_path_prob=0.99, parent=parent, pipelines=[],
806+
targeted_path_prob=0.99, parent=parent, pipelines=[],
788807
transform=transform, name=name)
789808
self.pixel_samples = 1000
790809
self.spectral_bins = 1
@@ -896,6 +915,24 @@ def accumulate(self, value):
896915
if pipeline.frame is not None:
897916
pipeline.frame.clear()
898917

918+
@property
919+
def targetted_path_prob(self):
920+
warn(
921+
"The 'targetted_path_prob' property is deprecated, use 'targeted_path_prob' instead.",
922+
DeprecationWarning,
923+
stacklevel=2,
924+
)
925+
return self._targeted_path_prob
926+
927+
@targetted_path_prob.setter
928+
def targetted_path_prob(self, value):
929+
warn(
930+
"The 'targetted_path_prob' property is deprecated, use 'targeted_path_prob' instead.",
931+
DeprecationWarning,
932+
stacklevel=2,
933+
)
934+
self.targeted_path_prob = value
935+
899936
def as_sightlines(self):
900937
"""
901938
Constructs a SightLine observer for each pixel in this bolometer.

cherab/tools/observers/group/targettedpixel.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
# under the Licence.
1818

1919
from numpy import ndarray
20-
from raysect.optical.observer import TargettedPixel
20+
from raysect.optical.observer import TargetedPixel
2121

2222
from .base import Observer0DGroup
2323

2424

2525
class TargettedPixelGroup(Observer0DGroup):
2626
"""
27-
A group of targetted pixel under a single scene-graph node.
27+
A group of targeted pixel under a single scene-graph node.
2828
2929
A scene-graph object regrouping a series of 'TargettedPixel'
3030
observers as a scene-graph parent. Allows combined observation and display
@@ -35,7 +35,8 @@ class TargettedPixelGroup(Observer0DGroup):
3535
:ivar list targets: Targets for preferential sampling
3636
:ivar list targetted_path_prob: Probability of ray being casted at the target
3737
"""
38-
_OBSERVER_TYPE = TargettedPixel
38+
39+
_OBSERVER_TYPE = TargetedPixel
3940

4041
@property
4142
def x_width(self):
@@ -76,7 +77,7 @@ def targets(self):
7677
"""
7778
List of target lists used by pixels for preferential sampling
7879
79-
:param list value: List of primitives to be set to each pixel or
80+
:param list value: List of primitives to be set to each pixel or
8081
list of lists containing targets specific for each pixel
8182
in this case the number of lists must match number of pixels
8283
@@ -100,17 +101,16 @@ def targets(self, value):
100101

101102
@property
102103
def targetted_path_prob(self):
103-
return [pixel.targetted_path_prob for pixel in self._observers]
104-
104+
return [pixel.targeted_path_prob for pixel in self._observers]
105+
105106
@targetted_path_prob.setter
106107
def targetted_path_prob(self, value):
107108
if isinstance(value, (list, tuple)):
108109
if len(value) == len(self._observers):
109110
for pixel, v in zip(self._observers, value):
110-
pixel.targetted_path_prob = v
111+
pixel.targeted_path_prob = v
111112
else:
112-
raise ValueError("The length of 'value' ({}) "
113-
"mismatches the number of pixels ({}).".format(len(value), len(self._observers)))
113+
raise ValueError("The length of 'value' ({}) mismatches the number of pixels ({}).".format(len(value), len(self._observers)))
114114
else:
115115
for pixel in self._observers:
116-
pixel.targetted_path_prob = value
116+
pixel.targeted_path_prob = value

cherab/tools/tests/test_observer_groups.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import unittest
22

33
from raysect.core.workflow import RenderEngine
4-
from raysect.optical.observer import Observer0D, SightLine, FibreOptic, Pixel, TargettedPixel, PowerPipeline0D, SpectralPowerPipeline0D
4+
from raysect.optical.observer import Observer0D, SightLine, FibreOptic, Pixel, TargetedPixel, PowerPipeline0D, SpectralPowerPipeline0D
55
from raysect.primitive import Sphere
66

77
from cherab.tools.observers.group.base import Observer0DGroup
@@ -26,7 +26,7 @@ def test_get_item(self):
2626
idx = slice(1, 3, 1)
2727
for observer, input_observer in zip(group[idx], self.observers[idx]):
2828
self.assertIs(observer, input_observer)
29-
29+
3030
for i, name in enumerate(names):
3131
self.assertIs(group[name], self.observers[i])
3232

@@ -83,7 +83,7 @@ def test_assignments(self):
8383
with self.assertRaises(ValueError):
8484
group.pipelines = [ppln_0]
8585

86-
# render_engine
86+
# render_engine
8787
engine = RenderEngine()
8888
group.render_engine = engine
8989
for group_engine in group.render_engine:
@@ -102,7 +102,7 @@ def test_assignments(self):
102102
with self.assertRaises(ValueError):
103103
group.render_engine = [RenderEngine() for _ in range(len(group) - 1)]
104104

105-
# wavelengths
105+
# wavelengths
106106
wvl = 500
107107
group.min_wavelength = wvl - 100
108108
group.max_wavelength = wvl + 100
@@ -139,7 +139,7 @@ def test_assignments(self):
139139
with self.assertRaises(ValueError):
140140
group.spectral_bins = [1000] * (len(group) + 1)
141141

142-
# quiet
142+
# quiet
143143
quiet = [True] * len(group)
144144
group.quiet = quiet
145145
self.assertListEqual(group.quiet, quiet)
@@ -152,7 +152,7 @@ def test_assignments(self):
152152
with self.assertRaises(ValueError):
153153
group.quiet = [False] * (len(group) + 1)
154154

155-
# rays
155+
# rays
156156
probs = [0.2 + i*0.1 for i in range(len(group))]
157157
max_depths = [5 + i for i in range(len(group))]
158158
min_depths = [2 + i for i in range(len(group))]
@@ -196,7 +196,7 @@ def test_assignments(self):
196196
group.ray_importance_sampling = [False] * (len(group) + 1)
197197
with self.assertRaises(ValueError):
198198
group.ray_important_path_weight = [0.7] * (len(group) + 1)
199-
199+
200200
# samples
201201
pixel_samples = [2000 + i*500 for i in range(len(group))]
202202
per_task = [5000 + i*100 for i in range(len(group))]
@@ -352,7 +352,7 @@ class TargettedPixelGroupTestCase(PixelGroupTestCase):
352352
_GROUP_CLASS = TargettedPixelGroup
353353

354354
def setUp(self):
355-
self.observers = [TargettedPixel(targets=[Sphere()], pipelines=[PowerPipeline0D()]) for _ in range(self._NUM)]
355+
self.observers = [TargetedPixel(targets=[Sphere()], pipelines=[PowerPipeline0D()]) for _ in range(self._NUM)]
356356

357357
def test_targets(self):
358358
group = self._GROUP_CLASS(observers=self.observers)
@@ -381,8 +381,8 @@ def test_targets(self):
381381

382382
prob = 0.8
383383
group.targetted_path_prob = prob
384-
for group_targetted_path_prob in group.targetted_path_prob:
385-
self.assertEqual(group_targetted_path_prob, prob)
384+
for group_targeted_path_prob in group.targetted_path_prob:
385+
self.assertEqual(group_targeted_path_prob, prob)
386386

387387
with self.assertRaises(ValueError):
388388
group.targetted_path_prob = [0.7] * (len(group) + 1)

cherab/tools/tests/test_voxels.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,7 @@ def test_rectangle_area(self):
280280
for rectangle in RECTANGULAR_VOXEL_COORDS:
281281
coords = np.asarray(rectangle)
282282
voxel = AxisymmetricVoxel(coords)
283-
dx = coords[:, 0].ptp()
284-
dy = coords[:, 1].ptp()
283+
dx, dy = np.ptp(coords, axis=0)
285284
expected_area = dx * dy
286285
self.assertEqual(voxel.cross_sectional_area, expected_area)
287286

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[build-system]
2-
requires = ["setuptools>=62.3", "oldest-supported-numpy", "cython~=3.0", "raysect==0.8.1.*"]
2+
requires = ["setuptools>=62.3", "numpy", "cython~=3.1", "raysect==0.9.1.*"]
33
build-backend="setuptools.build_meta"

requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
cython~=3.0
2-
numpy>=1.14,<2.0
1+
cython~=3.1
2+
numpy>=2.0
33
scipy
44
matplotlib
5-
raysect==0.8.1.*
5+
raysect==0.9.1.*

0 commit comments

Comments
 (0)