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

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

from builtins import zip 

import numpy as np 

import os 

import unittest 

import tempfile 

import shutil 

import lsst.utils.tests 

from lsst.utils import getPackageDir 

import lsst.afw.image as afwImage 

from lsst.sims.utils.CodeUtilities import sims_clean_up 

from lsst.sims.utils import ObservationMetaData, radiansFromArcsec 

from lsst.sims.catalogs.db import fileDBObject 

from lsst.sims.GalSimInterface import GalSimGalaxies 

from lsst.sims.GalSimInterface import GalSimCameraWrapper 

from lsst.sims.coordUtils import _raDecFromPixelCoords 

 

#afrom lsst.sims.coordUtils.utils import ReturnCamera 

 

from testUtils import create_text_catalog 

 

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

 

 

def setup_module(module): 

lsst.utils.tests.init() 

 

 

class paFileDBObj(fileDBObject): 

idColKey = 'test_id' 

objectTypeId = 88 

tableid = 'test' 

raColName = 'ra' 

decColName = 'dec' 

# sedFilename 

 

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

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

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

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

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

 

 

class paCat(GalSimGalaxies): 

bandpassNames = ['u'] 

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

('magNorm', 21.0, float), 

('galacticAv', 0.1, float), 

('galacticRv', 3.1, float), 

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

('internalAv', 0.1, float), 

('internalRv', 3.1, float), 

('redshift', 0.0, float), 

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

('minorAxis', radiansFromArcsec(0.5), float), 

('sindex', 4.0, float), 

('npoints', 0, int), 

('gamma1', 0.0, float), 

('gamma2', 0.0, float), 

('kappa', 0.0, float), 

] 

 

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

class GalSimPositionAngleTest(unittest.TestCase): 

 

@classmethod 

def tearDownClass(cls): 

sims_clean_up() 

 

def get_position_angle(self, imageName, afwCamera, afwDetector, 

obs_metadata, epoch): 

""" 

Read in a FITS image containing one extended object. 

 

Determine its north and east axes by examining how RA and Dec change 

with pixel position. 

 

Determine the semi-major axis of the object by treating the distribution 

of flux as a covariance matrix and finding its eigen vectors. 

 

Return the angle between the semi-major axis and the north axis of 

the image 

 

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

 

@param [in] afwCamera is an afw.cameraGeom.Camera 

 

@param [in] afwDetector is an afw.cameraGeom.Detector 

 

@param [in] obs_metadata is an ObservationMetaData describing the 

pointing of the telescope 

 

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

which RA and Dec are measured 

 

@param [out] the position angle of the object in the image in degrees 

""" 

 

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

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

self.assertGreater(len(activePixels), 0) 

xPixList = activePixels[1] 

yPixList = activePixels[0] 

 

xCenterPix = np.array([im.shape[1]/2]) 

yCenterPix = np.array([im.shape[0]/2]) 

 

raCenter, decCenter = _raDecFromPixelCoords(xCenterPix, yCenterPix, 

[afwDetector.getName()], 

camera=afwCamera, 

obs_metadata=obs_metadata, 

epoch=epoch) 

 

xCenterP1 = xCenterPix+1 

yCenterP1 = yCenterPix+1 

raCenterP1, decCenterP1 = _raDecFromPixelCoords(xCenterP1, yCenterP1, 

[afwDetector.getName()], 

camera=afwCamera, 

obs_metadata=obs_metadata, 

epoch=epoch) 

 

# find the angle between the (1,1) vector in pixel space and the 

# north axis of the image 

theta = np.arctan2((raCenterP1[0]-raCenter[0]), decCenterP1[0]-decCenter[0]) 

 

# rotate the (1,1) vector in pixel space so that it is pointing 

# along the north axis 

north = np.array([np.cos(theta)-np.sin(theta), np.cos(theta)+np.sin(theta)]) 

north = north/np.sqrt(north[0]*north[0]+north[1]*north[1]) 

 

# find the east axis of the image 

east = np.array([north[1], -1.0*north[0]]) 

 

# now find the covariance matrix of the x, y pixel space distribution 

# of flux on the image 

maxPixel = np.array([im.argmax()%im.shape[1], im.argmax()/im.shape[1]]) 

 

xx = np.array([im[iy][ix]*np.power(ix-maxPixel[0], 2) 

for ix, iy in zip(xPixList, yPixList)]).sum() 

 

xy = np.array([im[iy][ix]*(ix-maxPixel[0])*(iy-maxPixel[1]) 

for ix, iy in zip(xPixList, yPixList)]).sum() 

 

yy = np.array([im[iy][ix]*(iy-maxPixel[1])*(iy-maxPixel[1]) 

for ix, iy in zip(xPixList, yPixList)]).sum() 

 

covar = np.array([[xx, xy], [xy, yy]]) 

 

# find the eigen vectors of this covarinace matrix; 

# treat the one with the largest eigen value as the 

# semi-major axis of the object 

eigenVals, eigenVecs = np.linalg.eig(covar) 

 

iMax = eigenVals.argmax() 

majorAxis = eigenVecs[:, iMax] 

 

majorAxis = majorAxis/np.sqrt(majorAxis[0]*majorAxis[0]+majorAxis[1]*majorAxis[1]) 

 

# return the angle between the north axis of the image 

# and the semi-major axis of the object 

cosTheta = np.dot(majorAxis, north) 

sinTheta = np.dot(majorAxis, east) 

 

theta = np.arctan2(sinTheta, cosTheta) 

 

return np.degrees(theta) 

 

def testPositionAngle(self): 

""" 

Test that GalSim is generating images with the correct position angle 

by creating a FITS image with one extended source in it. Measure 

the angle between the semi-major axis of the source and the north 

axis of the image. Throw an exception if that angle differs 

from the expected position angle by more than 2 degrees. 

""" 

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

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

imageRoot = os.path.join(scratchDir, 'pa_test_Image') 

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

 

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

camera = ReturnCamera(baseDir) 

detector = camera[0] 

detName = detector.getName() 

 

rng = np.random.RandomState(42) 

paList = rng.random_sample(7)*360.0 

rotSkyPosList = rng.random_sample(77)*360.0 

 

for pa, rotSkyPos in zip(paList, rotSkyPosList): 

 

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

 

obs = ObservationMetaData(pointingRA = 75.0, 

pointingDec = -12.0, 

boundType = 'circle', 

boundLength = 4.0, 

rotSkyPos = rotSkyPos, 

mjd = 49250.0) 

 

create_text_catalog(obs, dbFileName, 

rng.random_sample(1)*20.0-10.0, 

rng.random_sample(1)*20.0-10.0, 

pa=[pa], 

mag_norm=[17.0]) 

 

db = paFileDBObj(dbFileName, runtable='test') 

 

cat = paCat(db, obs_metadata=obs) 

cat.camera_wrapper = GalSimCameraWrapper(camera) 

 

cat.write_catalog(catName) 

cat.write_images(nameRoot=imageRoot) 

 

paTest = self.get_position_angle(imageName, camera, detector, obs, 2000.0) 

 

# need to compare against all angles displaced by either 180 or 360 degrees 

# from expected answer 

deviation = np.abs(np.array([pa-paTest, 

pa-180.0-paTest, 

pa+180.0-paTest, 

pa-360.0-paTest, 

pa+360.0-paTest])).min() 

 

self.assertLess(deviation, 3.0) 

 

if os.path.exists(catName): 

os.unlink(catName) 

if os.path.exists(dbFileName): 

os.unlink(dbFileName) 

if os.path.exists(imageName): 

os.unlink(imageName) 

 

if os.path.exists(scratchDir): 

shutil.rmtree(scratchDir) 

 

 

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

pass 

 

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

lsst.utils.tests.init() 

unittest.main()