Skip to content

Commit

Permalink
Merge pull request #1161 from lsst/tickets/DM-49180
Browse files Browse the repository at this point in the history
DM-49180: Check universe version before registering dataset type
  • Loading branch information
andy-slac authored Feb 28, 2025
2 parents e74e7f7 + dcbe85a commit 6704b41
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 1 deletion.
10 changes: 10 additions & 0 deletions python/lsst/daf/butler/registry/datasets/byDimensions/_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,16 @@ def register_dataset_type(self, dataset_type: DatasetType) -> bool:
raise ValueError(
f"Component dataset types can not be stored in registry. Rejecting {dataset_type.name}"
)

# If database universe and dimension group universe are different it
# can cause unexpected effects.
if dataset_type.dimensions.universe is not self._dimensions.universe:
raise ValueError(
"Incompatible dimension universe versions - "
f"database universe: {self._dimensions.universe}, "
f"dataset type universe: {dataset_type.dimensions.universe}."
)

record = self._fetch_dataset_type_record(dataset_type.name)
if record is None:
if (dynamic_tables := self._cache.get_by_dimensions(dataset_type.dimensions)) is None:
Expand Down
13 changes: 12 additions & 1 deletion python/lsst/daf/butler/registry/tests/_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
from ..._exceptions_legacy import DatasetTypeError
from ..._storage_class import StorageClass
from ..._timespan import Timespan
from ...dimensions import DataCoordinate, DataCoordinateSet, SkyPixDimension
from ...dimensions import DataCoordinate, DataCoordinateSet, DimensionUniverse, SkyPixDimension
from .._collection_summary import CollectionSummary
from .._config import RegistryConfig
from .._exceptions import (
Expand Down Expand Up @@ -326,6 +326,17 @@ def testDatasetType(self):
self.assertCountEqual([dt.name for dt in types], ["test", "testNoneTemplate"])
self.assertEqual(missing, ["notarealdatasettype"])

# Trying to register a dataset type with different universe version or
# namespace will raise.
wrong_universes = (DimensionUniverse(version=-1), DimensionUniverse(namespace="🔭"))
for universe in wrong_universes:
storageClass = StorageClass("testDatasetType")
dataset_type = DatasetType(
"wrong_universe", ("instrument", "visit"), storageClass, universe=universe
)
with self.assertRaisesRegex(ValueError, "Incompatible dimension universe versions"):
registry.registerDatasetType(dataset_type)

def testDatasetTypeCache(self):
"""Test for dataset type cache update logic after a cache miss."""
butler1 = self.make_butler()
Expand Down
10 changes: 10 additions & 0 deletions python/lsst/daf/butler/tests/hybrid_butler_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ def getCollectionSummary(self, collection: str) -> CollectionSummary:
return self._remote.getCollectionSummary(collection)

def registerDatasetType(self, datasetType: DatasetType) -> bool:
# We need to make sure that dataset type universe is the same as
# direct registry universe.
if datasetType.dimensions.universe is self._remote.dimensions:
datasetType = DatasetType(
datasetType.name,
datasetType.dimensions.names,
datasetType.storageClass,
universe=self._direct.dimensions,
isCalibration=datasetType.isCalibration(),
)
return self._direct.registerDatasetType(datasetType)

def removeDatasetType(self, name: str | tuple[str, ...]) -> None:
Expand Down
10 changes: 10 additions & 0 deletions tests/test_simpleButler.py
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,16 @@ def test_calibration_dataset_type_registration(self) -> None:
self.assertEqual(butler1.get_dataset_type("b"), b)
# Register them in the opposite order in a new repo.
butler2 = self.makeButler(writeable=True)
# Dataset types have to use correct universe and with RemoteButler
# each butler instance has its own universe instance.
a = DatasetType("a", ["instrument"], universe=butler2.dimensions, storageClass="StructuredDataDict")
b = DatasetType(
"b",
["instrument"],
universe=butler2.dimensions,
storageClass="StructuredDataDict",
isCalibration=True,
)
butler2.registry.registerDatasetType(b)
butler2.registry.registerDatasetType(a)
self.assertEqual(butler2.get_dataset_type("a"), a)
Expand Down

0 comments on commit 6704b41

Please sign in to comment.