Coverage for python/lsst/daf/butler/registry/_defaults.py: 31%

44 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-12-01 19:55 +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 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/>. 

21 

22from __future__ import annotations 

23 

24__all__ = ("RegistryDefaults",) 

25 

26from typing import Any, Optional, TYPE_CHECKING 

27 

28from ..core import DataCoordinate 

29from ..core.utils import immutable 

30from ._exceptions import MissingCollectionError 

31from .summaries import CollectionSummary 

32from .wildcards import CollectionSearch 

33 

34if TYPE_CHECKING: 34 ↛ 35line 34 didn't jump to line 35, because the condition on line 34 was never true

35 from ._registry import Registry 

36 

37 

38@immutable 

39class RegistryDefaults: 

40 """A struct used to provide the default collections searched or written to 

41 by a `Registry` or `Butler` instance. 

42 

43 Parameters 

44 ---------- 

45 collections : `str` or `Iterable` [ `str` ], optional 

46 An expression specifying the collections to be searched (in order) when 

47 reading datasets. If a default value for a governor dimension is not 

48 given via ``**kwargs``, and exactly one value for that dimension 

49 appears in the datasets in ``collections``, that value is also used as 

50 the default for that dimension. 

51 This may be a `str` collection name or an iterable thereof. 

52 See :ref:`daf_butler_collection_expressions` for more information. 

53 These collections are not registered automatically and must be 

54 manually registered before they are used by any `Registry` or `Butler` 

55 method, but they may be manually registered after a `Registry` or 

56 `Butler` is initialized with this struct. 

57 run : `str`, optional 

58 Name of the `~CollectionType.RUN` collection new datasets should be 

59 inserted into. If ``collections`` is `None` and ``run`` is not `None`, 

60 ``collections`` will be set to ``[run]``. If not `None`, this 

61 collection will automatically be registered when the default struct is 

62 attached to a `Registry` instance. 

63 infer : `bool`, optional 

64 If `True` (default) infer default data ID values from the values 

65 present in the datasets in ``collections``: if all collections have the 

66 same value (or no value) for a governor dimension, that value will be 

67 the default for that dimension. Nonexistent collections are ignored. 

68 If a default value is provided explicitly for a governor dimension via 

69 ``**kwargs``, no default will be inferred for that dimension. 

70 **kwargs : `str` 

71 Default data ID key-value pairs. These may only identify "governor" 

72 dimensions like ``instrument`` and ``skymap``, though this is only 

73 checked when the defaults struct is actually attached to a `Registry`. 

74 """ 

75 def __init__(self, collections: Any = None, run: Optional[str] = None, infer: bool = True, **kwargs: str): 

76 if collections is None: 

77 if run is not None: 

78 collections = (run,) 

79 else: 

80 collections = () 

81 self.collections = CollectionSearch.fromExpression(collections) 

82 self.run = run 

83 self._infer = infer 

84 self._kwargs = kwargs 

85 

86 def finish(self, registry: Registry) -> None: 

87 """Validate the defaults struct and standardize its data ID. 

88 

89 This should be called only by a `Registry` instance when the defaults 

90 struct is first associated with it. 

91 

92 Parameters 

93 ---------- 

94 registry : `Registry` 

95 Registry instance these defaults are being attached to. 

96 

97 Raises 

98 ------ 

99 TypeError 

100 Raised if a non-governor dimension was included in ``**kwargs`` 

101 at construction. 

102 """ 

103 allGovernorDimensions = registry.dimensions.getGovernorDimensions() 

104 if not self._kwargs.keys() <= allGovernorDimensions.names: 

105 raise TypeError( 

106 "Only governor dimensions may be identified by a default data " 

107 f"ID, not {self._kwargs.keys() - allGovernorDimensions.names}. " 

108 "(These may just be unrecognized keyword arguments passed at " 

109 "Butler construction.)" 

110 ) 

111 if self._infer and not self._kwargs.keys() == allGovernorDimensions.names: 

112 summaries = [] 

113 for collection in self.collections: 

114 try: 

115 summaries.append(registry.getCollectionSummary(collection)) 

116 except MissingCollectionError: 

117 pass 

118 if summaries: 

119 summary = CollectionSummary.union(*summaries) 

120 for dimensionName in (allGovernorDimensions.names - self._kwargs.keys()): 

121 values = summary.dimensions[dimensionName] 

122 if len(values) == 1: 

123 (value,) = values 

124 self._kwargs[dimensionName] = value 

125 self.dataId = registry.expandDataId(self._kwargs, withDefaults=False) 

126 

127 collections: CollectionSearch 

128 """The collections to search by default, in order (`CollectionSearch`). 

129 """ 

130 

131 run: Optional[str] 

132 """Name of the run this butler writes outputs to by default (`str` or 

133 `None`). 

134 """ 

135 

136 dataId: DataCoordinate 

137 """The default data ID (`DataCoordinate`). 

138 

139 Dimensions without defaults are simply not included. Only governor 

140 dimensions are ever included in defaults. 

141 

142 This attribute may not be accessed before the defaults struct is 

143 attached to a `Registry` instance. It always satisfies both ``hasFull`` 

144 and ``hasRecords``. 

145 """