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
43 """A specialization of `RepoConverter` for calibration repositories. 47 mapper : `CameraMapper` 48 Gen2 mapper for the data repository. The root associated with the 49 mapper is ignored and need not match the root of the repository. 51 Additional keyword arguments are forwarded to (and required by) 55 def __init__(self, *, mapper: CameraMapper, **kwds):
62 return datasetTypeName
in self.
task.config.curatedCalibrations
64 def iterMappings(self) -> Iterator[Tuple[str, CameraMapperMapping]]:
66 yield from self.
mapper.calibrations.items()
69 storageClass: StorageClass) -> RepoWalker.Target:
71 target = RepoWalker.Target(
72 datasetTypeName=datasetTypeName,
73 storageClass=storageClass,
76 instrument=self.
task.instrument.getName(),
77 universe=self.
task.registry.dimensions,
87 db = sqlite3.connect(os.path.join(self.
root,
"calibRegistry.sqlite3"))
88 db.row_factory = sqlite3.Row
91 if "calibration_label" not in datasetType.dimensions:
93 fields = [
"validStart",
"validEnd",
"calibDate"]
94 if "detector" in datasetType.dimensions.names:
95 fields.append(self.
task.config.ccdKey)
97 fields.append(f
"NULL AS {self.task.config.ccdKey}")
98 if (
"physical_filter" in datasetType.dimensions.names
99 or "abstract_filter" in datasetType.dimensions.names):
100 fields.append(
"filter")
102 fields.append(
"NULL AS filter")
103 query = f
"SELECT DISTINCT {', '.join(fields)} FROM {datasetType.name};" 105 results = db.execute(query)
106 except sqlite3.OperationalError
as e:
107 if (self.
mapper.mappings[datasetType.name].tables
is None 108 or len(self.
mapper.mappings[datasetType.name].tables) == 0):
109 self.
task.log.warn(
"Could not extract calibration ranges for %s in %s: %r",
110 datasetType.name, self.
root, e)
113 name = self.
mapper.mappings[datasetType.name].tables[0]
114 query = f
"SELECT DISTINCT {', '.join(fields)} FROM {name};" 116 results = db.execute(query)
117 except sqlite3.OperationalError
as e:
118 self.
task.log.warn(
"Could not extract calibration ranges for %s in %s: %r",
119 datasetType.name, self.
root, e)
123 ccd=row[self.
task.config.ccdKey], filter=row[
"filter"])
125 "instrument": self.
task.instrument.getName(),
127 "datetime_begin": datetime.strptime(row[
"validStart"],
"%Y-%m-%d"),
128 "datetime_end": datetime.strptime(row[
"validEnd"],
"%Y-%m-%d") + timedelta(days=1),
131 self.
task.registry.insertDimensionData(
"calibration_label", *records)
135 if self.
task.config.doWriteCuratedCalibrations:
138 except LookupError
as err:
139 raise ValueError(
"Cannot ingest curated calibration into a calibration repo with no " 140 "collections of its own; skipping.")
from err
143 assert len(collections) == 1, \
144 "Multiple collections for curated calibrations is not yet supported." 145 butler3 = Butler3(butler=self.
task.butler3, run=collections[0])
146 self.
task.instrument.writeCuratedCalibrations(butler3)
153 """Gen2 mapper associated with this repository.
def insertDimensionData(self)