Coverage for python/lsst/daf/butler/core/dimensions/config.py : 22%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
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__ = ("DimensionConfig",)
26from typing import Any, Dict, Tuple
28from ..config import Config, ConfigSubset
29from ..utils import doImport
30from .. import ddl
31from .elements import DimensionElement, Dimension, SkyPixDimension, RelatedDimensions
34class DimensionConfig(ConfigSubset):
35 """Configuration that defines a `DimensionUniverse`.
37 The configuration tree for dimensions is a (nested) dictionary
38 with four top-level entries:
40 - version: an integer version number, used as keys in a singleton registry
41 of all `DimensionUniverse` instances;
43 - skypix: a dictionary whose entries each define a `SkyPixDimension`,
44 along with a special "common" key whose value is the name of a skypix
45 dimension that is used to relate all other spatial dimensions in the
46 `Registry` database;
48 - elements: a nested dictionary whose entries each define a non-skypix
49 `DimensionElement`;
51 - packers: a nested dictionary whose entries define a factory for a
52 `DimensionPacker` instance.
53 """
54 component = "dimensions"
55 requiredKeys = ("version", "elements", "skypix")
56 defaultConfigFile = "dimensions.yaml"
59def processSkyPixConfig(config: Config) -> Tuple[Dict[str, SkyPixDimension], SkyPixDimension]:
60 """Process the "skypix" section of a `DimensionConfig`.
62 Parameters
63 ----------
64 config : `Config`
65 The subset of a `DimensionConfig` that corresponds to the "skypix" key.
67 Returns
68 -------
69 dimensions: `dict`
70 A dictionary mapping `str` names to partially-constructed
71 `SkyPixDimension` instances; the caller (i.e. a `DimensionUniverse`)
72 is responsible for calling `DimensionElement._finish` to complete
73 construction.
74 common: `SkyPixDimension`
75 The special dimension used to relate all other spatial dimensions in
76 the universe. This instance is also guaranteed to be a value in
77 the returned ``dimensions``.
78 """
79 skyPixNames = set(config.keys())
80 try:
81 skyPixNames.remove("common")
82 except KeyError as err:
83 raise ValueError("No common skypix dimension defined in configuration.") from err
84 dimensions = {}
85 for name in skyPixNames:
86 subconfig = config[name]
87 pixelizationClass = doImport(subconfig["class"])
88 level = subconfig.get("level", None)
89 if level is not None:
90 pixelization = pixelizationClass(level)
91 else:
92 pixelization = pixelizationClass()
93 dimensions[name] = SkyPixDimension(name, pixelization)
94 try:
95 common = dimensions[config["common"]]
96 except KeyError as err:
97 raise ValueError(f"Undefined name for common skypix dimension ({config['common']}).") from err
98 return dimensions, common
101def processElementsConfig(config: Config) -> Dict[str, DimensionElement]:
102 """Process the "elements" section of a `DimensionConfig`.
104 Parameters
105 ----------
106 config : `Config`
107 The subset of a `DimensionConfig` that corresponds to the "elements"
108 key.
110 Returns
111 -------
112 dimensions : `dict`
113 A dictionary mapping `str` names to partially-constructed
114 `DimensionElement` instances; the caller (i.e. a `DimensionUniverse`)
115 is responsible for calling `DimensionElement._finish` to complete
116 construction.
117 """
118 elements: Dict[str, DimensionElement] = dict()
119 for name, subconfig in config.items():
120 kwargs: Dict[str, Any] = {}
121 kwargs["related"] = RelatedDimensions(
122 required=set(subconfig.get("requires", ())),
123 implied=set(subconfig.get("implies", ())),
124 spatial=subconfig.get("spatial"),
125 temporal=subconfig.get("temporal"),
126 )
127 kwargs["metadata"] = [ddl.FieldSpec.fromConfig(c) for c in subconfig.get("metadata", ())]
128 kwargs["cached"] = subconfig.get("cached", False)
129 kwargs["viewOf"] = subconfig.get("view_of", None)
130 kwargs["alwaysJoin"] = subconfig.get("always_join", False)
131 keys = subconfig.get("keys")
132 if keys is not None:
133 uniqueKeys = [ddl.FieldSpec.fromConfig(c, nullable=False) for c in keys]
134 uniqueKeys[0].primaryKey = True
135 elements[name] = Dimension(name, uniqueKeys=uniqueKeys, **kwargs)
136 else:
137 elements[name] = DimensionElement(name, **kwargs)
138 return elements