Skip to content

Commit 0c98d56

Browse files
authored
Merge pull request #487 from munechika-koyo/feature/API-change-targetedpixel
feat: Rename `TargettedPixelGroup` to `TargetedPixelGroup`
2 parents bbc1ed7 + f0a38db commit 0c98d56

File tree

7 files changed

+177
-89
lines changed

7 files changed

+177
-89
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Release 1.6.0 (TBD)
55
-------------------
66

77
API changes:
8+
* Rename `TargettedPixelGroup` to `TargetedPixelGroup` for correct spelling. Still keep `TargettedPixelGroup` as an alias for backwards compatibility until the next major release. (#487)
89
* Add emission model attribute access to line and lineshape . (#294)
910

1011
New:

cherab/tools/observers/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121
from .calcam import load_calcam_calibration
2222
from .intersections import find_wall_intersection
2323
from .spectroscopy import SpectroscopicSightLine, SpectroscopicFibreOptic
24-
from .group import PixelGroup, TargettedPixelGroup, SightLineGroup, FibreOpticGroup, SpectroscopicFibreOpticGroup, SpectroscopicSightLineGroup
24+
from .group import PixelGroup, TargetedPixelGroup, TargettedPixelGroup, SightLineGroup, FibreOpticGroup, SpectroscopicFibreOpticGroup, SpectroscopicSightLineGroup

cherab/tools/observers/group/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
# under the Licence.
1818

1919
from .fibreoptic import FibreOpticGroup
20-
from .sightline import SightLineGroup
21-
from .targettedpixel import TargettedPixelGroup
2220
from .pixel import PixelGroup
21+
from .sightline import SightLineGroup
2322
from .spectroscopic import SpectroscopicFibreOpticGroup, SpectroscopicSightLineGroup
23+
from .targetedpixel import TargetedPixelGroup
24+
from .targettedpixel import TargettedPixelGroup
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Copyright 2016-2021 Euratom
2+
# Copyright 2016-2021 United Kingdom Atomic Energy Authority
3+
# Copyright 2016-2021 Centro de Investigaciones Energéticas, Medioambientales y Tecnológicas
4+
#
5+
# Licensed under the EUPL, Version 1.1 or – as soon they will be approved by the
6+
# European Commission - subsequent versions of the EUPL (the "Licence");
7+
# You may not use this work except in compliance with the Licence.
8+
# You may obtain a copy of the Licence at:
9+
#
10+
# https://joinup.ec.europa.eu/software/page/eupl5
11+
#
12+
# Unless required by applicable law or agreed to in writing, software distributed
13+
# under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
14+
# CONDITIONS OF ANY KIND, either express or implied.
15+
#
16+
# See the Licence for the specific language governing permissions and limitations
17+
# under the Licence.
18+
19+
from numpy import ndarray
20+
from raysect.optical.observer import TargetedPixel
21+
22+
from .base import Observer0DGroup
23+
24+
25+
class TargetedPixelGroup(Observer0DGroup):
26+
"""
27+
A group of targeted pixels under a single scene-graph node.
28+
29+
A scene-graph object regrouping a series of 'TargetedPixel'
30+
observers as a scene-graph parent. Allows combined observation and display
31+
control simultaneously.
32+
33+
:ivar list x_width: Width of pixel along local x axis
34+
:ivar list y_width: Width of pixel along local y axis
35+
:ivar list targets: Targets for preferential sampling
36+
:ivar list targeted_path_prob: Probability of ray being casted at the target
37+
"""
38+
39+
_OBSERVER_TYPE = TargetedPixel
40+
41+
@property
42+
def x_width(self):
43+
return [pixel.x_width for pixel in self._observers]
44+
45+
@x_width.setter
46+
def x_width(self, value):
47+
if isinstance(value, (list, tuple, ndarray)):
48+
if len(value) == len(self._observers):
49+
for pixel, v in zip(self._observers, value):
50+
pixel.x_width = v
51+
else:
52+
raise ValueError(
53+
"The length of 'x_width' ({}) mismatches the number of pixels ({}).".format(len(value), len(self._observers))
54+
)
55+
else:
56+
for pixel in self._observers:
57+
pixel.x_width = value
58+
59+
@property
60+
def y_width(self):
61+
return [pixel.y_width for pixel in self._observers]
62+
63+
@y_width.setter
64+
def y_width(self, value):
65+
if isinstance(value, (list, tuple, ndarray)):
66+
if len(value) == len(self._observers):
67+
for pixel, v in zip(self._observers, value):
68+
pixel.y_width = v
69+
else:
70+
raise ValueError(
71+
"The length of 'y_width' ({}) mismatches the number of pixels ({}).".format(len(value), len(self._observers))
72+
)
73+
else:
74+
for pixel in self._observers:
75+
pixel.y_width = value
76+
77+
@property
78+
def targets(self):
79+
"""
80+
List of target lists used by pixels for preferential sampling
81+
82+
:param list value: List of primitives to be set to each pixel or
83+
list of lists containing targets specific for each pixel
84+
in this case the number of lists must match number of pixels
85+
86+
:rtype: list
87+
"""
88+
return [pixel.targets for pixel in self._observers]
89+
90+
@targets.setter
91+
def targets(self, value):
92+
if all(isinstance(v, (list, tuple)) for v in value):
93+
if len(value) == len(self._observers):
94+
for pixel, v in zip(self._observers, value):
95+
pixel.targets = v
96+
else:
97+
raise ValueError(
98+
"The number of provided target lists' ({}) mismatches the number of pixels ({}).".format(
99+
len(value), len(self._observers)
100+
)
101+
)
102+
else:
103+
# assuming a list of primitives, the pixel's setter will throw an error if not
104+
for pixel in self._observers:
105+
pixel.targets = value
106+
107+
@property
108+
def targeted_path_prob(self):
109+
return [pixel.targeted_path_prob for pixel in self._observers]
110+
111+
@targeted_path_prob.setter
112+
def targeted_path_prob(self, value):
113+
if isinstance(value, (list, tuple)):
114+
if len(value) == len(self._observers):
115+
for pixel, v in zip(self._observers, value):
116+
pixel.targeted_path_prob = v
117+
else:
118+
raise ValueError(
119+
"The length of 'value' ({}) mismatches the number of pixels ({}).".format(len(value), len(self._observers))
120+
)
121+
else:
122+
for pixel in self._observers:
123+
pixel.targeted_path_prob = value

cherab/tools/observers/group/targettedpixel.py

Lines changed: 18 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,20 @@
1616
# See the Licence for the specific language governing permissions and limitations
1717
# under the Licence.
1818

19-
from numpy import ndarray
20-
from raysect.optical.observer import TargetedPixel
19+
import warnings
2120

22-
from .base import Observer0DGroup
21+
from .targetedpixel import TargetedPixelGroup as _TargetedPixelGroup
2322

2423

25-
class TargettedPixelGroup(Observer0DGroup):
24+
class TargettedPixelGroup(_TargetedPixelGroup):
2625
"""
2726
A group of targeted pixel under a single scene-graph node.
2827
29-
A scene-graph object regrouping a series of 'TargettedPixel'
28+
.. deprecated::
29+
`TargettedPixelGroup` is deprecated and will be removed in version 2.0.
30+
Use `TargetedPixelGroup` instead.
31+
32+
A scene-graph object regrouping a series of `TargetedPixel`
3033
observers as a scene-graph parent. Allows combined observation and display
3134
control simultaneously.
3235
@@ -36,81 +39,19 @@ class TargettedPixelGroup(Observer0DGroup):
3639
:ivar list targetted_path_prob: Probability of ray being casted at the target
3740
"""
3841

39-
_OBSERVER_TYPE = TargetedPixel
40-
41-
@property
42-
def x_width(self):
43-
return [pixel.x_width for pixel in self._observers]
44-
45-
@x_width.setter
46-
def x_width(self, value):
47-
if isinstance(value, (list, tuple, ndarray)):
48-
if len(value) == len(self._observers):
49-
for pixel, v in zip(self._observers, value):
50-
pixel.x_width = v
51-
else:
52-
raise ValueError("The length of 'x_width' ({}) "
53-
"mismatches the number of pixels ({}).".format(len(value), len(self._observers)))
54-
else:
55-
for pixel in self._observers:
56-
pixel.x_width = value
57-
58-
@property
59-
def y_width(self):
60-
return [pixel.y_width for pixel in self._observers]
61-
62-
@y_width.setter
63-
def y_width(self, value):
64-
if isinstance(value, (list, tuple, ndarray)):
65-
if len(value) == len(self._observers):
66-
for pixel, v in zip(self._observers, value):
67-
pixel.y_width = v
68-
else:
69-
raise ValueError("The length of 'y_width' ({}) "
70-
"mismatches the number of pixels ({}).".format(len(value), len(self._observers)))
71-
else:
72-
for pixel in self._observers:
73-
pixel.y_width = value
74-
75-
@property
76-
def targets(self):
77-
"""
78-
List of target lists used by pixels for preferential sampling
79-
80-
:param list value: List of primitives to be set to each pixel or
81-
list of lists containing targets specific for each pixel
82-
in this case the number of lists must match number of pixels
83-
84-
:rtype: list
85-
"""
86-
return [pixel.targets for pixel in self._observers]
87-
88-
@targets.setter
89-
def targets(self, value):
90-
if all(isinstance(v, (list, tuple)) for v in value):
91-
if len(value) == len(self._observers):
92-
for pixel, v in zip(self._observers, value):
93-
pixel.targets = v
94-
else:
95-
raise ValueError("The number of provided target lists' ({}) "
96-
"mismatches the number of pixels ({}).".format(len(value), len(self._observers)))
97-
else:
98-
# assuming a list of primitives, the pixel's setter will throw an error if not
99-
for pixel in self._observers:
100-
pixel.targets = value
42+
def __init__(self, *args, **kwargs):
43+
warnings.warn(
44+
"TargettedPixelGroup is deprecated and will be removed in version 2.0. "
45+
+ "Use TargetedPixelGroup instead.",
46+
DeprecationWarning,
47+
stacklevel=2,
48+
)
49+
super().__init__(*args, **kwargs)
10150

10251
@property
10352
def targetted_path_prob(self):
104-
return [pixel.targeted_path_prob for pixel in self._observers]
53+
return self.targeted_path_prob
10554

10655
@targetted_path_prob.setter
10756
def targetted_path_prob(self, value):
108-
if isinstance(value, (list, tuple)):
109-
if len(value) == len(self._observers):
110-
for pixel, v in zip(self._observers, value):
111-
pixel.targeted_path_prob = v
112-
else:
113-
raise ValueError("The length of 'value' ({}) mismatches the number of pixels ({}).".format(len(value), len(self._observers)))
114-
else:
115-
for pixel in self._observers:
116-
pixel.targeted_path_prob = value
57+
self.targeted_path_prob = value

cherab/tools/tests/test_observer_groups.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import unittest
2+
import warnings
23

34
from raysect.core.workflow import RenderEngine
45
from raysect.optical.observer import Observer0D, SightLine, FibreOptic, Pixel, TargetedPixel, PowerPipeline0D, SpectralPowerPipeline0D
56
from raysect.primitive import Sphere
67

8+
from cherab.tools.observers.group import FibreOpticGroup, PixelGroup, SightLineGroup, TargetedPixelGroup, TargettedPixelGroup
79
from cherab.tools.observers.group.base import Observer0DGroup
8-
from cherab.tools.observers.group import SightLineGroup, FibreOpticGroup, PixelGroup, TargettedPixelGroup
910
from cherab.tools.raytransfer import pipelines
1011

1112

@@ -348,8 +349,8 @@ def test_widths(self):
348349
group.y_width = [1e-1] * (len(group) + 1)
349350

350351

351-
class TargettedPixelGroupTestCase(PixelGroupTestCase):
352-
_GROUP_CLASS = TargettedPixelGroup
352+
class TargetedPixelGroupTestCase(PixelGroupTestCase):
353+
_GROUP_CLASS = TargetedPixelGroup
353354

354355
def setUp(self):
355356
self.observers = [TargetedPixel(targets=[Sphere()], pipelines=[PowerPipeline0D()]) for _ in range(self._NUM)]
@@ -374,15 +375,33 @@ def test_targets(self):
374375
with self.assertRaises(ValueError):
375376
group.targets = targets
376377

377-
# targetted path prob
378+
# targeted path prob
378379
prob = [0.9, 0.95, 1]
379-
group.targetted_path_prob = prob
380-
self.assertListEqual(group.targetted_path_prob, prob)
380+
group.targeted_path_prob = prob
381+
self.assertListEqual(group.targeted_path_prob, prob)
381382

382383
prob = 0.8
383-
group.targetted_path_prob = prob
384-
for group_targeted_path_prob in group.targetted_path_prob:
384+
group.targeted_path_prob = prob
385+
for group_targeted_path_prob in group.targeted_path_prob:
385386
self.assertEqual(group_targeted_path_prob, prob)
386387

387388
with self.assertRaises(ValueError):
388-
group.targetted_path_prob = [0.7] * (len(group) + 1)
389+
group.targeted_path_prob = [0.7] * (len(group) + 1)
390+
391+
392+
class TargettedPixelGroupTestCase(TargetedPixelGroupTestCase):
393+
"""Test case for deprecated TargettedPixelGroup class."""
394+
395+
_GROUP_CLASS = TargettedPixelGroup
396+
397+
def test_deprecation_warning(self):
398+
"""Test that using TargettedPixelGroup raises a deprecation warning."""
399+
with warnings.catch_warnings(record=True) as w:
400+
warnings.simplefilter("always")
401+
group = TargettedPixelGroup(observers=self.observers)
402+
403+
# Check that a warning was issued
404+
self.assertEqual(len(w), 1)
405+
self.assertTrue(issubclass(w[0].category, DeprecationWarning))
406+
self.assertIn("TargettedPixelGroup is deprecated", str(w[0].message))
407+
self.assertIn("Use TargetedPixelGroup instead", str(w[0].message))

docs/source/tools/observers.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ in the group.
127127
.. autoclass:: cherab.tools.observers.group.PixelGroup
128128
:members:
129129

130+
.. autoclass:: cherab.tools.observers.group.TargetedPixelGroup
131+
:members:
132+
130133
.. autoclass:: cherab.tools.observers.group.TargettedPixelGroup
131134
:members:
132135

0 commit comments

Comments
 (0)