Coverage for python/lsst/daf/butler/registry/_defaults.py: 33%
46 statements
« prev ^ index » next coverage.py v6.4.1, created at 2022-06-17 02:08 -0700
« prev ^ index » next coverage.py v6.4.1, created at 2022-06-17 02:08 -0700
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 program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
22from __future__ import annotations
24__all__ = ("RegistryDefaults",)
26from typing import TYPE_CHECKING, Any, Optional
28from lsst.utils.classes import immutable
30from ..core import DataCoordinate
31from ._exceptions import MissingCollectionError
32from .summaries import CollectionSummary
33from .wildcards import CollectionSearch
35if TYPE_CHECKING: 35 ↛ 36line 35 didn't jump to line 36, because the condition on line 35 was never true
36 from ._registry import Registry
39@immutable
40class RegistryDefaults:
41 """A struct used to provide the default collections searched or written to
42 by a `Registry` or `Butler` instance.
44 Parameters
45 ----------
46 collections : `str` or `Iterable` [ `str` ], optional
47 An expression specifying the collections to be searched (in order) when
48 reading datasets. If a default value for a governor dimension is not
49 given via ``**kwargs``, and exactly one value for that dimension
50 appears in the datasets in ``collections``, that value is also used as
51 the default for that dimension.
52 This may be a `str` collection name or an iterable thereof.
53 See :ref:`daf_butler_collection_expressions` for more information.
54 These collections are not registered automatically and must be
55 manually registered before they are used by any `Registry` or `Butler`
56 method, but they may be manually registered after a `Registry` or
57 `Butler` is initialized with this struct.
58 run : `str`, optional
59 Name of the `~CollectionType.RUN` collection new datasets should be
60 inserted into. If ``collections`` is `None` and ``run`` is not `None`,
61 ``collections`` will be set to ``[run]``. If not `None`, this
62 collection will automatically be registered when the default struct is
63 attached to a `Registry` instance.
64 infer : `bool`, optional
65 If `True` (default) infer default data ID values from the values
66 present in the datasets in ``collections``: if all collections have the
67 same value (or no value) for a governor dimension, that value will be
68 the default for that dimension. Nonexistent collections are ignored.
69 If a default value is provided explicitly for a governor dimension via
70 ``**kwargs``, no default will be inferred for that dimension.
71 **kwargs : `str`
72 Default data ID key-value pairs. These may only identify "governor"
73 dimensions like ``instrument`` and ``skymap``, though this is only
74 checked when the defaults struct is actually attached to a `Registry`.
75 """
77 def __init__(self, collections: Any = None, run: Optional[str] = None, infer: bool = True, **kwargs: str):
78 if collections is None:
79 if run is not None:
80 collections = (run,)
81 else:
82 collections = ()
83 self.collections = CollectionSearch.fromExpression(collections)
84 self.run = run
85 self._infer = infer
86 self._kwargs = kwargs
88 def finish(self, registry: Registry) -> None:
89 """Validate the defaults struct and standardize its data ID.
91 This should be called only by a `Registry` instance when the defaults
92 struct is first associated with it.
94 Parameters
95 ----------
96 registry : `Registry`
97 Registry instance these defaults are being attached to.
99 Raises
100 ------
101 TypeError
102 Raised if a non-governor dimension was included in ``**kwargs``
103 at construction.
104 """
105 allGovernorDimensions = registry.dimensions.getGovernorDimensions()
106 if not self._kwargs.keys() <= allGovernorDimensions.names:
107 raise TypeError(
108 "Only governor dimensions may be identified by a default data "
109 f"ID, not {self._kwargs.keys() - allGovernorDimensions.names}. "
110 "(These may just be unrecognized keyword arguments passed at "
111 "Butler construction.)"
112 )
113 if self._infer and not self._kwargs.keys() == allGovernorDimensions.names:
114 summaries = []
115 for collection in self.collections:
116 try:
117 summaries.append(registry.getCollectionSummary(collection))
118 except MissingCollectionError:
119 pass
120 if summaries:
121 summary = CollectionSummary.union(*summaries)
122 for dimensionName in allGovernorDimensions.names - self._kwargs.keys():
123 values = summary.dimensions[dimensionName]
124 if len(values) == 1:
125 (value,) = values
126 self._kwargs[dimensionName] = value
127 self.dataId = registry.expandDataId(self._kwargs, withDefaults=False)
129 collections: CollectionSearch
130 """The collections to search by default, in order (`CollectionSearch`).
131 """
133 run: Optional[str]
134 """Name of the run this butler writes outputs to by default (`str` or
135 `None`).
136 """
138 dataId: DataCoordinate
139 """The default data ID (`DataCoordinate`).
141 Dimensions without defaults are simply not included. Only governor
142 dimensions are ever included in defaults.
144 This attribute may not be accessed before the defaults struct is
145 attached to a `Registry` instance. It always satisfies both ``hasFull``
146 and ``hasRecords``.
147 """