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

183

184

185

186

187

188

# This file is part of meas_base. 

# 

# Developed for the LSST Data Management System. 

# This product includes software developed by the LSST Project 

# (https://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 <https://www.gnu.org/licenses/>. 

 

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): 

"""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): 

"""Test plugin which operates on single records. 

 

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): 

"""Test plugin which operates on multiple records. 

 

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): 

"""Test plugin which depends on a previous plugin execution. 

 

Used to test runlevel resolution. This plugin takes in single records, 

reads a value calculated by 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 using 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() 

 

 

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

lsst.utils.tests.init() 

unittest.main()