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
......@@ -86,12 +86,12 @@ def disperse_grism_object(np.ndarray[FTYPE_t, ndim=2] flam,
k1 = idxl[k]+j*shg[1]+i
if (k1 >= 0) & (k1 < nl):
flat_ids = k1*nlamb+k
full[k1] += fl_ij*yfrac[k]*flat_eff_all[flat_ids]
full[k1] += fl_ij*(1-yfrac[k])*flat_eff_all[flat_ids]
k2 = idxl[k]+(j-1)*shg[1]+i
k2 = idxl[k]+(j+1)*shg[1]+i
if (k2 >= 0) & (k2 < nl):
flat_ids = k2*nlamb+k
full[k2] += fl_ij*(1-yfrac[k])*flat_eff_all[flat_ids]
full[k2] += fl_ij*yfrac[k]*flat_eff_all[flat_ids]
else:
for i in range(0-x0[1], x0[1]):
......@@ -109,11 +109,11 @@ def disperse_grism_object(np.ndarray[FTYPE_t, ndim=2] flam,
for k in range(nk):
k1 = idxl[k]+j*shg[1]+i
if (k1 >= 0) & (k1 < nl):
full[k1] += ysens[k]*fl_ij*yfrac[k]
full[k1] += ysens[k]*fl_ij*(1-yfrac[k])
k2 = idxl[k]+(j-1)*shg[1]+i
k2 = idxl[k]+(j+1)*shg[1]+i
if (k2 >= 0) & (k2 < nl):
full[k2] += ysens[k]*fl_ij*(1-yfrac[k])
full[k2] += ysens[k]*fl_ij*yfrac[k]
return True
......
......@@ -4,5 +4,5 @@ from .CatalogBase import CatalogBase
from .Quasar import Quasar
from .Star import Star
from .Stamp import Stamp
from .SkybackgroundMap import *
# from .SkybackgroundMap import *
# from .CosmicRay import CosmicRay
......@@ -14,7 +14,7 @@ from ObservationSim.Config import config_dir, ChipOutput
from ObservationSim.Config.Header import generatePrimaryHeader, generateExtensionHeader
from ObservationSim.Instrument import Telescope, Filter, FilterParam, FocalPlane, Chip
from ObservationSim.Instrument.Chip import Effects
from ObservationSim.MockObject import calculateSkyMap_split_g
from ObservationSim.Straylight import calculateSkyMap_split_g
from ObservationSim.PSF import PSFGauss, FieldDistortion, PSFInterp
from ObservationSim._util import get_shear_field, makeSubDir_PointingList
from ObservationSim.Astrometry.Astrometry_util import on_orbit_obs_position
......@@ -48,7 +48,7 @@ class Observation(object):
self.filter_list.append(filt)
self.all_filter.append(filt)
def run_one_chip(self, chip, filt, pointing, chip_output, wcs_fp=None, psf_model=None, shear_cat_file=None, cat_dir=None, sed_dir=None):
def run_one_chip(self, chip, filt, pointing, chip_output, wcs_fp=None, psf_model=None, cat_dir=None, sed_dir=None):
chip_output.Log_info(':::::::::::::::::::Current Pointing Information::::::::::::::::::')
chip_output.Log_info("RA: %f, DEC; %f" % (pointing.ra, pointing.dec))
......@@ -68,8 +68,7 @@ class Observation(object):
chip_output.Log_error("unrecognized PSF model type!!", flush=True)
# Figure out shear fields
if shear_cat_file is not None:
self.g1_field, self.g2_field, self.nshear = get_shear_field(config=self.config, shear_cat_file=shear_cat_file)
self.g1_field, self.g2_field, self.nshear = get_shear_field(config=self.config)
# Apply astrometric simulation for pointing
if self.config["obs_setting"]["enable_astrometric_model"]:
......@@ -107,6 +106,13 @@ class Observation(object):
chip.img = galsim.ImageF(chip.npix_x, chip.npix_y)
chip.img.setOrigin(chip.bound.xmin, chip.bound.ymin)
chip.img.wcs = wcs_fp
if self.config["obs_setting"]["enable_straylight_model"]:
filt.setFilterStrayLightPixel(jtime = pointing.jdt, sat_pos = np.array([pointing.sat_x, pointing.sat_y, pointing.sat_z]), pointing_radec = np.array([pointing.ra,pointing.dec]), sun_pos = np.array([pointing.sun_x,pointing.sun_y,pointing.sun_z]))
chip_output.Log_info("========================sky pix========================")
chip_output.Log_info(filt.sky_background)
if chip.survey_type == "photometric":
sky_map = None
elif chip.survey_type == "spectroscopic":
......@@ -133,7 +139,8 @@ class Observation(object):
conf=chip.sls_conf,
pixelSize=chip.pix_scale,
isAlongY=0,
flat_cube=chip.flat_cube)
flat_cube=chip.flat_cube, zoldial_spec = filt.zodical_spec)
sky_map = sky_map+filt.sky_background
del flat_normal
if pointing.pointing_type == 'MS':
......@@ -152,7 +159,7 @@ class Observation(object):
cut_filter = temp_filter
if self.config["ins_effects"]["field_dist"] == True:
self.fd_model = FieldDistortion(chip=chip)
self.fd_model = FieldDistortion(chip=chip, img_rot=pointing.img_pa.deg)
else:
self.fd_model = None
......@@ -176,7 +183,12 @@ class Observation(object):
pixel_size=chip.pix_size,
xcen=chip.x_cen,
ycen=chip.y_cen,
extName='raw')
extName='SCI',
timestamp = pointing.timestamp,
exptime = pointing.exp_time,
readoutTime = 40.)
chip_wcs = galsim.FitsWCS(header=h_ext)
for j in range(self.nobj):
......@@ -232,12 +244,6 @@ class Observation(object):
obj.g1, obj.g2 = 0., 0.
else:
obj.g1, obj.g2 = self.g1_field, self.g2_field
elif self.config["shear_setting"]["shear_type"] == "extra":
try:
# [TODO]: every object with individual shear from input catalog(s)
obj.g1, obj.g2 = self.g1_field[j], self.g2_field[j]
except:
chip_output.Log_error("failed to load external shear.")
elif self.config["shear_setting"]["shear_type"] == "catalog":
pass
else:
......@@ -245,7 +251,7 @@ class Observation(object):
raise ValueError("Unknown shear input")
# Get position of object on the focal plane
pos_img, offset, local_wcs, real_wcs, fd_shear = obj.getPosImg_Offset_WCS(img=chip.img, fdmodel=self.fd_model, chip=chip, verbose=False, img_header=h_ext)
pos_img, offset, local_wcs, real_wcs, fd_shear = obj.getPosImg_Offset_WCS(img=chip.img, fdmodel=self.fd_model, chip=chip, verbose=False, chip_wcs=chip_wcs, img_header=h_ext)
# [TODO] For now, only consider objects which their centers (after field distortion) are projected within the focal plane
# Otherwise they will be considered missed objects
......@@ -358,12 +364,36 @@ class Observation(object):
sat_pos=[pointing.sat_x, pointing.sat_y, pointing.sat_z],
sat_vel=[pointing.sat_vx, pointing.sat_vy, pointing.sat_vz],
chip_name=str(chip.chipID).rjust(2, '0'))
h_ext = generateExtensionHeader(
chip=chip,
xlen=chip.npix_x,
ylen=chip.npix_y,
ra=pointing.ra,
dec=pointing.dec,
pa=pointing.img_pa.deg,
gain=chip.gain,
readout=chip.read_noise,
dark=chip.dark_noise,
saturation=90000,
pixel_scale=chip.pix_scale,
pixel_size=chip.pix_size,
xcen=chip.x_cen,
ycen=chip.y_cen,
extName='SCI',
timestamp=pointing.timestamp,
exptime=pointing.exp_time,
readoutTime=40.)
chip.img = galsim.Image(chip.img.array, dtype=np.uint16)
hdu1 = fits.PrimaryHDU(header=h_prim)
hdu1.add_checksum()
hdu1.header.comments['CHECKSUM'] = 'HDU checksum'
hdu1.header.comments['DATASUM'] = 'data unit checksum'
hdu2 = fits.ImageHDU(chip.img.array, header=h_ext)
hdu2.add_checksum()
hdu2.header.comments['XTENSION'] = 'extension type'
hdu2.header.comments['CHECKSUM'] = 'HDU checksum'
hdu2.header.comments['DATASUM'] = 'data unit checksum'
hdu1 = fits.HDUList([hdu1, hdu2])
fname = os.path.join(chip_output.subdir, h_prim['FILENAME'] + '.fits')
hdu1.writeto(fname, output_verify='ignore', overwrite=True)
......@@ -375,7 +405,7 @@ class Observation(object):
chip_output.Log_info("check running:2: pointing-%d chip-%d pid-%d memory-%6.2fGB"%(pointing.id, chip.chipID, os.getpid(), (psutil.Process(os.getpid()).memory_info().rss / 1024 / 1024 / 1024) ))
def runExposure_MPI_PointingList(self, pointing_list, shear_cat_file=None, chips=None, use_mpi=False):
def runExposure_MPI_PointingList(self, pointing_list,chips=None, use_mpi=False):
if use_mpi:
comm = MPI.COMM_WORLD
ind_thread = comm.Get_rank()
......
import galsim
import numpy as np
import cmath
class FieldDistortion(object):
def __init__(self, chip, fdModel=None, fdModel_path=None):
def __init__(self, chip, fdModel=None, fdModel_path=None, img_rot=0.):
if fdModel is None:
if hasattr(chip, 'fdModel'):
self.fdModel = chip.fdModel
......@@ -15,6 +16,7 @@ class FieldDistortion(object):
raise ValueError("Error: no field distortion model has been specified!")
else:
self.fdModel = fdModel
self.img_rot = img_rot
self.ifdModel = self.fdModel["wave1"]
self.ixfdModel = self.ifdModel["xImagePos"]
self.iyfdModel = self.ifdModel["yImagePos"]
......@@ -42,7 +44,7 @@ class FieldDistortion(object):
return False
return True
def get_distorted(self, chip, pos_img, bandpass=None):
def get_distorted(self, chip, pos_img, bandpass=None, img_rot=None):
""" Get the distored position for an undistorted image position
Parameters:
......@@ -58,14 +60,14 @@ class FieldDistortion(object):
"""
if not self.isContainObj_FD(chip=chip, pos_img=pos_img):
return galsim.PositionD(-1, -1), None
if not img_rot:
img_rot = np.radians(self.img_rot)
else:
img_rot = np.radians(img_rot)
x, y = pos_img.x, pos_img.y
x = self.ixfdModel(x, y)[0][0]
y = self.iyfdModel(x, y)[0][0]
ix_dx = self.ifx_dx(x, y)
ix_dy = self.ifx_dy(x, y)
iy_dx = self.ify_dx(x, y)
iy_dy = self.ify_dy(x, y)
if self.irsModel is not None:
if self.irsModel:
# x1LowI, x1UpI, y1LowI, y1UpI = self.irsModel["interpLimit"]
# if (x1LowI-x)*(x1UpI-x) <=0 and (y1LowI-y)*(y1UpI-y)<=0:
# dx = self.ixrsModel(x, y)[0][0]
......@@ -88,8 +90,21 @@ class FieldDistortion(object):
ix_dy = self.ifx_dy(x, y) + self.irx_dy(x, y)
iy_dx = self.ify_dx(x, y) + self.iry_dx(x, y)
iy_dy = self.ify_dy(x, y) + self.iry_dy(x, y)
else:
ix_dx = self.ifx_dx(x, y)
ix_dy = self.ifx_dy(x, y)
iy_dx = self.ify_dx(x, y)
iy_dy = self.ify_dy(x, y)
g1k_fd = 0.0 + (iy_dy - ix_dx) / (iy_dy + ix_dx)
g2k_fd = 0.0 - (iy_dx + ix_dy) / (iy_dy + ix_dx)
# [TODO] [TESTING] Rotate the shear:
g_abs = np.sqrt(g1k_fd**2 + g2k_fd**2)
phi = cmath.phase(complex(g1k_fd, g2k_fd))
# g_abs = 0.7
g1k_fd = g_abs * np.cos(phi + 2*img_rot)
g2k_fd = g_abs * np.sin(phi + 2*img_rot)
fd_shear = galsim.Shear(g1=g1k_fd, g2=g2k_fd)
return galsim.PositionD(x, y), fd_shear
......@@ -7,6 +7,7 @@ from astropy.table import Table
from scipy import interpolate
import galsim
import astropy.constants as cons
import os
......@@ -22,7 +23,7 @@ except ImportError:
###calculate sky map by sky SED
def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='sky_emiss_hubble_50_50_A.dat', conf=[''], pixelSize=0.074, isAlongY=0,
split_pos=3685, flat_cube = None):
split_pos=3685, flat_cube = None, zoldial_spec = None):
# skyMap = np.ones([yLen, xLen], dtype='float32')
#
# if isAlongY == 1:
......@@ -44,14 +45,24 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s
fImg = galsim.Image(fimg)
try:
with pkg_resources.files('ObservationSim.MockObject.data').joinpath(skyfn) as data_path:
with pkg_resources.files('ObservationSim.Straylight.data.sky').joinpath(skyfn) as data_path:
skySpec = np.loadtxt(data_path)
except AttributeError:
with pkg_resources.path('ObservationSim.MockObject.data', skyfn) as data_path:
with pkg_resources.path('ObservationSim.Straylight.data.sky', skyfn) as data_path:
skySpec = np.loadtxt(data_path)
# skySpec = np.loadtxt(skyfn)
spec = Table(np.array([skySpec[:, 0], skySpec[:, 1]]).T, names=('WAVELENGTH', 'FLUX'))
if zoldial_spec is not None:
deltL = 0.5
lamb = np.arange(2000, 11000, deltL)
speci = interpolate.interp1d(zoldial_spec['WAVELENGTH'], zoldial_spec['FLUX'])
y = speci(lamb)
# erg/s/cm2/A --> photo/s/m2/A
s_flux = y * lamb / (cons.h.value * cons.c.value) * 1e-13
spec = Table(np.array([lamb, s_flux]).T, names=('WAVELENGTH', 'FLUX'))
if isAlongY == 0:
directParm = 0
if isAlongY ==1:
......@@ -266,10 +277,10 @@ def calculateSkyMap(xLen=9232, yLen=9126, blueLimit=4200, redLimit=6500,
fimg = np.zeros_like(skyMap)
fImg = galsim.Image(fimg)
try:
with pkg_resources.files('ObservationSim.MockObject.data').joinpath(skyfn) as data_path:
with pkg_resources.files('ObservationSim.Straylight.data.sky').joinpath(skyfn) as data_path:
skySpec = np.loadtxt(data_path)
except AttributeError:
with pkg_resources.path('ObservationSim.MockObject.data', skyfn) as data_path:
with pkg_resources.path('ObservationSim.Straylight.data.sky', skyfn) as data_path:
skySpec = np.loadtxt(data_path)
# skySpec = np.loadtxt(skyfn)
......
This diff is collapsed.
from .Straylight import Straylight
from .SkybackgroundMap import *
0 0 5 10 15 20 25 30 45 60 75 90
0 30000 150000 7000 3140 1610 985 640 275 150 100 76
5 20000 12000 6000 2940 1540 945 625 271 150 100 76
10 16000 8000 4740 2470 1370 865 590 264 148 100 76
15 11500 6780 3440 1860 1110 755 525 251 146 100 76
20 6400 4480 2410 1410 910 635 454 237 141 99 76
25 3840 2830 1730 1100 749 545 410 223 136 97 76
30 2480 1870 1220 845 615 467 365 207 131 95 76
35 1650 1270 910 680 510 397 320 193 125 93 76
40 1180 940 700 530 416 338 282 179 120 92 76
45 910 730 555 442 356 292 250 166 116 90 76
60 505 442 352 292 243 209 183 134 104 86 76
75 338 317 269 227 196 172 151 116 93 82 76
90 259 251 225 193 166 147 132 104 86 79 76
105 212 210 197 170 150 133 119 96 82 77 76
120 188 186 177 154 138 125 113 90 77 74 76
135 179 178 166 147 134 122 110 90 77 73 76
150 179 178 165 148 137 127 116 96 79 72 76
165 196 192 179 165 151 141 131 104 82 72 76
180 230 212 195 178 163 148 134 105 83 72 76
\ No newline at end of file
#A erg/s/A/arcsec^2/cm^2
1000 2.41e-23
1100 4.38e-22
1200 4.01e-23
1300 7.41e-25
1400 4.29e-25
1500 4.16e-25
1600 2.55e-25
1700 7.89e-25
1800 9.33e-23
1900 4.39e-22
2000 1.01e-21
2100 1.6e-21
2200 7.49e-22
2300 3.32e-22
2400 2.5e-22
2500 2.39e-22
2600 5.62e-22
2700 6.77e-21
2800 2.03e-21
2900 4.32e-20
3000 9.34e-20
3100 2.07e-19
3200 3.6e-19
3300 4.27e-19
3400 6.4e-19
3500 8.2e-19
3600 1.06e-18
3700 1.22e-18
3800 1.23e-18
3900 1.52e-18
4000 2.38e-18
4250 2.38e-18
4500 2.86e-18
4750 2.79e-18
5000 2.63e-18
5250 2.67e-18
5500 2.58e-18
5750 2.54e-18
6000 2.42e-18
6250 2.26e-18
6500 2.17e-18
6750 2.07e-18
7000 1.93e-18
7250 1.85e-18
7500 1.74e-18
7750 1.63e-18
8000 1.56e-18
8250 1.48e-18
8500 1.35e-18
8750 1.31e-18
9000 1.22e-18
9250 1.15e-18
9500 1.1e-18
9750 1.04e-18
10000 1e-18
10250 9.45e-19
10500 9.04e-19
10750 8.41e-19
11000 8.03e-19
2000 7.69E-22
2500 1.53E-21
3000 1.43E-19
3500 8.33E-19
4000 1.66E-18
4500 2.59E-18
5000 2.63E-18
5500 2.55E-18
6000 2.42E-18
7000 1.95E-18
8000 1.56E-18
9000 1.23E-18
10000 9.97E-19
11000 8.02E-19
12000 6.65E-19
13000 5.58E-19
14000 4.70E-19
15000 3.97E-19
16000 3.35E-19
17000 2.79E-19
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