Coverage for python/lsst/daf/butler/registry/_collection_type.py: 68%
28 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-01 11:20 +0000
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-01 11:20 +0000
1# This file is part of daf_butler.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This software is dual licensed under the GNU General Public License and also
10# under a 3-clause BSD license. Recipients may choose which of these licenses
11# to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12# respectively. If you choose the GPL option then the following text applies
13# (but note that there is still no warranty even if you opt for BSD instead):
14#
15# This program is free software: you can redistribute it and/or modify
16# it under the terms of the GNU General Public License as published by
17# the Free Software Foundation, either version 3 of the License, or
18# (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program. If not, see <http://www.gnu.org/licenses/>.
28from __future__ import annotations
30__all__ = [
31 "CollectionType",
32]
34import enum
35from collections.abc import Iterable
38class CollectionType(enum.IntEnum):
39 """Enumeration used to label different types of collections."""
41 RUN = 1
42 """A ``RUN`` collection (also just called a 'run') is the initial
43 collection a dataset is inserted into and the only one it can never be
44 removed from.
46 Within a particular run, there may only be one dataset with a particular
47 dataset type and data ID.
48 """
50 TAGGED = 2
51 """Datasets can be associated with and removed from ``TAGGED`` collections
52 arbitrarily.
54 Within a particular tagged collection, there may only be one dataset with
55 a particular dataset type and data ID.
56 """
58 CHAINED = 3
59 """A ``CHAINED`` collection is simply an ordered list of other collections
60 to be searched. These may include other ``CHAINED`` collections.
61 """
63 CALIBRATION = 4
64 """A ``CALIBRATION`` collection operates like a ``TAGGED`` collection, but
65 also associates each dataset with a validity range as well. Queries
66 against calibration collections must include a timestamp as an input.
68 It is difficult (perhaps impossible) to enforce a constraint that there be
69 one dataset with a particular dataset type and data ID at any particular
70 timestamp in the database, so higher-level tools that populate calibration
71 collections are expected to maintain that invariant instead.
72 """
74 @classmethod
75 def all(cls) -> frozenset[CollectionType]:
76 """Return a `frozenset` containing all members."""
77 return frozenset(cls.__members__.values())
79 @classmethod
80 def from_name(cls, name: str) -> CollectionType:
81 """Return the `CollectionType` given its name.
83 Parameters
84 ----------
85 name : `str`
86 Name of the collection type. Case insensitive.
88 Returns
89 -------
90 collection_type : `CollectionType`
91 The matching collection type.
93 Raises
94 ------
95 KeyError
96 Raised if the name does not match a collection type.
97 """
98 name = name.upper()
99 try:
100 return CollectionType.__members__[name]
101 except KeyError:
102 raise KeyError(f"Collection type of '{name}' not known to Butler.") from None
104 @classmethod
105 def from_names(cls, names: Iterable[str] | None) -> frozenset[CollectionType]:
106 """Return a `frozenset` containing the `CollectionType` instances
107 corresponding to the names.
109 Parameters
110 ----------
111 names : iterable of `str`, or `None`
112 Names of collection types. Case insensitive. If `None` or empty,
113 all collection types will be returned.
115 Returns
116 -------
117 types : `frozenset` of `CollectionType`
118 The matching types.
120 Raises
121 ------
122 KeyError
123 Raised if the name does not correspond to a collection type.
124 """
125 if not names:
126 return CollectionType.all()
128 # Convert to real collection types
129 return frozenset({CollectionType.from_name(name) for name in names})