Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix empty reference location #2402

Merged
merged 10 commits into from
Sep 28, 2023
3 changes: 2 additions & 1 deletion ctapipe/calib/camera/tests/test_flatfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from ctapipe.instrument import SubarrayDescription


def test_flasherflatfieldcalculator(prod5_sst):
def test_flasherflatfieldcalculator(prod5_sst, reference_location):
"""test of flasherFlatFieldCalculator"""
tel_id = 0
n_gain = 2
Expand All @@ -22,6 +22,7 @@ def test_flasherflatfieldcalculator(prod5_sst):
"test array",
tel_positions={0: np.zeros(3) * u.m},
tel_descriptions={0: deepcopy(prod5_sst)},
reference_location=reference_location,
)
subarray.tel[0].camera.readout.reference_pulse_shape = np.ones((1, 2))
subarray.tel[0].camera.readout.reference_pulse_sample_width = u.Quantity(1, u.ns)
Expand Down
3 changes: 2 additions & 1 deletion ctapipe/calib/camera/tests/test_pedestals.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from ctapipe.instrument import SubarrayDescription


def test_pedestal_integrator(prod5_sst):
def test_pedestal_integrator(prod5_sst, reference_location):
"""test of PedestalIntegrator"""

tel_id = 0
Expand All @@ -28,6 +28,7 @@ def test_pedestal_integrator(prod5_sst):
"test array",
tel_positions={0: np.zeros(3) * u.m},
tel_descriptions={0: deepcopy(prod5_sst)},
reference_location=reference_location,
)
subarray.tel[0].camera.readout.reference_pulse_shape = np.ones((1, 2))
subarray.tel[0].camera.readout.reference_pulse_sample_width = u.Quantity(1, u.ns)
Expand Down
8 changes: 8 additions & 0 deletions ctapipe/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

from copy import deepcopy

import astropy.units as u
import pytest
from astropy.coordinates import EarthLocation
from pytest_astropy_header.display import PYTEST_HEADER_MODULES

from ctapipe.core import run_tool
Expand Down Expand Up @@ -616,3 +618,9 @@ def disp_reconstructor_path(model_tmp_path, gamma_train_clf):
)
assert ret == 0
return out_file


@pytest.fixture(scope="session")
def reference_location():
"""a dummy EarthLocation to use for SubarrayDescriptions"""
return EarthLocation(lon=-17 * u.deg, lat=28 * u.deg, height=2200 * u.m)
3 changes: 2 additions & 1 deletion ctapipe/coordinates/tests/test_impact_distance.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def test_impact_distance():
assert np.allclose(impacts, expected_impacts)


def test_shower_impact_distance():
def test_shower_impact_distance(reference_location):
"""test several boundary cases using the function that takes a Subarray and
Container
"""
Expand All @@ -63,6 +63,7 @@ def test_shower_impact_distance():
name="test",
tel_positions={1: [0, 0, 0] * u.m, 2: [0, 1, 0] * u.m, 3: [0, 2, 0] * u.m},
tel_descriptions={1: None, 2: None, 3: None},
reference_location=reference_location,
)

# coming from zenith to the center of the array, the impact distance should
Expand Down
18 changes: 10 additions & 8 deletions ctapipe/image/muon/tests/test_intensity_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def test_chord_length():
assert np.isclose(length, 0, atol=1e-15)


def test_muon_efficiency_fit(prod5_lst):
def test_muon_efficiency_fit(prod5_lst, reference_location):
from ctapipe.coordinates import CameraFrame, TelescopeFrame
from ctapipe.image.muon.intensity_fitter import (
MuonIntensityFitter,
Expand All @@ -29,9 +29,10 @@ def test_muon_efficiency_fit(prod5_lst):

telescope = prod5_lst
subarray = SubarrayDescription(
"LSTMono",
{0: [0, 0, 0] * u.m},
{0: telescope},
name="LSTMono",
tel_positions={0: [0, 0, 0] * u.m},
tel_descriptions={0: telescope},
reference_location=reference_location,
)

center_x = 0.8 * u.deg
Expand Down Expand Up @@ -94,15 +95,16 @@ def test_muon_efficiency_fit(prod5_lst):
assert np.isfinite(result.likelihood_value)


def test_scts(prod5_sst):
def test_scts(prod5_sst, reference_location):
from ctapipe.image.muon.intensity_fitter import MuonIntensityFitter
from ctapipe.instrument import SubarrayDescription

telescope = prod5_sst
subarray = SubarrayDescription(
"ssts",
{0: [0, 0, 0] * u.m},
{0: telescope},
name="ssts",
tel_positions={0: [0, 0, 0] * u.m},
tel_descriptions={0: telescope},
reference_location=reference_location,
)

fitter = MuonIntensityFitter(subarray=subarray)
Expand Down
9 changes: 6 additions & 3 deletions ctapipe/image/tests/test_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@


@pytest.fixture(scope="module")
def subarray(prod5_sst):
def subarray(prod5_sst, reference_location):
subarray = SubarrayDescription(
"test array",
tel_positions={1: np.zeros(3) * u.m, 2: np.zeros(3) * u.m},
tel_descriptions={
1: deepcopy(prod5_sst),
2: deepcopy(prod5_sst),
},
reference_location=reference_location,
)

# Create reference pulse
Expand All @@ -67,21 +68,23 @@ def subarray(prod5_sst):


@pytest.fixture(scope="module")
def subarray_1_LST(prod3_lst):
def subarray_1_LST(prod3_lst, reference_location):
subarray = SubarrayDescription(
"One LST",
tel_positions={1: np.zeros(3) * u.m},
tel_descriptions={1: prod3_lst},
reference_location=reference_location,
)
return subarray


@pytest.fixture(scope="module")
def subarray_mst_fc(prod5_mst_flashcam):
def subarray_mst_fc(prod5_mst_flashcam, reference_location):
subarray = SubarrayDescription(
"One MST with FlashCam",
tel_positions={1: np.zeros(3) * u.m},
tel_descriptions={1: prod5_mst_flashcam},
reference_location=reference_location,
)
return subarray

Expand Down
3 changes: 2 additions & 1 deletion ctapipe/image/tests/test_image_cleaner_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


@pytest.mark.parametrize("method", ImageCleaner.non_abstract_subclasses().keys())
def test_image_cleaner(method, prod5_mst_nectarcam):
def test_image_cleaner(method, prod5_mst_nectarcam, reference_location):
"""Test that we can construct and use a component-based ImageCleaner"""

config = Config(
Expand All @@ -32,6 +32,7 @@ def test_image_cleaner(method, prod5_mst_nectarcam):
name="test",
tel_positions={1: None},
tel_descriptions={1: prod5_mst_nectarcam},
reference_location=reference_location,
)

clean = ImageCleaner.from_name(method, config=config, subarray=subarray)
Expand Down
3 changes: 2 additions & 1 deletion ctapipe/image/tests/test_reducer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


@pytest.fixture(scope="module")
def subarray_lst(prod3_lst):
def subarray_lst(prod3_lst, reference_location):
tel_id = 1
subarray = SubarrayDescription(
"test array lst",
Expand All @@ -18,6 +18,7 @@ def subarray_lst(prod3_lst):
1: prod3_lst,
2: prod3_lst,
},
reference_location=reference_location,
)

n_pixels = subarray.tel[tel_id].camera.geometry.n_pixels
Expand Down
3 changes: 2 additions & 1 deletion ctapipe/image/tests/test_sliding_window_correction.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from ctapipe.instrument import SubarrayDescription


def test_sw_pulse_lst(prod5_lst):
def test_sw_pulse_lst(prod5_lst, reference_location):
"""
Test function of sliding window extractor for LST camera pulse shape with
the correction for the integration window completeness
Expand All @@ -25,6 +25,7 @@ def test_sw_pulse_lst(prod5_lst):
"LST1",
tel_positions={1: np.zeros(3) * u.m},
tel_descriptions={1: prod5_lst},
reference_location=reference_location,
)

tel_id = list(subarray.tel.keys())[0]
Expand Down
18 changes: 13 additions & 5 deletions ctapipe/instrument/subarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ class SubarrayDescription:
def __init__(
self,
name,
tel_positions=None,
tel_descriptions=None,
reference_location=None,
tel_positions,
tel_descriptions,
reference_location,
):
"""
Initialize a new SubarrayDescription
Expand Down Expand Up @@ -126,6 +126,11 @@ def info(self, printer=print):
printer(f"Subarray : {self.name}")
printer(f"Num Tels : {self.n_tels}")
printer(f"Footprint: {self.footprint:.2f}")
printer(f"Height : {self.reference_location.geodetic.height:.2f}")
printer(
f"Lon/Lat : {self.reference_location.geodetic.lon}, "
f"{self.reference_location.geodetic.lat} "
)
printer("")

# print the per-telescope-type informatino:
Expand Down Expand Up @@ -353,7 +358,7 @@ def to_table(self, kind="subarray"):
tab.meta.update(meta)
return tab

def select_subarray(self, tel_ids, name=None):
def select_subarray(self, tel_ids, name=None) -> "SubarrayDescription":
"""
return a new SubarrayDescription that is a sub-array of this one

Expand All @@ -380,7 +385,10 @@ def select_subarray(self, tel_ids, name=None):
name = self.name + "_" + _range_extraction(tel_ids)

newsub = SubarrayDescription(
name, tel_positions=tel_positions, tel_descriptions=tel_descriptions
name,
tel_positions=tel_positions,
tel_descriptions=tel_descriptions,
reference_location=self.reference_location,
)
return newsub

Expand Down
27 changes: 22 additions & 5 deletions ctapipe/instrument/tests/test_subarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,12 @@ def test_tel_indexing(example_subarray):
assert np.all(sub.tel_ids_to_indices([1, 2, 3]) == np.array([0, 1, 2]))


def test_tel_ids_to_mask(prod5_lst):
def test_tel_ids_to_mask(prod5_lst, reference_location):
subarray = SubarrayDescription(
"someone_counted_in_binary",
tel_positions={1: [0, 0, 0] * u.m, 10: [50, 0, 0] * u.m},
tel_descriptions={1: prod5_lst, 10: prod5_lst},
reference_location=reference_location,
)

assert np.all(subarray.tel_ids_to_mask([]) == [False, False])
Expand Down Expand Up @@ -153,7 +154,7 @@ def test_hdf(example_subarray, tmp_path):
assert read == example_subarray


def test_hdf_same_camera(tmp_path, prod5_lst, prod5_mst_flashcam):
def test_hdf_same_camera(tmp_path, prod5_lst, prod5_mst_flashcam, reference_location):
"""Test writing / reading subarray to hdf5 with a subarray that has two
different telescopes with the same camera
"""
Expand All @@ -168,15 +169,20 @@ def test_hdf_same_camera(tmp_path, prod5_lst, prod5_mst_flashcam):
}
pos = {1: [0, 0, 0] * u.m, 2: [50, 0, 0] * u.m}

array = SubarrayDescription("test array", tel_positions=pos, tel_descriptions=tel)
array = SubarrayDescription(
"test array",
tel_positions=pos,
tel_descriptions=tel,
reference_location=reference_location,
)

path = tmp_path / "subarray.h5"
array.to_hdf(path)
read = SubarrayDescription.from_hdf(path, focal_length_choice="EQUIVALENT")
assert array == read


def test_hdf_duplicate_string_repr(tmp_path, prod5_lst):
def test_hdf_duplicate_string_repr(tmp_path, prod5_lst, reference_location):
"""Test writing and reading of a subarray with two telescopes that
are different but have the same name.
"""
Expand All @@ -193,6 +199,7 @@ def test_hdf_duplicate_string_repr(tmp_path, prod5_lst):
"test array",
tel_positions={1: [0, 0, 0] * u.m, 2: [50, 0, 0] * u.m},
tel_descriptions={1: tel1, 2: tel2},
reference_location=reference_location,
)

# defensive checks to make sure we are actually testing this
Expand Down Expand Up @@ -249,7 +256,6 @@ def test_unknown_telescopes(example_subarray):


def test_multiplicity(subarray_prod5_paranal):

subarray = subarray_prod5_paranal.select_subarray([1, 2, 20, 21, 80, 81])

mask = np.array([True, False, True, True, False, False])
Expand All @@ -270,3 +276,14 @@ def test_multiplicity(subarray_prod5_paranal):
np.testing.assert_equal(subarray.multiplicity(masks, "LST_LST_LSTCam"), [1, 2])
np.testing.assert_equal(subarray.multiplicity(masks, "MST_MST_FlashCam"), [2, 1])
np.testing.assert_equal(subarray.multiplicity(masks, "SST_ASTRI_CHEC"), [0, 1])


def test_subarrays(subarray_prod5_paranal: SubarrayDescription):
"""
Check that constructing a new SubarrayDescription by using
`select_subarray()` works as expected.
"""
subarray = subarray_prod5_paranal.select_subarray([1, 2, 3, 4], name="NewArray")
assert subarray.name == "NewArray"
assert isinstance(subarray.reference_location, EarthLocation)
assert subarray.reference_location == subarray_prod5_paranal.reference_location
Loading