ctao-calibpipe 0.1.0__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.

Files changed (93) hide show
  1. calibpipe/__init__.py +5 -0
  2. calibpipe/_dev_version/__init__.py +9 -0
  3. calibpipe/_version.py +21 -0
  4. calibpipe/atmosphere/__init__.py +1 -0
  5. calibpipe/atmosphere/atmosphere_containers.py +109 -0
  6. calibpipe/atmosphere/meteo_data_handlers.py +485 -0
  7. calibpipe/atmosphere/models/README.md +14 -0
  8. calibpipe/atmosphere/models/__init__.py +1 -0
  9. calibpipe/atmosphere/models/macobac.ecsv +23 -0
  10. calibpipe/atmosphere/models/reference_MDPs/__init__.py +1 -0
  11. calibpipe/atmosphere/models/reference_MDPs/ref_density_at_15km_ctao-north_intermediate.ecsv +8 -0
  12. calibpipe/atmosphere/models/reference_MDPs/ref_density_at_15km_ctao-north_summer.ecsv +8 -0
  13. calibpipe/atmosphere/models/reference_MDPs/ref_density_at_15km_ctao-north_winter.ecsv +8 -0
  14. calibpipe/atmosphere/models/reference_MDPs/ref_density_at_15km_ctao-south_summer.ecsv +8 -0
  15. calibpipe/atmosphere/models/reference_MDPs/ref_density_at_15km_ctao-south_winter.ecsv +8 -0
  16. calibpipe/atmosphere/models/reference_atmospheres/__init__.py +1 -0
  17. calibpipe/atmosphere/models/reference_atmospheres/reference_atmo_model_v0_ctao-north_intermediate.ecsv +73 -0
  18. calibpipe/atmosphere/models/reference_atmospheres/reference_atmo_model_v0_ctao-north_summer.ecsv +73 -0
  19. calibpipe/atmosphere/models/reference_atmospheres/reference_atmo_model_v0_ctao-north_winter.ecsv +73 -0
  20. calibpipe/atmosphere/models/reference_atmospheres/reference_atmo_model_v0_ctao-south_summer.ecsv +73 -0
  21. calibpipe/atmosphere/models/reference_atmospheres/reference_atmo_model_v0_ctao-south_winter.ecsv +73 -0
  22. calibpipe/atmosphere/models/reference_rayleigh_scattering_profiles/__init__.py +1 -0
  23. calibpipe/atmosphere/models/reference_rayleigh_scattering_profiles/reference_rayleigh_extinction_profile_v0_ctao-north_intermediate.ecsv +857 -0
  24. calibpipe/atmosphere/models/reference_rayleigh_scattering_profiles/reference_rayleigh_extinction_profile_v0_ctao-north_summer.ecsv +857 -0
  25. calibpipe/atmosphere/models/reference_rayleigh_scattering_profiles/reference_rayleigh_extinction_profile_v0_ctao-north_winter.ecsv +857 -0
  26. calibpipe/atmosphere/models/reference_rayleigh_scattering_profiles/reference_rayleigh_extinction_profile_v0_ctao-south_summer.ecsv +857 -0
  27. calibpipe/atmosphere/models/reference_rayleigh_scattering_profiles/reference_rayleigh_extinction_profile_v0_ctao-south_winter.ecsv +857 -0
  28. calibpipe/atmosphere/templates/request_templates/__init__.py +1 -0
  29. calibpipe/atmosphere/templates/request_templates/copernicus.json +11 -0
  30. calibpipe/atmosphere/templates/request_templates/gdas.json +12 -0
  31. calibpipe/core/__init__.py +39 -0
  32. calibpipe/core/common_metadata_containers.py +195 -0
  33. calibpipe/core/exceptions.py +87 -0
  34. calibpipe/database/__init__.py +24 -0
  35. calibpipe/database/adapter/__init__.py +23 -0
  36. calibpipe/database/adapter/adapter.py +80 -0
  37. calibpipe/database/adapter/database_containers/__init__.py +61 -0
  38. calibpipe/database/adapter/database_containers/atmosphere.py +199 -0
  39. calibpipe/database/adapter/database_containers/common_metadata.py +148 -0
  40. calibpipe/database/adapter/database_containers/container_map.py +59 -0
  41. calibpipe/database/adapter/database_containers/observatory.py +61 -0
  42. calibpipe/database/adapter/database_containers/table_version_manager.py +39 -0
  43. calibpipe/database/adapter/database_containers/version_control.py +17 -0
  44. calibpipe/database/connections/__init__.py +28 -0
  45. calibpipe/database/connections/calibpipe_database.py +60 -0
  46. calibpipe/database/connections/postgres_utils.py +97 -0
  47. calibpipe/database/connections/sql_connection.py +103 -0
  48. calibpipe/database/connections/user_confirmation.py +19 -0
  49. calibpipe/database/interfaces/__init__.py +71 -0
  50. calibpipe/database/interfaces/hashable_row_data.py +54 -0
  51. calibpipe/database/interfaces/queries.py +180 -0
  52. calibpipe/database/interfaces/sql_column_info.py +67 -0
  53. calibpipe/database/interfaces/sql_metadata.py +6 -0
  54. calibpipe/database/interfaces/sql_table_info.py +131 -0
  55. calibpipe/database/interfaces/table_handler.py +351 -0
  56. calibpipe/database/interfaces/types.py +96 -0
  57. calibpipe/tests/data/atmosphere/molecular_atmosphere/__init__.py +0 -0
  58. calibpipe/tests/data/atmosphere/molecular_atmosphere/contemporary_MDP.ecsv +34 -0
  59. calibpipe/tests/data/atmosphere/molecular_atmosphere/macobac.csv +852 -0
  60. calibpipe/tests/data/atmosphere/molecular_atmosphere/macobac.ecsv +23 -0
  61. calibpipe/tests/data/atmosphere/molecular_atmosphere/merged_file.ecsv +1082 -0
  62. calibpipe/tests/data/atmosphere/molecular_atmosphere/meteo_data_copernicus.ecsv +1082 -0
  63. calibpipe/tests/data/atmosphere/molecular_atmosphere/meteo_data_gdas.ecsv +66 -0
  64. calibpipe/tests/data/atmosphere/molecular_atmosphere/observatory_configurations.json +71 -0
  65. calibpipe/tests/data/utils/__init__.py +0 -0
  66. calibpipe/tests/data/utils/meteo_data_winter_and_summer.ecsv +12992 -0
  67. calibpipe/tests/unittests/atmosphere/astral_testing.py +107 -0
  68. calibpipe/tests/unittests/atmosphere/test_meteo_data_handler.py +775 -0
  69. calibpipe/tests/unittests/atmosphere/test_molecular_atmosphere.py +327 -0
  70. calibpipe/tests/unittests/database/test_table_handler.py +66 -0
  71. calibpipe/tests/unittests/database/test_types.py +38 -0
  72. calibpipe/tests/unittests/test_bootstrap_db.py +79 -0
  73. calibpipe/tests/unittests/utils/test_observatory.py +309 -0
  74. calibpipe/tools/atmospheric_base_tool.py +78 -0
  75. calibpipe/tools/atmospheric_model_db_loader.py +181 -0
  76. calibpipe/tools/basic_tool_with_db.py +38 -0
  77. calibpipe/tools/contemporary_mdp_producer.py +87 -0
  78. calibpipe/tools/init_db.py +37 -0
  79. calibpipe/tools/macobac_calculator.py +82 -0
  80. calibpipe/tools/molecular_atmospheric_model_producer.py +197 -0
  81. calibpipe/tools/observatory_data_db_loader.py +71 -0
  82. calibpipe/tools/reference_atmospheric_model_selector.py +201 -0
  83. calibpipe/utils/__init__.py +10 -0
  84. calibpipe/utils/observatory.py +486 -0
  85. calibpipe/utils/observatory_containers.py +26 -0
  86. calibpipe/version.py +24 -0
  87. ctao_calibpipe-0.1.0.dist-info/METADATA +86 -0
  88. ctao_calibpipe-0.1.0.dist-info/RECORD +93 -0
  89. ctao_calibpipe-0.1.0.dist-info/WHEEL +5 -0
  90. ctao_calibpipe-0.1.0.dist-info/entry_points.txt +8 -0
  91. ctao_calibpipe-0.1.0.dist-info/licenses/AUTHORS.md +13 -0
  92. ctao_calibpipe-0.1.0.dist-info/licenses/LICENSE +21 -0
  93. ctao_calibpipe-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,327 @@
1
+ # Set up logging
2
+ from datetime import datetime, timezone
3
+ from pathlib import Path
4
+ from unittest.mock import MagicMock, patch
5
+
6
+ import pytest
7
+ import yaml
8
+ from astropy.table import QTable
9
+ from astropy.time import Time
10
+ from calibpipe.core.exceptions import IntermittentError, MissingInputDataError
11
+ from calibpipe.tools.contemporary_mdp_producer import CreateMolecularDensityProfile
12
+ from calibpipe.tools.macobac_calculator import CalculateMACOBAC
13
+ from calibpipe.tools.molecular_atmospheric_model_producer import (
14
+ CreateMolecularAtmosphericModel,
15
+ )
16
+ from calibpipe.tools.reference_atmospheric_model_selector import (
17
+ SelectMolecularAtmosphericModel,
18
+ )
19
+ from ctapipe.core import run_tool
20
+ from traitlets.config import Config
21
+
22
+
23
+ @pytest.mark.verifies_usecase("UC-120-1.2")
24
+ def test_calculate_macobac(tmp_path):
25
+ config = Config()
26
+ config.CalculateMACOBAC = Config()
27
+ config.CalculateMACOBAC.output_file = str(tmp_path / "macobac.ecsv")
28
+
29
+ with patch(
30
+ "calibpipe.tools.macobac_calculator.CO2DataHandler",
31
+ new_callable=MagicMock,
32
+ ) as mock_class:
33
+ mock_class.return_value.data_path = str(
34
+ Path(__file__).parent.parent.parent
35
+ / "data/atmosphere/molecular_atmosphere/"
36
+ )
37
+ tool = CalculateMACOBAC(config=config)
38
+ run_tool(tool)
39
+
40
+ output_file = Path(config.CalculateMACOBAC.output_file)
41
+ assert output_file.exists(), "Output file was not created."
42
+
43
+ result_table = QTable.read(output_file, format="ascii.ecsv")
44
+ expected_co2_concentration = 419.3
45
+ assert (
46
+ result_table["co2_concentration"][0].value
47
+ == pytest.approx(expected_co2_concentration, abs=0.1)
48
+ ), f"CO2 concentration does not match expected value ({result_table['co2_concentration'][0]} != {expected_co2_concentration})."
49
+ assert (
50
+ result_table["estimation_date"][0]
51
+ == Time(str(datetime.now(timezone.utc).date()), out_subfmt="date").iso
52
+ ), "Estimation date does not match expected value."
53
+
54
+
55
+ @pytest.mark.db()
56
+ @pytest.mark.verifies_usecase("UC-120-1.7")
57
+ @pytest.mark.verifies_usecase("UC-120-1.8")
58
+ def test_create_molecular_atmospheric_model(tmp_path):
59
+ config_path = (
60
+ Path(__file__).parent.parent.parent.parent.parent.parent
61
+ / "docs/source/examples/atmosphere/configuration/create_molecular_atmospheric_model.yaml"
62
+ )
63
+ with open(config_path) as file:
64
+ config = Config(yaml.load(file, Loader=yaml.SafeLoader))
65
+
66
+ config.CreateMolecularAtmosphericModel.output_path = str(tmp_path)
67
+ # Mock the necessary components
68
+ with patch(
69
+ # "calibpipe.tools.molecular_atmospheric_model_producer.MeteoDataHandler",
70
+ "calibpipe.tools.atmospheric_base_tool.MeteoDataHandler",
71
+ new_callable=MagicMock,
72
+ ) as mock_meteo_handler_class:
73
+ tool = CreateMolecularAtmosphericModel(config=config)
74
+ # Test missing input data
75
+ with pytest.raises(MissingInputDataError):
76
+ run_tool(
77
+ tool,
78
+ argv=[
79
+ "-c",
80
+ str(
81
+ Path(__file__).parent.parent.parent.parent.parent.parent
82
+ / "docs/source/examples/utils/configuration/db_config.yaml"
83
+ ),
84
+ "--macobac12-table-path",
85
+ str(
86
+ Path(__file__).parent.parent.parent
87
+ / "data/atmosphere/molecular_atmosphere/macobac.ecsv"
88
+ ),
89
+ ],
90
+ raises=True,
91
+ )
92
+
93
+ # Now set up the mock data handler
94
+ mock_meteo_handler = MagicMock()
95
+ mock_meteo_handler_class.from_name.return_value = mock_meteo_handler
96
+ mock_meteo_handler.data_path = str(
97
+ Path(__file__).parent.parent.parent
98
+ / "data/atmosphere/molecular_atmosphere/"
99
+ )
100
+ mock_meteo_handler.request_data.return_value = 0
101
+
102
+ run_tool(
103
+ tool,
104
+ argv=[
105
+ "-c",
106
+ str(
107
+ Path(__file__).parent.parent.parent.parent.parent.parent
108
+ / "docs/source/examples/utils/configuration/db_config.yaml"
109
+ ),
110
+ "--macobac12-table-path",
111
+ str(
112
+ Path(__file__).parent.parent.parent
113
+ / "data/atmosphere/molecular_atmosphere/macobac.ecsv"
114
+ ),
115
+ ],
116
+ raises=True,
117
+ )
118
+
119
+ # Check if the output files were created
120
+ output_profile = (
121
+ Path(config.CreateMolecularAtmosphericModel.output_path)
122
+ / "contemporary_atmospheric_profile.ascii.ecsv"
123
+ )
124
+ output_extinction = (
125
+ Path(config.CreateMolecularAtmosphericModel.output_path)
126
+ / "contemporary_rayleigh_extinction_profile.ascii.ecsv"
127
+ )
128
+ assert (
129
+ output_profile.exists()
130
+ ), "Contemporary atmospheric profile file was not created."
131
+ assert (
132
+ output_extinction.exists()
133
+ ), "Contemporary Rayleigh extinction profile file was not created."
134
+
135
+ # Read and validate the output files
136
+ profile_table = QTable.read(output_profile, format="ascii.ecsv")
137
+ extinction_table = QTable.read(output_extinction, format="ascii.ecsv")
138
+
139
+ expected_profile_columns = [
140
+ "altitude",
141
+ "atmospheric_density",
142
+ "atmospheric_thickness",
143
+ "refractive_index_m_1",
144
+ "temperature",
145
+ "pressure",
146
+ "partial_water_pressure",
147
+ ]
148
+
149
+ for column in expected_profile_columns:
150
+ assert (
151
+ column in profile_table.colnames
152
+ ), f"{column} column missing in profile table."
153
+
154
+ assert (
155
+ "altitude_max" in extinction_table.colnames
156
+ ), "Altitude_max column missing in extinction table."
157
+ assert (
158
+ "altitude_min" in extinction_table.colnames
159
+ ), "Altitude_min column missing in extinction table."
160
+
161
+
162
+ @pytest.mark.db()
163
+ @pytest.mark.verifies_usecase("UC-120-1.6")
164
+ def test_create_molecular_density_profile(tmp_path):
165
+ config_path = (
166
+ Path(__file__).parent.parent.parent.parent.parent.parent
167
+ / "docs/source/examples/atmosphere/configuration/create_molecular_density_profile.yaml"
168
+ )
169
+ with open(config_path) as file:
170
+ config = Config(yaml.load(file, Loader=yaml.SafeLoader))
171
+
172
+ config.CreateMolecularDensityProfile.output_path = str(tmp_path)
173
+ # Mock the necessary components
174
+ with patch(
175
+ "calibpipe.tools.atmospheric_base_tool.MeteoDataHandler",
176
+ new_callable=MagicMock,
177
+ ) as mock_meteo_handler_class:
178
+ tool = CreateMolecularDensityProfile(config=config)
179
+ # Test missing input data
180
+ with pytest.raises(MissingInputDataError):
181
+ run_tool(
182
+ tool,
183
+ argv=[
184
+ "-c",
185
+ str(
186
+ Path(__file__).parent.parent.parent.parent.parent.parent
187
+ / "docs/source/examples/utils/configuration/db_config.yaml"
188
+ ),
189
+ ],
190
+ raises=True,
191
+ )
192
+
193
+ # Now set up the mock data handler
194
+ mock_meteo_handler = MagicMock()
195
+ mock_meteo_handler_class.from_name.return_value = mock_meteo_handler
196
+ mock_meteo_handler.data_path = str(
197
+ Path(__file__).parent.parent.parent
198
+ / "data/atmosphere/molecular_atmosphere/"
199
+ )
200
+ mock_meteo_handler.request_data.return_value = 0
201
+
202
+ run_tool(
203
+ tool,
204
+ argv=[
205
+ "-c",
206
+ str(
207
+ Path(__file__).parent.parent.parent.parent.parent.parent
208
+ / "docs/source/examples/utils/configuration/db_config.yaml"
209
+ ),
210
+ ],
211
+ raises=True,
212
+ )
213
+
214
+ # Check if the output file was created
215
+ output_file = (
216
+ Path(config.CreateMolecularDensityProfile.output_path)
217
+ / "contemporary_molecular_density_profile.ascii.ecsv"
218
+ )
219
+ assert (
220
+ output_file.exists()
221
+ ), "Contemporary molecular density profile file was not created."
222
+
223
+ # Read and validate the output file
224
+ mdp_table = QTable.read(output_file, format="ascii.ecsv")
225
+
226
+ expected_columns = [
227
+ "altitude",
228
+ "number density",
229
+ ]
230
+
231
+ for column in expected_columns:
232
+ assert (
233
+ column in mdp_table.colnames
234
+ ), f"{column} column missing in molecular density profile table."
235
+
236
+
237
+ @pytest.mark.db()
238
+ @pytest.mark.verifies_usecase("UC-120-1.3")
239
+ def test_select_molecular_atmospheric_model(tmp_path):
240
+ config_path = (
241
+ Path(__file__).parent.parent.parent.parent.parent.parent
242
+ / "docs/source/examples/atmosphere/configuration/select_reference_atmospheric_model.yaml"
243
+ )
244
+ with open(config_path) as file:
245
+ config = Config(yaml.load(file, Loader=yaml.SafeLoader))
246
+
247
+ config.SelectMolecularAtmosphericModel.output_path = str(tmp_path)
248
+ # Mock the necessary components
249
+ with patch(
250
+ "calibpipe.tools.atmospheric_base_tool.MeteoDataHandler",
251
+ new_callable=MagicMock,
252
+ ) as mock_meteo_handler_class:
253
+ tool = SelectMolecularAtmosphericModel(config=config)
254
+
255
+ # Mock database and data handler behavior
256
+ mock_meteo_handler = MagicMock()
257
+ mock_meteo_handler_class.from_name.return_value = mock_meteo_handler
258
+ mock_meteo_handler.data_path = str(
259
+ Path(__file__).parent.parent.parent
260
+ / "data/atmosphere/molecular_atmosphere/"
261
+ )
262
+
263
+ # Test missing input data
264
+ mock_meteo_handler.request_data.return_value = 1
265
+
266
+ with pytest.raises(IntermittentError):
267
+ run_tool(
268
+ tool,
269
+ argv=[
270
+ "-c",
271
+ str(
272
+ Path(__file__).parent.parent.parent.parent.parent.parent
273
+ / "docs/source/examples/utils/configuration/db_config.yaml"
274
+ ),
275
+ ],
276
+ raises=True,
277
+ )
278
+
279
+ # Check if the output files were created
280
+ output_profile = (
281
+ Path(config.SelectMolecularAtmosphericModel.output_path)
282
+ / "selected_atmospheric_profile.ascii.ecsv"
283
+ )
284
+ output_extinction = (
285
+ Path(config.SelectMolecularAtmosphericModel.output_path)
286
+ / "selected_rayleigh_extinction_profile.ascii.ecsv"
287
+ )
288
+ assert (
289
+ output_profile.exists()
290
+ ), "Selected atmospheric profile file was not created."
291
+ assert (
292
+ output_extinction.exists()
293
+ ), "Selected Rayleigh extinction profile file was not created."
294
+
295
+ # Read and validate the output files
296
+ profile_table = QTable.read(output_profile, format="ascii.ecsv")
297
+ extinction_table = QTable.read(output_extinction, format="ascii.ecsv")
298
+
299
+ expected_profile_columns = [
300
+ "altitude",
301
+ "atmospheric_density",
302
+ "atmospheric_thickness",
303
+ "refractive_index_m_1",
304
+ "temperature",
305
+ "pressure",
306
+ "partial_water_pressure",
307
+ ]
308
+
309
+ for column in expected_profile_columns:
310
+ assert (
311
+ column in profile_table.colnames
312
+ ), f"{column} column missing in profile table."
313
+
314
+ expected_extinction_columns = ["altitude_min", "altitude_max"]
315
+ expected_extinction_columns.extend([f"{i}.0 nm" for i in range(200, 1000)])
316
+
317
+ for column in expected_extinction_columns:
318
+ assert (
319
+ column in extinction_table.colnames
320
+ ), f"{column} column missing in extinction table."
321
+ if "altitude" in column:
322
+ assert (
323
+ extinction_table[column].unit == "km"
324
+ ), f"Column {column} unit does not match expected unit."
325
+ assert (
326
+ extinction_table[column].ndim == 1
327
+ ), f"Column {column} does not have the expected number of dimensions."
@@ -0,0 +1,66 @@
1
+ # Import the necessary modules and classes for testing
2
+ from pathlib import Path
3
+
4
+ import astropy.units as u
5
+ import pytest
6
+ import yaml
7
+ from calibpipe.database.connections import CalibPipeDatabase
8
+ from calibpipe.database.interfaces import TableHandler
9
+ from calibpipe.utils.observatory import (
10
+ Observatory,
11
+ )
12
+ from traitlets.config import Config
13
+
14
+
15
+ # Fixture to provide a database connection
16
+ @pytest.fixture()
17
+ def test_config():
18
+ # Setup and connect to the test database
19
+ config_path = Path(__file__).parent.joinpath(
20
+ "../../../../../docs/source/examples/utils/configuration/"
21
+ )
22
+ with open(config_path.joinpath("upload_observatory_data_db.yaml")) as yaml_file:
23
+ config_data = yaml.safe_load(yaml_file)
24
+ config_data = config_data["UploadObservatoryData"]
25
+
26
+ with open(config_path.joinpath("db_config.yaml")) as yaml_file:
27
+ config_data |= yaml.safe_load(yaml_file)
28
+ return config_data
29
+
30
+
31
+ @pytest.fixture()
32
+ def test_container(test_config):
33
+ return Observatory(config=Config(test_config["observatories"][0])).containers[0]
34
+
35
+
36
+ # Test cases for TableHandler class and other functions in the module
37
+ class TestTableHandler:
38
+ # Test get_database_table_insertion method
39
+ @pytest.mark.db()
40
+ def test_get_database_table_insertion(self, test_container):
41
+ # Prepare a mock container and call the method
42
+ table, kwargs = TableHandler.get_database_table_insertion(test_container)
43
+
44
+ # Assert that the table and kwargs are not None
45
+ assert table is not None
46
+ assert kwargs is not None
47
+
48
+ # Test read_table_from_database method
49
+ @pytest.mark.db()
50
+ def test_read_table_from_database(self, test_container, test_config):
51
+ TableHandler.prepare_db_tables(
52
+ [
53
+ test_container,
54
+ ],
55
+ test_config["database_configuration"],
56
+ )
57
+ condition = "c.elevation == 3000"
58
+ with CalibPipeDatabase(**test_config["database_configuration"]) as connection:
59
+ qtable = TableHandler.read_table_from_database(
60
+ type(test_container), connection, condition
61
+ )
62
+
63
+ # Assert that qtable is not None and has the expected columns
64
+ assert qtable is not None
65
+ assert "elevation" in qtable.colnames
66
+ assert qtable["elevation"].unit == u.m
@@ -0,0 +1,38 @@
1
+ """Test sqlalchemy types."""
2
+
3
+ from calibpipe.database.interfaces.types import (
4
+ BigInteger,
5
+ Boolean,
6
+ ColumnType,
7
+ Date,
8
+ DateTime,
9
+ Double,
10
+ Float,
11
+ Integer,
12
+ NDArray,
13
+ Numeric,
14
+ SmallInteger,
15
+ String,
16
+ Time,
17
+ )
18
+ from sqlalchemy.sql.type_api import TypeEngine
19
+
20
+
21
+ def test_types():
22
+ """Test that types are instance of TypeEngine."""
23
+ for type_ in [
24
+ Boolean,
25
+ SmallInteger,
26
+ Integer,
27
+ BigInteger,
28
+ Float,
29
+ Double,
30
+ Numeric,
31
+ String,
32
+ Date,
33
+ DateTime,
34
+ Time,
35
+ ColumnType,
36
+ NDArray,
37
+ ]:
38
+ assert issubclass(type_, TypeEngine)
@@ -0,0 +1,79 @@
1
+ from copy import deepcopy
2
+ from pathlib import Path
3
+
4
+ import pytest
5
+ import yaml
6
+ from calibpipe.tools.atmospheric_model_db_loader import UploadAtmosphericModel
7
+ from calibpipe.tools.init_db import CalibPipeDatabaseInitialization
8
+ from calibpipe.tools.observatory_data_db_loader import UploadObservatoryData
9
+ from ctapipe.core import run_tool
10
+ from traitlets.config import Config
11
+
12
+
13
+ @pytest.mark.db()
14
+ @pytest.mark.order(1)
15
+ def test_init_database():
16
+ """
17
+ Fixture to initialize the database and upload required data.
18
+ This runs before any other database-related tests.
19
+ """
20
+ # Paths to configuration files
21
+ db_config_path = (
22
+ Path(__file__).parent.parent.parent.parent.parent
23
+ / "docs/source/examples/utils/configuration/db_config.yaml"
24
+ )
25
+
26
+ # Initialize the database
27
+ with open(db_config_path) as file:
28
+ db_config = Config(yaml.load(file, Loader=yaml.SafeLoader))
29
+ tool = CalibPipeDatabaseInitialization(config=db_config)
30
+ run_tool(tool)
31
+
32
+
33
+ @pytest.mark.db()
34
+ @pytest.mark.order(2)
35
+ def test_upload_observatory():
36
+ db_config_path = (
37
+ Path(__file__).parent.parent.parent.parent.parent
38
+ / "docs/source/examples/utils/configuration/db_config.yaml"
39
+ )
40
+ with open(db_config_path) as file:
41
+ db_config = Config(yaml.load(file, Loader=yaml.SafeLoader))
42
+
43
+ observatory_data_config_path = (
44
+ Path(__file__).parent.parent.parent.parent.parent
45
+ / "docs/source/examples/utils/configuration/upload_observatory_data_db.yaml"
46
+ )
47
+ # Upload observatory data
48
+ config = deepcopy(db_config)
49
+ with open(observatory_data_config_path) as file:
50
+ observatory_data_config = Config(yaml.load(file, Loader=yaml.SafeLoader))
51
+ config.update(observatory_data_config)
52
+ tool = UploadObservatoryData(config=config)
53
+ run_tool(tool)
54
+
55
+
56
+ @pytest.mark.db()
57
+ @pytest.mark.order(3)
58
+ def test_upload_atmospheric_models():
59
+ db_config_path = (
60
+ Path(__file__).parent.parent.parent.parent.parent
61
+ / "docs/source/examples/utils/configuration/db_config.yaml"
62
+ )
63
+
64
+ with open(db_config_path) as file:
65
+ db_config = Config(yaml.load(file, Loader=yaml.SafeLoader))
66
+
67
+ atmospheric_model_configs = list(
68
+ Path(__file__).parent.parent.parent.parent.parent.glob(
69
+ "docs/source/examples/utils/configuration/upload_atmospheric*.yaml"
70
+ )
71
+ )
72
+ # Upload atmospheric model data
73
+ for config_path in atmospheric_model_configs:
74
+ config = deepcopy(db_config)
75
+ with open(config_path) as file:
76
+ atmospheric_model_config = Config(yaml.load(file, Loader=yaml.SafeLoader))
77
+ config.update(atmospheric_model_config)
78
+ tool = UploadAtmosphericModel(config=config)
79
+ run_tool(tool)