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 @@
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,195 @@
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
+
26
+
27
+ class ProductReferenceMetadataContainer(Container):
28
+ """
29
+ Container to store product-related reference metadata.
30
+
31
+ Describes the details of the data product, including its type and links to the data model definition.
32
+ """
33
+
34
+ ID = Field(
35
+ None,
36
+ description="Autoincremented value to serve as primary/foreign key",
37
+ type=int,
38
+ )
39
+ description = Field(
40
+ None, description="Human-readable description of data product", type=str
41
+ )
42
+ creation_time = Field(
43
+ None,
44
+ description="Human-readable date and time of file creation, in ISO format, UTC",
45
+ type=str,
46
+ )
47
+ product_id = Field(
48
+ None,
49
+ description="A fixed-id to identify this product, e.g. UUID or VFN",
50
+ type=str,
51
+ )
52
+ data_category = Field(None, description="A,B,C", type=str)
53
+ data_level = Field(None, description="R0, R1, DL0, DL1, etc", type=str)
54
+ data_association = Field(
55
+ None, description="CTAO, Site, Subarray, Telescope, etc", type=str
56
+ )
57
+ data_type = Field(None, description="Event, Monitoring, Service, etc", type=str)
58
+ data_model_name = Field(
59
+ None, description="Identifying name of the data model used", type=str
60
+ )
61
+ data_model_version = Field(
62
+ None, description="Version of the data model used", type=str
63
+ )
64
+ data_model_url = Field(
65
+ None,
66
+ description="Link to definition of data model, if available, and preferably a DOI",
67
+ type=str,
68
+ )
69
+ format = Field(None, description="File format of the data product", type=str)
70
+
71
+
72
+ class ContactReferenceMetadataContainer(Container):
73
+ """
74
+ Container to store contact reference metadata.
75
+
76
+ Describes the person or institution that is responsible for this data product.
77
+ """
78
+
79
+ ID = Field(
80
+ None,
81
+ description="Autoincremented value to serve as primary/foreign key",
82
+ type=int,
83
+ )
84
+ organization = Field(
85
+ None,
86
+ description="Organization to which this data product is associated",
87
+ type=str,
88
+ )
89
+ name = Field(None, description="Name of contact within organization", type=str)
90
+ email = Field(None, description="Contact email address", type=str)
91
+
92
+
93
+ class ProcessReferenceMetadataContainer(Container):
94
+ """
95
+ Container to store process reference metadata.
96
+
97
+ Describes the top-level process
98
+ to which the activity that generated this product belongs.
99
+ """
100
+
101
+ ID = Field(
102
+ None,
103
+ description="Autoincremented value to serve as primary/foreign key",
104
+ type=int,
105
+ )
106
+ type = Field(None, description="General type of the process", type=str)
107
+ subtype = Field(
108
+ None,
109
+ description="More specific class of the process if the class is not sufficient to describe it",
110
+ type=str,
111
+ )
112
+ subtype_id = Field(
113
+ None,
114
+ description="Unique identifier of the process, e.g. if the type is observation this is the obs_id",
115
+ type=str,
116
+ )
117
+
118
+
119
+ class ActivityReferenceMetadataContainer(Container):
120
+ """
121
+ Container to store activity reference metadata.
122
+
123
+ Describes the specific software
124
+ or task that generated this particular data product.
125
+ """
126
+
127
+ ID = Field(
128
+ None,
129
+ description="Autoincremented value to serve as primary/foreign key",
130
+ type=int,
131
+ )
132
+ activity_id = Field(
133
+ None,
134
+ description="Unique identifier of the instance of this activity, if software a UUID",
135
+ type=str,
136
+ )
137
+ name = Field(
138
+ None,
139
+ description="Name of activity that produced this data product, e.g. the software/script name",
140
+ type=str,
141
+ )
142
+ type = Field(None, description="General type of the activity", type=str)
143
+ start = Field(
144
+ None, description="Starting date/time of activity, in ISO format, UTC", type=str
145
+ )
146
+ end = Field(
147
+ None, description="Ending date/time of activity, in ISO format, UTC", type=str
148
+ )
149
+ software_name = Field(
150
+ None,
151
+ description="Name of software framework/library that was used if the activity if it involved software",
152
+ type=str,
153
+ )
154
+ software_version = Field(None, description="Version of software used", type=str)
155
+
156
+
157
+ class InstrumentReferenceMetadataContainer(Container):
158
+ """
159
+ Container to store instrument reference metadata.
160
+
161
+ Describes the subset of CTAO Instrument Description to which this data product is associated,
162
+ which could be e.g. a Sub-array, or a small part such as a photo-sensor.
163
+ """
164
+
165
+ ID = Field(
166
+ None,
167
+ description="Autoincremented value to serve as primary/foreign key",
168
+ type=int,
169
+ )
170
+ site = Field(
171
+ None,
172
+ description="CTAO-South, CTAO-North, or other site associated with the data product",
173
+ type=str,
174
+ )
175
+ type = Field(
176
+ None,
177
+ description=(
178
+ "The specific type of instrument in the class. E.g. if class=camera, ",
179
+ "the type might be CHEC, or if class=telescope, the type might be 'SST'",
180
+ ),
181
+ type=str,
182
+ )
183
+ subtype = Field(
184
+ None,
185
+ description="Sub-type of the instrument. For example if the type is MST, this might be 'NectarCAM' or 'FlashCAM'",
186
+ type=str,
187
+ )
188
+ instrument_id = Field(
189
+ None,
190
+ description=(
191
+ "The unique ID of the specific instrument in the class. Depending on the instrument class,"
192
+ "this might be for example is a telescope id, nominal subarray name, camera_id, or part serial number"
193
+ ),
194
+ type=str,
195
+ )
@@ -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 to 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,61 @@
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 .version_control import version_control_sql_info
41
+
42
+ __all__ = [
43
+ "atmospheric_model_sql_info",
44
+ "map_meta_sql_info",
45
+ "map_sql_info",
46
+ "mdp_sql_info",
47
+ "macobac_sql_info",
48
+ "selected_model_sql_info",
49
+ "observatory_sql_info",
50
+ "rayleigh_extinction_sql_info",
51
+ "season_sql_info",
52
+ "version_control_sql_info",
53
+ "TableVersionManager",
54
+ "ContainerMap",
55
+ "reference_metadata_sql_info",
56
+ "product_reference_metadata_sql_info",
57
+ "contact_reference_metadata_sql_info",
58
+ "activity_reference_metadata_sql_info",
59
+ "process_reference_metadata_sql_info",
60
+ "instrument_reference_metadata_sql_info",
61
+ ]