ctao-calibpipe 0.3.0rc2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- calibpipe/__init__.py +5 -0
- calibpipe/_dev_version/__init__.py +9 -0
- calibpipe/_version.py +34 -0
- calibpipe/atmosphere/__init__.py +1 -0
- calibpipe/atmosphere/atmosphere_containers.py +109 -0
- calibpipe/atmosphere/meteo_data_handlers.py +485 -0
- calibpipe/atmosphere/models/README.md +14 -0
- calibpipe/atmosphere/models/__init__.py +1 -0
- calibpipe/atmosphere/models/macobac.ecsv +23 -0
- calibpipe/atmosphere/models/reference_MDPs/__init__.py +1 -0
- calibpipe/atmosphere/models/reference_MDPs/ref_density_at_15km_ctao-north_intermediate.ecsv +8 -0
- calibpipe/atmosphere/models/reference_MDPs/ref_density_at_15km_ctao-north_summer.ecsv +8 -0
- calibpipe/atmosphere/models/reference_MDPs/ref_density_at_15km_ctao-north_winter.ecsv +8 -0
- calibpipe/atmosphere/models/reference_MDPs/ref_density_at_15km_ctao-south_summer.ecsv +8 -0
- calibpipe/atmosphere/models/reference_MDPs/ref_density_at_15km_ctao-south_winter.ecsv +8 -0
- calibpipe/atmosphere/models/reference_atmospheres/__init__.py +1 -0
- calibpipe/atmosphere/models/reference_atmospheres/reference_atmo_model_v0_ctao-north_intermediate.ecsv +73 -0
- calibpipe/atmosphere/models/reference_atmospheres/reference_atmo_model_v0_ctao-north_summer.ecsv +73 -0
- calibpipe/atmosphere/models/reference_atmospheres/reference_atmo_model_v0_ctao-north_winter.ecsv +73 -0
- calibpipe/atmosphere/models/reference_atmospheres/reference_atmo_model_v0_ctao-south_summer.ecsv +73 -0
- calibpipe/atmosphere/models/reference_atmospheres/reference_atmo_model_v0_ctao-south_winter.ecsv +73 -0
- calibpipe/atmosphere/models/reference_rayleigh_scattering_profiles/__init__.py +1 -0
- calibpipe/atmosphere/models/reference_rayleigh_scattering_profiles/reference_rayleigh_extinction_profile_v0_ctao-north_intermediate.ecsv +857 -0
- calibpipe/atmosphere/models/reference_rayleigh_scattering_profiles/reference_rayleigh_extinction_profile_v0_ctao-north_summer.ecsv +857 -0
- calibpipe/atmosphere/models/reference_rayleigh_scattering_profiles/reference_rayleigh_extinction_profile_v0_ctao-north_winter.ecsv +857 -0
- calibpipe/atmosphere/models/reference_rayleigh_scattering_profiles/reference_rayleigh_extinction_profile_v0_ctao-south_summer.ecsv +857 -0
- calibpipe/atmosphere/models/reference_rayleigh_scattering_profiles/reference_rayleigh_extinction_profile_v0_ctao-south_winter.ecsv +857 -0
- calibpipe/atmosphere/templates/request_templates/__init__.py +1 -0
- calibpipe/atmosphere/templates/request_templates/copernicus.json +11 -0
- calibpipe/atmosphere/templates/request_templates/gdas.json +12 -0
- calibpipe/core/__init__.py +39 -0
- calibpipe/core/common_metadata_containers.py +198 -0
- calibpipe/core/exceptions.py +87 -0
- calibpipe/database/__init__.py +24 -0
- calibpipe/database/adapter/__init__.py +23 -0
- calibpipe/database/adapter/adapter.py +80 -0
- calibpipe/database/adapter/database_containers/__init__.py +63 -0
- calibpipe/database/adapter/database_containers/atmosphere.py +199 -0
- calibpipe/database/adapter/database_containers/common_metadata.py +150 -0
- calibpipe/database/adapter/database_containers/container_map.py +59 -0
- calibpipe/database/adapter/database_containers/observatory.py +61 -0
- calibpipe/database/adapter/database_containers/table_version_manager.py +39 -0
- calibpipe/database/adapter/database_containers/throughput.py +30 -0
- calibpipe/database/adapter/database_containers/version_control.py +17 -0
- calibpipe/database/connections/__init__.py +28 -0
- calibpipe/database/connections/calibpipe_database.py +60 -0
- calibpipe/database/connections/postgres_utils.py +97 -0
- calibpipe/database/connections/sql_connection.py +103 -0
- calibpipe/database/connections/user_confirmation.py +19 -0
- calibpipe/database/interfaces/__init__.py +71 -0
- calibpipe/database/interfaces/hashable_row_data.py +54 -0
- calibpipe/database/interfaces/queries.py +180 -0
- calibpipe/database/interfaces/sql_column_info.py +67 -0
- calibpipe/database/interfaces/sql_metadata.py +6 -0
- calibpipe/database/interfaces/sql_table_info.py +131 -0
- calibpipe/database/interfaces/table_handler.py +333 -0
- calibpipe/database/interfaces/types.py +96 -0
- calibpipe/telescope/throughput/containers.py +66 -0
- calibpipe/tests/conftest.py +274 -0
- calibpipe/tests/data/atmosphere/molecular_atmosphere/__init__.py +0 -0
- calibpipe/tests/data/atmosphere/molecular_atmosphere/contemporary_MDP.ecsv +34 -0
- calibpipe/tests/data/atmosphere/molecular_atmosphere/macobac.csv +852 -0
- calibpipe/tests/data/atmosphere/molecular_atmosphere/macobac.ecsv +23 -0
- calibpipe/tests/data/atmosphere/molecular_atmosphere/merged_file.ecsv +1082 -0
- calibpipe/tests/data/atmosphere/molecular_atmosphere/meteo_data_copernicus.ecsv +1082 -0
- calibpipe/tests/data/atmosphere/molecular_atmosphere/meteo_data_gdas.ecsv +66 -0
- calibpipe/tests/data/atmosphere/molecular_atmosphere/observatory_configurations.json +71 -0
- calibpipe/tests/data/utils/__init__.py +0 -0
- calibpipe/tests/data/utils/meteo_data_winter_and_summer.ecsv +12992 -0
- calibpipe/tests/test_conftest_data.py +200 -0
- calibpipe/tests/unittests/array/test_cross_calibration.py +412 -0
- calibpipe/tests/unittests/atmosphere/astral_testing.py +107 -0
- calibpipe/tests/unittests/atmosphere/test_meteo_data_handler.py +775 -0
- calibpipe/tests/unittests/atmosphere/test_molecular_atmosphere.py +327 -0
- calibpipe/tests/unittests/database/test_table_handler.py +163 -0
- calibpipe/tests/unittests/database/test_types.py +38 -0
- calibpipe/tests/unittests/telescope/camera/test_calculate_camcalib_coefficients.py +456 -0
- calibpipe/tests/unittests/telescope/camera/test_produce_camcalib_test_data.py +37 -0
- calibpipe/tests/unittests/telescope/throughput/test_muon_throughput_calibrator.py +693 -0
- calibpipe/tests/unittests/test_bootstrap_db.py +79 -0
- calibpipe/tests/unittests/utils/test_observatory.py +309 -0
- calibpipe/tools/atmospheric_base_tool.py +78 -0
- calibpipe/tools/atmospheric_model_db_loader.py +181 -0
- calibpipe/tools/basic_tool_with_db.py +38 -0
- calibpipe/tools/camcalib_test_data.py +374 -0
- calibpipe/tools/camera_calibrator.py +462 -0
- calibpipe/tools/contemporary_mdp_producer.py +87 -0
- calibpipe/tools/init_db.py +37 -0
- calibpipe/tools/macobac_calculator.py +82 -0
- calibpipe/tools/molecular_atmospheric_model_producer.py +197 -0
- calibpipe/tools/muon_throughput_calculator.py +219 -0
- calibpipe/tools/observatory_data_db_loader.py +71 -0
- calibpipe/tools/reference_atmospheric_model_selector.py +201 -0
- calibpipe/tools/telescope_cross_calibration_calculator.py +721 -0
- calibpipe/utils/__init__.py +10 -0
- calibpipe/utils/observatory.py +486 -0
- calibpipe/utils/observatory_containers.py +26 -0
- calibpipe/version.py +24 -0
- ctao_calibpipe-0.3.0rc2.dist-info/METADATA +92 -0
- ctao_calibpipe-0.3.0rc2.dist-info/RECORD +105 -0
- ctao_calibpipe-0.3.0rc2.dist-info/WHEEL +5 -0
- ctao_calibpipe-0.3.0rc2.dist-info/entry_points.txt +12 -0
- ctao_calibpipe-0.3.0rc2.dist-info/licenses/AUTHORS.md +13 -0
- ctao_calibpipe-0.3.0rc2.dist-info/licenses/LICENSE +21 -0
- ctao_calibpipe-0.3.0rc2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Templates for DAS data requests."""
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"product_type": "reanalysis",
|
|
3
|
+
"variable": ["divergence", "geopotential", "ozone_mass_mixing_ratio", "potential_vorticity", "relative_humidity", "temperature", "u_component_of_wind", "v_component_of_wind", "vertical_velocity"],
|
|
4
|
+
"pressure_level": ["1", "2", "3", "5", "7", "10", "20", "30", "50", "70", "100", "125", "150", "175", "200", "225", "250", "300", "350", "400", "450", "500", "550", "600", "650", "700", "750", "775", "800", "825", "850", "875", "900", "925", "950", "975", "1000"],
|
|
5
|
+
"year": [2023],
|
|
6
|
+
"month": [1],
|
|
7
|
+
"day": [20],
|
|
8
|
+
"time": ["19:00", "20:00", "21:00", "22:00", "23:00"],
|
|
9
|
+
"area": [28.74, -18.01, 28.76, -17.99],
|
|
10
|
+
"format": "grib"
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dataset": "ds083.2",
|
|
3
|
+
"date": "202301260600/to/202301270600",
|
|
4
|
+
"datetype": "init",
|
|
5
|
+
"param": "HGT/PRES/TMP/R H/P WAT/A PCP/U GRD/V GRD/T CDC/LANDN/TOZNE",
|
|
6
|
+
"level": "ISBL:1000/975/950/925/900/850/800/750/700/650/600/550/500/450/400/350/300/250/200/150/100/50/20",
|
|
7
|
+
"nlat": -24,
|
|
8
|
+
"slat": -24,
|
|
9
|
+
"elon": -70,
|
|
10
|
+
"wlon": -70,
|
|
11
|
+
"product": "Analysis"
|
|
12
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Provide core classes and methods for CalibPipe."""
|
|
2
|
+
|
|
3
|
+
from .common_metadata_containers import (
|
|
4
|
+
ActivityReferenceMetadataContainer,
|
|
5
|
+
ContactReferenceMetadataContainer,
|
|
6
|
+
InstrumentReferenceMetadataContainer,
|
|
7
|
+
ProcessReferenceMetadataContainer,
|
|
8
|
+
ProductReferenceMetadataContainer,
|
|
9
|
+
ReferenceMetadataContainer,
|
|
10
|
+
)
|
|
11
|
+
from .exceptions import (
|
|
12
|
+
CalibrationStorageError,
|
|
13
|
+
ConfigurationError,
|
|
14
|
+
CorruptedInputDataError,
|
|
15
|
+
DBStorageError,
|
|
16
|
+
FileStorageError,
|
|
17
|
+
InsufficientStatisticsError,
|
|
18
|
+
IntermittentError,
|
|
19
|
+
MissingInputDataError,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
# exceptions
|
|
24
|
+
"CorruptedInputDataError",
|
|
25
|
+
"ConfigurationError",
|
|
26
|
+
"MissingInputDataError",
|
|
27
|
+
"InsufficientStatisticsError",
|
|
28
|
+
"IntermittentError",
|
|
29
|
+
"DBStorageError",
|
|
30
|
+
"FileStorageError",
|
|
31
|
+
"CalibrationStorageError",
|
|
32
|
+
# common_metadata_containers
|
|
33
|
+
"ReferenceMetadataContainer",
|
|
34
|
+
"ProductReferenceMetadataContainer",
|
|
35
|
+
"ContactReferenceMetadataContainer",
|
|
36
|
+
"ProcessReferenceMetadataContainer",
|
|
37
|
+
"ActivityReferenceMetadataContainer",
|
|
38
|
+
"InstrumentReferenceMetadataContainer",
|
|
39
|
+
]
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"""Common metadata containers."""
|
|
2
|
+
|
|
3
|
+
from ctapipe.core import Container, Field
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ReferenceMetadataContainer(Container):
|
|
7
|
+
"""
|
|
8
|
+
Container to store reference metadata.
|
|
9
|
+
|
|
10
|
+
Serves as a central node for other metadata containers.
|
|
11
|
+
This is the essential metadata that must be attached
|
|
12
|
+
to all data products to uniquely describe the data product.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
version_atmospheric_model = Field(
|
|
16
|
+
None,
|
|
17
|
+
description="Atmospheric Model version value to serve as a foreign key",
|
|
18
|
+
type=str,
|
|
19
|
+
)
|
|
20
|
+
version = Field(
|
|
21
|
+
None,
|
|
22
|
+
description="Version of the reference metadata schema used in the data product",
|
|
23
|
+
type=int,
|
|
24
|
+
)
|
|
25
|
+
ID_optical_throughput = Field(
|
|
26
|
+
None, description="Optical throughput ID to serve as a foreign key", type=int
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ProductReferenceMetadataContainer(Container):
|
|
31
|
+
"""
|
|
32
|
+
Container to store product-related reference metadata.
|
|
33
|
+
|
|
34
|
+
Describes the details of the data product, including its type and links to the data model definition.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
ID = Field(
|
|
38
|
+
None,
|
|
39
|
+
description="Autoincremented value to serve as primary/foreign key",
|
|
40
|
+
type=int,
|
|
41
|
+
)
|
|
42
|
+
description = Field(
|
|
43
|
+
None, description="Human-readable description of data product", type=str
|
|
44
|
+
)
|
|
45
|
+
creation_time = Field(
|
|
46
|
+
None,
|
|
47
|
+
description="Human-readable date and time of file creation, in ISO format, UTC",
|
|
48
|
+
type=str,
|
|
49
|
+
)
|
|
50
|
+
product_id = Field(
|
|
51
|
+
None,
|
|
52
|
+
description="A fixed-id to identify this product, e.g. UUID or VFN",
|
|
53
|
+
type=str,
|
|
54
|
+
)
|
|
55
|
+
data_category = Field(None, description="A,B,C", type=str)
|
|
56
|
+
data_level = Field(None, description="R0, R1, DL0, DL1, etc", type=str)
|
|
57
|
+
data_association = Field(
|
|
58
|
+
None, description="CTAO, Site, Subarray, Telescope, etc", type=str
|
|
59
|
+
)
|
|
60
|
+
data_type = Field(None, description="Event, Monitoring, Service, etc", type=str)
|
|
61
|
+
data_model_name = Field(
|
|
62
|
+
None, description="Identifying name of the data model used", type=str
|
|
63
|
+
)
|
|
64
|
+
data_model_version = Field(
|
|
65
|
+
None, description="Version of the data model used", type=str
|
|
66
|
+
)
|
|
67
|
+
data_model_url = Field(
|
|
68
|
+
None,
|
|
69
|
+
description="Link to definition of data model, if available, and preferably a DOI",
|
|
70
|
+
type=str,
|
|
71
|
+
)
|
|
72
|
+
format = Field(None, description="File format of the data product", type=str)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class ContactReferenceMetadataContainer(Container):
|
|
76
|
+
"""
|
|
77
|
+
Container to store contact reference metadata.
|
|
78
|
+
|
|
79
|
+
Describes the person or institution that is responsible for this data product.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
ID = Field(
|
|
83
|
+
None,
|
|
84
|
+
description="Autoincremented value to serve as primary/foreign key",
|
|
85
|
+
type=int,
|
|
86
|
+
)
|
|
87
|
+
organization = Field(
|
|
88
|
+
None,
|
|
89
|
+
description="Organization to which this data product is associated",
|
|
90
|
+
type=str,
|
|
91
|
+
)
|
|
92
|
+
name = Field(None, description="Name of contact within organization", type=str)
|
|
93
|
+
email = Field(None, description="Contact email address", type=str)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class ProcessReferenceMetadataContainer(Container):
|
|
97
|
+
"""
|
|
98
|
+
Container to store process reference metadata.
|
|
99
|
+
|
|
100
|
+
Describes the top-level process
|
|
101
|
+
to which the activity that generated this product belongs.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
ID = Field(
|
|
105
|
+
None,
|
|
106
|
+
description="Autoincremented value to serve as primary/foreign key",
|
|
107
|
+
type=int,
|
|
108
|
+
)
|
|
109
|
+
type = Field(None, description="General type of the process", type=str)
|
|
110
|
+
subtype = Field(
|
|
111
|
+
None,
|
|
112
|
+
description="More specific class of the process if the class is not sufficient to describe it",
|
|
113
|
+
type=str,
|
|
114
|
+
)
|
|
115
|
+
subtype_id = Field(
|
|
116
|
+
None,
|
|
117
|
+
description="Unique identifier of the process, e.g. if the type is observation this is the obs_id",
|
|
118
|
+
type=str,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class ActivityReferenceMetadataContainer(Container):
|
|
123
|
+
"""
|
|
124
|
+
Container to store activity reference metadata.
|
|
125
|
+
|
|
126
|
+
Describes the specific software
|
|
127
|
+
or task that generated this particular data product.
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
ID = Field(
|
|
131
|
+
None,
|
|
132
|
+
description="Autoincremented value to serve as primary/foreign key",
|
|
133
|
+
type=int,
|
|
134
|
+
)
|
|
135
|
+
activity_id = Field(
|
|
136
|
+
None,
|
|
137
|
+
description="Unique identifier of the instance of this activity, if software a UUID",
|
|
138
|
+
type=str,
|
|
139
|
+
)
|
|
140
|
+
name = Field(
|
|
141
|
+
None,
|
|
142
|
+
description="Name of activity that produced this data product, e.g. the software/script name",
|
|
143
|
+
type=str,
|
|
144
|
+
)
|
|
145
|
+
type = Field(None, description="General type of the activity", type=str)
|
|
146
|
+
start = Field(
|
|
147
|
+
None, description="Starting date/time of activity, in ISO format, UTC", type=str
|
|
148
|
+
)
|
|
149
|
+
end = Field(
|
|
150
|
+
None, description="Ending date/time of activity, in ISO format, UTC", type=str
|
|
151
|
+
)
|
|
152
|
+
software_name = Field(
|
|
153
|
+
None,
|
|
154
|
+
description="Name of software framework/library that was used if the activity if it involved software",
|
|
155
|
+
type=str,
|
|
156
|
+
)
|
|
157
|
+
software_version = Field(None, description="Version of software used", type=str)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class InstrumentReferenceMetadataContainer(Container):
|
|
161
|
+
"""
|
|
162
|
+
Container to store instrument reference metadata.
|
|
163
|
+
|
|
164
|
+
Describes the subset of CTAO Instrument Description to which this data product is associated,
|
|
165
|
+
which could be e.g. a Sub-array, or a small part such as a photo-sensor.
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
ID = Field(
|
|
169
|
+
None,
|
|
170
|
+
description="Autoincremented value to serve as primary/foreign key",
|
|
171
|
+
type=int,
|
|
172
|
+
)
|
|
173
|
+
site = Field(
|
|
174
|
+
None,
|
|
175
|
+
description="CTAO-South, CTAO-North, or other site associated with the data product",
|
|
176
|
+
type=str,
|
|
177
|
+
)
|
|
178
|
+
type = Field(
|
|
179
|
+
None,
|
|
180
|
+
description=(
|
|
181
|
+
"The specific type of instrument in the class. E.g. if class=camera, ",
|
|
182
|
+
"the type might be CHEC, or if class=telescope, the type might be 'SST'",
|
|
183
|
+
),
|
|
184
|
+
type=str,
|
|
185
|
+
)
|
|
186
|
+
subtype = Field(
|
|
187
|
+
None,
|
|
188
|
+
description="Sub-type of the instrument. For example if the type is MST, this might be 'NectarCAM' or 'FlashCAM'",
|
|
189
|
+
type=str,
|
|
190
|
+
)
|
|
191
|
+
instrument_id = Field(
|
|
192
|
+
None,
|
|
193
|
+
description=(
|
|
194
|
+
"The unique ID of the specific instrument in the class. Depending on the instrument class,"
|
|
195
|
+
"this might be for example is a telescope id, nominal subarray name, camera_id, or part serial number"
|
|
196
|
+
),
|
|
197
|
+
type=str,
|
|
198
|
+
)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Calibpipe-specific exceptions.
|
|
3
|
+
|
|
4
|
+
Exit code values are following the ICD_.
|
|
5
|
+
|
|
6
|
+
.. _ICD: https://gitlab.cta-observatory.org/cta-computing/dpps/dpps-project-management/icd-pipelines-workload/-/jobs/artifacts/main/raw/build/pipelines-workload.pdf?job=build
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CalibrationError(Exception):
|
|
11
|
+
"""Base class for all CalibPipe exceptions."""
|
|
12
|
+
|
|
13
|
+
exit_code = 1
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class IntermittentError(CalibrationError):
|
|
17
|
+
"""Indicate an intermittent known issue that might be resolved by re-submitting the job."""
|
|
18
|
+
|
|
19
|
+
exit_code = 100
|
|
20
|
+
|
|
21
|
+
def __init__(self, message="Intermittent runtime error."):
|
|
22
|
+
super().__init__(message)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class CorruptedInputDataError(CalibrationError):
|
|
26
|
+
"""Raise when the input data file is available but cannot be correctly processed."""
|
|
27
|
+
|
|
28
|
+
exit_code = 104 # Activate an alternative scenario
|
|
29
|
+
|
|
30
|
+
def __init__(self, message="Input data is corrupted."):
|
|
31
|
+
super().__init__(message)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class MissingInputDataError(CalibrationError):
|
|
35
|
+
"""Raise when expected input data is missing."""
|
|
36
|
+
|
|
37
|
+
exit_code = 105 # Activate an alternative scenario
|
|
38
|
+
|
|
39
|
+
def __init__(self, message="Input data is missing."):
|
|
40
|
+
super().__init__(message)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class InsufficientStatisticsError(CalibrationError):
|
|
44
|
+
"""Raise when data quality is found to be insufficient after processing."""
|
|
45
|
+
|
|
46
|
+
exit_code = 106 # Activate an alternative scenario
|
|
47
|
+
|
|
48
|
+
def __init__(self, message="Quality of input data is not sufficient."):
|
|
49
|
+
super().__init__(message)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ConfigurationError(CalibrationError):
|
|
53
|
+
"""Raise for issues with the configuration files."""
|
|
54
|
+
|
|
55
|
+
exit_code = 101 # Configuration problem exit code due to IOError
|
|
56
|
+
|
|
57
|
+
def __init__(self, message="Problem with the input configuration file.", *args):
|
|
58
|
+
if args:
|
|
59
|
+
message = message % args
|
|
60
|
+
super().__init__(message)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class CalibrationStorageError(CalibrationError):
|
|
64
|
+
"""Raise for database/ECSV table storage related exceptions."""
|
|
65
|
+
|
|
66
|
+
exit_code = 102 # Runtime error exit code due to IOError
|
|
67
|
+
|
|
68
|
+
def __init__(self, message="Calibration coefficient cannot be stored."):
|
|
69
|
+
super().__init__(message)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class DBStorageError(CalibrationStorageError):
|
|
73
|
+
"""Raise for issues with data storage in the database."""
|
|
74
|
+
|
|
75
|
+
exit_code = 102 # Runtime error exit code due to IOError
|
|
76
|
+
|
|
77
|
+
def __init__(self, message="Storage in the database cannot be performed."):
|
|
78
|
+
super().__init__(message)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class FileStorageError(CalibrationStorageError):
|
|
82
|
+
"""Raise for issues with data storage in ECSV files."""
|
|
83
|
+
|
|
84
|
+
exit_code = 102 # Runtime error exit code due to IOError
|
|
85
|
+
|
|
86
|
+
def __init__(self, message="Storage in the output file cannot be performed."):
|
|
87
|
+
super().__init__(message)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Database utilities.
|
|
3
|
+
|
|
4
|
+
This sub-package contains general purpose utilities for database management,
|
|
5
|
+
and also the specialization for LST. LST-related code is contained in
|
|
6
|
+
the sub-packages starting with `lst_`, the rest is decoupled from it.
|
|
7
|
+
|
|
8
|
+
*Content:*
|
|
9
|
+
- :mod:`connections <calibpipe.database.connections>`:
|
|
10
|
+
|
|
11
|
+
General purpose connection (`SQLConnection`) using sqlalchemy
|
|
12
|
+
and specialisation for a `PostgreSQL+psycopg` database.
|
|
13
|
+
|
|
14
|
+
- :mod:`interfaces <calibpipe.database.interfaces>`:
|
|
15
|
+
|
|
16
|
+
General utilities to create and manipulate database objects
|
|
17
|
+
(fields, columns, tables, and the hashable row information used for cache
|
|
18
|
+
indexing, queries).
|
|
19
|
+
|
|
20
|
+
- :mod:`adapter <calibpipe.database.adapter>`:
|
|
21
|
+
|
|
22
|
+
All containers and utilities to convert ctapipe containers to tables that fill
|
|
23
|
+
the CalibPipe postgres database.
|
|
24
|
+
"""
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Adapter sub-package.
|
|
3
|
+
|
|
4
|
+
Contains all utilities to adapt CalibPipe data to a DB and use it.
|
|
5
|
+
|
|
6
|
+
Sub-package content:
|
|
7
|
+
|
|
8
|
+
- :mod:`database_containers<calibpipe.database.adapter.database_containers>`:
|
|
9
|
+
DB containers (in correspondence with CalibPipe containers)
|
|
10
|
+
to connect CalibPipe data and the DB system.
|
|
11
|
+
- :mod:`adapter<calibpipe.database.adapter.adapter>`:
|
|
12
|
+
Small class used to translate CalibPipe container data
|
|
13
|
+
to DB-level data that can be directly inserted in a DB.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from . import database_containers
|
|
18
|
+
from .adapter import Adapter
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"database_containers",
|
|
22
|
+
"Adapter",
|
|
23
|
+
]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Adapter class."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
import astropy.units
|
|
6
|
+
import sqlalchemy as sa
|
|
7
|
+
|
|
8
|
+
from .database_containers.container_map import ContainerMap
|
|
9
|
+
from .database_containers.table_version_manager import TableVersionManager
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Adapter:
|
|
13
|
+
"""
|
|
14
|
+
Adapt CalibPipe containers into DB objects.
|
|
15
|
+
|
|
16
|
+
The main method is to_postgres(), converting a CalibPipe container
|
|
17
|
+
to a tuple containing the objects required to interact with the
|
|
18
|
+
corresponding data in the database.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def to_postgres(
|
|
23
|
+
container: ContainerMap.cp_container, version: str | None = None
|
|
24
|
+
) -> tuple[sa.Table, dict[str, Any]] | None:
|
|
25
|
+
"""
|
|
26
|
+
Convert a CalibPipe container in DB data that can be inserted or queried.
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
container: ContainerMap.cp_container
|
|
31
|
+
CalibPipe container (containing data) to convert to DB-level data
|
|
32
|
+
|
|
33
|
+
version: str
|
|
34
|
+
Software version corresponding to the data
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
Optional[tuple[sa.Table, dict[str, Any]]]
|
|
39
|
+
None if no DB table information is associated to the container.
|
|
40
|
+
A tuple containing the SQL table corresponding to the container,
|
|
41
|
+
and a dictionary with the valued attributes contained in the
|
|
42
|
+
CalibPipe container.
|
|
43
|
+
"""
|
|
44
|
+
try:
|
|
45
|
+
table_info = ContainerMap.map_to_db_container(type(container))
|
|
46
|
+
table = TableVersionManager.apply_version(
|
|
47
|
+
table_info=table_info, version=version
|
|
48
|
+
)
|
|
49
|
+
return table, Adapter.get_db_kwargs(container, table_info)
|
|
50
|
+
except KeyError:
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def get_db_kwargs(
|
|
55
|
+
container: ContainerMap.cp_container,
|
|
56
|
+
table_info: ContainerMap.db_container_info,
|
|
57
|
+
) -> dict[str, Any]:
|
|
58
|
+
"""Get kwargs required to insert a row from a CalibPipe container."""
|
|
59
|
+
return {
|
|
60
|
+
name: Adapter._remove_astropy_unit(value, col.unit)
|
|
61
|
+
for (name, value), col in zip(container.items(), table_info.columns)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def _remove_astropy_unit(value, unit):
|
|
66
|
+
"""
|
|
67
|
+
Remove the astropy unit from a value if necessary.
|
|
68
|
+
|
|
69
|
+
Astropy units cannot be stored in a database, or at least not
|
|
70
|
+
in a single field. Units are therefore removed and the value is
|
|
71
|
+
converted to either units from the column description
|
|
72
|
+
or to SI units for consistency.
|
|
73
|
+
"""
|
|
74
|
+
if isinstance(value, astropy.units.Quantity):
|
|
75
|
+
if unit is not None:
|
|
76
|
+
return (
|
|
77
|
+
value.decompose().to(unit).value
|
|
78
|
+
) # Value only, in the units from column description
|
|
79
|
+
return value.decompose().value # Value only, in S.I. units
|
|
80
|
+
return value
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Contain database containers for CalibPipe and the table version manager.
|
|
3
|
+
|
|
4
|
+
All CalibPipe data is defined at the database level
|
|
5
|
+
in this sub-package. In particular, a `SQLTableInformation` can be
|
|
6
|
+
found for each CalibPipe container.
|
|
7
|
+
|
|
8
|
+
In addition, two utilities are present here to ease the use of DB
|
|
9
|
+
containers:
|
|
10
|
+
|
|
11
|
+
- `TableVersionManager`: Creates tables objects specific to a version number
|
|
12
|
+
(needed for CalibPipe data).
|
|
13
|
+
- `ContainerMap`: Maps CalibPipe containers (ultimately `ctapipe.core.container`)
|
|
14
|
+
to database table information. The mapping is built-in,
|
|
15
|
+
and allows users to quickly access the DB container
|
|
16
|
+
corresponding to a CalibPipe container (or the contrary).
|
|
17
|
+
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from .atmosphere import (
|
|
21
|
+
atmospheric_model_sql_info,
|
|
22
|
+
macobac_sql_info,
|
|
23
|
+
map_meta_sql_info,
|
|
24
|
+
map_sql_info,
|
|
25
|
+
mdp_sql_info,
|
|
26
|
+
rayleigh_extinction_sql_info,
|
|
27
|
+
selected_model_sql_info,
|
|
28
|
+
)
|
|
29
|
+
from .common_metadata import (
|
|
30
|
+
activity_reference_metadata_sql_info,
|
|
31
|
+
contact_reference_metadata_sql_info,
|
|
32
|
+
instrument_reference_metadata_sql_info,
|
|
33
|
+
process_reference_metadata_sql_info,
|
|
34
|
+
product_reference_metadata_sql_info,
|
|
35
|
+
reference_metadata_sql_info,
|
|
36
|
+
)
|
|
37
|
+
from .container_map import ContainerMap
|
|
38
|
+
from .observatory import observatory_sql_info, season_sql_info
|
|
39
|
+
from .table_version_manager import TableVersionManager
|
|
40
|
+
from .throughput import optical_throughput_sql_info
|
|
41
|
+
from .version_control import version_control_sql_info
|
|
42
|
+
|
|
43
|
+
__all__ = [
|
|
44
|
+
"atmospheric_model_sql_info",
|
|
45
|
+
"map_meta_sql_info",
|
|
46
|
+
"map_sql_info",
|
|
47
|
+
"mdp_sql_info",
|
|
48
|
+
"macobac_sql_info",
|
|
49
|
+
"selected_model_sql_info",
|
|
50
|
+
"observatory_sql_info",
|
|
51
|
+
"rayleigh_extinction_sql_info",
|
|
52
|
+
"season_sql_info",
|
|
53
|
+
"version_control_sql_info",
|
|
54
|
+
"TableVersionManager",
|
|
55
|
+
"ContainerMap",
|
|
56
|
+
"reference_metadata_sql_info",
|
|
57
|
+
"product_reference_metadata_sql_info",
|
|
58
|
+
"contact_reference_metadata_sql_info",
|
|
59
|
+
"activity_reference_metadata_sql_info",
|
|
60
|
+
"process_reference_metadata_sql_info",
|
|
61
|
+
"instrument_reference_metadata_sql_info",
|
|
62
|
+
"optical_throughput_sql_info",
|
|
63
|
+
]
|