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

1import numpy as np 

2import os 

3import unittest 

4import tempfile 

5import shutil 

6import lsst.utils.tests 

7from lsst.utils import getPackageDir 

8import lsst.afw.image as afwImage 

9from lsst.sims.utils.CodeUtilities import sims_clean_up 

10from lsst.sims.utils import ObservationMetaData, radiansFromArcsec, arcsecFromRadians 

11from lsst.sims.utils import haversine 

12from lsst.sims.catalogs.db import fileDBObject 

13from lsst.sims.GalSimInterface import GalSimGalaxies, GalSimRandomWalk 

14from lsst.sims.GalSimInterface import GalSimCameraWrapper 

15from lsst.sims.coordUtils import _raDecFromPixelCoords 

16 

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

18 

19from testUtils import create_text_catalog 

20 

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

22 

23 

24def setup_module(module): 

25 lsst.utils.tests.init() 

26 

27 

28class hlrFileDBObj(fileDBObject): 

29 idColKey = 'test_id' 

30 objectTypeId = 88 

31 tableid = 'test' 

32 raColName = 'ra' 

33 decColName = 'dec' 

34 # sedFilename 

35 

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

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

38 ('halfLightRadius', 'hlr*PI()/648000.0', np.float), 

39 ('magNorm', 'mag_norm', np.float), 

40 ('positionAngle', 'pa*PI()/180.0', np.float)] 

41 

42 

43class hlrCatSersic(GalSimGalaxies): 

44 bandpassNames = ['u'] 

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

46 ('magNorm', 21.0, float), 

47 ('galacticAv', 0.1, float), 

48 ('galacticRv', 3.1, float), 

49 ('galSimType', 'sersic', (str, 11)), 

50 ('internalAv', 0.1, float), 

51 ('internalRv', 3.1, float), 

52 ('redshift', 0.0, float), 

53 ('majorAxis', radiansFromArcsec(1.0), float), 

54 ('minorAxis', radiansFromArcsec(1.0), float), 

55 ('sindex', 4.0, float), 

56 ('npoints', 0, int), 

57 ('gamma1', 0.0, float), 

58 ('gamma2', 0.0, float), 

59 ('kappa', 0.0, float), 

60 ] 

61 

62class hlrCatRandomWalk(GalSimRandomWalk): 

63 bandpassNames = ['u'] 

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

65 ('magNorm', 21.0, float), 

66 ('galacticAv', 0.1, float), 

67 ('galacticRv', 3.1, float), 

68 ('galSimType', 'RandomWalk', (str, 10)), 

69 ('internalAv', 0.1, float), 

70 ('internalRv', 3.1, float), 

71 ('redshift', 0.0, float), 

72 ('majorAxis', radiansFromArcsec(1.0), float), 

73 ('minorAxis', radiansFromArcsec(1.0), float), 

74 ('npoints', 10000, int), 

75 ('sindex', 0.0, float), 

76 ('gamma1', 0.0, float), 

77 ('gamma2', 0.0, float), 

78 ('kappa', 0.0, float), 

79 ] 

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

81class GalSimHlrTest(unittest.TestCase): 

82 

83 @classmethod 

84 def setUpClass(cls): 

85 cls.camera = ReturnCamera(os.path.join(getPackageDir('sims_GalSimInterface'), 

86 'tests', 'cameraData')) 

87 

88 @classmethod 

89 def tearDownClass(cls): 

90 sims_clean_up() 

91 del cls.camera 

92 

93 def get_flux_in_half_light_radius(self, fileName, hlr, detector, camera, obs, epoch=2000.0): 

94 """ 

95 Read in a FITS image. Return the total flux in that image as well as the flux contained 

96 within a specified radius of the maximum pixel of the image. 

97 

98 @param [in] fileName is the name of the FITS file to be read in 

99 

100 @param [in] hlr is the half light radius to be tested (in arc seconds) 

101 

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

103 class characterizing the detector corresponding to this image 

104 

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

106 characterizing the camera to which detector belongs 

107 

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

109 the telescope pointing 

110 

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

112 RA and Dec are measured. 

113 

114 @param [out] totalFlux is the total number of counts in the images 

115 

116 @param [out] measuredHalfFlux is the measured flux within hlr of the maximum pixel 

117 """ 

118 

119 im = afwImage.ImageF(fileName).getArray() 

120 totalFlux = im.sum() 

121 

122 activePoints = np.where(im > 1.0e-10) 

123 self.assertGreater(len(activePoints), 0) 

124 

125 xPixList = activePoints[1] # this looks backwards, but remember: the way numpy handles 

126 yPixList = activePoints[0] # arrays, the first index indicates what row it is in (the y coordinate) 

127 chipNameList = [detector.getName()]*len(xPixList) 

128 

129 # Compute luminosity weighted centroid 

130 xCen = np.sum(im[yPixList, xPixList] * xPixList) / np.sum(im[yPixList, xPixList]) 

131 yCen = np.sum(im[yPixList, xPixList] * yPixList) / np.sum(im[yPixList, xPixList]) 

132 cenPixel = np.array([xCen, yCen]) 

133 

134 raCen, decCen = _raDecFromPixelCoords(cenPixel[0:1], 

135 cenPixel[1:2], 

136 [detector.getName()], 

137 camera=camera, 

138 obs_metadata=obs, 

139 epoch=epoch) 

140 

141 raList, decList = _raDecFromPixelCoords(xPixList, yPixList, chipNameList, 

142 camera=camera, obs_metadata=obs, 

143 epoch=epoch) 

144 

145 distanceList = arcsecFromRadians(haversine(raList, decList, raCen[0], decCen[0])) 

146 

147 dexContained = [ix for ix, dd in enumerate(distanceList) if dd <= hlr] 

148 measuredHalfFlux = np.array([im[yPixList[dex]][xPixList[dex]] for dex in dexContained]).sum() 

149 return totalFlux, measuredHalfFlux 

150 

151 def testHalfLightRadiusOfImageSersic(self): 

152 """ 

153 Test that GalSim is generating images of objects with the expected half light radius 

154 by generating images with one object on them and comparing the total flux in the image 

155 with the flux contained within the expected half light radius. Raise an exception 

156 if the deviation is greater than 3-sigma. 

157 """ 

158 scratchDir = tempfile.mkdtemp(dir=ROOT, prefix='testHalfLightRadiusOfImage-') 

159 catName = os.path.join(scratchDir, 'hlr_test_Catalog.dat') 

160 imageRoot = os.path.join(scratchDir, 'hlr_test_Image') 

161 dbFileName = os.path.join(scratchDir, 'hlr_test_InputCatalog.dat') 

162 

163 detector = self.camera[0] 

164 detName = detector.getName() 

165 imageName = '%s_%s_u.fits' % (imageRoot, detName) 

166 

167 obs = ObservationMetaData(pointingRA = 75.0, 

168 pointingDec = -12.0, 

169 boundType = 'circle', 

170 boundLength = 4.0, 

171 rotSkyPos = 33.0, 

172 mjd = 49250.0) 

173 

174 hlrTestList = [1.0, 2.0, 4.0] 

175 

176 for hlr in hlrTestList: 

177 create_text_catalog(obs, dbFileName, np.array([3.0]), np.array([1.0]), 

178 hlr=[hlr]) 

179 

180 db = hlrFileDBObj(dbFileName, runtable='test') 

181 

182 cat = hlrCatSersic(db, obs_metadata=obs) 

183 cat.camera_wrapper = GalSimCameraWrapper(self.camera) 

184 

185 cat.write_catalog(catName) 

186 cat.write_images(nameRoot=imageRoot) 

187 

188 totalFlux, hlrFlux = self.get_flux_in_half_light_radius(imageName, hlr, detector, self.camera, obs) 

189 self.assertGreater(totalFlux, 1000.0) # make sure the image is not blank 

190 

191 # divide by gain because Poisson stats apply to photons 

192 sigmaFlux = np.sqrt(0.5*totalFlux/cat.photParams.gain) 

193 self.assertLess(np.abs(hlrFlux-0.5*totalFlux), 4.0*sigmaFlux) 

194 

195 if os.path.exists(catName): 

196 os.unlink(catName) 

197 if os.path.exists(dbFileName): 

198 os.unlink(dbFileName) 

199 if os.path.exists(imageName): 

200 os.unlink(imageName) 

201 

202 if os.path.exists(scratchDir): 

203 shutil.rmtree(scratchDir) 

204 

205 def testHalfLightRadiusOfImageRandomWalk(self): 

206 """ 

207 Test that GalSim is generating images of objects with the expected half light radius 

208 by generating images with one object on them and comparing the total flux in the image 

209 with the flux contained within the expected half light radius. Raise an exception 

210 if the deviation is greater than 3-sigma. 

211 """ 

212 scratchDir = tempfile.mkdtemp(dir=ROOT, prefix='testHalfLightRadiusOfImage-') 

213 catName = os.path.join(scratchDir, 'hlr_test_Catalog.dat') 

214 imageRoot = os.path.join(scratchDir, 'hlr_test_Image') 

215 dbFileName = os.path.join(scratchDir, 'hlr_test_InputCatalog.dat') 

216 

217 detector = self.camera[0] 

218 detName = detector.getName() 

219 imageName = '%s_%s_u.fits' % (imageRoot, detName) 

220 

221 obs = ObservationMetaData(pointingRA = 75.0, 

222 pointingDec = -12.0, 

223 boundType = 'circle', 

224 boundLength = 4.0, 

225 rotSkyPos = 33.0, 

226 mjd = 49250.0) 

227 

228 hlrTestList = [1., 2., 4.] 

229 

230 for hlr in hlrTestList: 

231 create_text_catalog(obs, dbFileName, np.array([3.0]), np.array([1.0]), 

232 hlr=[hlr]) 

233 

234 db = hlrFileDBObj(dbFileName, runtable='test') 

235 

236 cat = hlrCatRandomWalk(db, obs_metadata=obs) 

237 cat.camera_wrapper = GalSimCameraWrapper(self.camera) 

238 

239 cat.write_catalog(catName) 

240 cat.write_images(nameRoot=imageRoot) 

241 

242 totalFlux, hlrFlux = self.get_flux_in_half_light_radius(imageName, hlr, detector, self.camera, obs) 

243 self.assertGreater(totalFlux, 1000.0) # make sure the image is not blank 

244 

245 # divide by gain because Poisson stats apply to photons 

246 sigmaFlux = np.sqrt(0.5*totalFlux/cat.photParams.gain) 

247 self.assertLess(np.abs(hlrFlux-0.5*totalFlux), 4.0*sigmaFlux) 

248 

249 if os.path.exists(catName): 

250 os.unlink(catName) 

251 if os.path.exists(dbFileName): 

252 os.unlink(dbFileName) 

253 if os.path.exists(imageName): 

254 os.unlink(imageName) 

255 

256 if os.path.exists(scratchDir): 

257 shutil.rmtree(scratchDir) 

258 

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

260 pass 

261 

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

263 lsst.utils.tests.init() 

264 unittest.main()