ctao-calibpipe 0.1.0rc7__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.
Potentially problematic release.
This version of ctao-calibpipe might be problematic. Click here for more details.
- calibpipe/__init__.py +5 -0
- calibpipe/_dev_version/__init__.py +9 -0
- calibpipe/_version.py +21 -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 +195 -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 +61 -0
- calibpipe/database/adapter/database_containers/atmosphere.py +199 -0
- calibpipe/database/adapter/database_containers/common_metadata.py +148 -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/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 +351 -0
- calibpipe/database/interfaces/types.py +96 -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/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 +66 -0
- calibpipe/tests/unittests/database/test_types.py +38 -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/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/observatory_data_db_loader.py +71 -0
- calibpipe/tools/reference_atmospheric_model_selector.py +201 -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.1.0rc7.dist-info/METADATA +86 -0
- ctao_calibpipe-0.1.0rc7.dist-info/RECORD +93 -0
- ctao_calibpipe-0.1.0rc7.dist-info/WHEEL +5 -0
- ctao_calibpipe-0.1.0rc7.dist-info/entry_points.txt +8 -0
- ctao_calibpipe-0.1.0rc7.dist-info/licenses/AUTHORS.md +13 -0
- ctao_calibpipe-0.1.0rc7.dist-info/licenses/LICENSE +21 -0
- ctao_calibpipe-0.1.0rc7.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"""Atmospheric SQL table info."""
|
|
2
|
+
|
|
3
|
+
from sqlalchemy.schema import ForeignKeyConstraint
|
|
4
|
+
|
|
5
|
+
from ....atmosphere.atmosphere_containers import (
|
|
6
|
+
AtmosphericModelContainer,
|
|
7
|
+
MacobacContainer,
|
|
8
|
+
MolecularAtmosphericProfileContainer,
|
|
9
|
+
MolecularAtmosphericProfileMetaContainer,
|
|
10
|
+
MolecularDensityContainer,
|
|
11
|
+
RayleighExtinctionContainer,
|
|
12
|
+
SelectedAtmosphericModelContainer,
|
|
13
|
+
)
|
|
14
|
+
from ...interfaces.sql_column_info import SQLColumnInfo
|
|
15
|
+
from ...interfaces.sql_metadata import sql_metadata
|
|
16
|
+
from ...interfaces.sql_table_info import SQLTableInfo
|
|
17
|
+
from ...interfaces.types import (
|
|
18
|
+
ArrayF1D,
|
|
19
|
+
ArrayF2D,
|
|
20
|
+
Boolean,
|
|
21
|
+
Date,
|
|
22
|
+
Float,
|
|
23
|
+
Integer,
|
|
24
|
+
String,
|
|
25
|
+
)
|
|
26
|
+
from .container_map import ContainerMap
|
|
27
|
+
|
|
28
|
+
atmospheric_model_sql_info = SQLTableInfo(
|
|
29
|
+
table_name="AtmosphericModel",
|
|
30
|
+
metadata=sql_metadata,
|
|
31
|
+
columns=[
|
|
32
|
+
SQLColumnInfo("start", Date),
|
|
33
|
+
SQLColumnInfo("stop", Date),
|
|
34
|
+
SQLColumnInfo("version", String, primary_key=True),
|
|
35
|
+
SQLColumnInfo("current", Boolean),
|
|
36
|
+
SQLColumnInfo("season", String),
|
|
37
|
+
SQLColumnInfo("name_Observatory", String, nullable=False),
|
|
38
|
+
SQLColumnInfo("version_Observatory", Integer, nullable=False),
|
|
39
|
+
],
|
|
40
|
+
constraints=[
|
|
41
|
+
ForeignKeyConstraint(
|
|
42
|
+
["name_Observatory", "version_Observatory"],
|
|
43
|
+
["Observatory.name", "Observatory.version"],
|
|
44
|
+
)
|
|
45
|
+
],
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
mdp_sql_info = SQLTableInfo(
|
|
49
|
+
table_name="MolecularDensity",
|
|
50
|
+
metadata=sql_metadata,
|
|
51
|
+
columns=[
|
|
52
|
+
SQLColumnInfo("season", String),
|
|
53
|
+
SQLColumnInfo("density", Float, unit="1/cm^3"),
|
|
54
|
+
SQLColumnInfo("version", String, primary_key=True),
|
|
55
|
+
],
|
|
56
|
+
constraints=[
|
|
57
|
+
ForeignKeyConstraint(
|
|
58
|
+
[
|
|
59
|
+
"version",
|
|
60
|
+
],
|
|
61
|
+
[
|
|
62
|
+
"AtmosphericModel.version",
|
|
63
|
+
],
|
|
64
|
+
)
|
|
65
|
+
],
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
map_meta_sql_info = SQLTableInfo(
|
|
69
|
+
table_name="MolecularAtmosphericProfileMeta",
|
|
70
|
+
metadata=sql_metadata,
|
|
71
|
+
columns=[
|
|
72
|
+
SQLColumnInfo("data_assimilation_system", String),
|
|
73
|
+
SQLColumnInfo("dataset", String),
|
|
74
|
+
SQLColumnInfo("description", String),
|
|
75
|
+
SQLColumnInfo("version", String, primary_key=True),
|
|
76
|
+
],
|
|
77
|
+
constraints=[
|
|
78
|
+
ForeignKeyConstraint(
|
|
79
|
+
[
|
|
80
|
+
"version",
|
|
81
|
+
],
|
|
82
|
+
[
|
|
83
|
+
"AtmosphericModel.version",
|
|
84
|
+
],
|
|
85
|
+
)
|
|
86
|
+
],
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
map_sql_info = SQLTableInfo(
|
|
90
|
+
table_name="MolecularAtmosphericProfile",
|
|
91
|
+
metadata=sql_metadata,
|
|
92
|
+
columns=[
|
|
93
|
+
SQLColumnInfo("altitude", ArrayF1D, unit="km"),
|
|
94
|
+
SQLColumnInfo("pressure", ArrayF1D, unit="hPa"),
|
|
95
|
+
SQLColumnInfo("temperature", ArrayF1D, unit="K"),
|
|
96
|
+
SQLColumnInfo("partial_water_pressure", ArrayF1D),
|
|
97
|
+
SQLColumnInfo("refractive_index_m_1", ArrayF1D),
|
|
98
|
+
SQLColumnInfo("atmospheric_density", ArrayF1D, unit="g/cm^3"),
|
|
99
|
+
SQLColumnInfo("atmospheric_thickness", ArrayF1D, unit="g/cm^2"),
|
|
100
|
+
SQLColumnInfo("version", String, primary_key=True),
|
|
101
|
+
],
|
|
102
|
+
constraints=[
|
|
103
|
+
ForeignKeyConstraint(
|
|
104
|
+
[
|
|
105
|
+
"version",
|
|
106
|
+
],
|
|
107
|
+
[
|
|
108
|
+
"AtmosphericModel.version",
|
|
109
|
+
],
|
|
110
|
+
)
|
|
111
|
+
],
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
macobac_sql_info = SQLTableInfo(
|
|
115
|
+
table_name="MACOBAC",
|
|
116
|
+
metadata=sql_metadata,
|
|
117
|
+
columns=[
|
|
118
|
+
SQLColumnInfo("co2_concentration", Float, unit="ppm"),
|
|
119
|
+
SQLColumnInfo("estimation_date", Date),
|
|
120
|
+
SQLColumnInfo("version", String, primary_key=True),
|
|
121
|
+
],
|
|
122
|
+
constraints=[
|
|
123
|
+
ForeignKeyConstraint(
|
|
124
|
+
[
|
|
125
|
+
"version",
|
|
126
|
+
],
|
|
127
|
+
[
|
|
128
|
+
"AtmosphericModel.version",
|
|
129
|
+
],
|
|
130
|
+
)
|
|
131
|
+
],
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
rayleigh_extinction_sql_info = SQLTableInfo(
|
|
135
|
+
table_name="RayleighExtinction",
|
|
136
|
+
metadata=sql_metadata,
|
|
137
|
+
columns=[
|
|
138
|
+
SQLColumnInfo("wavelength", ArrayF1D, unit="nm"),
|
|
139
|
+
SQLColumnInfo("altitude", ArrayF2D, unit="km"),
|
|
140
|
+
SQLColumnInfo("AOD", ArrayF2D),
|
|
141
|
+
SQLColumnInfo("version", String, primary_key=True),
|
|
142
|
+
],
|
|
143
|
+
constraints=[
|
|
144
|
+
ForeignKeyConstraint(
|
|
145
|
+
[
|
|
146
|
+
"version",
|
|
147
|
+
],
|
|
148
|
+
[
|
|
149
|
+
"AtmosphericModel.version",
|
|
150
|
+
],
|
|
151
|
+
)
|
|
152
|
+
],
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
selected_model_sql_info = SQLTableInfo(
|
|
156
|
+
table_name="SelectedAtmosphericModel",
|
|
157
|
+
metadata=sql_metadata,
|
|
158
|
+
columns=[
|
|
159
|
+
SQLColumnInfo("date", Date),
|
|
160
|
+
SQLColumnInfo("provenance", String),
|
|
161
|
+
SQLColumnInfo("season", String),
|
|
162
|
+
SQLColumnInfo("site", String),
|
|
163
|
+
SQLColumnInfo("version", String),
|
|
164
|
+
],
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
ContainerMap.register_container_pair(
|
|
168
|
+
cp_container=AtmosphericModelContainer,
|
|
169
|
+
db_container=atmospheric_model_sql_info,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
ContainerMap.register_container_pair(
|
|
173
|
+
cp_container=MolecularAtmosphericProfileMetaContainer,
|
|
174
|
+
db_container=map_meta_sql_info,
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
ContainerMap.register_container_pair(
|
|
178
|
+
cp_container=MolecularAtmosphericProfileContainer,
|
|
179
|
+
db_container=map_sql_info,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
ContainerMap.register_container_pair(
|
|
183
|
+
cp_container=MolecularDensityContainer,
|
|
184
|
+
db_container=mdp_sql_info,
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
ContainerMap.register_container_pair(
|
|
188
|
+
cp_container=MacobacContainer,
|
|
189
|
+
db_container=macobac_sql_info,
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
ContainerMap.register_container_pair(
|
|
193
|
+
cp_container=RayleighExtinctionContainer,
|
|
194
|
+
db_container=rayleigh_extinction_sql_info,
|
|
195
|
+
)
|
|
196
|
+
ContainerMap.register_container_pair(
|
|
197
|
+
cp_container=SelectedAtmosphericModelContainer,
|
|
198
|
+
db_container=selected_model_sql_info,
|
|
199
|
+
)
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""Common Metadata SQL info."""
|
|
2
|
+
|
|
3
|
+
from sqlalchemy.schema import ForeignKeyConstraint, UniqueConstraint
|
|
4
|
+
|
|
5
|
+
from ....core.common_metadata_containers import (
|
|
6
|
+
ActivityReferenceMetadataContainer,
|
|
7
|
+
ContactReferenceMetadataContainer,
|
|
8
|
+
InstrumentReferenceMetadataContainer,
|
|
9
|
+
ProcessReferenceMetadataContainer,
|
|
10
|
+
ProductReferenceMetadataContainer,
|
|
11
|
+
ReferenceMetadataContainer,
|
|
12
|
+
)
|
|
13
|
+
from ...interfaces.sql_column_info import SQLColumnInfo
|
|
14
|
+
from ...interfaces.sql_metadata import sql_metadata
|
|
15
|
+
from ...interfaces.sql_table_info import SQLTableInfo
|
|
16
|
+
from ...interfaces.types import Integer, String
|
|
17
|
+
from .container_map import ContainerMap
|
|
18
|
+
|
|
19
|
+
reference_metadata_sql_info = SQLTableInfo(
|
|
20
|
+
table_name="reference_metadata",
|
|
21
|
+
metadata=sql_metadata,
|
|
22
|
+
columns=[
|
|
23
|
+
SQLColumnInfo("ID", Integer, unique=True, primary_key=True, autoincrement=True),
|
|
24
|
+
SQLColumnInfo("version_atmospheric_model", String),
|
|
25
|
+
SQLColumnInfo("version", String),
|
|
26
|
+
],
|
|
27
|
+
constraints=[
|
|
28
|
+
ForeignKeyConstraint(
|
|
29
|
+
["version_atmospheric_model"], ["AtmosphericModel.version"]
|
|
30
|
+
),
|
|
31
|
+
UniqueConstraint("ID"),
|
|
32
|
+
],
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
product_reference_metadata_sql_info = SQLTableInfo(
|
|
36
|
+
table_name="product_reference_metadata",
|
|
37
|
+
metadata=sql_metadata,
|
|
38
|
+
columns=[
|
|
39
|
+
SQLColumnInfo("ID", Integer, unique=True, primary_key=True),
|
|
40
|
+
SQLColumnInfo("description", String),
|
|
41
|
+
SQLColumnInfo("creation_time", String),
|
|
42
|
+
SQLColumnInfo("product_id", String),
|
|
43
|
+
SQLColumnInfo("data_category", String),
|
|
44
|
+
SQLColumnInfo("data_level", String),
|
|
45
|
+
SQLColumnInfo("data_association", String),
|
|
46
|
+
SQLColumnInfo("data_type", String),
|
|
47
|
+
SQLColumnInfo("data_model_name", String),
|
|
48
|
+
SQLColumnInfo("data_model_version", String),
|
|
49
|
+
SQLColumnInfo("data_model_url", String),
|
|
50
|
+
SQLColumnInfo("format", String),
|
|
51
|
+
],
|
|
52
|
+
constraints=[
|
|
53
|
+
ForeignKeyConstraint(["ID"], ["reference_metadata.ID"]),
|
|
54
|
+
UniqueConstraint("ID"),
|
|
55
|
+
],
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
contact_reference_metadata_sql_info = SQLTableInfo(
|
|
59
|
+
table_name="contact_reference_metadata",
|
|
60
|
+
metadata=sql_metadata,
|
|
61
|
+
columns=[
|
|
62
|
+
SQLColumnInfo("ID", Integer, unique=True, primary_key=True),
|
|
63
|
+
SQLColumnInfo("organization", String),
|
|
64
|
+
SQLColumnInfo("name", String),
|
|
65
|
+
SQLColumnInfo("email", String),
|
|
66
|
+
],
|
|
67
|
+
constraints=[
|
|
68
|
+
ForeignKeyConstraint(["ID"], ["reference_metadata.ID"]),
|
|
69
|
+
UniqueConstraint("ID"),
|
|
70
|
+
],
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
activity_reference_metadata_sql_info = SQLTableInfo(
|
|
74
|
+
table_name="activity_reference_metadata",
|
|
75
|
+
metadata=sql_metadata,
|
|
76
|
+
columns=[
|
|
77
|
+
SQLColumnInfo("ID", Integer, unique=True, primary_key=True),
|
|
78
|
+
SQLColumnInfo("activity_id", String),
|
|
79
|
+
SQLColumnInfo("name", String),
|
|
80
|
+
SQLColumnInfo("type", String),
|
|
81
|
+
SQLColumnInfo("start", String),
|
|
82
|
+
SQLColumnInfo("end", String),
|
|
83
|
+
SQLColumnInfo("software_name", String),
|
|
84
|
+
SQLColumnInfo("software_version", String),
|
|
85
|
+
],
|
|
86
|
+
constraints=[
|
|
87
|
+
ForeignKeyConstraint(["ID"], ["reference_metadata.ID"]),
|
|
88
|
+
UniqueConstraint("ID"),
|
|
89
|
+
],
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
process_reference_metadata_sql_info = SQLTableInfo(
|
|
93
|
+
table_name="process_reference_metadata",
|
|
94
|
+
metadata=sql_metadata,
|
|
95
|
+
columns=[
|
|
96
|
+
SQLColumnInfo("ID", Integer, unique=True, primary_key=True),
|
|
97
|
+
SQLColumnInfo("type", String),
|
|
98
|
+
SQLColumnInfo("subtype", String),
|
|
99
|
+
SQLColumnInfo("subtype_id", String),
|
|
100
|
+
],
|
|
101
|
+
constraints=[
|
|
102
|
+
ForeignKeyConstraint(["ID"], ["activity_reference_metadata.ID"]),
|
|
103
|
+
UniqueConstraint("ID"),
|
|
104
|
+
],
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
instrument_reference_metadata_sql_info = SQLTableInfo(
|
|
108
|
+
table_name="instrument_reference_metadata",
|
|
109
|
+
metadata=sql_metadata,
|
|
110
|
+
columns=[
|
|
111
|
+
SQLColumnInfo("ID", Integer, unique=True, primary_key=True),
|
|
112
|
+
SQLColumnInfo("site", String),
|
|
113
|
+
SQLColumnInfo("type", String),
|
|
114
|
+
SQLColumnInfo("subtype", String),
|
|
115
|
+
SQLColumnInfo("instrument_id", String),
|
|
116
|
+
],
|
|
117
|
+
constraints=[ForeignKeyConstraint(["ID"], ["process_reference_metadata.ID"])],
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
ContainerMap.register_container_pair(
|
|
121
|
+
cp_container=ReferenceMetadataContainer,
|
|
122
|
+
db_container=reference_metadata_sql_info,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
ContainerMap.register_container_pair(
|
|
126
|
+
cp_container=ProductReferenceMetadataContainer,
|
|
127
|
+
db_container=product_reference_metadata_sql_info,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
ContainerMap.register_container_pair(
|
|
131
|
+
cp_container=ContactReferenceMetadataContainer,
|
|
132
|
+
db_container=contact_reference_metadata_sql_info,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
ContainerMap.register_container_pair(
|
|
136
|
+
cp_container=ActivityReferenceMetadataContainer,
|
|
137
|
+
db_container=activity_reference_metadata_sql_info,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
ContainerMap.register_container_pair(
|
|
141
|
+
cp_container=ProcessReferenceMetadataContainer,
|
|
142
|
+
db_container=process_reference_metadata_sql_info,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
ContainerMap.register_container_pair(
|
|
146
|
+
cp_container=InstrumentReferenceMetadataContainer,
|
|
147
|
+
db_container=instrument_reference_metadata_sql_info,
|
|
148
|
+
)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""ContainerMap class."""
|
|
2
|
+
|
|
3
|
+
from ctapipe.core import Container
|
|
4
|
+
|
|
5
|
+
from ...interfaces.sql_table_info import SQLTableInfo
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ContainerMap:
|
|
9
|
+
"""
|
|
10
|
+
Map CalibPipe and database containers.
|
|
11
|
+
|
|
12
|
+
The correspondence must be set using the `register_container_pair()`
|
|
13
|
+
method, called automatically for the built-in CalibPipe containers. Once
|
|
14
|
+
set, this map allows us to quickly get the DB container associated
|
|
15
|
+
to a CalilbPipe container (or contrary) to switch between the two worlds.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
cp_container = Container
|
|
19
|
+
|
|
20
|
+
db_container_info = SQLTableInfo
|
|
21
|
+
cp_container_type = type[cp_container]
|
|
22
|
+
|
|
23
|
+
_cp_containers: dict[db_container_info, cp_container_type] = {}
|
|
24
|
+
_db_containers: dict[cp_container_type, db_container_info] = {}
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def map_to_cp_container(
|
|
28
|
+
db_container: db_container_info,
|
|
29
|
+
) -> cp_container_type:
|
|
30
|
+
"""Return the CalibPipe container corresponding to a DB container."""
|
|
31
|
+
return ContainerMap._cp_containers[db_container]
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def map_to_db_container(
|
|
35
|
+
cp_container: cp_container_type,
|
|
36
|
+
) -> db_container_info:
|
|
37
|
+
"""Return the DB container corresponding to a CalibPipe container."""
|
|
38
|
+
return ContainerMap._db_containers[cp_container]
|
|
39
|
+
|
|
40
|
+
@staticmethod
|
|
41
|
+
def get_cp_containers() -> list:
|
|
42
|
+
"""Return the list of registered CalibPipe containers."""
|
|
43
|
+
return [*ContainerMap._db_containers]
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def register_container_pair(
|
|
47
|
+
cp_container: cp_container_type, db_container: db_container_info
|
|
48
|
+
) -> None:
|
|
49
|
+
"""Associate a CalibPipe container and a DB container."""
|
|
50
|
+
ContainerMap._cp_containers[db_container] = cp_container
|
|
51
|
+
ContainerMap._db_containers[cp_container] = db_container
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def unregister_container_pair(
|
|
55
|
+
cp_container: cp_container_type, db_container: db_container_info
|
|
56
|
+
) -> None:
|
|
57
|
+
"""Deassociate a CalibPipe container and a DB container."""
|
|
58
|
+
ContainerMap._db_containers[cp_container].pop(db_container, None)
|
|
59
|
+
ContainerMap._cp_containers[db_container].pop(cp_container, None)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Observatory SQL table info."""
|
|
2
|
+
|
|
3
|
+
from sqlalchemy.schema import ForeignKeyConstraint, UniqueConstraint
|
|
4
|
+
|
|
5
|
+
from ....utils.observatory_containers import ObservatoryContainer, SeasonContainer
|
|
6
|
+
from ...interfaces.sql_column_info import SQLColumnInfo
|
|
7
|
+
from ...interfaces.sql_metadata import sql_metadata
|
|
8
|
+
from ...interfaces.sql_table_info import SQLTableInfo
|
|
9
|
+
from ...interfaces.types import Date, Float, Integer, String
|
|
10
|
+
from .container_map import ContainerMap
|
|
11
|
+
|
|
12
|
+
observatory_sql_info = SQLTableInfo(
|
|
13
|
+
table_name="Observatory",
|
|
14
|
+
metadata=sql_metadata,
|
|
15
|
+
columns=[
|
|
16
|
+
SQLColumnInfo("name", String, primary_key=True),
|
|
17
|
+
SQLColumnInfo("latitude", Float, unit="deg"),
|
|
18
|
+
SQLColumnInfo("longitude", Float, unit="deg"),
|
|
19
|
+
SQLColumnInfo("elevation", Integer, unit="m"),
|
|
20
|
+
SQLColumnInfo("version", Integer, primary_key=True),
|
|
21
|
+
],
|
|
22
|
+
constraints=[
|
|
23
|
+
UniqueConstraint("name", "version", name="observatory_name_version_unique"),
|
|
24
|
+
],
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
season_sql_info = SQLTableInfo(
|
|
28
|
+
table_name="Season",
|
|
29
|
+
metadata=sql_metadata,
|
|
30
|
+
columns=[
|
|
31
|
+
SQLColumnInfo("start", Date),
|
|
32
|
+
SQLColumnInfo("stop", Date),
|
|
33
|
+
SQLColumnInfo("name", String),
|
|
34
|
+
SQLColumnInfo("alias", String),
|
|
35
|
+
SQLColumnInfo("name_Observatory", String, nullable=False),
|
|
36
|
+
SQLColumnInfo("version_Observatory", Integer, nullable=False),
|
|
37
|
+
],
|
|
38
|
+
constraints=[
|
|
39
|
+
ForeignKeyConstraint(
|
|
40
|
+
["name_Observatory", "version_Observatory"],
|
|
41
|
+
["Observatory.name", "Observatory.version"],
|
|
42
|
+
),
|
|
43
|
+
UniqueConstraint(
|
|
44
|
+
"start",
|
|
45
|
+
"stop",
|
|
46
|
+
"name_Observatory",
|
|
47
|
+
"version_Observatory",
|
|
48
|
+
name="season_unique",
|
|
49
|
+
),
|
|
50
|
+
],
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
ContainerMap.register_container_pair(
|
|
54
|
+
cp_container=ObservatoryContainer,
|
|
55
|
+
db_container=observatory_sql_info,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
ContainerMap.register_container_pair(
|
|
59
|
+
cp_container=SeasonContainer,
|
|
60
|
+
db_container=season_sql_info,
|
|
61
|
+
)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""TableVersionManager class."""
|
|
2
|
+
|
|
3
|
+
from sqlalchemy import Table
|
|
4
|
+
|
|
5
|
+
from ...interfaces.sql_table_info import SQLTableInfo
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TableVersionManager:
|
|
9
|
+
"""
|
|
10
|
+
Create versioned tables for CalibPipe.
|
|
11
|
+
|
|
12
|
+
The main method is `apply_version()` that returns a table given
|
|
13
|
+
a table information and a version. The returned table will
|
|
14
|
+
contain the same data as the table information and have
|
|
15
|
+
a unique name containing the common table name and the
|
|
16
|
+
software version.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def get_safe_version_string(version: str) -> str:
|
|
21
|
+
"""Create a string from a version that is safe for table names."""
|
|
22
|
+
return version.replace("-", "_").replace(".", "_")
|
|
23
|
+
|
|
24
|
+
@staticmethod
|
|
25
|
+
def update_version(old_name: str, version: str) -> str:
|
|
26
|
+
"""Update the DB object name with a new version number."""
|
|
27
|
+
safe_version = TableVersionManager.get_safe_version_string(version)
|
|
28
|
+
root_name = old_name.rsplit("_v")[0]
|
|
29
|
+
new_name = "".join([root_name, "_v", safe_version])
|
|
30
|
+
return new_name
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def apply_version(table_info: SQLTableInfo, version: str | None = None) -> Table:
|
|
34
|
+
"""Create a DB object class with a particular version number."""
|
|
35
|
+
if not version:
|
|
36
|
+
return table_info.get_table()
|
|
37
|
+
safe_version = TableVersionManager.get_safe_version_string(version)
|
|
38
|
+
table_name = "".join([table_info.table_name, "_v", safe_version])
|
|
39
|
+
return table_info.get_table(table_name=table_name)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""SQL info for run metadata."""
|
|
2
|
+
|
|
3
|
+
from ...interfaces.sql_column_info import SQLColumnInfo
|
|
4
|
+
from ...interfaces.sql_metadata import sql_metadata
|
|
5
|
+
from ...interfaces.sql_table_info import SQLTableInfo
|
|
6
|
+
from ...interfaces.types import DateTime, String
|
|
7
|
+
|
|
8
|
+
version_control_sql_info = SQLTableInfo(
|
|
9
|
+
table_name="version_control_table",
|
|
10
|
+
metadata=sql_metadata,
|
|
11
|
+
columns=[
|
|
12
|
+
SQLColumnInfo("name", String),
|
|
13
|
+
SQLColumnInfo("version", String),
|
|
14
|
+
SQLColumnInfo("validity_start", DateTime(timezone=True)),
|
|
15
|
+
SQLColumnInfo("validity_end", DateTime(timezone=True)),
|
|
16
|
+
],
|
|
17
|
+
)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Connection utilities for the database.
|
|
3
|
+
|
|
4
|
+
The framework used here is `sqlachemy` that can be used with
|
|
5
|
+
different engines and dialects. For now the calibration data
|
|
6
|
+
is stored in a `PostgreSQL` database and accessed using the
|
|
7
|
+
`psycopg` dialect.
|
|
8
|
+
|
|
9
|
+
The main connection object is the :class:`SQLConnection` that provides the
|
|
10
|
+
interface to a SQL database, not knowing which engine it is
|
|
11
|
+
(can be `Postgres`, `MySQL`, `Oracle` etc.).
|
|
12
|
+
|
|
13
|
+
To use the :class:`SQLConnection` with a different DB system or dialect,
|
|
14
|
+
it is enough to change the uri and generate the relevant one
|
|
15
|
+
following the example of the postgres uri.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from .calibpipe_database import CalibPipeDatabase
|
|
19
|
+
from .postgres_utils import get_postgres_uri
|
|
20
|
+
from .sql_connection import SQLConnection
|
|
21
|
+
from .user_confirmation import get_user_confirmation
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"SQLConnection",
|
|
25
|
+
"get_user_confirmation",
|
|
26
|
+
"get_postgres_uri",
|
|
27
|
+
"CalibPipeDatabase",
|
|
28
|
+
]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""CalibPipeDatabase class."""
|
|
2
|
+
|
|
3
|
+
from .postgres_utils import (
|
|
4
|
+
get_postgres_uri,
|
|
5
|
+
)
|
|
6
|
+
from .sql_connection import SQLConnection
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CalibPipeDatabase(SQLConnection):
|
|
10
|
+
"""
|
|
11
|
+
CalibPipeDatabase connection. For now `SQLConnection` (`PostgreSQL+psycopg`).
|
|
12
|
+
|
|
13
|
+
This class simply creates a valid URI from named parameters to create the
|
|
14
|
+
particular instance of DB used for CalibPipe data and provides no additional
|
|
15
|
+
interface.
|
|
16
|
+
|
|
17
|
+
A few built-in queries can be found in the module
|
|
18
|
+
:mod:`queries<calibpipe.database.interfaces.queries>`.
|
|
19
|
+
|
|
20
|
+
Attributes
|
|
21
|
+
----------
|
|
22
|
+
user: str
|
|
23
|
+
Username used to connect to the database.
|
|
24
|
+
|
|
25
|
+
database: str
|
|
26
|
+
Name of the database with which the connection must be established.
|
|
27
|
+
|
|
28
|
+
password: str
|
|
29
|
+
Password for the given user.
|
|
30
|
+
|
|
31
|
+
host: str, default=`localhost`
|
|
32
|
+
Database host.
|
|
33
|
+
|
|
34
|
+
port: Optional[int], default=None
|
|
35
|
+
Database port.
|
|
36
|
+
|
|
37
|
+
autocommit: bool, default=False
|
|
38
|
+
Tell if the modifications to the DB must be committed automatically when the
|
|
39
|
+
connection closes. Default is `False`, in this case the `commit()` method
|
|
40
|
+
has to be called explicitly.
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def __init__(
|
|
45
|
+
self,
|
|
46
|
+
user: str,
|
|
47
|
+
database: str,
|
|
48
|
+
password: str,
|
|
49
|
+
host: str = "localhost",
|
|
50
|
+
port: int | None = None,
|
|
51
|
+
autocommit: bool = False,
|
|
52
|
+
) -> None:
|
|
53
|
+
"""Initialize the database connection."""
|
|
54
|
+
uri = get_postgres_uri(
|
|
55
|
+
user=user, database=database, passwd=password, host=host, port=port
|
|
56
|
+
)
|
|
57
|
+
super().__init__(
|
|
58
|
+
uri=uri,
|
|
59
|
+
autocommit=autocommit,
|
|
60
|
+
)
|