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 mimics testPlacement.py, but is designed to specifically 

3test the placement of objects on the LSST camera. This is to make 

4sure that we have correctly handled the band-dependent optical distortions 

5in the LSST camera. 

6""" 

7from builtins import range 

8import unittest 

9import tempfile 

10import shutil 

11import lsst.utils.tests 

12 

13import numpy as np 

14import os 

15from lsst.utils import getPackageDir 

16import lsst.afw.image as afwImage 

17from lsst.sims.utils.CodeUtilities import sims_clean_up 

18from lsst.sims.catUtils.utils import ObservationMetaDataGenerator 

19from lsst.sims.catalogs.db import fileDBObject 

20from lsst.sims.GalSimInterface import GalSimStars, SNRdocumentPSF 

21from lsst.sims.GalSimInterface import LSSTCameraWrapper 

22from testUtils import create_text_catalog 

23 

24from lsst.sims.coordUtils import pixelCoordsFromRaDec 

25from lsst.sims.coordUtils import DMtoCameraPixelTransformer 

26from lsst.sims.coordUtils import raDecFromPixelCoordsLSST 

27from lsst.sims.coordUtils import pixelCoordsFromRaDecLSST 

28from lsst.sims.coordUtils import chipNameFromPupilCoordsLSST 

29from lsst.sims.coordUtils import pupilCoordsFromFocalPlaneCoordsLSST 

30from lsst.sims.coordUtils import focalPlaneCoordsFromPupilCoordsLSST 

31from lsst.sims.coordUtils import lsst_camera 

32 

33ROOT = os.path.abspath(os.path.dirname(__file__)) 

34 

35 

36def setup_module(module): 

37 lsst.utils.tests.init() 

38 

39 

40class LSSTPlacementFileDBObj(fileDBObject): 

41 idColKey = 'test_id' 

42 objectTypeId = 88 

43 tableid = 'test' 

44 raColName = 'ra' 

45 decColName = 'dec' 

46 

47 columns = [('raJ2000', 'ra*PI()/180.0', np.float), 

48 ('decJ2000', 'dec*PI()/180.0', np.float), 

49 ('magNorm', 'mag_norm', np.float)] 

50 

51 

52class LSSTPlacementCatalog(GalSimStars): 

53 

54 def get_galacticAv(self): 

55 ra = self.column_by_name('raJ2000') 

56 return np.array([0.1]*len(ra)) 

57 

58 default_columns = GalSimStars.default_columns 

59 

60 default_columns += [('sedFilename', 'sed_flat.txt', (str, 12)), 

61 ('properMotionRa', 0.0, np.float), 

62 ('properMotionDec', 0.0, np.float), 

63 ('radialVelocity', 0.0, np.float), 

64 ('parallax', 0.0, np.float) 

65 ] 

66 

67 

68class GalSimPlacementTest(unittest.TestCase): 

69 

70 @classmethod 

71 def tearDownClass(cls): 

72 sims_clean_up() 

73 if hasattr(chipNameFromPupilCoordsLSST, '_detector_arr'): 

74 del chipNameFromPupilCoordsLSST._detector_arr 

75 if hasattr(focalPlaneCoordsFromPupilCoordsLSST, '_z_fitter'): 

76 del focalPlaneCoordsFromPupilCoordsLSST._z_fitter 

77 if hasattr(pupilCoordsFromFocalPlaneCoordsLSST, '_z_fitter'): 

78 del pupilCoordsFromFocalPlaneCoordsLSST._z_fitter 

79 if hasattr(lsst_camera, '_lsst_camera'): 

80 del lsst_camera._lsst_camera 

81 

82 @classmethod 

83 def setUpClass(cls): 

84 opsimdb = os.path.join(getPackageDir('sims_data'), 'OpSimData', 

85 'opsimblitz1_1133_sqlite.db') 

86 obs_gen = ObservationMetaDataGenerator(opsimdb) 

87 cls.obs_dict = {} 

88 for band in 'ugrizy': 

89 obs_list = obs_gen.getObservationMetaData(telescopeFilter=band, limit=10) 

90 assert len(obs_list) > 0 

91 cls.obs_dict[band] = obs_list[0] 

92 

93 

94 def testObjectPlacement(self): 

95 """ 

96 Test that GalSim places objects on the correct pixel by drawing 

97 images containing single objects and no background, reading those 

98 images back in, and comparing the flux-averaged centroids of the 

99 images with the expected pixel positions of the input objects. 

100 """ 

101 scratchDir = tempfile.mkdtemp(dir=ROOT, prefix='testLSSTObjectPlacement-') 

102 if os.path.exists(scratchDir): 

103 shutil.rmtree(scratchDir) 

104 os.mkdir(scratchDir) 

105 

106 detector = lsst_camera()['R:0,3 S:2,2'] 

107 det_name = 'R03_S22' 

108 

109 magNorm = 19.0 

110 

111 pixel_transformer = DMtoCameraPixelTransformer() 

112 

113 for band in 'ugrizy': 

114 obs = self.obs_dict[band] 

115 

116 catName = os.path.join(scratchDir, 'placementCatalog.dat') 

117 imageRoot = os.path.join(scratchDir, 'placementImage') 

118 dbFileName = os.path.join(scratchDir, 'placementInputCatalog.dat') 

119 

120 

121 imageName = '%s_%s_%s.fits' % (imageRoot, det_name, obs.bandpass) 

122 

123 ra_c, dec_c = raDecFromPixelCoordsLSST(2000.0, 2000.0, 

124 detector.getName(), 

125 band=obs.bandpass, 

126 obs_metadata=obs) 

127 

128 nSamples = 3 

129 rng = np.random.RandomState(42) 

130 fwhm = 0.2 

131 

132 for iteration in range(nSamples): 

133 if os.path.exists(dbFileName): 

134 os.unlink(dbFileName) 

135 

136 ra_obj = ra_c + rng.random_sample()*0.2 - 0.1 

137 dec_obj = dec_c + rng.random_sample()*0.2 - 0.1 

138 

139 dmx_wrong, dmy_wrong = pixelCoordsFromRaDec(ra_obj, dec_obj, 

140 chipName=detector.getName(), 

141 obs_metadata=obs, 

142 camera=lsst_camera()) 

143 

144 dmx_pix, dmy_pix = pixelCoordsFromRaDecLSST(ra_obj, dec_obj, 

145 chipName=detector.getName(), 

146 obs_metadata=obs, 

147 band=obs.bandpass) 

148 

149 x_pix, y_pix = pixel_transformer.cameraPixFromDMPix(dmx_pix, dmy_pix, 

150 detector.getName()) 

151 

152 x_pix_wrong, y_pix_wrong = pixel_transformer.cameraPixFromDMPix(dmx_wrong, dmy_wrong, 

153 detector.getName()) 

154 

155 d_ra = 3600.0*(ra_obj - obs.pointingRA) # in arcseconds 

156 d_dec = 3600.0*(dec_obj - obs.pointingDec) 

157 

158 create_text_catalog(obs, dbFileName, 

159 np.array([d_ra]), np.array([d_dec]), 

160 mag_norm=[magNorm]) 

161 

162 db = LSSTPlacementFileDBObj(dbFileName, runtable='test') 

163 cat = LSSTPlacementCatalog(db, obs_metadata=obs) 

164 cat.camera_wrapper = LSSTCameraWrapper() 

165 psf = SNRdocumentPSF(fwhm=fwhm) 

166 cat.setPSF(psf) 

167 

168 cat.write_catalog(catName) 

169 cat.write_images(nameRoot=imageRoot) 

170 

171 im = afwImage.ImageF(imageName).getArray() 

172 tot_flux = im.sum() 

173 self.assertGreater(tot_flux, 100.0) 

174 

175 y_centroid = sum([ii*im[ii,:].sum() for ii in range(im.shape[0])])/tot_flux 

176 x_centroid = sum([ii*im[:,ii].sum() for ii in range(im.shape[1])])/tot_flux 

177 dd = np.sqrt((x_pix-x_centroid)**2 + (y_pix-y_centroid)**2) 

178 self.assertLess(dd, 0.5*fwhm) 

179 

180 dd_wrong = np.sqrt((x_pix_wrong-x_centroid)**2 + 

181 (y_pix_wrong-y_centroid)**2) 

182 

183 self.assertLess(dd, dd_wrong) 

184 

185 if os.path.exists(dbFileName): 

186 os.unlink(dbFileName) 

187 if os.path.exists(catName): 

188 os.unlink(catName) 

189 if os.path.exists(imageName): 

190 os.unlink(imageName) 

191 

192 if os.path.exists(scratchDir): 

193 shutil.rmtree(scratchDir) 

194 

195 

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

197 pass 

198 

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

200 lsst.utils.tests.init() 

201 unittest.main()