diff --git a/ctapipe/calib/camera/calibrator.py b/ctapipe/calib/camera/calibrator.py index 373301ce82b..9f8dbc11ce6 100644 --- a/ctapipe/calib/camera/calibrator.py +++ b/ctapipe/calib/camera/calibrator.py @@ -9,7 +9,7 @@ import numpy as np from numba import float32, float64, guvectorize, int64 -from ctapipe.containers import DL1CameraContainer +from ctapipe.containers import TelescopeDL1Container from ctapipe.core import TelescopeComponent from ctapipe.core.traits import ( BoolTelescopeParameter, @@ -223,7 +223,7 @@ def _calibrate_dl1(self, event, tel_id): # - Read into dl1 container directly? # - Don't do anything if dl1 container already filled # - Update on SST review decision - dl1 = DL1CameraContainer( + dl1 = TelescopeDL1Container( image=waveforms[..., 0].astype(np.float32), peak_time=np.zeros(n_pixels, dtype=np.float32), is_valid=True, diff --git a/ctapipe/calib/camera/flatfield.py b/ctapipe/calib/camera/flatfield.py index 2a6c178f5ea..21497781550 100644 --- a/ctapipe/calib/camera/flatfield.py +++ b/ctapipe/calib/camera/flatfield.py @@ -7,7 +7,7 @@ import numpy as np from astropy import units as u -from ctapipe.containers import DL1CameraContainer +from ctapipe.containers import TelescopeDL1Container from ctapipe.core import Component from ctapipe.core.traits import Int, List, Unicode from ctapipe.image.extractor import ImageExtractor @@ -169,7 +169,7 @@ def __init__(self, **kwargs): self.arrival_times = None # arrival time per event in sample self.sample_masked_pixels = None # masked pixels per event in sample - def _extract_charge(self, event) -> DL1CameraContainer: + def _extract_charge(self, event) -> TelescopeDL1Container: """ Extract the charge and the time from a calibration event @@ -195,7 +195,7 @@ def _extract_charge(self, event) -> DL1CameraContainer: waveforms, self.tel_id, selected_gain_channel, broken_pixels ) else: - return DL1CameraContainer(image=0, peak_pos=0, is_valid=False) + return TelescopeDL1Container(image=0, peak_pos=0, is_valid=False) def calculate_relative_gain(self, event): """ @@ -237,7 +237,7 @@ def calculate_relative_gain(self, event): # extract the charge of the event and # the peak position (assumed as time for the moment) - dl1: DL1CameraContainer = self._extract_charge(event) + dl1: TelescopeDL1Container = self._extract_charge(event) if not dl1.is_valid: return False diff --git a/ctapipe/calib/camera/pedestals.py b/ctapipe/calib/camera/pedestals.py index d8a5576e7b8..a815b9ea3e5 100644 --- a/ctapipe/calib/camera/pedestals.py +++ b/ctapipe/calib/camera/pedestals.py @@ -7,7 +7,7 @@ import numpy as np from astropy import units as u -from ctapipe.containers import DL1CameraContainer +from ctapipe.containers import TelescopeDL1Container from ctapipe.core import Component from ctapipe.core.traits import Int, List, Unicode from ctapipe.image.extractor import ImageExtractor @@ -197,7 +197,7 @@ def __init__(self, **kwargs): self.charges = None # charge per event in sample self.sample_masked_pixels = None # pixels tp be masked per event in sample - def _extract_charge(self, event) -> DL1CameraContainer: + def _extract_charge(self, event) -> TelescopeDL1Container: """ Extract the charge and the time from a pedestal event @@ -224,7 +224,7 @@ def _extract_charge(self, event) -> DL1CameraContainer: waveforms, self.tel_id, selected_gain_channel, broken_pixels ) else: - return DL1CameraContainer(image=0, peak_pos=0, is_valid=False) + return TelescopeDL1Container(image=0, peak_pos=0, is_valid=False) def calculate_pedestals(self, event): """ @@ -258,7 +258,7 @@ def calculate_pedestals(self, event): # extract the charge of the event and # the peak position (assumed as time for the moment) - dl1: DL1CameraContainer = self._extract_charge(event) + dl1: TelescopeDL1Container = self._extract_charge(event) if not dl1.is_valid: return False diff --git a/ctapipe/containers.py b/ctapipe/containers.py index d31c4f055e6..b16e9319f04 100644 --- a/ctapipe/containers.py +++ b/ctapipe/containers.py @@ -14,23 +14,19 @@ __all__ = [ "ArrayEventContainer", "ConcentrationContainer", - "DL0CameraContainer", - "DL0Container", + "TelescopeDL0Container", "DL1CameraCalibrationContainer", - "DL1CameraContainer", - "DL1Container", - "DL2Container", - "EventCalibrationContainer", - "EventCameraCalibrationContainer", - "EventIndexContainer", + "TelescopeDL1Container", + "ArrayDL2Container", + "TelescopeCalibrationContainer", + "ArrayEventIndexContainer", "EventType", "FlatFieldContainer", "HillasParametersContainer", "CoreParametersContainer", "ImageParametersContainer", "LeakageContainer", - "MonitoringCameraContainer", - "MonitoringContainer", + "TelescopeMonitoringContainer", "MorphologyContainer", "BaseHillasParametersContainer", "CameraHillasParametersContainer", @@ -38,21 +34,18 @@ "ParticleClassificationContainer", "PedestalContainer", "PixelStatusContainer", - "R0CameraContainer", - "R0Container", - "R1CameraContainer", - "R1Container", - "ReconstructedContainer", + "TelescopeR0Container", + "TelescopeR1Container", "ReconstructedEnergyContainer", "ReconstructedGeometryContainer", - "SimulatedCameraContainer", + "TelescopeSimulationContainer", "SimulatedShowerContainer", "SimulatedShowerDistribution", "SimulationConfigContainer", - "TelEventIndexContainer", + "TelescopeEventIndexContainer", "BaseTimingParametersContainer", "TimingParametersContainer", - "TriggerContainer", + "ArrayTriggerContainer", "WaveformCalibrationContainer", "StatisticsContainer", "IntensityStatisticsContainer", @@ -164,7 +157,31 @@ class EventType(enum.Enum): UNKNOWN = 255 -class EventIndexContainer(Container): +class TelescopeEventType(enum.Enum): + """Enum of EventTypes as defined in the CTA Data Model [cta_r1event]_""" + + # calibrations are 0-15 + FLATFIELD = 0 + SINGLE_PE = 1 + SKY_PEDESTAL = 2 + DARK_PEDESTAL = 3 + ELECTRONIC_PEDESTAL = 4 + OTHER_CALIBRATION = 15 + + #: For mono-telescope triggers (not used in MC) + MUON = 16 + HARDWARE_STEREO = 17 + + #: ACADA (DAQ) software trigger + DAQ = 24 + + #: Standard Physics stereo trigger + SUBARRAY = 32 + + UNKNOWN = 255 + + +class ArrayEventIndexContainer(Container): """index columns to include in event lists, common to all data levels""" default_prefix = "" # don't want to prefix these @@ -172,7 +189,7 @@ class EventIndexContainer(Container): event_id = event_id_field() -class TelEventIndexContainer(Container): +class TelescopeEventIndexContainer(Container): """ index columns to include in telescope-wise event lists, common to all data levels that have telescope-wise information @@ -398,7 +415,7 @@ class ImageParametersContainer(Container): ) -class DL1CameraContainer(Container): +class TelescopeDL1Container(Container): """ Storage of output of camera calibration e.g the final calibrated image in intensity units and the pulse time. @@ -438,15 +455,6 @@ class DL1CameraContainer(Container): ) -class DL1Container(Container): - """DL1 Calibrated Camera Images and associated data""" - - tel = Field( - default_factory=partial(Map, DL1CameraContainer), - description="map of tel_id to DL1CameraContainer", - ) - - class DL1CameraCalibrationContainer(Container): """ Storage of DL1 calibration parameters for the current event @@ -476,7 +484,7 @@ class DL1CameraCalibrationContainer(Container): ) -class R0CameraContainer(Container): +class TelescopeR0Container(Container): """ Storage of raw data from a single telescope """ @@ -486,18 +494,7 @@ class R0CameraContainer(Container): ) -class R0Container(Container): - """ - Storage of a Merged Raw Data Event - """ - - tel = Field( - default_factory=partial(Map, R0CameraContainer), - description="map of tel_id to R0CameraContainer", - ) - - -class R1CameraContainer(Container): +class TelescopeR1Container(Container): """ Storage of r1 calibrated data from a single telescope """ @@ -518,18 +515,7 @@ class R1CameraContainer(Container): ) -class R1Container(Container): - """ - Storage of a r1 calibrated Data Event - """ - - tel = Field( - default_factory=partial(Map, R1CameraContainer), - description="map of tel_id to R1CameraContainer", - ) - - -class DL0CameraContainer(Container): +class TelescopeDL0Container(Container): """ Storage of data volume reduced dl0 data from a single telescope """ @@ -553,17 +539,6 @@ class DL0CameraContainer(Container): ) -class DL0Container(Container): - """ - Storage of a data volume reduced Event - """ - - tel = Field( - default_factory=partial(Map, DL0CameraContainer), - description="map of tel_id to DL0CameraContainer", - ) - - class TelescopeImpactParameterContainer(Container): """ Impact Parameter computed from reconstructed shower geometry @@ -596,7 +571,7 @@ class SimulatedShowerContainer(Container): ) -class SimulatedCameraContainer(Container): +class TelescopeSimulationContainer(Container): """ True images and parameters derived from them, analgous to the `DL1CameraContainer` but for simulated data. @@ -627,12 +602,11 @@ class SimulatedCameraContainer(Container): ) -class SimulatedEventContainer(Container): +class ArraySimulationContainer(Container): shower = Field( default_factory=SimulatedShowerContainer, description="True event information", ) - tel = Field(default_factory=partial(Map, SimulatedCameraContainer)) class SimulationConfigContainer(Container): @@ -728,19 +702,16 @@ class TelescopeTriggerContainer(Container): -1, description="Number of trigger groups (sectors) listed" ) trigger_pixels = Field(None, description="pixels involved in the camera trigger") + event_type = Field(TelescopeEventType.SUBARRAY, description="Event type") -class TriggerContainer(Container): +class ArrayTriggerContainer(Container): default_prefix = "" time = Field(NAN_TIME, description="central average time stamp") tels_with_trigger = Field( None, description="List of telescope ids that triggered the array event" ) event_type = Field(EventType.SUBARRAY, description="Event type") - tel = Field( - default_factory=partial(Map, TelescopeTriggerContainer), - description="telescope-wise trigger information", - ) class ReconstructedGeometryContainer(Container): @@ -843,16 +814,11 @@ class ParticleClassificationContainer(Container): telescopes = Field(None, "Telescopes used if stereo, or None if Mono") -class ReconstructedContainer(Container): - """Reconstructed shower info from multiple algorithms""" - - # Note: there is a reason why the hiererchy is - # `event.dl2.stereo.geometry[algorithm]` and not - # `event.dl2[algorithm].stereo.geometry` and that is because when writing - # the data, the former makes it easier to only write information that a - # particular reconstructor generates, e.g. only write the geometry in cases - # where energy is not yet computed. Some algorithms will compute all three, - # but most will compute only fill or two of these sub-Contaiers: +class ArrayDL2Container(Container): + """Reconstructed Shower information for a given reconstruction algorithm, + including optionally both per-telescope mono reconstruction and per-shower + stereo reconstructions + """ geometry = Field( default_factory=partial(Map, ReconstructedGeometryContainer), @@ -868,28 +834,12 @@ class ReconstructedContainer(Container): ) -class TelescopeReconstructedContainer(ReconstructedContainer): +class TelescopeDL2Container(ArrayDL2Container): """Telescope-wise reconstructed quantities""" impact = Field( default_factory=partial(Map, TelescopeImpactParameterContainer), - description="map of algorithm to impact parameter info", - ) - - -class DL2Container(Container): - """Reconstructed Shower information for a given reconstruction algorithm, - including optionally both per-telescope mono reconstruction and per-shower - stereo reconstructions - """ - - tel = Field( - default_factory=partial(Map, TelescopeReconstructedContainer), - description="map of tel_id to single-telescope reconstruction (DL2a)", - ) - stereo = Field( - default_factory=ReconstructedContainer, - description="Stereo Shower reconstruction results", + description="map of algorithm to reconstructed impact distance", ) @@ -905,18 +855,14 @@ class TelescopePointingContainer(Container): altitude = Field(nan * u.rad, "Altitude", unit=u.rad) -class PointingContainer(Container): - tel = Field( - default_factory=partial(Map, TelescopePointingContainer), - description="Telescope pointing positions", - ) - array_azimuth = Field(nan * u.rad, "Array pointing azimuth", unit=u.rad) - array_altitude = Field(nan * u.rad, "Array pointing altitude", unit=u.rad) - array_ra = Field(nan * u.rad, "Array pointing right ascension", unit=u.rad) - array_dec = Field(nan * u.rad, "Array pointing declination", unit=u.rad) +class ArrayPointingContainer(Container): + azimuth = Field(nan * u.rad, "Array pointing azimuth", unit=u.rad) + altitude = Field(nan * u.rad, "Array pointing altitude", unit=u.rad) + ra = Field(nan * u.rad, "Array pointing right ascension", unit=u.rad) + dec = Field(nan * u.rad, "Array pointing declination", unit=u.rad) -class EventCameraCalibrationContainer(Container): +class TelescopeCalibrationContainer(Container): """ Container for the calibration coefficients for the current event and camera """ @@ -927,18 +873,6 @@ class EventCameraCalibrationContainer(Container): ) -class EventCalibrationContainer(Container): - """ - Container for calibration coefficients for the current event - """ - - # create the camera container - tel = Field( - default_factory=partial(Map, EventCameraCalibrationContainer), - description="map of tel_id to EventCameraCalibrationContainer", - ) - - class MuonRingContainer(Container): """Container for the result of a ring fit, center_x, center_y""" @@ -954,6 +888,8 @@ class MuonRingContainer(Container): class MuonEfficiencyContainer(Container): + """Container for the result of the MuonIntensityFitter""" + width = Field(nan * u.deg, "width of the muon ring in degrees") impact = Field(nan * u.m, "distance of muon impact position from center of mirror") impact_x = Field(nan * u.m, "impact parameter x position") @@ -962,6 +898,8 @@ class MuonEfficiencyContainer(Container): class MuonParametersContainer(Container): + """Container for muon-ring-related image parameters""" + containment = Field(nan, "containment of the ring inside the camera") completeness = Field( nan, @@ -1118,7 +1056,7 @@ class WaveformCalibrationContainer(Container): ) -class MonitoringCameraContainer(Container): +class TelescopeMonitoringContainer(Container): """ Container for camera monitoring data """ @@ -1141,18 +1079,6 @@ class MonitoringCameraContainer(Container): ) -class MonitoringContainer(Container): - """ - Root container for monitoring data (MON) - """ - - # create the camera container - tel = Field( - default_factory=partial(Map, MonitoringCameraContainer), - description="map of tel_id to MonitoringCameraContainer", - ) - - class SimulatedShowerDistribution(Container): """ 2D histogram of simulated number of showers simulated as function of energy and @@ -1179,40 +1105,86 @@ class SimulatedShowerDistribution(Container): ) -class ArrayEventContainer(Container): - """Top-level container for all event information""" +class TelescopeEventContainer(Container): + """Container for single-telescope data""" index = Field( - default_factory=EventIndexContainer, description="event indexing information" + default_factory=TelescopeEventIndexContainer, + description="event indexing information", ) - r0 = Field(default_factory=R0Container, description="Raw Data") - r1 = Field(default_factory=R1Container, description="R1 Calibrated Data") + + simulation = Field( + None, + description="Simulated Event Information", + type=TelescopeSimulationContainer, + ) + + r0 = Field(default_factory=TelescopeR0Container, description="Raw Data") + r1 = Field(default_factory=TelescopeR1Container, description="R1 Calibrated Data") dl0 = Field( - default_factory=DL0Container, description="DL0 Data Volume Reduced Data" + default_factory=TelescopeDL0Container, + description="DL0 Data Volume Reduced Data", ) - dl1 = Field(default_factory=DL1Container, description="DL1 Calibrated image") - dl2 = Field(default_factory=DL2Container, description="DL2 reconstruction info") - simulation = Field( - None, description="Simulated Event Information", type=SimulatedEventContainer + dl1 = Field( + default_factory=TelescopeDL1Container, description="DL1 images and parameters" + ) + dl2 = Field( + default_factory=TelescopeDL2Container, + description="DL2 reconstructed event properties", ) trigger = Field( - default_factory=TriggerContainer, description="central trigger information" + default_factory=TelescopeTriggerContainer, + description="central trigger information", ) count = Field(0, description="number of events processed") pointing = Field( - default_factory=PointingContainer, + default_factory=TelescopePointingContainer, description="Array and telescope pointing positions", ) calibration = Field( - default_factory=EventCalibrationContainer, + default_factory=TelescopeCalibrationContainer, description="Container for calibration coefficients for the current event", ) mon = Field( - default_factory=MonitoringContainer, + default_factory=TelescopeMonitoringContainer, description="container for event-wise monitoring data (MON)", ) +class ArrayEventContainer(Container): + """Top-level container for all event information""" + + count = Field(0, description="number of events processed") + + index = Field( + default_factory=ArrayEventIndexContainer, + description="event indexing information", + ) + + simulation = Field( + None, description="Simulated Event Information", type=ArraySimulationContainer + ) + + trigger = Field( + default_factory=ArrayTriggerContainer, description="central trigger information" + ) + + dl2 = Field( + default_factory=ArrayDL2Container, + description="DL2 reconstructed event properties", + ) + + pointing = Field( + default_factory=ArrayPointingContainer, + description="Array and telescope pointing positions", + ) + + tel = Field( + default_factory=partial(Map, TelescopeEventContainer), + description="Telescope Events", + ) + + class SchedulingBlockContainer(Container): """Stores information about the scheduling block. This is a simplified version of the SB model, only storing what is necessary for analysis. From diff --git a/ctapipe/image/extractor.py b/ctapipe/image/extractor.py index 0e078582ef8..97f2eec7227 100644 --- a/ctapipe/image/extractor.py +++ b/ctapipe/image/extractor.py @@ -29,7 +29,7 @@ from scipy.ndimage import convolve1d from traitlets import Bool, Int -from ctapipe.containers import DL1CameraContainer +from ctapipe.containers import TelescopeDL1Container from ctapipe.core import TelescopeComponent from ctapipe.core.traits import ( BoolTelescopeParameter, @@ -382,7 +382,7 @@ def __init__(self, subarray, config=None, parent=None, **kwargs): @abstractmethod def __call__( self, waveforms, tel_id, selected_gain_channel, broken_pixels - ) -> DL1CameraContainer: + ) -> TelescopeDL1Container: """ Call the relevant functions to fully extract the charge and time for the particular extractor. @@ -414,11 +414,11 @@ class FullWaveformSum(ImageExtractor): def __call__( self, waveforms, tel_id, selected_gain_channel, broken_pixels - ) -> DL1CameraContainer: + ) -> TelescopeDL1Container: charge, peak_time = extract_around_peak( waveforms, 0, waveforms.shape[-1], 0, self.sampling_rate_ghz[tel_id] ) - return DL1CameraContainer(image=charge, peak_time=peak_time, is_valid=True) + return TelescopeDL1Container(image=charge, peak_time=peak_time, is_valid=True) class FixedWindowSum(ImageExtractor): @@ -473,7 +473,7 @@ def _calculate_correction(self, tel_id): def __call__( self, waveforms, tel_id, selected_gain_channel, broken_pixels - ) -> DL1CameraContainer: + ) -> TelescopeDL1Container: charge, peak_time = extract_around_peak( waveforms, self.peak_index.tel[tel_id], @@ -483,7 +483,7 @@ def __call__( ) if self.apply_integration_correction.tel[tel_id]: charge *= self._calculate_correction(tel_id=tel_id)[selected_gain_channel] - return DL1CameraContainer(image=charge, peak_time=peak_time, is_valid=True) + return TelescopeDL1Container(image=charge, peak_time=peak_time, is_valid=True) class GlobalPeakWindowSum(ImageExtractor): @@ -552,7 +552,7 @@ def _calculate_correction(self, tel_id): def __call__( self, waveforms, tel_id, selected_gain_channel, broken_pixels - ) -> DL1CameraContainer: + ) -> TelescopeDL1Container: if self.pixel_fraction.tel[tel_id] == 1.0: # average over pixels then argmax over samples peak_index = waveforms[~broken_pixels].mean(axis=-2).argmax() @@ -574,7 +574,7 @@ def __call__( ) if self.apply_integration_correction.tel[tel_id]: charge *= self._calculate_correction(tel_id=tel_id)[selected_gain_channel] - return DL1CameraContainer(image=charge, peak_time=peak_time, is_valid=True) + return TelescopeDL1Container(image=charge, peak_time=peak_time, is_valid=True) class LocalPeakWindowSum(ImageExtractor): @@ -628,7 +628,7 @@ def _calculate_correction(self, tel_id): def __call__( self, waveforms, tel_id, selected_gain_channel, broken_pixels - ) -> DL1CameraContainer: + ) -> TelescopeDL1Container: peak_index = waveforms.argmax(axis=-1).astype(np.int64) charge, peak_time = extract_around_peak( waveforms, @@ -639,7 +639,7 @@ def __call__( ) if self.apply_integration_correction.tel[tel_id]: charge *= self._calculate_correction(tel_id=tel_id)[selected_gain_channel] - return DL1CameraContainer(image=charge, peak_time=peak_time, is_valid=True) + return TelescopeDL1Container(image=charge, peak_time=peak_time, is_valid=True) class SlidingWindowMaxSum(ImageExtractor): @@ -710,13 +710,13 @@ def _calculate_correction(self, tel_id): def __call__( self, waveforms, tel_id, selected_gain_channel, broken_pixels - ) -> DL1CameraContainer: + ) -> TelescopeDL1Container: charge, peak_time = extract_sliding_window( waveforms, self.window_width.tel[tel_id], self.sampling_rate_ghz[tel_id] ) if self.apply_integration_correction.tel[tel_id]: charge *= self._calculate_correction(tel_id=tel_id)[selected_gain_channel] - return DL1CameraContainer(image=charge, peak_time=peak_time, is_valid=True) + return TelescopeDL1Container(image=charge, peak_time=peak_time, is_valid=True) class NeighborPeakWindowSum(ImageExtractor): @@ -776,7 +776,7 @@ def _calculate_correction(self, tel_id): def __call__( self, waveforms, tel_id, selected_gain_channel, broken_pixels - ) -> DL1CameraContainer: + ) -> TelescopeDL1Container: neighbors = self.subarray.tel[tel_id].camera.geometry.neighbor_matrix_sparse peak_index = neighbor_average_maximum( waveforms, @@ -794,7 +794,7 @@ def __call__( ) if self.apply_integration_correction.tel[tel_id]: charge *= self._calculate_correction(tel_id=tel_id)[selected_gain_channel] - return DL1CameraContainer(image=charge, peak_time=peak_time, is_valid=True) + return TelescopeDL1Container(image=charge, peak_time=peak_time, is_valid=True) class BaselineSubtractedNeighborPeakWindowSum(NeighborPeakWindowSum): @@ -810,7 +810,7 @@ class BaselineSubtractedNeighborPeakWindowSum(NeighborPeakWindowSum): def __call__( self, waveforms, tel_id, selected_gain_channel, broken_pixels - ) -> DL1CameraContainer: + ) -> TelescopeDL1Container: baseline_corrected = subtract_baseline( waveforms, self.baseline_start, self.baseline_end ) @@ -1259,12 +1259,12 @@ def _apply_second_pass( def __call__( self, waveforms, tel_id, selected_gain_channel, broken_pixels - ) -> DL1CameraContainer: + ) -> TelescopeDL1Container: charge1, pulse_time1, correction1 = self._apply_first_pass(waveforms, tel_id) # FIXME: properly make sure that output is 32Bit instead of downcasting here if self.disable_second_pass: - return DL1CameraContainer( + return TelescopeDL1Container( image=(charge1 * correction1[selected_gain_channel]).astype("float32"), peak_time=pulse_time1.astype("float32"), is_valid=True, @@ -1280,7 +1280,7 @@ def __call__( broken_pixels, ) # FIXME: properly make sure that output is 32Bit instead of downcasting here - return DL1CameraContainer( + return TelescopeDL1Container( image=charge2.astype("float32"), peak_time=pulse_time2.astype("float32"), is_valid=is_valid, diff --git a/ctapipe/image/reducer.py b/ctapipe/image/reducer.py index f7e63734d53..307cf6c1db6 100644 --- a/ctapipe/image/reducer.py +++ b/ctapipe/image/reducer.py @@ -5,7 +5,7 @@ import numpy as np -from ctapipe.containers import DL1CameraContainer +from ctapipe.containers import TelescopeDL1Container from ctapipe.core import TelescopeComponent from ctapipe.core.traits import ( BoolTelescopeParameter, @@ -183,7 +183,7 @@ def select_pixels(self, waveforms, tel_id=None, selected_gain_channel=None): extractor = self.image_extractors[self.image_extractor_type.tel[tel_id]] # do not treat broken pixels in data volume reduction broken_pixels = np.zeros(camera_geom.n_pixels, dtype=bool) - dl1: DL1CameraContainer = extractor( + dl1: TelescopeDL1Container = extractor( waveforms, tel_id=tel_id, selected_gain_channel=selected_gain_channel, diff --git a/ctapipe/image/tests/test_sliding_window_correction.py b/ctapipe/image/tests/test_sliding_window_correction.py index 7f8806ebc7a..bb17daaf1f3 100644 --- a/ctapipe/image/tests/test_sliding_window_correction.py +++ b/ctapipe/image/tests/test_sliding_window_correction.py @@ -8,7 +8,7 @@ from numpy.testing import assert_allclose from traitlets.config.loader import Config -from ctapipe.containers import DL1CameraContainer +from ctapipe.containers import TelescopeDL1Container from ctapipe.image.extractor import ImageExtractor, SlidingWindowMaxSum from ctapipe.image.toymodel import WaveformModel from ctapipe.instrument import SubarrayDescription @@ -53,7 +53,7 @@ def test_sw_pulse_lst(prod5_lst): ) broken_pixels = np.zeros(n_pixels, dtype=bool) - dl1: DL1CameraContainer = extractor( + dl1: TelescopeDL1Container = extractor( waveform, tel_id, selected_gain_channel, broken_pixels ) print(dl1.image / charge_true) diff --git a/ctapipe/io/datawriter.py b/ctapipe/io/datawriter.py index 8ddf8cae23d..4b1034a17df 100644 --- a/ctapipe/io/datawriter.py +++ b/ctapipe/io/datawriter.py @@ -16,7 +16,7 @@ from ..containers import ( ArrayEventContainer, SimulatedShowerDistribution, - TelEventIndexContainer, + TelescopeEventIndexContainer, ) from ..core import Component, Container, Field, Provenance, ToolConfigurationError from ..core.traits import Bool, CaselessStrEnum, Float, Int, Path, Unicode @@ -34,7 +34,7 @@ def _get_tel_index(event, tel_id): - return TelEventIndexContainer( + return TelescopeEventIndexContainer( obs_id=event.index.obs_id, event_id=event.index.event_id, tel_id=np.int16(tel_id), diff --git a/ctapipe/io/hdf5eventsource.py b/ctapipe/io/hdf5eventsource.py index 3a2da088897..f8c228dbc6d 100644 --- a/ctapipe/io/hdf5eventsource.py +++ b/ctapipe/io/hdf5eventsource.py @@ -13,11 +13,12 @@ from ..containers import ( ArrayEventContainer, + ArrayEventIndexContainer, + ArraySimulationContainer, + ArrayTriggerContainer, CameraHillasParametersContainer, CameraTimingParametersContainer, ConcentrationContainer, - DL1CameraContainer, - EventIndexContainer, HillasParametersContainer, ImageParametersContainer, IntensityStatisticsContainer, @@ -26,18 +27,17 @@ ObservationBlockContainer, ParticleClassificationContainer, PeakTimeStatisticsContainer, - R1CameraContainer, ReconstructedEnergyContainer, ReconstructedGeometryContainer, SchedulingBlockContainer, - SimulatedEventContainer, SimulatedShowerContainer, SimulationConfigContainer, + TelescopeDL1Container, + TelescopeEventIndexContainer, TelescopeImpactParameterContainer, + TelescopeR1Container, TelescopeTriggerContainer, - TelEventIndexContainer, TimingParametersContainer, - TriggerContainer, ) from ..core import Container, Field from ..core.traits import UseEnum @@ -372,7 +372,7 @@ def _generator(self): if DataLevel.R1 in self.datalevels: waveform_readers = { table.name: self.reader.read( - f"/r1/event/telescope/{table.name}", R1CameraContainer + f"/r1/event/telescope/{table.name}", TelescopeR1Container ) for table in self.file_.root.r1.event.telescope } @@ -387,7 +387,7 @@ def _generator(self): image_readers = { table.name: self.reader.read( f"/dl1/event/telescope/images/{table.name}", - DL1CameraContainer, + TelescopeDL1Container, ignore_columns=ignore_columns, ) for table in self.file_.root.dl1.event.telescope.images @@ -521,12 +521,12 @@ def _generator(self): # Setup iterators for the array events events = HDF5TableReader(self.file_).read( "/dl1/event/subarray/trigger", - [TriggerContainer, EventIndexContainer], + [ArrayTriggerContainer, ArrayEventIndexContainer], ignore_columns={"tel"}, ) telescope_trigger_reader = HDF5TableReader(self.file_).read( "/dl1/event/telescope/trigger", - [TelEventIndexContainer, TelescopeTriggerContainer], + [TelescopeEventIndexContainer, TelescopeTriggerContainer], ignore_columns={"trigger_pixels"}, ) @@ -545,7 +545,7 @@ def _generator(self): trigger=trigger, count=counter, index=index, - simulation=SimulatedEventContainer() if self.is_simulation else None, + simulation=ArraySimulationContainer() if self.is_simulation else None, ) # Maybe take some other metadata, but there are still some 'unknown' # written out by the stage1 tool diff --git a/ctapipe/io/simteleventsource.py b/ctapipe/io/simteleventsource.py index 5dd00a226e7..dcf5c0a052b 100644 --- a/ctapipe/io/simteleventsource.py +++ b/ctapipe/io/simteleventsource.py @@ -23,8 +23,10 @@ from ..calib.camera.gainselection import GainSelector from ..containers import ( ArrayEventContainer, + ArrayEventIndexContainer, + ArraySimulationContainer, + ArrayTriggerContainer, CoordinateFrameType, - EventIndexContainer, EventType, ObservationBlockContainer, ObservationBlockState, @@ -32,18 +34,16 @@ PixelStatusContainer, PointingContainer, PointingMode, - R0CameraContainer, - R1CameraContainer, SchedulingBlockContainer, SchedulingBlockType, - SimulatedCameraContainer, - SimulatedEventContainer, SimulatedShowerContainer, SimulationConfigContainer, TelescopeImpactParameterContainer, TelescopePointingContainer, + TelescopeR0Container, + TelescopeR1Container, + TelescopeSimulationContainer, TelescopeTriggerContainer, - TriggerContainer, ) from ..coordinates import CameraFrame, shower_impact_distance from ..core import Map @@ -730,9 +730,9 @@ def _generate_events(self): shower = None data = ArrayEventContainer( - simulation=SimulatedEventContainer(shower=shower), + simulation=ArraySimulationContainer(shower=shower), pointing=self._fill_array_pointing(), - index=EventIndexContainer(obs_id=obs_id, event_id=event_id), + index=ArrayEventIndexContainer(obs_id=obs_id, event_id=event_id), count=counter, trigger=trigger, ) @@ -785,7 +785,7 @@ def _generate_events(self): prefix="true_impact", ) - data.simulation.tel[tel_id] = SimulatedCameraContainer( + data.simulation.tel[tel_id] = TelescopeSimulationContainer( true_image_sum=true_image_sums[ self.telescope_indices_original[tel_id] ], @@ -797,7 +797,7 @@ def _generate_events(self): tracking_positions[tel_id] ) - data.r0.tel[tel_id] = R0CameraContainer(waveform=adc_samples) + data.r0.tel[tel_id] = TelescopeR0Container(waveform=adc_samples) cam_mon = array_event["camera_monitorings"][tel_id] pedestal = cam_mon["pedestal"] / cam_mon["n_ped_slices"] @@ -818,7 +818,7 @@ def _generate_events(self): self.calib_scale, self.calib_shift, ) - data.r1.tel[tel_id] = R1CameraContainer( + data.r1.tel[tel_id] = TelescopeR1Container( waveform=r1_waveform, selected_gain_channel=selected_gain_channel, ) @@ -930,7 +930,7 @@ def _fill_trigger_info(self, array_event): n_trigger_pixels=n_trigger_pixels, trigger_pixels=trigger_pixels, ) - return TriggerContainer( + return ArrayTriggerContainer( event_type=event_type, time=central_time, tels_with_trigger=tels_with_trigger, diff --git a/ctapipe/io/tests/test_hdf5.py b/ctapipe/io/tests/test_hdf5.py index 1ffa6c97750..92d933fa168 100644 --- a/ctapipe/io/tests/test_hdf5.py +++ b/ctapipe/io/tests/test_hdf5.py @@ -11,9 +11,9 @@ from ctapipe.containers import ( HillasParametersContainer, LeakageContainer, - R0CameraContainer, SimulatedShowerContainer, - TelEventIndexContainer, + TelescopeEventIndexContainer, + TelescopeR0Container, ) from ctapipe.core.container import Container, Field from ctapipe.io import read_table @@ -25,7 +25,7 @@ def test_h5_file(tmp_path_factory): """Test hdf5 file with some tables for the reader tests""" path = tmp_path_factory.mktemp("hdf5") / "test.h5" - r0 = R0CameraContainer() + r0 = TelescopeR0Container() shower = SimulatedShowerContainer() r0.waveform = np.random.uniform(size=(50, 10)) r0.meta["test_attribute"] = 3.14159 @@ -92,12 +92,12 @@ def test_append_container(tmp_path): with HDF5TableWriter(path, mode="w") as writer: for event_id in range(10): hillas = HillasParametersContainer() - index = TelEventIndexContainer(obs_id=1, event_id=event_id, tel_id=1) + index = TelescopeEventIndexContainer(obs_id=1, event_id=event_id, tel_id=1) writer.write("data", [index, hillas]) with HDF5TableWriter(path, mode="a") as writer: for event_id in range(10): - index = TelEventIndexContainer(obs_id=2, event_id=event_id, tel_id=1) + index = TelescopeEventIndexContainer(obs_id=2, event_id=event_id, tel_id=1) hillas = HillasParametersContainer() writer.write("data", [index, hillas]) @@ -380,8 +380,8 @@ def test_read_container(test_h5_file): # test supplying a single container as well as an # iterable with one entry only simtab = reader.read("/R0/sim_shower", (SimulatedShowerContainer,)) - r0tab1 = reader.read("/R0/tel_001", R0CameraContainer) - r0tab2 = reader.read("/R0/tel_002", R0CameraContainer) + r0tab1 = reader.read("/R0/tel_001", TelescopeR0Container) + r0tab2 = reader.read("/R0/tel_002", TelescopeR0Container) # read all 3 tables in sync for _ in range(3): diff --git a/ctapipe/io/toymodel.py b/ctapipe/io/toymodel.py index 552fd3def5b..1fa3037ba53 100644 --- a/ctapipe/io/toymodel.py +++ b/ctapipe/io/toymodel.py @@ -10,10 +10,10 @@ from ..containers import ( ArrayEventContainer, - DL1CameraContainer, - EventIndexContainer, + ArrayEventIndexContainer, ObservationBlockContainer, SchedulingBlockContainer, + TelescopeDL1Container, ) from ..core import TelescopeComponent, traits from ..image import toymodel @@ -108,7 +108,7 @@ def _generator(self): def generate_event(self): event = ArrayEventContainer( - index=EventIndexContainer(obs_id=1, event_id=self.event_id), + index=ArrayEventIndexContainer(obs_id=1, event_id=self.event_id), trigger=None, r0=None, dl0=None, @@ -159,6 +159,6 @@ def generate_event(self): ) image, _, _ = model.generate_image(cam, intensity) - event.dl1.tel[tel_id] = DL1CameraContainer(image=image) + event.dl1.tel[tel_id] = TelescopeDL1Container(image=image) return event diff --git a/ctapipe/tools/muon_reconstruction.py b/ctapipe/tools/muon_reconstruction.py index b61617a54f8..e74d3db976a 100644 --- a/ctapipe/tools/muon_reconstruction.py +++ b/ctapipe/tools/muon_reconstruction.py @@ -12,7 +12,7 @@ ) from ..calib import CameraCalibrator -from ..containers import MuonParametersContainer, TelEventIndexContainer +from ..containers import MuonParametersContainer, TelescopeEventIndexContainer from ..coordinates import CameraFrame, TelescopeFrame from ..core import Provenance, Tool, ToolConfigurationError, traits from ..core.traits import flag @@ -197,7 +197,7 @@ def process_telescope_event(self, event_index, tel_id, dl1): f", efficiency={result.optical_efficiency:.2%}" ) - tel_event_index = TelEventIndexContainer(**event_index, tel_id=tel_id) + tel_event_index = TelescopeEventIndexContainer(**event_index, tel_id=tel_id) self.writer.write( "dl1/event/telescope/parameters/muons", diff --git a/ctapipe/tools/tests/test_apply_models.py b/ctapipe/tools/tests/test_apply_models.py index 2735f91a531..b5d502daca8 100644 --- a/ctapipe/tools/tests/test_apply_models.py +++ b/ctapipe/tools/tests/test_apply_models.py @@ -1,7 +1,7 @@ import numpy as np from ctapipe.containers import ( - EventIndexContainer, + ArrayEventIndexContainer, ParticleClassificationContainer, ReconstructedEnergyContainer, ) @@ -35,7 +35,9 @@ def test_apply_energy_regressor( prefix = "ExtraTreesRegressor" table = read_table(output_path, f"/dl2/event/subarray/energy/{prefix}") for col in "obs_id", "event_id": - assert table[col].description == EventIndexContainer.fields[col].description + assert ( + table[col].description == ArrayEventIndexContainer.fields[col].description + ) for name, field in ReconstructedEnergyContainer.fields.items(): colname = f"{prefix}_{name}" @@ -95,7 +97,9 @@ def test_apply_both( prefix = "ExtraTreesClassifier" table = read_table(output_path, f"/dl2/event/subarray/classification/{prefix}") for col in "obs_id", "event_id": - assert table[col].description == EventIndexContainer.fields[col].description + assert ( + table[col].description == ArrayEventIndexContainer.fields[col].description + ) for name, field in ParticleClassificationContainer.fields.items(): colname = f"ExtraTreesClassifier_{name}"