Coverage for python/lsst/sims/GalSimInterface/galSimCelestialObject.py : 43%

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 object
2import numpy as np
3from lsst.sims.utils import arcsecFromRadians
5__all__ = ["GalSimCelestialObject"]
7class GalSimCelestialObject(object):
8 """
9 This is a class meant to carry around all of the data required by
10 the GalSimInterpreter to draw an image of a single object. The idea
11 is that all of the drawing functions in the GalSimInterpreter will
12 just take a GalSimCelestialObject as an argument, rather than taking
13 a bunch of different arguments, one for each datum.
14 """
16 def __init__(self, galSimType, xPupil, yPupil,
17 halfLightRadius, minorAxis, majorAxis, positionAngle,
18 sindex, sed, bp_dict, photParams, npoints,
19 fits_image_file, pixel_scale, rotation_angle,
20 gamma1=0, gamma2=0, kappa=0, uniqueId=None):
21 """
22 @param [in] galSimType is a string, either 'pointSource', 'sersic',
23 'RandomWalk', or 'FitsImage' denoting the shape of the object
25 @param [in] xPupil is the x pupil coordinate of the object in radians
27 @param [in] yPupil is the y pupil coordinate of the object in radians
29 @param [in] halfLightRadius is the halfLightRadius of the object in radians
31 @param [in] minorAxis is the semi-minor axis of the object in radians
33 @param [in] majorAxis is the semi-major axis of the object in radians
35 @param [in] positionAngle is the position angle of the object in radians
37 @param [in] sindex is the sersic index of the object
39 @param [in] sed is an instantiation of lsst.sims.photUtils.Sed
40 representing the SED of the object (with all normalization,
41 dust extinction, redshifting, etc. applied)
43 @param [in] bp_dict is an instantiation of lsst.sims.photUtils.BandpassDict
44 representing the bandpasses of this telescope
46 @param [in] photParams is an instantioation of
47 lsst.sims.photUtils.PhotometricParameters representing the physical
48 parameters of the telescope that inform simulated photometry
50 Together, sed, bp_dict, and photParams will be used to create
51 a dict that maps bandpass name to electron counts for this
52 celestial object.
54 @param [in] npoints is the number of point sources in a RandomWalk
56 @param [in] fits_image_file is the filename for the FitsImage
58 @param [in] pixel_scale is the pixel size in arcsec of the FitsImage
60 @param [in] rotation_angle is the rotation angle in degrees for
61 the FitsImage
63 @param [in] gamma1 is the real part of the WL shear parameter
65 @param [in] gamma2 is the imaginary part of the WL shear parameter
67 @param [in] kappa is the WL convergence parameter
69 @param [in] uniqueId is an int storing a unique identifier for this object
70 """
71 self._uniqueId = uniqueId
72 self._galSimType = galSimType
73 self._fits_image_file = fits_image_file
75 # The galsim.lens(...) function wants to be passed reduced
76 # shears and magnification, so convert the WL parameters as
77 # defined in phosim instance catalogs to these values. See
78 # https://github.com/GalSim-developers/GalSim/blob/releases/1.4/doc/GalSim_Quick_Reference.pdf
79 # and Hoekstra, 2013, http://lanl.arxiv.org/abs/1312.5981
80 g1 = gamma1/(1. - kappa) # real part of reduced shear
81 g2 = gamma2/(1. - kappa) # imaginary part of reduced shear
82 mu = 1./((1. - kappa)**2 - (gamma1**2 + gamma2**2)) # magnification
84 self._fluxDict = {}
85 self._sed = sed
86 self._bp_dict = bp_dict
87 self._photParams = photParams
89 # Put all the float values into a numpy array for better memory usage.
90 # (Otherwise, python allocates a shared pointer for each one of these 15 values, which
91 # adds up to a significant memory overhead.)
92 self._float_values = np.array([
93 xPupil, # xPupilRadians, 0
94 arcsecFromRadians(xPupil), # xPupilArcsec, 1
95 yPupil, # yPupilRadians, 2
96 arcsecFromRadians(yPupil), # yPupilArcsec, 3
97 halfLightRadius, # halfLightRadiusRadians, 4
98 arcsecFromRadians(halfLightRadius), # halfLightRadiusArcsec, 5
99 minorAxis, # minorAxisRadians, 6
100 majorAxis, # majorAxisRadians, 7
101 positionAngle, # positionAngleRadians, 8
102 sindex, # sindex, 9
103 pixel_scale, # pixel_scale, 10
104 rotation_angle, # rotation_angle, 11
105 g1, # g1, 12
106 g2, # g2, 13
107 mu, # mu, 14
108 npoints # npoints, 15
109 ], dtype=float)
111 # XXX: We could probably get away with np.float32 for these, but the main
112 # advantage is from only allocating the actual memory, and not the python
113 # pointers to the memory. So not so much more gain to be had from switching
114 # to single precision.
116 #
117 # First properties for all the non-float values.
118 #
120 @property
121 def sed(self):
122 return self._sed
124 @property
125 def uniqueId(self):
126 return self._uniqueId
128 # XXX: I'd recommend removing all these setters and just let python raise an
129 # AttributeError if people try to set the values, rather than raising a
130 # RuntimeError manually. -- MJ
131 @uniqueId.setter
132 def uniqueId(self, value):
133 raise RuntimeError("You should not be setting the unique id on the fly; " \
134 + "just instantiate a new GalSimCelestialObject")
136 @property
137 def galSimType(self):
138 return self._galSimType
140 @galSimType.setter
141 def galSimType(self, value):
142 raise RuntimeError("You should not be setting galSimType on the fly; " \
143 + "just instantiate a new GalSimCelestialObject")
145 @property
146 def npoints(self):
147 return int(self._float_values[15]+0.5)
149 @npoints.setter
150 def npoints(self, value):
151 raise RuntimeError("You should not be setting npoints on the fly; " \
152 + "just instantiate a new GalSimCelestialObject")
154 @property
155 def fits_image_file(self):
156 return self._fits_image_file
158 @fits_image_file.setter
159 def fits_image_file(self, value):
160 raise RuntimeError("You should not be setting fits_image_file on the fly; "
161 "just instantiate a new GalSimCelestialObject")
164 #
165 # The float values are accessed from the numpy array called self._float_values.
166 #
168 @property
169 def xPupilRadians(self):
170 return self._float_values[0]
172 @xPupilRadians.setter
173 def xPupilRadians(self, value):
174 raise RuntimeError("You should not be setting xPupilRadians on the fly; " \
175 + "just instantiate a new GalSimCelestialObject")
178 @property
179 def xPupilArcsec(self):
180 return self._float_values[1]
182 @xPupilArcsec.setter
183 def xPupilArcsec(self, value):
184 raise RuntimeError("You should not be setting xPupilArcsec on the fly; " \
185 + "just instantiate a new GalSimCelestialObject")
188 @property
189 def yPupilRadians(self):
190 return self._float_values[2]
192 @yPupilRadians.setter
193 def yPupilRadians(self, value):
194 raise RuntimeError("You should not be setting yPupilRadians on the fly; " \
195 + "just instantiate a new GalSimCelestialObject")
198 @property
199 def yPupilArcsec(self):
200 return self._float_values[3]
202 @yPupilArcsec.setter
203 def yPupilArcsec(self, value):
204 raise RuntimeError("You should not be setting yPupilArcsec on the fly; " \
205 + "just instantiate a new GalSimCelestialObject")
208 @property
209 def halfLightRadiusRadians(self):
210 return self._float_values[4]
212 @halfLightRadiusRadians.setter
213 def halfLightRadiusRadians(self, value):
214 raise RuntimeError("You should not be setting halfLightRadiusRadians on the fly; " \
215 + "just instantiate a new GalSimCelestialObject")
218 @property
219 def halfLightRadiusArcsec(self):
220 return self._float_values[5]
222 @halfLightRadiusArcsec.setter
223 def halfLightRadiusArcsec(self, value):
224 raise RuntimeError("You should not be setting halfLightRadiusArcsec on the fly; " \
225 + "just instantiate a new GalSimCelestialObject")
228 @property
229 def minorAxisRadians(self):
230 return self._float_values[6]
232 @minorAxisRadians.setter
233 def minorAxisRadians(self, value):
234 raise RuntimeError("You should not be setting minorAxisRadians on the fly; " \
235 + "just instantiate a new GalSimCelestialObject")
238 @property
239 def majorAxisRadians(self):
240 return self._float_values[7]
242 @majorAxisRadians.setter
243 def majorAxisRadians(self, value):
244 raise RuntimeError("You should not be setting majorAxisRadians on the fly; " \
245 + "just instantiate a new GalSimCelestialObject")
248 @property
249 def positionAngleRadians(self):
250 return self._float_values[8]
252 @positionAngleRadians.setter
253 def positionAngleRadians(self, value):
254 raise RuntimeError("You should not be setting positionAngleRadians on the fly; " \
255 + "just instantiate a new GalSimCelestialObject")
258 @property
259 def sindex(self):
260 return self._float_values[9]
262 @sindex.setter
263 def sindex(self, value):
264 raise RuntimeError("You should not be setting sindex on the fly; " \
265 + "just instantiate a new GalSimCelestialObject")
267 @property
268 def pixel_scale(self):
269 return self._float_values[10]
271 @pixel_scale.setter
272 def pixel_scale(self, value):
273 raise RuntimeError("You should not be setting pixel_scale on the fly; "
274 "just instantiate a new GalSimCelestialObject")
276 @property
277 def rotation_angle(self):
278 return self._float_values[11]
280 @rotation_angle.setter
281 def rotation_angle(self, value):
282 raise RuntimeError("You should not be setting rotation_angle on the fly; "
283 "just instantiate a new GalSimCelestialObject")
285 @property
286 def g1(self):
287 return self._float_values[12]
289 @g1.setter
290 def g1(self, value):
291 raise RuntimeError("You should not be setting g1 on the fly; " \
292 + "just instantiate a new GalSimCelestialObject")
295 @property
296 def g2(self):
297 return self._float_values[13]
299 @g2.setter
300 def g2(self, value):
301 raise RuntimeError("You should not be setting g2 on the fly; " \
302 + "just instantiate a new GalSimCelestialObject")
305 @property
306 def mu(self):
307 return self._float_values[14]
309 @mu.setter
310 def mu(self, value):
311 raise RuntimeError("You should not be setting mu on the fly; " \
312 + "just instantiate a new GalSimCelestialObject")
316 def flux(self, band):
317 """
318 @param [in] band is the name of a bandpass
320 @param [out] the ADU in that bandpass, as stored in self._fluxDict
321 """
322 if band not in self._bp_dict:
323 raise RuntimeError("Asked GalSimCelestialObject for flux in %s; that band does not exist" % band)
325 if band not in self._fluxDict:
326 adu = self.sed.calcADU(self._bp_dict[band], self._photParams)
327 self._fluxDict[band] = adu*self._photParams.gain
329 return self._fluxDict[band]