Skip to content

Commit 7fe063c

Browse files
authored
Merge pull request #2854 from cta-observatory/sonar-fixes
Fix sonar complaints about float comparisons
2 parents a00a66b + 3c4007f commit 7fe063c

File tree

7 files changed

+122
-102
lines changed

7 files changed

+122
-102
lines changed

docs/conf.py

Lines changed: 79 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -104,65 +104,82 @@ def setup(app):
104104
getattr(traits, alias).__module__ = "ctapipe.core.traits"
105105

106106

107+
def add_reference_type(prefix, objs):
108+
return [(prefix, o) for o in objs]
109+
110+
107111
# These links are ignored in the checks, necessary due to broken intersphinx for
108112
# these
109-
nitpick_ignore = [
110-
# needed for building the docs with python 3.11 locally.
111-
# we use the lowest supported version on readthedocs,
112-
# so that is what we use in the intersphinx link above
113-
("py:class", "enum.StrEnum"),
114-
# these are coming from traitlets:
115-
("py:class", "t.Union"),
116-
("py:class", "t.Any"),
117-
("py:class", "t.Dict"),
118-
("py:class", "t.Optional"),
119-
("py:class", "t.Type"),
120-
("py:class", "t.List"),
121-
("py:class", "t.Tuple"),
122-
("py:class", "t.Sequence"),
123-
("py:class", "Config"),
124-
("py:class", "traitlets.config.configurable.Configurable"),
125-
("py:class", "traitlets.traitlets.HasTraits"),
126-
("py:class", "traitlets.traitlets.HasDescriptors"),
127-
("py:class", "traitlets.traitlets.TraitType"),
128-
("py:class", "traitlets.traitlets.BaseDescriptor"),
129-
("py:class", "traitlets.traitlets.List"),
130-
("py:class", "traitlets.traitlets.Container"),
131-
("py:class", "traitlets.traitlets.Instance"),
132-
("py:class", "traitlets.traitlets.ClassBasedTraitType"),
133-
("py:class", "traitlets.traitlets.Int"),
134-
("py:class", "traitlets.config.application.Application"),
135-
("py:class", "traitlets.utils.sentinel.Sentinel"),
136-
("py:class", "traitlets.traitlets.ObserveHandler"),
137-
("py:class", "traitlets.traitlets.T"),
138-
("py:class", "traitlets.traitlets.G"),
139-
("py:class", "Sentinel"),
140-
("py:class", "ObserveHandler"),
141-
("py:class", "dict[K, V]"),
142-
("py:class", "G"),
143-
("py:class", "K"),
144-
("py:class", "V"),
145-
("py:class", "StrDict"),
146-
("py:class", "ClassesType"),
147-
("py:class", "re.Pattern"),
148-
("py:class", "re.Pattern[t.Any]"),
149-
("py:class", "astropy.coordinates.baseframe.BaseCoordinateFrame"),
150-
("py:class", "astropy.table.table.Table"),
151-
("py:class", "eventio.simtel.simtelfile.SimTelFile"),
152-
("py:class", "ctapipe.compat.StrEnum"),
153-
("py:class", "ctapipe.compat.StrEnum"),
154-
("py:obj", "traitlets.traitlets.T"),
155-
("py:obj", "traitlets.traitlets.G"),
156-
("py:obj", "traitlets.traitlets.S"),
157-
("py:obj", "traitlets.config.boolean_flag"),
158-
("py:obj", "traitlets.TraitError"),
159-
("py:obj", "-v"), # fix for wrong syntax in a traitlets docstring
160-
("py:obj", "cls"),
161-
("py:obj", "name"),
162-
("py:meth", "MetaHasDescriptors.__init__"),
163-
("py:meth", "HasTraits.__new__"),
164-
("py:meth", "BaseDescriptor.instance_init"),
165-
]
113+
nitpick_ignore = add_reference_type(
114+
"py:class",
115+
[
116+
"enum.StrEnum",
117+
"t.Union",
118+
"t.Any",
119+
"t.Dict",
120+
"t.Optional",
121+
"t.Type",
122+
"t.List",
123+
"t.Tuple",
124+
"t.Sequence",
125+
"Config",
126+
"traitlets.config.configurable.Configurable",
127+
"traitlets.traitlets.HasTraits",
128+
"traitlets.traitlets.HasDescriptors",
129+
"traitlets.traitlets.TraitType",
130+
"traitlets.traitlets.BaseDescriptor",
131+
"traitlets.traitlets.List",
132+
"traitlets.traitlets.Container",
133+
"traitlets.traitlets.Instance",
134+
"traitlets.traitlets.ClassBasedTraitType",
135+
"traitlets.traitlets.Int",
136+
"traitlets.config.application.Application",
137+
"traitlets.utils.sentinel.Sentinel",
138+
"traitlets.traitlets.ObserveHandler",
139+
"traitlets.traitlets.T",
140+
"traitlets.traitlets.G",
141+
"Sentinel",
142+
"ObserveHandler",
143+
"dict[K, V]",
144+
"G",
145+
"K",
146+
"V",
147+
"StrDict",
148+
"ClassesType",
149+
"re.Pattern",
150+
"re.Pattern[t.Any]",
151+
"astropy.coordinates.baseframe.BaseCoordinateFrame",
152+
"astropy.table.table.Table",
153+
"eventio.simtel.simtelfile.SimTelFile",
154+
"ctapipe.compat.StrEnum",
155+
"ctapipe.compat.StrEnum",
156+
],
157+
)
158+
nitpick_ignore += add_reference_type(
159+
"py:obj",
160+
[
161+
# needed for building the docs with python 3.11 locally.
162+
# we use the lowest supported version on readthedocs,
163+
# so that is what we use in the intersphinx link above
164+
# these are coming from traitlets:
165+
"traitlets.traitlets.T",
166+
"traitlets.traitlets.G",
167+
"traitlets.traitlets.S",
168+
"traitlets.config.boolean_flag",
169+
"traitlets.TraitError",
170+
"-v", # fix for wrong syntax in a traitlets docstring
171+
"cls",
172+
"name",
173+
],
174+
)
175+
nitpick_ignore += add_reference_type(
176+
"py:meth",
177+
[
178+
"MetaHasDescriptors.__init__",
179+
"HasTraits.__new__",
180+
"BaseDescriptor.instance_init",
181+
],
182+
)
166183

167184
# Sphinx gallery config
168185

@@ -379,15 +396,18 @@ def setup(app):
379396
# Grouping the document tree into Texinfo files. List of tuples
380397
# (source start file, target name, title, author,
381398
# dir menu entry, description, category)
399+
description = (
400+
"Experimental Data Analysis for the"
401+
" Cherenkov Telescope Array Observatory (CTAO)."
402+
)
382403
texinfo_documents = [
383404
(
384405
master_doc,
385406
"ctapipe",
386407
"ctapipe Documentation",
387408
author,
388409
"ctapipe",
389-
"Experimental Data Analysis for the"
390-
"Cherenkov Telescope Array Observatory (CTAO).",
410+
description,
391411
"Science",
392412
)
393413
]

src/ctapipe/calib/camera/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from .calibrator import CameraCalibrator # noqa: F401
77
from .gainselection import GainSelector # noqa: F401
88

9-
__all__ = [
10-
# "CameraCalibrator",
11-
# "GainSelector",
12-
]
9+
# CameraCalibrator and GainSelector not added to __all__ here to avoid
10+
# docs build error as it would result in the class being exposed at 3 levels
11+
# which is not supported by sphinx
12+
__all__ = []

src/ctapipe/calib/camera/tests/test_calibrator.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import astropy.units as u
88
import numpy as np
9+
import pytest
910
from scipy.stats import norm
1011
from traitlets.config import Config
1112

@@ -367,8 +368,9 @@ def test_invalid_pixels(example_event, example_subarray):
367368
config=config,
368369
)
369370
calibrator(event)
370-
assert np.all(event.dl1.tel[tel_id].image == 1.0)
371-
assert np.all(event.dl1.tel[tel_id].peak_time == 20.0 / sampling_rate)
371+
dl1 = event.dl1.tel[tel_id]
372+
np.testing.assert_array_equal(dl1.image, 1.0)
373+
np.testing.assert_array_equal(dl1.peak_time, 20.0 / sampling_rate)
372374

373375
# test we can set the invalid pixel handler to None
374376
config.CameraCalibrator.invalid_pixel_handler_type = None
@@ -378,7 +380,7 @@ def test_invalid_pixels(example_event, example_subarray):
378380
)
379381
calibrator(event)
380382
assert event.dl1.tel[tel_id].image[0] == 9999
381-
assert event.dl1.tel[tel_id].peak_time[0] == 10.0 / sampling_rate
383+
assert event.dl1.tel[tel_id].peak_time[0] == pytest.approx(10.0 / sampling_rate)
382384

383385

384386
def test_no_gain_selection(prod5_gamma_simtel_path):
Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import astropy.units as u
22
from astropy.coordinates import AltAz, SkyCoord
3-
from pytest import approx
43

54

65
def test_nominal_to_horizontal_alt0_az0():
@@ -13,23 +12,23 @@ def test_nominal_to_horizontal_alt0_az0():
1312

1413
nominal_coord = SkyCoord(fov_lon=1 * u.deg, fov_lat=0 * u.deg, frame=nominal_frame)
1514
horizon_coord = nominal_coord.transform_to(horizon_frame)
16-
assert horizon_coord.az.deg == 1.0
17-
assert horizon_coord.alt.deg == 0.0
15+
assert u.isclose(horizon_coord.az, 1.0 * u.deg)
16+
assert u.isclose(horizon_coord.alt, 0.0 * u.deg)
1817

1918
nominal_coord = SkyCoord(fov_lon=-1 * u.deg, fov_lat=0 * u.deg, frame=nominal_frame)
2019
horizon_coord = nominal_coord.transform_to(horizon_frame)
21-
assert horizon_coord.az.wrap_at("180d").deg == -1.0
22-
assert horizon_coord.alt.deg == 0.0
20+
assert u.isclose(horizon_coord.az.wrap_at("180d"), -1.0 * u.deg)
21+
assert u.isclose(horizon_coord.alt, 0.0 * u.deg)
2322

2423
nominal_coord = SkyCoord(fov_lon=0 * u.deg, fov_lat=1 * u.deg, frame=nominal_frame)
2524
horizon_coord = nominal_coord.transform_to(horizon_frame)
26-
assert horizon_coord.az.deg == 0.0
27-
assert horizon_coord.alt.deg == 1.0
25+
assert u.isclose(horizon_coord.az, 0.0 * u.deg)
26+
assert u.isclose(horizon_coord.alt, 1.0 * u.deg)
2827

2928
nominal_coord = SkyCoord(fov_lon=0 * u.deg, fov_lat=-1 * u.deg, frame=nominal_frame)
3029
horizon_coord = nominal_coord.transform_to(horizon_frame)
31-
assert horizon_coord.az.deg == 0.0
32-
assert horizon_coord.alt.deg == -1.0
30+
assert u.isclose(horizon_coord.az, 0.0 * u.deg)
31+
assert u.isclose(horizon_coord.alt, -1.0 * u.deg)
3332

3433

3534
def test_nominal_to_horizontal_alt0_az180():
@@ -42,20 +41,20 @@ def test_nominal_to_horizontal_alt0_az180():
4241

4342
nominal_coord = SkyCoord(fov_lon=1 * u.deg, fov_lat=0 * u.deg, frame=nominal_frame)
4443
horizon_coord = nominal_coord.transform_to(horizon_frame)
45-
assert horizon_coord.az.deg == approx(181.0)
46-
assert horizon_coord.alt.deg == 0.0
44+
assert u.isclose(horizon_coord.az, 181.0 * u.deg)
45+
assert u.isclose(horizon_coord.alt, 0.0 * u.deg)
4746

4847
nominal_coord = SkyCoord(fov_lon=-1 * u.deg, fov_lat=0 * u.deg, frame=nominal_frame)
4948
horizon_coord = nominal_coord.transform_to(horizon_frame)
50-
assert horizon_coord.az.deg == approx(179.0)
51-
assert horizon_coord.alt.deg == 0.0
49+
assert u.isclose(horizon_coord.az, 179.0 * u.deg)
50+
assert u.isclose(horizon_coord.alt, 0.0 * u.deg)
5251

5352
nominal_coord = SkyCoord(fov_lon=0 * u.deg, fov_lat=1 * u.deg, frame=nominal_frame)
5453
horizon_coord = nominal_coord.transform_to(horizon_frame)
55-
assert horizon_coord.az.deg == 180.0
56-
assert horizon_coord.alt.deg == 1.0
54+
assert u.isclose(horizon_coord.az, 180.0 * u.deg)
55+
assert u.isclose(horizon_coord.alt, 1.0 * u.deg)
5756

5857
nominal_coord = SkyCoord(fov_lon=0 * u.deg, fov_lat=-1 * u.deg, frame=nominal_frame)
5958
horizon_coord = nominal_coord.transform_to(horizon_frame)
60-
assert horizon_coord.az.deg == 180.0
61-
assert horizon_coord.alt.deg == -1.0
59+
assert u.isclose(horizon_coord.az, 180.0 * u.deg)
60+
assert u.isclose(horizon_coord.alt, -1.0 * u.deg)
Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import astropy.units as u
22
from astropy.coordinates import AltAz, SkyCoord
3-
from pytest import approx
43

54

65
def test_telescope_to_horizontal_alt0_az0():
@@ -15,29 +14,29 @@ def test_telescope_to_horizontal_alt0_az0():
1514
fov_lon=1 * u.deg, fov_lat=0 * u.deg, frame=telescope_frame
1615
)
1716
horizon_coord = telescope_coord.transform_to(horizon_frame)
18-
assert horizon_coord.az.deg == 1.0
19-
assert horizon_coord.alt.deg == 0.0
17+
assert u.isclose(horizon_coord.az, 1.0 * u.deg)
18+
assert u.isclose(horizon_coord.alt, 0.0 * u.deg)
2019

2120
telescope_coord = SkyCoord(
2221
fov_lon=-1 * u.deg, fov_lat=0 * u.deg, frame=telescope_frame
2322
)
2423
horizon_coord = telescope_coord.transform_to(horizon_frame)
25-
assert horizon_coord.az.wrap_at("180d").deg == -1.0
26-
assert horizon_coord.alt.deg == 0.0
24+
assert u.isclose(horizon_coord.az.wrap_at("180d"), -1.0 * u.deg)
25+
assert u.isclose(horizon_coord.alt, 0.0 * u.deg)
2726

2827
telescope_coord = SkyCoord(
2928
fov_lon=0 * u.deg, fov_lat=1 * u.deg, frame=telescope_frame
3029
)
3130
horizon_coord = telescope_coord.transform_to(horizon_frame)
32-
assert horizon_coord.az.deg == 0.0
33-
assert horizon_coord.alt.deg == 1.0
31+
assert u.isclose(horizon_coord.az, 0.0 * u.deg)
32+
assert u.isclose(horizon_coord.alt, 1.0 * u.deg)
3433

3534
telescope_coord = SkyCoord(
3635
fov_lon=0 * u.deg, fov_lat=-1 * u.deg, frame=telescope_frame
3736
)
3837
horizon_coord = telescope_coord.transform_to(horizon_frame)
39-
assert horizon_coord.az.deg == 0.0
40-
assert horizon_coord.alt.deg == -1.0
38+
assert u.isclose(horizon_coord.az, 0.0 * u.deg)
39+
assert u.isclose(horizon_coord.alt, -1.0 * u.deg)
4140

4241

4342
def test_telescope_to_horizontal_alt0_az180():
@@ -52,26 +51,26 @@ def test_telescope_to_horizontal_alt0_az180():
5251
fov_lon=1 * u.deg, fov_lat=0 * u.deg, frame=telescope_frame
5352
)
5453
horizon_coord = telescope_coord.transform_to(horizon_frame)
55-
assert horizon_coord.az.deg == approx(181.0)
56-
assert horizon_coord.alt.deg == 0.0
54+
assert u.isclose(horizon_coord.az, 181.0 * u.deg)
55+
assert u.isclose(horizon_coord.alt, 0.0 * u.deg)
5756

5857
telescope_coord = SkyCoord(
5958
fov_lon=-1 * u.deg, fov_lat=0 * u.deg, frame=telescope_frame
6059
)
6160
horizon_coord = telescope_coord.transform_to(horizon_frame)
62-
assert horizon_coord.az.deg == approx(179.0)
63-
assert horizon_coord.alt.deg == 0.0
61+
assert u.isclose(horizon_coord.az, 179.0 * u.deg)
62+
assert u.isclose(horizon_coord.alt, 0.0 * u.deg)
6463

6564
telescope_coord = SkyCoord(
6665
fov_lon=0 * u.deg, fov_lat=1 * u.deg, frame=telescope_frame
6766
)
6867
horizon_coord = telescope_coord.transform_to(horizon_frame)
69-
assert horizon_coord.az.deg == 180.0
70-
assert horizon_coord.alt.deg == 1.0
68+
assert u.isclose(horizon_coord.az, 180.0 * u.deg)
69+
assert u.isclose(horizon_coord.alt, 1.0 * u.deg)
7170

7271
telescope_coord = SkyCoord(
7372
fov_lon=0 * u.deg, fov_lat=-1 * u.deg, frame=telescope_frame
7473
)
7574
horizon_coord = telescope_coord.transform_to(horizon_frame)
76-
assert horizon_coord.az.deg == 180.0
77-
assert horizon_coord.alt.deg == -1.0
75+
assert u.isclose(horizon_coord.az, 180.0 * u.deg)
76+
assert u.isclose(horizon_coord.alt, -1.0 * u.deg)

src/ctapipe/reco/impact.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ class before minimisation can take place. This simply copies a
758758
self.spe[i][:] = 0.5
759759

760760
# Set the image mask
761-
mask = self.image == 0.0
761+
mask = self.image <= 0.0
762762
self.pixel_x[mask], self.pixel_y[mask] = ma.masked, ma.masked
763763
self.image[mask] = ma.masked
764764
self.time[mask] = ma.masked

src/ctapipe/reco/tests/test_stereo_combination.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,4 +239,4 @@ def test_mean_prediction_single_event(weights):
239239
assert u.isclose(event.dl2.stereo.energy["dummy"].energy, 30 * u.GeV)
240240
assert u.isclose(event.dl2.stereo.geometry["dummy"].alt, 60.9748605 * u.deg)
241241
assert u.isclose(event.dl2.stereo.geometry["dummy"].az, 316.0365515 * u.deg)
242-
assert event.dl2.stereo.classification["dummy"].prediction == 0.6
242+
assert event.dl2.stereo.classification["dummy"].prediction == pytest.approx(0.6)

0 commit comments

Comments
 (0)