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

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

# 

# LSST Data Management System 

# Copyright 2008-2017 LSST Corporation. 

# 

# This product includes software developed by the 

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

# 

# 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 LSST License Statement and 

# the GNU General Public License along with this program. If not, 

# see <http://www.lsstcorp.org/LegalNotices/>. 

# 

import unittest 

import lsst.utils.tests 

 

import lsst.meas.base.catalogCalculation as catCalc 

import lsst.afw.table as afwTable 

from lsst.meas.base.pluginRegistry import register 

from lsst.meas.base import MeasurementError 

 

 

@register("FailcatalogCalculation") 

class FailCC(catCalc.CatalogCalculationPlugin): 

''' 

catalogCalculation plugin which is guaranteed to fail, testing the failure framework 

''' 

@classmethod 

def getExecutionOrder(cls): 

return cls.DEFAULT_CATALOGCALCULATION 

 

def __init__(self, config, name, schema, metadata): 

catCalc.CatalogCalculationPlugin.__init__(self, config, name, schema, metadata) 

self.failKey = schema.addField(name + "_fail", type="Flag", doc="Failure test") 

 

def calculate(self, measRecord): 

# note: flagbit doesn't matter, since a FlagHandler isn't used 

raise MeasurementError("Supposed to fail", 0) 

 

def fail(self, measRecord, error=None): 

measRecord.set(self.failKey, True) 

 

 

@register("singleRecordCatalogCalculation") 

class SingleRecordCC(catCalc.CatalogCalculationPlugin): 

''' 

CatalogCalculation plugin which works in single mode. It takes a single record, reads a value, squares it, 

and writes out the results to the record 

''' 

@classmethod 

def getExecutionOrder(cls): 

return cls.DEFAULT_CATALOGCALCULATION 

 

def __init__(self, config, name, schema, metadata): 

catCalc.CatalogCalculationPlugin.__init__(self, config, name, schema, metadata) 

self.failKey = schema.addField(name + "_fail", type="Flag", doc="Failure flag") 

self.squareKey = schema.addField(name + "_square", type="D", doc="Square of input catalog") 

 

def calculate(self, measRecord): 

value = measRecord.get("start") 

measRecord.set(self.squareKey, value**2) 

 

def fail(self, measRecord, error=None): 

measRecord.set(self.failKey, True) 

 

 

@register("multiRecordCatalogCalculation") 

class MultiRecordAb(catCalc.CatalogCalculationPlugin): 

""" 

CatalogCalcuation plugin to test the framework in multimode. This plugin takes the whole source catalog at 

once, and loops over the catalog internally. The algorithm simply reads a value, cubes it, and writes the 

results out to the table 

""" 

plugType = 'multi' 

 

@classmethod 

def getExecutionOrder(cls): 

return cls.DEFAULT_CATALOGCALCULATION 

 

def __init__(self, config, name, schema, metadata): 

catCalc.CatalogCalculationPlugin.__init__(self, config, name, schema, metadata) 

self.failKey = schema.addField(name + "_fail", type="Flag", doc="Failure flag") 

self.cubeKey = schema.addField(name + "_cube", type="D", doc="Cube of input catalog") 

 

def calculate(self, catalog): 

for rec in catalog: 

value = rec.get("start") 

rec.set(self.cubeKey, value**3) 

 

def fail(self, catalog, error=None): 

for rec in catalog: 

rec.set(self.failKey, True) 

 

 

@register("dependentCatalogCalulation") 

class DependentAb(catCalc.CatalogCalculationPlugin): 

''' 

CatalogCalculation plugin to test the runlevel resolution. This plugin takes in single records, reads a 

value from a previous plugin computes a square root, and writes the results to the table. 

''' 

@classmethod 

def getExecutionOrder(cls): 

return cls.DEFAULT_CATALOGCALCULATION + 1 

 

def __init__(self, config, name, schema, metadata): 

catCalc.CatalogCalculationPlugin.__init__(self, config, name, schema, metadata) 

self.failKey = schema.addField(name + "_fail", type="Flag", doc="Failure flag") 

self.sqrtKey = schema.addField(name + "_sqrt", type="D", 

doc="Square root of singleRecord catalogCalculation") 

 

def calculate(self, measRecord): 

value = measRecord.get("singleRecordCatalogCalculation_square") 

measRecord.set(self.sqrtKey, value**0.5) 

 

def fail(self, measRecord, error=None): 

measRecord.set(self.failKey, True) 

 

 

class CatalogCalculationTest(unittest.TestCase): 

''' 

Test the catalogCalculation framework, running only the plugins defined above 

''' 

def setUp(self): 

# Create a schema object, and populate it with a field to simulate results from measurements on an 

# image 

schema = afwTable.SourceTable.makeMinimalSchema() 

schema.addField("start", type="D") 

# Instantiate a config object adding each of the above plugins, and use it to create a task 

catCalcConfig = catCalc.CatalogCalculationConfig() 

catCalcConfig.plugins.names = ["FailcatalogCalculation", "singleRecordCatalogCalculation", 

"multiRecordCatalogCalculation", "dependentCatalogCalulation"] 

catCalcTask = catCalc.CatalogCalculationTask(schema=schema, config=catCalcConfig) 

# Create a catalog with five sources as input to the task 

self.catalog = afwTable.SourceCatalog(schema) 

self.numObjects = 5 

for i in range(self.numObjects): 

rec = self.catalog.addNew() 

rec.set("start", float(i + 1)) 

# Run the catalogCalculation task, outputs will be checked in test methods 

catCalcTask.run(self.catalog) 

 

def testCatalogCalculation(self): 

# Verify the failure flag got set for the plugin expected to fail 

self.assertEqual(len(self.catalog), self.numObjects) 

for src in self.catalog: 

self.assertTrue(src.get("FailcatalogCalculation_fail")) 

 

# Verify the single record plugin ran successfully 

for rec in self.catalog: 

self.assertAlmostEqual(rec.get("start")**2, rec.get("singleRecordCatalogCalculation_square"), 4) 

 

# Verify that the system correctly handled a plugin which expects a full catalog to be passed 

for rec in self.catalog: 

self.assertAlmostEqual(rec.get("start")**3, rec.get("multiRecordCatalogCalculation_cube"), 4) 

 

# Verify that the system runs plugins in the correct run order 

for rec in self.catalog: 

self.assertAlmostEqual(rec.get("start"), rec.get("dependentCatalogCalulation_sqrt"), 4) 

 

def tearDown(self): 

del self.catalog, self.numObjects, 

 

 

class TestMemory(lsst.utils.tests.MemoryTestCase): 

pass 

 

 

def setup_module(module): 

lsst.utils.tests.init() 

 

 

180 ↛ 181line 180 didn't jump to line 181, because the condition on line 180 was never trueif __name__ == "__main__": 

lsst.utils.tests.init() 

unittest.main()