Hide keyboard shortcuts

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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

# This file is part of daf_butler. 

# 

# Developed for the LSST Data Management System. 

# This product includes software developed by the LSST Project 

# (http://www.lsst.org). 

# See the COPYRIGHT file at the top-level directory of this distribution 

# for details of code ownership. 

# 

# This program is free software: you can redistribute it and/or modify 

# it under the terms of the GNU General Public License as published by 

# the Free Software Foundation, either version 3 of the License, or 

# (at your option) any later version. 

# 

# This program is distributed in the hope that it will be useful, 

# but WITHOUT ANY WARRANTY; without even the implied warranty of 

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

# GNU General Public License for more details. 

# 

# You should have received a copy of the GNU General Public License 

# along with this program. If not, see <http://www.gnu.org/licenses/>. 

 

from __future__ import annotations 

 

__all__ = ("DimensionConfig",) 

 

from typing import Tuple, Dict 

 

from ..config import Config, ConfigSubset 

from ..utils import doImport 

from ..schema import FieldSpec 

from .elements import DimensionElement, Dimension, SkyPixDimension 

 

 

class DimensionConfig(ConfigSubset): 

"""Configuration that defines a `DimensionUniverse`. 

 

The configuration tree for dimensions is a (nested) dictionary 

with four top-level entries: 

 

- version: an integer version number, used as keys in a singleton registry 

of all `DimensionUniverse` instances; 

 

- skypix: a dictionary whose entries each define a `SkyPixDimension`, 

along with a special "common" key whose value is the name of a skypix 

dimension that is used to relate all other spatial dimensions in the 

`Registry` database; 

 

- elements: a nested dictionary whose entries each define a non-skypix 

`DimensionElement`; 

 

- packers: a nested dictionary whose entries define a factory for a 

`DimensionPacker` instance. 

""" 

component = "dimensions" 

requiredKeys = ("version", "elements", "skypix") 

defaultConfigFile = "dimensions.yaml" 

 

 

def processSkyPixConfig(config: Config) -> Tuple[Dict[str, SkyPixDimension], SkyPixDimension]: 

"""Process the "skypix" section of a `DimensionConfig`. 

 

Parameters 

---------- 

config : `Config` 

The subset of a `DimensionConfig` that corresponds to the "skypix" key. 

 

Returns 

------- 

dimensions: `dict` 

A dictionary mapping `str` names to partially-constructed 

`SkyPixDimension` instances; the caller (i.e. a `DimensionUniverse`) 

is responsible for calling `DimensionElement._finish` to complete 

construction. 

common: `SkyPixDimension` 

The special dimension used to relate all other spatial dimensions in 

the universe. This instance is also guaranteed to be a value in 

the returned ``dimensions``. 

""" 

skyPixNames = set(config.keys()) 

try: 

skyPixNames.remove("common") 

except KeyError as err: 

raise ValueError("No common skypix dimension defined in configuration.") from err 

dimensions = {} 

for name in skyPixNames: 

subconfig = config[name] 

pixelizationClass = doImport(subconfig["class"]) 

level = subconfig.get("level", None) 

if level is not None: 

pixelization = pixelizationClass(level) 

else: 

pixelization = pixelizationClass() 

dimensions[name] = SkyPixDimension(name, pixelization) 

try: 

common = dimensions[config["common"]] 

except KeyError as err: 

raise ValueError(f"Undefined name for common skypix dimension ({config['common']}).") from err 

return dimensions, common 

 

 

def processElementsConfig(config: Config) -> Dict[str, DimensionElement]: 

"""Process the "elements" section of a `DimensionConfig`. 

 

Parameters 

---------- 

config : `Config` 

The subset of a `DimensionConfig` that corresponds to the "elements" 

key. 

 

Returns 

------- 

dimensions : `dict` 

A dictionary mapping `str` names to partially-constructed 

`DimensionElement` instances; the caller (i.e. a `DimensionUniverse`) 

is responsible for calling `DimensionElement._finish` to complete 

construction. 

""" 

elements = dict() 

for name, subconfig in config.items(): 

kwargs = {} 

kwargs["impliedDependencyNames"] = frozenset(subconfig.get("implies", ())) 

kwargs["directDependencyNames"] = \ 

kwargs["impliedDependencyNames"].union(subconfig.get("requires", ())) 

kwargs["metadata"] = [FieldSpec.fromConfig(c) for c in subconfig.get("metadata", ())] 

kwargs["spatial"] = subconfig.get("spatial", False) 

kwargs["temporal"] = subconfig.get("temporal", False) 

kwargs["cached"] = subconfig.get("cached", False) 

kwargs["viewOf"] = subconfig.get("view_of", None) 

keys = subconfig.get("keys") 

if keys is not None: 

uniqueKeys = [FieldSpec.fromConfig(c, nullable=False) for c in keys] 

uniqueKeys[0].primaryKey = True 

elements[name] = Dimension(name, uniqueKeys=uniqueKeys, **kwargs) 

else: 

elements[name] = DimensionElement(name, **kwargs) 

return elements