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

1from builtins import zip 

2from builtins import range 

3import unittest 

4import tempfile 

5import shutil 

6import lsst.utils.tests 

7 

8import numpy as np 

9import os 

10from lsst.utils import getPackageDir 

11import lsst.afw.image as afwImage 

12from lsst.sims.utils.CodeUtilities import sims_clean_up 

13from lsst.sims.utils import ObservationMetaData, arcsecFromRadians, haversine 

14#from lsst.sims.coordUtils.utils import ReturnCamera 

15from lsst.sims.coordUtils import _pixelCoordsFromRaDec, _raDecFromPixelCoords 

16from lsst.sims.photUtils import Sed, Bandpass 

17from lsst.sims.catalogs.db import fileDBObject 

18from lsst.sims.GalSimInterface import GalSimStars, SNRdocumentPSF 

19from lsst.sims.GalSimInterface import GalSimCameraWrapper 

20from testUtils import create_text_catalog 

21 

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

23 

24 

25def setup_module(module): 

26 lsst.utils.tests.init() 

27 

28 

29class placementFileDBObj(fileDBObject): 

30 idColKey = 'test_id' 

31 objectTypeId = 88 

32 tableid = 'test' 

33 raColName = 'ra' 

34 decColName = 'dec' 

35 

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

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

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

39 

40 

41class placementCatalog(GalSimStars): 

42 

43 bandpassNames = ['u'] 

44 

45 def get_galacticAv(self): 

46 ra = self.column_by_name('raJ2000') 

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

48 

49 default_columns = GalSimStars.default_columns 

50 

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

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

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

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

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

56 ] 

57 

58@unittest.skip('ReturnCamera deprecated - need replacement') 

59class GalSimPlacementTest(unittest.TestCase): 

60 

61 @classmethod 

62 def tearDownClass(cls): 

63 sims_clean_up() 

64 

65 def setUp(self): 

66 self.magNorm = 19.0 

67 

68 def check_placement(self, imageName, raList, decList, fwhmList, 

69 countList, gain, 

70 detector, camera, obs, epoch=2000.0): 

71 """ 

72 Read in a FITS image and a list of objects meant to be on that 

73 image. Verify that the objects were placed at the correct pixel 

74 by counting up all of the flux within 2 fwhm of each object's 

75 expected location and verifying it with the counts expected for 

76 that object. 

77 

78 @param [in] imageName is the name of the FITS file to be read in 

79 

80 @param [in] raList is a numpy array of the RA coordinates of the objects 

81 in the image (in radians) 

82 

83 @param [in] decList is a numpy array of the Dec coordinates of the objects 

84 in the image (in radians) 

85 

86 @param [in] fwhmList is a list of the Full Width at Half Maximum of 

87 each object in arcseconds 

88 

89 @param [in] countList is a list of the counts expected for each object 

90 

91 @param [in] gain is the gain of the detector (electrons per ADU) 

92 

93 @param [in] detector is an instantiation of the afw.cameraGeom Detector 

94 class characterizing the detector corresponding to this image 

95 

96 @param [in] camera is an instantiation of the afw.cameraGeom Camera class 

97 characterizing the camera to which detector belongs 

98 

99 @param [in] obs is an instantiation of ObservationMetaData characterizing 

100 the telescope pointing 

101 

102 @param [in] epoch is the epoch in Julian years of the equinox against which 

103 RA and Dec are measured. 

104 

105 Raises an exception of the counts detected for each object differs from 

106 the expected amount by more than 3 sigma. 

107 """ 

108 

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

110 activePixels = np.where(im > 1.0e-10) 

111 

112 # I know this seems backwards, but the way numpy handles arrays, 

113 # the first index is the row (i.e. the y coordinate) 

114 imXList = activePixels[1] 

115 imYList = activePixels[0] 

116 

117 nameList = [detector.getName()]*len(raList) 

118 xPixList, yPixList = _pixelCoordsFromRaDec(raList, decList, 

119 chipName=nameList, 

120 camera=camera, 

121 obs_metadata=obs, 

122 epoch=epoch) 

123 

124 for rr, dd, xx, yy, fwhm, cc in \ 

125 zip(raList, decList, xPixList, yPixList, fwhmList, countList): 

126 

127 countSigma = np.sqrt(cc/gain) 

128 

129 imNameList = [detector.getName()]*len(imXList) 

130 raImList, decImList = _raDecFromPixelCoords(imXList, imYList, 

131 imNameList, 

132 camera=camera, 

133 obs_metadata=obs, 

134 epoch=epoch) 

135 

136 distanceList = arcsecFromRadians(haversine(raImList, decImList, rr, dd)) 

137 

138 fluxArray = np.array([im[imYList[ix]][imXList[ix]] 

139 for ix in range(len(distanceList)) 

140 if distanceList[ix] < 2.0*fwhm]) 

141 

142 totalFlux = fluxArray.sum() 

143 msg = 'totalFlux %e should be %e diff/sigma %e' \ 

144 % (totalFlux, cc, np.abs(totalFlux-cc)/countSigma) 

145 

146 self.assertLess(np.abs(totalFlux-cc), 3.0*countSigma, msg=msg) 

147 

148 def testObjectPlacement(self): 

149 """ 

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

151 images, reading them in, and then comparing the flux contained in 

152 circles of 2 fwhm radii about the object's expected positions with 

153 the actual expected flux of the objects. 

154 """ 

155 scratchDir = tempfile.mkdtemp(dir=ROOT, prefix='testObjectPlacement-') 

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

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

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

159 

160 cameraDir = os.path.join(getPackageDir('sims_GalSimInterface'), 'tests', 'cameraData') 

161 camera = ReturnCamera(cameraDir) 

162 detector = camera[0] 

163 imageName = '%s_%s_u.fits' % (imageRoot, detector.getName()) 

164 

165 controlSed = Sed() 

166 controlSed.readSED_flambda(os.path.join(getPackageDir('sims_sed_library'), 

167 'flatSED', 'sed_flat.txt.gz')) 

168 

169 uBandpass = Bandpass() 

170 uBandpass.readThroughput(os.path.join(getPackageDir('throughputs'), 

171 'baseline', 'total_u.dat')) 

172 

173 controlBandpass = Bandpass() 

174 controlBandpass.imsimBandpass() 

175 

176 ff = controlSed.calcFluxNorm(self.magNorm, uBandpass) 

177 controlSed.multiplyFluxNorm(ff) 

178 a_int, b_int = controlSed.setupCCM_ab() 

179 controlSed.addDust(a_int, b_int, A_v=0.1, R_v=3.1) 

180 

181 nSamples = 3 

182 rng = np.random.RandomState(42) 

183 pointingRaList = rng.random_sample(nSamples)*360.0 

184 pointingDecList = rng.random_sample(nSamples)*180.0 - 90.0 

185 rotSkyPosList = rng.random_sample(nSamples)*360.0 

186 fwhmList = rng.random_sample(nSamples)*1.0 + 0.3 

187 

188 actualCounts = None 

189 

190 for pointingRA, pointingDec, rotSkyPos, fwhm in \ 

191 zip(pointingRaList, pointingDecList, rotSkyPosList, fwhmList): 

192 

193 obs = ObservationMetaData(pointingRA=pointingRA, 

194 pointingDec=pointingDec, 

195 boundType='circle', 

196 boundLength=4.0, 

197 mjd=49250.0, 

198 rotSkyPos=rotSkyPos) 

199 

200 xDisplacementList = rng.random_sample(nSamples)*60.0-30.0 

201 yDisplacementList = rng.random_sample(nSamples)*60.0-30.0 

202 create_text_catalog(obs, dbFileName, xDisplacementList, yDisplacementList, 

203 mag_norm=[self.magNorm]*len(xDisplacementList)) 

204 db = placementFileDBObj(dbFileName, runtable='test') 

205 cat = placementCatalog(db, obs_metadata=obs) 

206 cat.camera_wrapper = GalSimCameraWrapper(camera) 

207 if actualCounts is None: 

208 actualCounts = controlSed.calcADU(uBandpass, cat.photParams) 

209 

210 psf = SNRdocumentPSF(fwhm=fwhm) 

211 cat.setPSF(psf) 

212 

213 cat.write_catalog(catName) 

214 cat.write_images(nameRoot=imageRoot) 

215 

216 objRaList = [] 

217 objDecList = [] 

218 with open(catName, 'r') as inFile: 

219 for line in inFile: 

220 if line[0] != '#': 

221 words = line.split(';') 

222 objRaList.append(np.radians(np.float(words[2]))) 

223 objDecList.append(np.radians(np.float(words[3]))) 

224 

225 objRaList = np.array(objRaList) 

226 objDecList = np.array(objDecList) 

227 

228 self.assertGreater(len(objRaList), 0) # make sure we aren't testing 

229 # an empty catalog/image 

230 

231 self.check_placement(imageName, objRaList, objDecList, 

232 [fwhm]*len(objRaList), 

233 np.array([actualCounts]*len(objRaList)), 

234 cat.photParams.gain, detector, camera, obs, epoch=2000.0) 

235 

236 if os.path.exists(dbFileName): 

237 os.unlink(dbFileName) 

238 if os.path.exists(catName): 

239 os.unlink(catName) 

240 if os.path.exists(imageName): 

241 os.unlink(imageName) 

242 

243 if os.path.exists(scratchDir): 

244 shutil.rmtree(scratchDir) 

245 

246 

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

248 pass 

249 

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

251 lsst.utils.tests.init() 

252 unittest.main()