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

137

138

139

140

141

142

143

144

145

146

147

# 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/>. 

 

__all__ = ("Quantum",) 

 

from .utils import slotValuesAreEqual 

 

from .execution import Execution 

 

 

class Quantum(Execution): 

"""A discrete unit of work that may depend on one or more datasets and 

produces one or more datasets. 

 

Most Quanta will be executions of a particular `SuperTask`’s `runQuantum` 

method, but they can also be used to represent discrete units of work 

performed manually by human operators or other software agents. 

 

Parameters 

---------- 

task : `str` or `SuperTask` 

Fully-qualified name of the SuperTask that executed this Quantum. 

run : `Run` 

The Run this Quantum is a part of. 

""" 

 

__slots__ = ("_task", "_run", "_predictedInputs", "_actualInputs", "_outputs") 

__eq__ = slotValuesAreEqual 

 

def __init__(self, task, run, *args, **kwargs): 

super().__init__(*args, **kwargs) 

self._task = task 

self._run = run 

self._predictedInputs = {} 

self._actualInputs = {} 

self._outputs = {} 

 

@property 

def task(self): 

"""Task associated with this `Quantum`. 

 

If the `Quantum` is associated with a `SuperTask`, this is the 

`SuperTask` instance that produced and should execute this set of 

inputs and outputs. If not, a human-readable string identifier 

for the operation. Some Registries may permit the value to be 

`None`, but are not required to in general. 

""" 

return self._task 

 

@property 

def run(self): 

"""The Run this Quantum is a part of (`Run`). 

""" 

return self._run 

 

@property 

def predictedInputs(self): 

r"""A `dict` of input datasets that were expected to be used, 

with `DatasetType` names as keys and a list of `DatasetRef` instances 

as values. 

 

Input `Datasets` that have already been stored may be 

`DatasetRef`\ s, and in many contexts may be guaranteed to be. 

Read-only; update via `Quantum.addPredictedInput()`. 

""" 

return self._predictedInputs 

 

@property 

def actualInputs(self): 

"""A `dict` of input datasets that were actually used, with the same 

form as `Quantum.predictedInputs`. 

 

All returned sets must be subsets of those in `predictedInputs`. 

 

Read-only; update via `Registry.markInputUsed()`. 

""" 

return self._actualInputs 

 

@property 

def outputs(self): 

"""A `dict` of output datasets (to be) generated for this quantum, 

with the same form as `predictedInputs`. 

 

Read-only; update via `addOutput()`. 

""" 

return self._outputs 

 

def addPredictedInput(self, ref): 

"""Add an input `DatasetRef` to the `Quantum`. 

 

This does not automatically update a `Registry`; all `predictedInputs` 

must be present before a `Registry.addQuantum()` is called. 

 

Parameters 

---------- 

ref : `DatasetRef` 

Reference for a Dataset to add to the Quantum's predicted inputs. 

""" 

datasetTypeName = ref.datasetType.name 

self._predictedInputs.setdefault(datasetTypeName, []).append(ref) 

 

def _markInputUsed(self, ref): 

"""Mark an input as used. 

 

This does not automatically update a `Registry`. 

For that use `Registry.markInputUsed()` instead. 

""" 

datasetTypeName = ref.datasetType.name 

# First validate against predicted 

if datasetTypeName not in self._predictedInputs: 

raise ValueError("Dataset type {} not in predicted inputs".format(datasetTypeName)) 

if ref not in self._predictedInputs[datasetTypeName]: 

raise ValueError("Actual input {} was not predicted".format(ref)) 

# Now insert as actual 

self._actualInputs.setdefault(datasetTypeName, []).append(ref) 

 

def addOutput(self, ref): 

"""Add an output `DatasetRef` to the `Quantum`. 

 

This does not automatically update a `Registry`; all `outputs` 

must be present before a `Registry.addQuantum()` is called. 

 

Parameters 

---------- 

ref : `DatasetRef` 

Reference for a Dataset to add to the Quantum's outputs. 

""" 

datasetTypeName = ref.datasetType.name 

self._outputs.setdefault(datasetTypeName, []).append(ref)