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

2This test suite will verify that the CatSim and PhoSim camera models 

3are in agreement by taking the chip and pixel positions found by 

4PhoSim and verifying that CatSim predicts similar positions. 

5""" 

6 

7import unittest 

8import numpy as np 

9import os 

10import lsst.utils.tests 

11from lsst.utils import getPackageDir 

12 

13from lsst.sims.utils import ObservationMetaData 

14from lsst.sims.coordUtils import chipNameFromRaDecLSST 

15from lsst.sims.coordUtils import pixelCoordsFromRaDecLSST 

16from lsst.sims.coordUtils import chipNameFromPupilCoordsLSST 

17from lsst.sims.coordUtils import getCornerPixels 

18from lsst.sims.utils import observedFromICRS 

19from lsst.sims.utils import arcsecFromRadians, angularSeparation 

20from lsst.sims.coordUtils import lsst_camera 

21from lsst.sims.coordUtils import focalPlaneCoordsFromPupilCoordsLSST 

22 

23from lsst.sims.coordUtils import clean_up_lsst_camera 

24 

25def setup_module(module): 

26 lsst.utils.tests.init() 

27 

28 

29class PhoSim_position_test_case(unittest.TestCase): 

30 

31 longMessage = True 

32 

33 @classmethod 

34 def setUpClass(cls): 

35 cat_name = os.path.join(getPackageDir('sims_coordUtils'), 

36 'tests', 'LSST_focal_plane_data', 

37 'source_position_catalog.txt') 

38 

39 dtype = np.dtype([('pointingRA', float), ('pointingDec', float), 

40 ('rotSkyPos', float), 

41 ('objRA', float), ('objDec', float), 

42 ('chipName', str, 6), 

43 ('xpix', float), ('ypix', float)]) 

44 

45 cls.data = np.genfromtxt(cat_name, dtype=dtype) 

46 

47 @classmethod 

48 def tearDownClass(cls): 

49 clean_up_lsst_camera() 

50 

51 def test_chipName(self): 

52 """ 

53 Simply verify that CatSim puts the sources on the right chip 

54 """ 

55 self.assertGreater(len(self.data), 10) 

56 for ix in range(len(self.data)): 

57 obs = ObservationMetaData(pointingRA=self.data['pointingRA'][ix], 

58 pointingDec=self.data['pointingDec'][ix], 

59 rotSkyPos=self.data['rotSkyPos'][ix], 

60 mjd=59580.0) 

61 

62 chipName = chipNameFromRaDecLSST(self.data['objRA'][ix], 

63 self.data['objDec'][ix], 

64 obs_metadata=obs) 

65 

66 self.assertEqual(chipName.replace(',','').replace(':','').replace(' ',''), 

67 self.data['chipName'][ix]) 

68 

69 def test_pixel_positions(self): 

70 """ 

71 Test that CatSim pixel positions are close to PhoSim pixel positions. 

72 

73 This is complicated by the fact that PhoSim uses the camera team definition 

74 of pixel space, which differs from the DM definition of pixel space as follows: 

75 

76 Camera +y = DM +x 

77 Camera +x = DM -y 

78 Camera +z = DM +z 

79 

80 This has been verified both by consulting documentation -- the documentation for 

81 afwCameraGeom says that +x is along the serial readout direction; LCA-13381 

82 indicates that, in the Camera team's definition, the serial readout is along +y -- 

83 and phenomenologically by comparing the relationship between 

84 pixelCoordsFromPupilCoords() to visual inspection of PhoSim-generated FITS images. 

85 """ 

86 self.assertGreater(len(self.data), 10) 

87 for ix in range(len(self.data)): 

88 

89 in_name = self.data['chipName'][ix] 

90 chip_name = in_name[0]+':'+in_name[1]+','+in_name[2] 

91 chip_name += ' '+in_name[3]+':'+in_name[4]+','+in_name[5] 

92 corner_pixels = getCornerPixels(chip_name, lsst_camera()) 

93 

94 x_center_dm = 0.25*(corner_pixels[0][0] + corner_pixels[1][0] + 

95 corner_pixels[2][0] + corner_pixels[3][0]) 

96 

97 y_center_dm = 0.25*(corner_pixels[0][1] + corner_pixels[1][1] + 

98 corner_pixels[2][1] + corner_pixels[3][1]) 

99 

100 obs = ObservationMetaData(pointingRA=self.data['pointingRA'][ix], 

101 pointingDec=self.data['pointingDec'][ix], 

102 rotSkyPos=self.data['rotSkyPos'][ix], 

103 mjd=59580.0) 

104 

105 xpix, ypix = pixelCoordsFromRaDecLSST(self.data['objRA'][ix], 

106 self.data['objDec'][ix], 

107 obs_metadata=obs) 

108 

109 raObs, decObs = observedFromICRS(self.data['objRA'][ix], 

110 self.data['objDec'][ix], 

111 obs_metadata=obs, 

112 epoch=2000.0) 

113 

114 # find displacement from center of DM coordinates of the 

115 # objects as placed by PhoSim 

116 d_y_phosim = y_center_dm - self.data['xpix'][ix] 

117 d_x_phosim = self.data['ypix'][ix] - x_center_dm 

118 

119 # displacement from center of DM coordinates as calculated 

120 # by DM 

121 d_x_dm = xpix - x_center_dm 

122 d_y_dm = ypix - y_center_dm 

123 

124 d_pix = np.sqrt((d_x_dm - d_x_phosim)**2 + 

125 (d_y_dm - d_y_phosim)**2) 

126 

127 # demand that the difference between the two displacements is less 

128 # than 0.05 of the total displacement from the center of the object 

129 # as calculated by DM 

130 msg = 'dx %e; dy %e' % (d_x_dm, d_y_dm) 

131 self.assertLess(d_pix, 0.05*np.sqrt(d_x_dm**2+d_y_dm**2), msg=msg) 

132 

133class MemoryTestClass(lsst.utils.tests.MemoryTestCase): 

134 pass 

135 

136if __name__ == "__main__": 136 ↛ 137line 136 didn't jump to line 137, because the condition on line 136 was never true

137 lsst.utils.tests.init() 

138 unittest.main()