Galaxy.py 19.4 KB
Newer Older
Fang Yuedong's avatar
Fang Yuedong committed
1
2
3
4
5
6
7
import numpy as np
import galsim
import os, sys
import astropy.constants as cons
from astropy.table import Table
from scipy import interpolate

8
9
10
11
from ObservationSim.MockObject._util import eObs, integrate_sed_bandpass, getNormFactorForSpecWithABMAG, getObservedSED, getABMAG,convolveGaussXorders
from ObservationSim.MockObject.SpecDisperser import SpecDisperser
from ObservationSim.MockObject.MockObject import MockObject

Fang Yuedong's avatar
Fang Yuedong committed
12
13
# import tracemalloc

Fang Yuedong's avatar
Fang Yuedong committed
14
class Galaxy(MockObject):
15
    def __init__(self, param, logger=None):
16
        super().__init__(param, logger=logger)
Fang Yuedong's avatar
Fang Yuedong committed
17
18
19
20
        # self.thetaR = self.param["theta"]
        # self.bfrac = self.param["bfrac"]
        # self.hlr_disk = self.param["hlr_disk"]
        # self.hlr_bulge = self.param["hlr_bulge"]
Fang Yuedong's avatar
Fang Yuedong committed
21
22

        # Extract ellipticity components
Fang Yuedong's avatar
Fang Yuedong committed
23
24
25
26
27
28
        # self.e_disk = galsim.Shear(g=self.param["ell_disk"], beta=self.thetaR*galsim.degrees)
        # self.e_bulge = galsim.Shear(g=self.param["ell_bulge"], beta=self.thetaR*galsim.degrees)
        # self.e_total = galsim.Shear(g=self.param["ell_tot"], beta=self.thetaR*galsim.degrees)
        # self.e1_disk, self.e2_disk = self.e_disk.g1, self.e_disk.g2
        # self.e1_bulge, self.e2_bulge = self.e_bulge.g1, self.e_bulge.g2
        # self.e1_total, self.e2_total = self.e_total.g1, self.e_total.g2
Fang Yuedong's avatar
Fang Yuedong committed
29

Fang Yuedong's avatar
Fang Yuedong committed
30
31
32
33
        if not hasattr(self, "disk_sersic_idx"):
            self.disk_sersic_idx = 1.
        if not hasattr(self, "bulge_sersic_idx"):
            self.bulge_sersic_idx = 4.
Fang Yuedong's avatar
Fang Yuedong committed
34
35
36
37
38
39

    def unload_SED(self):
        """(Test) free up SED memory
        """
        del self.sed

Fang Yuedong's avatar
Fang Yuedong committed
40
    def getGSObj_multiband(self, tel, psf_list, bandpass_list, filt, nphotons_tot=None, g1=0, g2=0, exptime=150., fd_shear=None):
Fang Yuedong's avatar
Fang Yuedong committed
41
42
43
44
45
46
47
48
49
50
51
        if len(psf_list) != len(bandpass_list):
            raise ValueError("!!!The number of PSF profiles and the number of bandpasses must be equal.")
        objs = []
        if nphotons_tot == None:
            nphotons_tot = self.getElectronFluxFilt(filt, tel, exptime)
        # print("nphotons_tot = ", nphotons_tot)

        try:
            full = integrate_sed_bandpass(sed=self.sed, bandpass=filt.bandpass_full)
        except Exception as e:
            print(e)
52
53
            if self.logger:
                self.logger.error(e)
Fang Yuedong's avatar
Fang Yuedong committed
54
55
56
57
58
59
60
            return -1
        for i in range(len(bandpass_list)):
            bandpass = bandpass_list[i]
            try:
                sub = integrate_sed_bandpass(sed=self.sed, bandpass=bandpass)
            except Exception as e:
                print(e)
61
62
                if self.logger:
                    self.logger.error(e)
Fang Yuedong's avatar
Fang Yuedong committed
63
64
65
66
67
68
69
70
71
                return -1
            
            ratio = sub/full
            if not (ratio == -1 or (ratio != ratio)):
                nphotons = ratio * nphotons_tot
            else:
                return -1

            psf = psf_list[i]
Fang Yuedong's avatar
Fang Yuedong committed
72
            disk = galsim.Sersic(n=self.disk_sersic_idx, half_light_radius=self.hlr_disk, flux=1.0)
Fang Yuedong's avatar
Fang Yuedong committed
73
74
            disk_shape = galsim.Shear(g1=self.e1_disk, g2=self.e2_disk)
            disk = disk.shear(disk_shape)
Fang Yuedong's avatar
Fang Yuedong committed
75
            bulge = galsim.Sersic(n=self.bulge_sersic_idx, half_light_radius=self.hlr_bulge, flux=1.0)
Fang Yuedong's avatar
Fang Yuedong committed
76
77
78
79
80
            bulge_shape = galsim.Shear(g1=self.e1_bulge, g2=self.e2_bulge)
            bulge = bulge.shear(bulge_shape)

            gal = self.bfrac * bulge + (1.0 - self.bfrac) * disk
            gal = gal.withFlux(nphotons)
81
82
83
            if fd_shear is not None:
                g1 += fd_shear.g1
                g2 += fd_shear.g2
Fang Yuedong's avatar
Fang Yuedong committed
84
85
86
            gal_shear = galsim.Shear(g1=g1, g2=g2)
            gal = gal.shear(gal_shear)
            gal = galsim.Convolve(psf, gal)
Fang Yuedong's avatar
Fang Yuedong committed
87
            
Fang Yuedong's avatar
Fang Yuedong committed
88
89
90
91
            objs.append(gal)
        final = galsim.Sum(objs)
        return final

Fang Yuedong's avatar
Fang Yuedong committed
92
    def drawObj_multiband(self, tel, pos_img, psf_model, bandpass_list, filt, chip, nphotons_tot=None, g1=0, g2=0, exptime=150., fd_shear=None):
Fang Yuedong's avatar
Fang Yuedong committed
93
94
95
96
97
98
99
100
        if nphotons_tot == None:
            nphotons_tot = self.getElectronFluxFilt(filt, tel, exptime)
        # print("nphotons_tot = ", nphotons_tot)

        try:
            full = integrate_sed_bandpass(sed=self.sed, bandpass=filt.bandpass_full)
        except Exception as e:
            print(e)
101
102
            if self.logger:
                self.logger.error(e)
Fang Yuedong's avatar
Fang Yuedong committed
103
            return 2, None
Fang Yuedong's avatar
Fang Yuedong committed
104
105
106
107

        nphotons_sum = 0
        photons_list = []
        xmax, ymax = 0, 0
Fang Yuedong's avatar
Fang Yuedong committed
108
109
        
        # # [C6 TEST]
Fang Yuedong's avatar
Fang Yuedong committed
110
        # print('hlr_disk = %.4f, hlr_bulge = %.4f'%(self.hlr_disk, self.hlr_bulge))
Fang Yuedong's avatar
Fang Yuedong committed
111
112
        # tracemalloc.start()

Fang Yuedong's avatar
Fang Yuedong committed
113
        big_galaxy = False
Fang Yuedong's avatar
Fang Yuedong committed
114
        if self.hlr_disk > 3.0 or self.hlr_bulge > 3.0: # Very big galaxy
Fang Yuedong's avatar
Fang Yuedong committed
115
116
117
118
119
120
121
122
123
            big_galaxy = True

        # (TEST) Galsim Parameters
        if self.getMagFilter(filt) <= 15 and (not big_galaxy):
            folding_threshold = 5.e-4
        else:
            folding_threshold = 5.e-3
        gsp = galsim.GSParams(folding_threshold=folding_threshold)

xin's avatar
xin committed
124
125
126
127
128
129
130
131
132
133
134
135
        self.real_pos = self.getRealPos(chip.img, global_x=self.posImg.x, global_y=self.posImg.y,
                                        img_real_wcs=self.real_wcs)

        x, y = self.real_pos.x + 0.5, self.real_pos.y + 0.5
        x_nominal = int(np.floor(x + 0.5))
        y_nominal = int(np.floor(y + 0.5))
        dx = x - x_nominal
        dy = y - y_nominal
        offset = galsim.PositionD(dx, dy)

        real_wcs_local = self.real_wcs.local(self.real_pos)

136
137
138
139
140
141
        disk = galsim.Sersic(n=self.disk_sersic_idx, half_light_radius=self.hlr_disk, flux=1.0, gsparams=gsp)
        disk_shape = galsim.Shear(g1=self.e1_disk, g2=self.e2_disk)
        disk = disk.shear(disk_shape)
        bulge = galsim.Sersic(n=self.bulge_sersic_idx, half_light_radius=self.hlr_bulge, flux=1.0, gsparams=gsp)
        bulge_shape = galsim.Shear(g1=self.e1_bulge, g2=self.e2_bulge)
        bulge = bulge.shear(bulge_shape)
142
143
144
145
146
        
        if fd_shear:
            g1 += fd_shear.g1
            g2 += fd_shear.g2
        gal_shear = galsim.Shear(g1=g1, g2=g2)
147

Fang Yuedong's avatar
Fang Yuedong committed
148
149
150
151
152
153
154
        for i in range(len(bandpass_list)):
            bandpass = bandpass_list[i]

            try:
                sub = integrate_sed_bandpass(sed=self.sed, bandpass=bandpass)
            except Exception as e:
                print(e)
155
156
                if self.logger:
                    self.logger.error(e)
Fang Yuedong's avatar
Fang Yuedong committed
157
158
159
160
161
162
163
164
165
                # return False
                continue
            
            ratio = sub/full
            if not (ratio == -1 or (ratio != ratio)):
                nphotons = ratio * nphotons_tot
            else:
                continue
            nphotons_sum += nphotons
Fang Yuedong's avatar
Fang Yuedong committed
166
167

            # # [C6 TEST]
Fang Yuedong's avatar
Fang Yuedong committed
168
169
170
            # print("nphotons_sub-band_%d = %.2f"%(i, nphotons))

            psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img, bandpass=bandpass, folding_threshold=folding_threshold)
171
172
            
            gal_temp = self.bfrac * bulge + (1.0 - self.bfrac) * disk
173
            gal_temp = gal_temp.shear(gal_shear)
Fang Yuedong's avatar
Fang Yuedong committed
174

175
176
177
178
179
180
181
182
            gal_temp = gal_temp.withFlux(nphotons)
            if not big_galaxy: # Not apply PSF for very big galaxy
                gal_temp = galsim.Convolve(psf, gal_temp)
            
            if i == 0:
                gal = gal_temp
            else:
                gal = gal + gal_temp
Fang Yuedong's avatar
Fang Yuedong committed
183

Fang Yuedong's avatar
Fang Yuedong committed
184
            # (TEST) Random knots
185
186
187
            # knots = galsim.RandomKnots(npoints=100, profile=disk)
            # kfrac = np.random.random()*(1.0 - self.bfrac)
            # gal = self.bfrac * bulge + (1.0 - self.bfrac - kfrac) * disk + kfrac * knots
Fang Yuedong's avatar
Fang Yuedong committed
188

Fang Yuedong's avatar
Fang Yuedong committed
189
        # # [C6 TEST]
Fang Yuedong's avatar
Fang Yuedong committed
190
        # print('xmax = %d, ymax = %d '%(xmax, ymax))
Fang Yuedong's avatar
Fang Yuedong committed
191
192
193
194
195
        # # Output memory usage
        # snapshot = tracemalloc.take_snapshot()
        # top_stats = snapshot.statistics('lineno')
        # for stat in top_stats[:10]:
        #     print(stat)
196
197
198
199
200
201
202

        stamp = gal.drawImage(wcs=real_wcs_local, method='phot', offset=offset, save_photons=True)
        photons = stamp.photons
        photons.x += x_nominal
        photons.y += y_nominal
        photons_list.append(photons)

xin's avatar
xin committed
203
204
205
        stamp.wcs = real_wcs_local
        stamp.setCenter(x_nominal, y_nominal)
        bounds = stamp.bounds & galsim.BoundsI(0, chip.npix_x - 1, 0, chip.npix_y - 1)
Fang Yuedong's avatar
Fang Yuedong committed
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

        if bounds.area() > 0:
            chip.img.setOrigin(0, 0)
            stamp[bounds] = chip.img[bounds]

            if not big_galaxy:
                for i in range(len(photons_list)):
                    if i == 0:
                        chip.sensor.accumulate(photons_list[i], stamp)
                    else:
                        chip.sensor.accumulate(photons_list[i], stamp, resume=True)
            else:
                sensor = galsim.Sensor()
                for i in range(len(photons_list)):
                    if i == 0:
                        sensor.accumulate(photons_list[i], stamp)
                    else:
                        sensor.accumulate(photons_list[i], stamp, resume=True)
                del sensor

            chip.img[bounds] = stamp[bounds]

            chip.img.setOrigin(chip.bound.xmin, chip.bound.ymin)
Fang Yuedong's avatar
Fang Yuedong committed
229
        else:
Fang Yuedong's avatar
Fang Yuedong committed
230
231
            # Return code 0: object photons missed this detector
            print("obj %s missed"%(self.id))
232
233
            if self.logger:
                self.logger.info("obj %s missed"%(self.id))
Fang Yuedong's avatar
Fang Yuedong committed
234
235
236
237
            return 0, pos_shear
        
        # # [C6 TEST]
        # print("nphotons_sum = ", nphotons_sum)
Fang Yuedong's avatar
Fang Yuedong committed
238
239
        del photons_list
        del stamp
Fang Yuedong's avatar
Fang Yuedong committed
240
        return 1, pos_shear
Fang Yuedong's avatar
Fang Yuedong committed
241
242

    def drawObj_slitless(self, tel, pos_img, psf_model, bandpass_list, filt, chip, nphotons_tot=None, g1=0, g2=0,
Fang Yuedong's avatar
Fang Yuedong committed
243
244
245
246
247
248
249
250
251
252
253
                         exptime=150., normFilter=None, grating_split_pos=3685, fd_shear=None):
        if normFilter is not None:
            norm_thr_rang_ids = normFilter['SENSITIVITY'] > 0.001
            sedNormFactor = getNormFactorForSpecWithABMAG(ABMag=self.param['mag_use_normal'], spectrum=self.sed,
                                                        norm_thr=normFilter,
                                                        sWave=np.floor(normFilter[norm_thr_rang_ids][0][0]),
                                                        eWave=np.ceil(normFilter[norm_thr_rang_ids][-1][0]))
            if sedNormFactor == 0:
                return 2, None
        else:
            sedNormFactor = 1.
Fang Yuedong's avatar
Fang Yuedong committed
254
255
256
        normalSED = Table(np.array([self.sed['WAVELENGTH'], self.sed['FLUX'] * sedNormFactor]).T,
                          names=('WAVELENGTH', 'FLUX'))

xin's avatar
xin committed
257
258
259
260
261
262
263
264
265
266
267
268
269
        self.real_pos = self.getRealPos(chip.img, global_x=self.posImg.x, global_y=self.posImg.y,
                                        img_real_wcs=self.real_wcs)

        x, y = self.real_pos.x + 0.5, self.real_pos.y + 0.5
        x_nominal = int(np.floor(x + 0.5))
        y_nominal = int(np.floor(y + 0.5))
        dx = x - x_nominal
        dy = y - y_nominal
        offset = galsim.PositionD(dx, dy)

        real_wcs_local = self.real_wcs.local(self.real_pos)


Fang Yuedong's avatar
Fang Yuedong committed
270
        big_galaxy = False
Fang Yuedong's avatar
Fang Yuedong committed
271
        if self.hlr_disk > 3.0 or self.hlr_bulge > 3.0: # Very big galaxy
Fang Yuedong's avatar
Fang Yuedong committed
272
273
274
275
276
277
278
279
            big_galaxy = True

        if self.getMagFilter(filt) <= 15 and (not big_galaxy):
            folding_threshold = 5.e-4
        else:
            folding_threshold = 5.e-3
        gsp = galsim.GSParams(folding_threshold=folding_threshold)
        # nphotons_sum = 0
280
281
282

        flat_cube = chip.flat_cube

Zhang Xin's avatar
Zhang Xin committed
283
        xOrderSigPlus = {'A':1.3909419820029296,'B':1.4760376591236062,'C':4.035447379743442,'D':5.5684364343742825,'E':16.260021029735388}
xin's avatar
xin committed
284
        grating_split_pos_chip = 0 + grating_split_pos
Fang Yuedong's avatar
Fang Yuedong committed
285
286
287
288
        for i in range(len(bandpass_list)):
            bandpass = bandpass_list[i]

            psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img, bandpass=bandpass, folding_threshold=folding_threshold)
Fang Yuedong's avatar
Fang Yuedong committed
289
            disk = galsim.Sersic(n=self.disk_sersic_idx, half_light_radius=self.hlr_disk, flux=1.0, gsparams=gsp)
Fang Yuedong's avatar
Fang Yuedong committed
290
291
            disk_shape = galsim.Shear(g1=self.e1_disk, g2=self.e2_disk)
            disk = disk.shear(disk_shape)
Fang Yuedong's avatar
Fang Yuedong committed
292
            bulge = galsim.Sersic(n=self.bulge_sersic_idx, half_light_radius=self.hlr_bulge, flux=1.0, gsparams=gsp)
Fang Yuedong's avatar
Fang Yuedong committed
293
294
295
            bulge_shape = galsim.Shear(g1=self.e1_bulge, g2=self.e2_bulge)
            bulge = bulge.shear(bulge_shape)

296
            gal = self.bfrac * bulge + (1.0 - self.bfrac) * disk
Fang Yuedong's avatar
Fang Yuedong committed
297
298

            # (TEST) Random knots
299
300
301
            # knots = galsim.RandomKnots(npoints=100, profile=disk)
            # kfrac = np.random.random()*(1.0 - self.bfrac)
            # gal = self.bfrac * bulge + (1.0 - self.bfrac - kfrac) * disk + kfrac * knots
Fang Yuedong's avatar
Fang Yuedong committed
302

Fang Yuedong's avatar
Fang Yuedong committed
303
            gal = gal.withFlux(tel.pupil_area * exptime)
304
305
306
            if fd_shear:
                g1 += fd_shear.g1
                g2 += fd_shear.g2
Fang Yuedong's avatar
Fang Yuedong committed
307
308
309
310
            gal_shear = galsim.Shear(g1=g1, g2=g2)
            gal = gal.shear(gal_shear)
            gal = galsim.Convolve(psf, gal)

Fang Yuedong's avatar
Fang Yuedong committed
311
312
            if not big_galaxy: # Not apply PSF for very big galaxy
                gal = galsim.Convolve(psf, gal)
313
314
                # if fd_shear is not None:
                #     gal = gal.shear(fd_shear)
Fang Yuedong's avatar
Fang Yuedong committed
315
316

            starImg = gal.drawImage(wcs=real_wcs_local, offset=offset)
Fang Yuedong's avatar
Fang Yuedong committed
317

xin's avatar
xin committed
318
319
            origin_star = [y_nominal - (starImg.center.y - starImg.ymin),
                           x_nominal - (starImg.center.x - starImg.xmin)]
Fang Yuedong's avatar
Fang Yuedong committed
320
            starImg.setOrigin(0, 0)
Xin Zhang's avatar
Xin Zhang committed
321
322
323
324
325
326
327
328
329
            gal_origin = [origin_star[0], origin_star[1]]
            gal_end = [origin_star[0] + starImg.array.shape[0] - 1, origin_star[1] + starImg.array.shape[1] - 1]

            if gal_origin[1] < grating_split_pos_chip < gal_end[1]:
                subSlitPos = int(grating_split_pos_chip - gal_origin[1] + 1)
                ## part img disperse

                subImg_p1 = starImg.array[:, 0:subSlitPos]
                star_p1 = galsim.Image(subImg_p1)
Fang Yuedong's avatar
Fang Yuedong committed
330
                star_p1.setOrigin(0, 0)
Xin Zhang's avatar
Xin Zhang committed
331
                origin_p1 = origin_star
xin's avatar
xin committed
332
333
                xcenter_p1 = min(x_nominal,grating_split_pos_chip-1) - 0
                ycenter_p1 = y_nominal-0
Xin Zhang's avatar
Xin Zhang committed
334
335
336
337
338
339

                sdp_p1 = SpecDisperser(orig_img=star_p1, xcenter=xcenter_p1,
                                    ycenter=ycenter_p1, origin=origin_p1,
                                    tar_spec=normalSED,
                                    band_start=bandpass.blue_limit * 10, band_end=bandpass.red_limit * 10,
                                    conf=chip.sls_conf[0],
340
341
                                    isAlongY=0,
                                    flat_cube=flat_cube)
Xin Zhang's avatar
Xin Zhang committed
342

xin's avatar
xin committed
343
                self.addSLStoChipImage(sdp=sdp_p1, chip=chip, xOrderSigPlus = xOrderSigPlus, local_wcs=real_wcs_local)
Xin Zhang's avatar
Xin Zhang committed
344
345
346

                subImg_p2 = starImg.array[:, subSlitPos+1:starImg.array.shape[1]]
                star_p2 = galsim.Image(subImg_p2)
Fang Yuedong's avatar
Fang Yuedong committed
347
                star_p2.setOrigin(0, 0)
Xin Zhang's avatar
Xin Zhang committed
348
                origin_p2 = [origin_star[0], grating_split_pos_chip]
xin's avatar
xin committed
349
350
                xcenter_p2 = max(x_nominal, grating_split_pos_chip - 1) - 0
                ycenter_p2 = y_nominal - 0
Xin Zhang's avatar
Xin Zhang committed
351
352
353
354
355
356

                sdp_p2 = SpecDisperser(orig_img=star_p2, xcenter=xcenter_p2,
                                       ycenter=ycenter_p2, origin=origin_p2,
                                       tar_spec=normalSED,
                                       band_start=bandpass.blue_limit * 10, band_end=bandpass.red_limit * 10,
                                       conf=chip.sls_conf[1],
357
358
                                       isAlongY=0,
                                       flat_cube=flat_cube)
Xin Zhang's avatar
Xin Zhang committed
359

xin's avatar
xin committed
360
                self.addSLStoChipImage(sdp=sdp_p2, chip=chip, xOrderSigPlus = xOrderSigPlus, local_wcs=real_wcs_local)
Xin Zhang's avatar
Xin Zhang committed
361
362
363
364

                del sdp_p1
                del sdp_p2
            elif grating_split_pos_chip<=gal_origin[1]:
xin's avatar
xin committed
365
366
                sdp = SpecDisperser(orig_img=starImg, xcenter=x_nominal - 0,
                                    ycenter=y_nominal - 0, origin=origin_star,
Xin Zhang's avatar
Xin Zhang committed
367
368
369
                                    tar_spec=normalSED,
                                    band_start=bandpass.blue_limit * 10, band_end=bandpass.red_limit * 10,
                                    conf=chip.sls_conf[1],
370
371
                                    isAlongY=0,
                                    flat_cube=flat_cube)
xin's avatar
xin committed
372
                self.addSLStoChipImage(sdp=sdp, chip=chip, xOrderSigPlus = xOrderSigPlus, local_wcs=real_wcs_local)
Xin Zhang's avatar
Xin Zhang committed
373
374
                del sdp
            elif grating_split_pos_chip>=gal_end[1]:
xin's avatar
xin committed
375
376
                sdp = SpecDisperser(orig_img=starImg, xcenter=x_nominal - 0,
                                    ycenter=y_nominal - 0, origin=origin_star,
Xin Zhang's avatar
Xin Zhang committed
377
378
379
                                    tar_spec=normalSED,
                                    band_start=bandpass.blue_limit * 10, band_end=bandpass.red_limit * 10,
                                    conf=chip.sls_conf[0],
380
381
                                    isAlongY=0,
                                    flat_cube=flat_cube)
xin's avatar
xin committed
382
                self.addSLStoChipImage(sdp=sdp, chip=chip, xOrderSigPlus = xOrderSigPlus, local_wcs=real_wcs_local)
Xin Zhang's avatar
Xin Zhang committed
383
                del sdp
Fang Yuedong's avatar
Fang Yuedong committed
384

Xin Zhang's avatar
Xin Zhang committed
385
            # print(self.y_nominal, starImg.center.y, starImg.ymin)
Fang Yuedong's avatar
Fang Yuedong committed
386
            del psf
Fang Yuedong's avatar
Fang Yuedong committed
387
        return 1, pos_shear
Fang Yuedong's avatar
Fang Yuedong committed
388
389
390
391

    def getGSObj(self, psf, g1=0, g2=0, flux=None, filt=None, tel=None, exptime=150.):
        if flux == None:
            flux = self.getElectronFluxFilt(filt, tel, exptime)
Fang Yuedong's avatar
Fang Yuedong committed
392
        disk = galsim.Sersic(n=self.disk_sersic_idx, half_light_radius=self.hlr_disk, flux=1.0)
Fang Yuedong's avatar
Fang Yuedong committed
393
394
395
        disk_shape = galsim.Shear(g1=self.e1_disk, g2=self.e2_disk)
        disk = disk.shear(disk_shape)

Fang Yuedong's avatar
Fang Yuedong committed
396
        bulge = galsim.Sersic(n=self.bulge_sersic_idx, half_light_radius=self.hlr_bulge, flux=1.0)
Fang Yuedong's avatar
Fang Yuedong committed
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
        bulge_shape = galsim.Shear(g1=self.e1_bulge, g2=self.e2_bulge)
        bulge = bulge.shear(bulge_shape)

        gal = self.bfrac * bulge + (1.0 - self.bfrac) * disk
        gal = gal.withFlux(flux)
        gal_shear = galsim.Shear(g1=g1, g2=g2)
        gal = gal.shear(gal_shear)
        final = galsim.Convolve(psf, gal)
        return final

    def drawObject(self, img, final, noise_level=0.0, flux=None, filt=None, tel=None, exptime=150.):
        """ Override the method in parent class 
        Need to constrain the size of image stamp for extended objects
        """
        isUpdated = True
        if flux == None:
            flux = self.getElectronFluxFilt(filt, tel, exptime)
        stamp = final.drawImage(wcs=self.localWCS, offset=self.offset)
        stamp_arr = stamp.array
        mask = (stamp_arr >= 0.001*noise_level) # why 0.001?
        err = int(np.sqrt(mask.sum()))
        if np.mod(err, 2) == 1:
            err += 1
        # if err == 1:
        if err == 0:
            subSize = 16 # why 16?
        else:
            subSize = max([err, 16])
            fluxRatio = flux / stamp_arr[mask].sum()
            final = final.withScaledFlux(fluxRatio)

        imgSub = galsim.ImageF(subSize, subSize)

        # Draw with FFT
        # stamp = final.drawImage(image=imgSub, wcs=self.localWCS, offset=self.offset)

        # Draw with Photon Shoot
        stamp = final.drawImage(image=imgSub, wcs=self.localWCS, method='phot', offset=self.offset)
        
        stamp.setCenter(self.x_nominal, self.y_nominal)
        if np.sum(np.isnan(stamp.array)) >= 1:
            stamp.setZero()
        bounds = stamp.bounds & img.bounds
        if bounds.area() == 0:
            isUpdated = False
        else:
            img[bounds] += stamp[bounds]
        return img, stamp, isUpdated


    def getObservedEll(self, g1=0, g2=0):
        e1_obs, e2_obs, e_obs, theta = eObs(self.e1_total, self.e2_total, g1, g2)
Zhang Xin's avatar
Zhang Xin committed
449
        return self.e1_total, self.e2_total, g1, g2, e1_obs, e2_obs