Commit 3226117c authored by Zhang Xin's avatar Zhang Xin
Browse files

Merge branch 'develop' into 'release_v2.0'

version 2.1.0

See merge request csst_sim/csst-simulation!16
parents 81589f9d f540664f
import numpy as np import numpy as np
import galsim import galsim
import copy import copy
import cmath
from astropy.table import Table from astropy.table import Table
from abc import abstractmethod, ABCMeta from abc import abstractmethod, ABCMeta
...@@ -72,6 +73,16 @@ class CatalogBase(metaclass=ABCMeta): ...@@ -72,6 +73,16 @@ class CatalogBase(metaclass=ABCMeta):
"parallax":1e-9 "parallax":1e-9
} }
return param return param
@staticmethod
def rotate_ellipticity(e1, e2, rotation=0., unit='radians'):
if unit == 'degree':
rotation = np.radians(rotation)
e_total = np.sqrt(e1**2 + e2**2)
phi = cmath.phase(complex(e1, e2))
e1 = e_total * np.cos(phi + 2*rotation)
e2 = e_total * np.sin(phi + 2*rotation)
return e1, e2, e_total
@staticmethod @staticmethod
def convert_sed(mag, sed, target_filt, norm_filt=None): def convert_sed(mag, sed, target_filt, norm_filt=None):
......
...@@ -12,7 +12,7 @@ from ObservationSim.MockObject.MockObject import MockObject ...@@ -12,7 +12,7 @@ from ObservationSim.MockObject.MockObject import MockObject
# import tracemalloc # import tracemalloc
class Galaxy(MockObject): class Galaxy(MockObject):
def __init__(self, param, rotation=None, logger=None): def __init__(self, param, logger=None):
super().__init__(param, logger=logger) super().__init__(param, logger=logger)
# self.thetaR = self.param["theta"] # self.thetaR = self.param["theta"]
# self.bfrac = self.param["bfrac"] # self.bfrac = self.param["bfrac"]
...@@ -27,8 +27,6 @@ class Galaxy(MockObject): ...@@ -27,8 +27,6 @@ class Galaxy(MockObject):
# self.e1_bulge, self.e2_bulge = self.e_bulge.g1, self.e_bulge.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 # self.e1_total, self.e2_total = self.e_total.g1, self.e_total.g2
if rotation is not None:
self.rotateEllipticity(rotation)
if not hasattr(self, "disk_sersic_idx"): if not hasattr(self, "disk_sersic_idx"):
self.disk_sersic_idx = 1. self.disk_sersic_idx = 1.
if not hasattr(self, "bulge_sersic_idx"): if not hasattr(self, "bulge_sersic_idx"):
...@@ -51,7 +49,8 @@ class Galaxy(MockObject): ...@@ -51,7 +49,8 @@ class Galaxy(MockObject):
full = integrate_sed_bandpass(sed=self.sed, bandpass=filt.bandpass_full) full = integrate_sed_bandpass(sed=self.sed, bandpass=filt.bandpass_full)
except Exception as e: except Exception as e:
print(e) print(e)
self.logger.error(e) if self.logger:
self.logger.error(e)
return -1 return -1
for i in range(len(bandpass_list)): for i in range(len(bandpass_list)):
bandpass = bandpass_list[i] bandpass = bandpass_list[i]
...@@ -59,7 +58,8 @@ class Galaxy(MockObject): ...@@ -59,7 +58,8 @@ class Galaxy(MockObject):
sub = integrate_sed_bandpass(sed=self.sed, bandpass=bandpass) sub = integrate_sed_bandpass(sed=self.sed, bandpass=bandpass)
except Exception as e: except Exception as e:
print(e) print(e)
self.logger.error(e) if self.logger:
self.logger.error(e)
return -1 return -1
ratio = sub/full ratio = sub/full
...@@ -78,12 +78,13 @@ class Galaxy(MockObject): ...@@ -78,12 +78,13 @@ class Galaxy(MockObject):
gal = self.bfrac * bulge + (1.0 - self.bfrac) * disk gal = self.bfrac * bulge + (1.0 - self.bfrac) * disk
gal = gal.withFlux(nphotons) gal = gal.withFlux(nphotons)
if fd_shear is not None:
g1 += fd_shear.g1
g2 += fd_shear.g2
gal_shear = galsim.Shear(g1=g1, g2=g2) gal_shear = galsim.Shear(g1=g1, g2=g2)
gal = gal.shear(gal_shear) gal = gal.shear(gal_shear)
gal = galsim.Convolve(psf, gal) gal = galsim.Convolve(psf, gal)
if fd_shear is not None:
gal = gal.shear(fd_shear)
objs.append(gal) objs.append(gal)
final = galsim.Sum(objs) final = galsim.Sum(objs)
return final return final
...@@ -97,7 +98,8 @@ class Galaxy(MockObject): ...@@ -97,7 +98,8 @@ class Galaxy(MockObject):
full = integrate_sed_bandpass(sed=self.sed, bandpass=filt.bandpass_full) full = integrate_sed_bandpass(sed=self.sed, bandpass=filt.bandpass_full)
except Exception as e: except Exception as e:
print(e) print(e)
self.logger.error(e) if self.logger:
self.logger.error(e)
return 2, None return 2, None
nphotons_sum = 0 nphotons_sum = 0
...@@ -131,6 +133,18 @@ class Galaxy(MockObject): ...@@ -131,6 +133,18 @@ class Galaxy(MockObject):
real_wcs_local = self.real_wcs.local(self.real_pos) real_wcs_local = self.real_wcs.local(self.real_pos)
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)
if fd_shear:
g1 += fd_shear.g1
g2 += fd_shear.g2
gal_shear = galsim.Shear(g1=g1, g2=g2)
for i in range(len(bandpass_list)): for i in range(len(bandpass_list)):
bandpass = bandpass_list[i] bandpass = bandpass_list[i]
...@@ -138,7 +152,8 @@ class Galaxy(MockObject): ...@@ -138,7 +152,8 @@ class Galaxy(MockObject):
sub = integrate_sed_bandpass(sed=self.sed, bandpass=bandpass) sub = integrate_sed_bandpass(sed=self.sed, bandpass=bandpass)
except Exception as e: except Exception as e:
print(e) print(e)
self.logger.error(e) if self.logger:
self.logger.error(e)
# return False # return False
continue continue
...@@ -153,41 +168,24 @@ class Galaxy(MockObject): ...@@ -153,41 +168,24 @@ class Galaxy(MockObject):
# print("nphotons_sub-band_%d = %.2f"%(i, nphotons)) # 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) psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img, bandpass=bandpass, folding_threshold=folding_threshold)
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) gal_temp = self.bfrac * bulge + (1.0 - self.bfrac) * disk
disk = disk.shear(disk_shape) gal_temp = gal_temp.shear(gal_shear)
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)
gal = self.bfrac * bulge + (1.0 - self.bfrac) * disk 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
# (TEST) Random knots # (TEST) Random knots
# knots = galsim.RandomKnots(npoints=100, profile=disk) # knots = galsim.RandomKnots(npoints=100, profile=disk)
# kfrac = np.random.random()*(1.0 - self.bfrac) # kfrac = np.random.random()*(1.0 - self.bfrac)
# gal = self.bfrac * bulge + (1.0 - self.bfrac - kfrac) * disk + kfrac * knots # gal = self.bfrac * bulge + (1.0 - self.bfrac - kfrac) * disk + kfrac * knots
gal = gal.withFlux(nphotons)
gal_shear = galsim.Shear(g1=g1, g2=g2)
gal = gal.shear(gal_shear)
if not big_galaxy: # Not apply PSF for very big galaxy
gal = galsim.Convolve(psf, gal)
if fd_shear is not None:
gal = gal.shear(fd_shear)
# Use (explicit) stamps to draw
stamp = gal.drawImage(wcs=real_wcs_local, method='phot', offset=offset, save_photons=True)
xmax = max(xmax, stamp.xmax - stamp.xmin)
ymax = max(ymax, stamp.ymax - stamp.ymin)
photons = stamp.photons
photons.x += x_nominal
photons.y += y_nominal
photons_list.append(photons)
del gal
# # [C6 TEST] # # [C6 TEST]
# print('xmax = %d, ymax = %d '%(xmax, ymax)) # print('xmax = %d, ymax = %d '%(xmax, ymax))
# # Output memory usage # # Output memory usage
...@@ -196,7 +194,12 @@ class Galaxy(MockObject): ...@@ -196,7 +194,12 @@ class Galaxy(MockObject):
# for stat in top_stats[:10]: # for stat in top_stats[:10]:
# print(stat) # print(stat)
stamp = galsim.ImageF(int(xmax * 1.1), int(ymax * 1.1)) 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)
stamp.wcs = real_wcs_local stamp.wcs = real_wcs_local
stamp.setCenter(x_nominal, y_nominal) stamp.setCenter(x_nominal, y_nominal)
bounds = stamp.bounds & galsim.BoundsI(0, chip.npix_x - 1, 0, chip.npix_y - 1) bounds = stamp.bounds & galsim.BoundsI(0, chip.npix_x - 1, 0, chip.npix_y - 1)
...@@ -226,7 +229,8 @@ class Galaxy(MockObject): ...@@ -226,7 +229,8 @@ class Galaxy(MockObject):
else: else:
# Return code 0: object photons missed this detector # Return code 0: object photons missed this detector
print("obj %s missed"%(self.id)) print("obj %s missed"%(self.id))
self.logger.info("obj %s missed"%(self.id)) if self.logger:
self.logger.info("obj %s missed"%(self.id))
return 0, pos_shear return 0, pos_shear
# # [C6 TEST] # # [C6 TEST]
...@@ -297,14 +301,17 @@ class Galaxy(MockObject): ...@@ -297,14 +301,17 @@ class Galaxy(MockObject):
# gal = self.bfrac * bulge + (1.0 - self.bfrac - kfrac) * disk + kfrac * knots # gal = self.bfrac * bulge + (1.0 - self.bfrac - kfrac) * disk + kfrac * knots
gal = gal.withFlux(tel.pupil_area * exptime) gal = gal.withFlux(tel.pupil_area * exptime)
if fd_shear:
g1 += fd_shear.g1
g2 += fd_shear.g2
gal_shear = galsim.Shear(g1=g1, g2=g2) gal_shear = galsim.Shear(g1=g1, g2=g2)
gal = gal.shear(gal_shear) gal = gal.shear(gal_shear)
gal = galsim.Convolve(psf, gal) gal = galsim.Convolve(psf, gal)
if not big_galaxy: # Not apply PSF for very big galaxy if not big_galaxy: # Not apply PSF for very big galaxy
gal = galsim.Convolve(psf, gal) gal = galsim.Convolve(psf, gal)
if fd_shear is not None: # if fd_shear is not None:
gal = gal.shear(fd_shear) # gal = gal.shear(fd_shear)
starImg = gal.drawImage(wcs=real_wcs_local, offset=offset) starImg = gal.drawImage(wcs=real_wcs_local, offset=offset)
...@@ -397,14 +404,6 @@ class Galaxy(MockObject): ...@@ -397,14 +404,6 @@ class Galaxy(MockObject):
final = galsim.Convolve(psf, gal) final = galsim.Convolve(psf, gal)
return final return final
def rotateEllipticity(self, rotation):
if rotation == 1:
self.e1_disk, self.e2_disk, self.e1_bulge, self.e2_bulge, self.e1_total, self.e2_total = -self.e2_disk, self.e1_disk, -self.e2_bulge, self.e1_bulge, -self.e2_total, self.e1_total
if rotation == 2:
self.e1_disk, self.e2_disk, self.e1_bulge, self.e2_bulge, self.e1_total, self.e2_total = -self.e1_disk, -self.e2_disk, -self.e1_bulge, -self.e2_bulge, -self.e1_total, -self.e2_total
if rotation == 3:
self.e1_disk, self.e2_disk, self.e1_bulge, self.e2_bulge, self.e1_total, self.e2_total = self.e2_disk, -self.e1_disk, self.e2_bulge, -self.e1_bulge, self.e2_total, -self.e1_total
def drawObject(self, img, final, noise_level=0.0, flux=None, filt=None, tel=None, exptime=150.): def drawObject(self, img, final, noise_level=0.0, flux=None, filt=None, tel=None, exptime=150.):
""" Override the method in parent class """ Override the method in parent class
Need to constrain the size of image stamp for extended objects Need to constrain the size of image stamp for extended objects
......
...@@ -32,6 +32,7 @@ class MockObject(object): ...@@ -32,6 +32,7 @@ class MockObject(object):
# Place holder for outputs # Place holder for outputs
self.additional_output_str = "" self.additional_output_str = ""
self.fd_shear = None self.fd_shear = None
self.logger = logger self.logger = logger
...@@ -61,7 +62,7 @@ class MockObject(object): ...@@ -61,7 +62,7 @@ class MockObject(object):
dec = self.param["dec"] dec = self.param["dec"]
return galsim.CelestialCoord(ra=ra * galsim.degrees, dec=dec * galsim.degrees) return galsim.CelestialCoord(ra=ra * galsim.degrees, dec=dec * galsim.degrees)
def getPosImg_Offset_WCS(self, img, fdmodel=None, chip=None, verbose=True, img_header=None): def getPosImg_Offset_WCS(self, img, fdmodel=None, chip=None, verbose=True, chip_wcs=None, img_header=None):
self.posImg = img.wcs.toImage(self.getPosWorld()) self.posImg = img.wcs.toImage(self.getPosWorld())
self.localWCS = img.wcs.local(self.posImg) self.localWCS = img.wcs.local(self.posImg)
if (fdmodel is not None) and (chip is not None): if (fdmodel is not None) and (chip is not None):
...@@ -79,8 +80,10 @@ class MockObject(object): ...@@ -79,8 +80,10 @@ class MockObject(object):
dx = x - self.x_nominal dx = x - self.x_nominal
dy = y - self.y_nominal dy = y - self.y_nominal
self.offset = galsim.PositionD(dx, dy) self.offset = galsim.PositionD(dx, dy)
if img_header is not None: if chip_wcs is not None:
self.real_wcs = chip_wcs
elif img_header is not None:
self.real_wcs = galsim.FitsWCS(header=img_header) self.real_wcs = galsim.FitsWCS(header=img_header)
else: else:
self.real_wcs = None self.real_wcs = None
...@@ -132,7 +135,8 @@ class MockObject(object): ...@@ -132,7 +135,8 @@ class MockObject(object):
full = integrate_sed_bandpass(sed=self.sed, bandpass=filt.bandpass_full) full = integrate_sed_bandpass(sed=self.sed, bandpass=filt.bandpass_full)
except Exception as e: except Exception as e:
print(e) print(e)
self.logger.error(e) if self.logger:
self.logger.error(e)
return 2, None return 2, None
nphotons_sum = 0 nphotons_sum = 0
...@@ -164,7 +168,8 @@ class MockObject(object): ...@@ -164,7 +168,8 @@ class MockObject(object):
sub = integrate_sed_bandpass(sed=self.sed, bandpass=bandpass) sub = integrate_sed_bandpass(sed=self.sed, bandpass=bandpass)
except Exception as e: except Exception as e:
print(e) print(e)
self.logger.error(e) if self.logger:
self.logger.error(e)
# return False # return False
continue continue
...@@ -214,7 +219,8 @@ class MockObject(object): ...@@ -214,7 +219,8 @@ class MockObject(object):
else: else:
# Return code 0: object photons missed this detector # Return code 0: object photons missed this detector
print("obj %s missed"%(self.id)) print("obj %s missed"%(self.id))
self.logger.info("obj %s missed"%(self.id)) if self.logger:
self.logger.info("obj %s missed"%(self.id))
return 0, pos_shear return 0, pos_shear
del photons_list del photons_list
......
...@@ -122,7 +122,7 @@ class SpecDisperser(object): ...@@ -122,7 +122,7 @@ class SpecDisperser(object):
beam=beam) beam=beam)
### Account for pixel centering of the trace ### Account for pixel centering of the trace
yfrac_beam = ytrace_beam - floor(ytrace_beam) yfrac_beam = ytrace_beam - floor(ytrace_beam+0.5)
ysens = lam_beam * 0 ysens = lam_beam * 0
lam_index = argsort(lam_beam) lam_index = argsort(lam_beam)
...@@ -155,7 +155,7 @@ class SpecDisperser(object): ...@@ -155,7 +155,7 @@ class SpecDisperser(object):
sensitivity_beam = ysens sensitivity_beam = ysens
len_spec_x = len(dx) len_spec_x = len(dx)
len_spec_y = int(ceil(yfrac_beam[-1]) - floor(yfrac_beam[0]) + 1) len_spec_y = int(ceil(ytrace_beam[-1]) - floor(ytrace_beam[0]) + 1)
beam_sh = (self.img_sh[0] + len_spec_y, self.img_sh[1] + len_spec_x) beam_sh = (self.img_sh[0] + len_spec_y, self.img_sh[1] + len_spec_x)
modelf = zeros(product(beam_sh), dtype=float) modelf = zeros(product(beam_sh), dtype=float)
...@@ -165,9 +165,15 @@ class SpecDisperser(object): ...@@ -165,9 +165,15 @@ class SpecDisperser(object):
dxpix = dx - dx[0] + x0[1] dxpix = dx - dx[0] + x0[1]
dyc = cast[int](ytrace_beam) dyc = cast[int](np.floor(ytrace_beam+0.5))
dypix = cast[int](np.floor(ytrace_beam - dyc[0] + x0[0] + 0.5))
frac_ids = yfrac_beam<0
dypix[frac_ids] = dypix[frac_ids] - 1
yfrac_beam[frac_ids] = 1+yfrac_beam[frac_ids]
dypix = dyc - dyc[0] + x0[0]
flat_index = idx[dypix, dxpix] flat_index = idx[dypix, dxpix]
nonz = sensitivity_beam != 0 nonz = sensitivity_beam != 0
...@@ -185,7 +191,7 @@ class SpecDisperser(object): ...@@ -185,7 +191,7 @@ class SpecDisperser(object):
origin_in[1] = self.origin[1] origin_in[1] = self.origin[1]
dx0_in = dx[0] dx0_in = dx[0]
dy0_in = dyc[0] dy0_in = dyc[0]
originOut_x = origin_in[1] + dx0_in originOut_x = origin_in[1] + dx0_in
originOut_y = origin_in[0] + dy0_in originOut_y = origin_in[0] + dy0_in
if self.flat_cube is None: if self.flat_cube is None:
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment