Skip to content

Commit 7590019

Browse files
authored
Merge pull request #2791 from cta-observatory/generalise_table_preprocessing
Generalise table preprocessing
2 parents fd1fb78 + d685e25 commit 7590019

19 files changed

+814
-498
lines changed

docs/api-reference/io/index.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,9 @@ Reference/API
281281
.. automodapi:: ctapipe.io.metadata
282282
:no-inheritance-diagram:
283283

284+
.. automodapi:: ctapipe.io.dl2_tables_preprocessing
285+
:no-inheritance-diagram:
286+
284287
.. automodapi:: ctapipe.io.eventsource
285288
:no-inheritance-diagram:
286289

docs/api-reference/irf/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ Submodules
3333
irfs
3434
benchmarks
3535
binning
36-
preprocessing
3736
spectra
3837

3938

docs/api-reference/irf/preprocessing.rst

Lines changed: 0 additions & 12 deletions
This file was deleted.

docs/changes/2791.feature.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Generalise the DL2 table processing implemented in IRF tools in order to be used by other usecases that ingest, filter and merge DL2 tables.
2+
The module was moved from IRF to IO.

src/ctapipe/conftest.py

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -905,11 +905,11 @@ def irf_event_loader_test_config():
905905

906906
return Config(
907907
{
908-
"EventPreprocessor": {
908+
"DL2EventPreprocessor": {
909909
"energy_reconstructor": "ExtraTreesRegressor",
910910
"geometry_reconstructor": "HillasReconstructor",
911911
"gammaness_classifier": "ExtraTreesClassifier",
912-
"EventQualityQuery": {
912+
"DL2EventQualityQuery": {
913913
"quality_criteria": [
914914
(
915915
"multiplicity 4",
@@ -936,15 +936,19 @@ def event_loader_config_path(irf_event_loader_test_config, irf_tmp_path):
936936

937937
@pytest.fixture(scope="session")
938938
def irf_events_table():
939-
from ctapipe.irf import EventPreprocessor
939+
from ctapipe.io import DL2EventPreprocessor
940940

941941
N1 = 1000
942942
N2 = 100
943943
N = N1 + N2
944-
epp = EventPreprocessor()
944+
epp = DL2EventPreprocessor()
945945
tab = epp.make_empty_table()
946946

947-
ids, bulk, unitless = tab.colnames[:2], tab.colnames[2:-2], tab.colnames[-2:]
947+
ids = ["obs_id", "event_id"]
948+
unitless = set(
949+
[colname for colname in tab.colnames if tab[colname].unit is None]
950+
) - set(ids)
951+
bulk = set(tab.colnames) - set(ids) - set(unitless)
948952

949953
id_tab = QTable(
950954
data=np.zeros((N, len(ids)), dtype=np.uint64),
@@ -956,16 +960,21 @@ def irf_events_table():
956960
names=bulk,
957961
units={c: tab[c].unit for c in bulk},
958962
)
959-
960963
# Setting values following pyirf test in pyirf/irf/tests/test_background.py
961-
bulk_tab["reco_energy"] = np.append(np.full(N1, 1), np.full(N2, 2)) * u.TeV
962-
bulk_tab["true_energy"] = np.append(np.full(N1, 0.9), np.full(N2, 2.1)) * u.TeV
963-
bulk_tab["reco_source_fov_offset"] = (
964-
np.append(np.full(N1, 0.1), np.full(N2, 0.05)) * u.deg
964+
bulk_tab.replace_column(
965+
"reco_energy", np.append(np.full(N1, 1), np.full(N2, 2)) * u.TeV
966+
)
967+
bulk_tab.replace_column(
968+
"true_energy", np.append(np.full(N1, 0.9), np.full(N2, 2.1)) * u.TeV
965969
)
966-
bulk_tab["true_source_fov_offset"] = (
967-
np.append(np.full(N1, 0.11), np.full(N2, 0.04)) * u.deg
970+
bulk_tab.replace_column(
971+
"reco_source_fov_offset", np.append(np.full(N1, 0.1), np.full(N2, 0.05)) * u.deg
968972
)
973+
bulk_tab.replace_column(
974+
"true_source_fov_offset",
975+
np.append(np.full(N1, 0.11), np.full(N2, 0.04)) * u.deg,
976+
)
977+
969978
for name in unitless:
970979
bulk_tab.add_column(
971980
Column(name=name, unit=tab[name].unit, data=np.zeros(N) * np.nan)
@@ -975,3 +984,40 @@ def irf_events_table():
975984

976985
ev = vstack([e_tab, tab], join_type="exact", metadata_conflicts="silent")
977986
return ev
987+
988+
989+
@pytest.fixture(scope="function")
990+
def test_config():
991+
return {
992+
"DL2EventLoader": {"event_reader_function": "read_telescope_events_chunked"},
993+
"DL2EventPreprocessor": {
994+
"energy_reconstructor": "ExtraTreesRegressor",
995+
"gammaness_classifier": "ExtraTreesClassifier",
996+
"columns_to_rename": {},
997+
"output_table_schema": [
998+
Column(
999+
name="obs_id", dtype=np.uint64, description="Observation Block ID"
1000+
),
1001+
Column(name="event_id", dtype=np.uint64, description="Array event ID"),
1002+
Column(name="tel_id", dtype=np.uint64, description="Telescope ID"),
1003+
Column(
1004+
name="ExtraTreesRegressor_tel_energy",
1005+
unit=u.TeV,
1006+
description="Reconstructed energy",
1007+
),
1008+
Column(
1009+
name="ExtraTreesRegressor_tel_energy_uncert",
1010+
unit=u.TeV,
1011+
description="Reconstructed energy uncertainty",
1012+
),
1013+
],
1014+
"apply_derived_columns": False,
1015+
# "disable_column_renaming": True,
1016+
"allow_unsupported_pointing_frames": True,
1017+
},
1018+
"DL2EventQualityQuery": {
1019+
"quality_criteria": [
1020+
("valid reco", "ExtraTreesRegressor_tel_is_valid"),
1021+
]
1022+
},
1023+
}

src/ctapipe/io/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77
from .astropy_helpers import read_table, write_table # noqa: I001
88
from .datalevels import DataLevel
9+
from .dl2_tables_preprocessing import DL2EventPreprocessor, DL2EventLoader
910
from .eventsource import EventSource
1011
from .eventseeker import EventSeeker
1112
from .tableio import TableReader, TableWriter
@@ -41,5 +42,7 @@
4142
"DataWriter",
4243
"DATA_MODEL_VERSION",
4344
"get_hdf5_datalevels",
45+
"DL2EventPreprocessor",
46+
"DL2EventLoader",
4447
"get_hdf5_monitoring_types",
4548
]

0 commit comments

Comments
 (0)