21 from __future__
import annotations
23 __all__ = [
"CalibRepoConverter"]
27 from datetime
import datetime, timedelta
28 from typing
import TYPE_CHECKING, Dict, Iterator, Tuple
30 from lsst.daf.butler
import Butler
as Butler3
32 from .repoConverter
import RepoConverter
33 from .repoWalker
import RepoWalker
34 from .translators
import makeCalibrationLabel
37 from lsst.daf.butler
import StorageClass
38 from ..cameraMapper
import CameraMapper
39 from ..mapping
import Mapping
as CameraMapperMapping
41 CURATED_CALIBRATION_DATASET_TYPES = (
44 "transmission_sensor",
45 "transmission_filter",
46 "transmission_optics",
47 "transmission_atmosphere",
53 """A specialization of `RepoConverter` for calibration repositories. 57 mapper : `CameraMapper` 58 Gen2 mapper for the data repository. The root associated with the 59 mapper is ignored and need not match the root of the repository. 61 Additional keyword arguments are forwarded to (and required by) 65 def __init__(self, *, mapper: CameraMapper, **kwds):
72 return datasetTypeName
in CURATED_CALIBRATION_DATASET_TYPES
74 def iterMappings(self) -> Iterator[Tuple[str, CameraMapperMapping]]:
76 yield from self.
mapper.calibrations.items()
79 storageClass: StorageClass) -> RepoWalker.Target:
81 target = RepoWalker.Target(
82 datasetTypeName=datasetTypeName,
83 storageClass=storageClass,
86 instrument=self.
task.instrument.getName(),
87 universe=self.
task.registry.dimensions,
97 db = sqlite3.connect(os.path.join(self.
root,
"calibRegistry.sqlite3"))
98 db.row_factory = sqlite3.Row
101 if "calibration_label" not in datasetType.dimensions:
103 fields = [
"validStart",
"validEnd",
"calibDate"]
104 if "detector" in datasetType.dimensions.names:
105 fields.append(self.
task.config.ccdKey)
107 fields.append(f
"NULL AS {self.task.config.ccdKey}")
108 if "physical_filter" in datasetType.dimensions.names:
109 fields.append(
"filter")
111 fields.append(
"NULL AS filter")
112 query = f
"SELECT DISTINCT {', '.join(fields)} FROM {datasetType.name};" 114 results = db.execute(query)
115 except sqlite3.OperationalError:
116 self.
task.log.warn(
"Could not extract calibration ranges for %s in %s.",
117 datasetType.name, self.
root)
121 ccd=row[self.
task.config.ccdKey], filter=row[
"filter"])
123 "instrument": self.
task.instrument.getName(),
125 "datetime_begin": datetime.strptime(row[
"validStart"],
"%Y-%m-%d"),
126 "datetime_end": datetime.strptime(row[
"validEnd"],
"%Y-%m-%d") + timedelta(days=1),
129 self.
task.registry.insertDimensionData(
"calibration_label", *records)
133 if self.
task.config.doWriteCuratedCalibrations:
136 except LookupError
as err:
137 raise ValueError(
"Cannot ingest curated calibration into a calibration repo with no " 138 "collections of its own; skipping.")
from err
141 assert len(collections) == 1, \
142 "Multiple collections for curated calibrations is not yet supported." 143 butler3 = Butler3(butler=self.
task.butler3, run=collections[0])
144 self.
task.instrument.writeCuratedCalibrations(butler3)
151 """Gen2 mapper associated with this repository.
def insertDimensionData(self)