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

import unittest 

import numpy as np 

 

import lsst.utils.tests 

 

from lsst.geom import Box2I, Point2I, Point2D, Extent2I, SpherePoint, degrees 

from lsst.afw.geom import makeCdMatrix, makeSkyWcs 

from lsst.afw.image import PARENT 

from lsst.afw.table import SourceTable 

from lsst.meas.algorithms import DynamicDetectionTask 

from lsst.meas.algorithms.testUtils import plantSources 

 

 

class DynamicDetectionTest(lsst.utils.tests.TestCase): 

def setUp(self): 

xy0 = Point2I(12345, 67890) # xy0 for image 

dims = Extent2I(2345, 2345) # Dimensions of image 

box = Box2I(xy0, dims) # Bounding box of image 

sigma = 3.21 # PSF sigma 

buffer = 4.0 # Buffer for star centers around edge 

nSigmaForKernel = 5.0 # Number of PSF sigmas for kernel 

sky = 12345.6 # Sky level 

numStars = 100 # Number of stars 

noise = np.sqrt(sky)*np.pi*sigma**2 # Poisson noise per PSF 

faint = 1.0*noise # Faintest level for star fluxes 

bright = 100.0*noise # Brightest level for star fluxes 

starBox = Box2I(box) # Area on image in which we can put star centers 

starBox.grow(-int(buffer*sigma)) 

scale = 1.0e-5*degrees # Pixel scale 

 

np.random.seed(12345) 

stars = [(xx, yy, ff, sigma) for xx, yy, ff in 

zip(np.random.uniform(starBox.getMinX(), starBox.getMaxX(), numStars), 

np.random.uniform(starBox.getMinY(), starBox.getMaxY(), numStars), 

np.linspace(faint, bright, numStars))] 

self.exposure = plantSources(box, 2*int(nSigmaForKernel*sigma) + 1, sky, stars, True) 

self.exposure.setWcs(makeSkyWcs(crpix=Point2D(0, 0), 

crval=SpherePoint(0, 0, degrees), 

cdMatrix=makeCdMatrix(scale=scale))) 

 

# Make a large area of extra background; we should be robust against it 

# Unfortunately, some tuning is required here to get something challenging but not impossible: 

# * A very large box will cause failures because the "extra" and the "normal" are reversed. 

# * A small box will not be challenging because it's simple to clip out. 

# * A large value will cause failures because it produces large edges in background-subtrction that 

# broaden flux distributions. 

# * A small value will not be challenging because it has little effect. 

extraBox = Box2I(xy0 + Extent2I(345, 456), Extent2I(1234, 1234)) # Box for extra background 

extraValue = 0.5*noise # Extra background value to add in 

self.exposure.image[extraBox, PARENT] += extraValue 

 

self.config = DynamicDetectionTask.ConfigClass() 

self.config.skyObjects.nSources = 300 

self.config.reEstimateBackground = False 

self.config.doTempWideBackground = True 

self.config.thresholdType = "pixel_stdev" 

 

# Relative tolerance for tweak factor 

# Not sure why this isn't smaller; maybe due to use of Poisson instead of Gaussian noise? 

self.rtol = 0.1 

 

def tearDown(self): 

del self.exposure 

 

def check(self, expectFactor): 

schema = SourceTable.makeMinimalSchema() 

task = DynamicDetectionTask(config=self.config, schema=schema) 

table = SourceTable.make(schema) 

 

results = task.run(table, self.exposure, expId=12345) 

self.assertFloatsAlmostEqual(results.factor, expectFactor, rtol=self.rtol) 

 

def testVanilla(self): 

"""Dynamic detection used as normal detection""" 

self.check(1.0) 

 

def testDynamic(self): 

"""Modify the variance plane, and see if the task is able to determine what we did""" 

factor = 2.0 

self.exposure.maskedImage.variance /= factor 

self.check(1.0/np.sqrt(factor)) 

 

def testNoSources(self): 

self.config.skyObjects.nSources = self.config.minNumSources - 1 

self.check(1.0) 

 

 

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

pass 

 

 

def setup_module(module): 

lsst.utils.tests.init() 

 

 

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

import sys 

setup_module(sys.modules['__main__']) 

unittest.main()