Commit 38e2c452 authored by Fang Yuedong's avatar Fang Yuedong
Browse files

Merge branch 'master' into 'current_stable_for_tests'

for tests before release

See merge request !23
parents e0f2b9f7 1c35c0e2
import galsim
import sep
import numpy as np
from scipy.interpolate import interp1d
from observation_sim.psf.PSFModel import PSFModel
class PSFGauss(PSFModel):
def __init__(self, chip, fwhm=0.187, sigSpin=0., psfRa=None):
self.pix_size = chip.pix_scale
self.chip = chip
if psfRa is None:
self.fwhm = fwhm
self.sigGauss = 0.15
else:
self.fwhm = self.fwhmGauss(r=psfRa)
self.sigGauss = psfRa # 80% light radius
self.sigSpin = sigSpin
self.psf = galsim.Gaussian(flux=1.0, fwhm=fwhm)
def perfGauss(self, r, sig):
"""
pseudo-error function, i.e. Cumulative distribution function of Gaussian distribution
Parameter:
r: radius
sig: sigma of the Gaussian distribution
Return:
the value of the pseudo CDF
"""
def gaussFun(sigma, r): return 1.0/(np.sqrt(2.0*np.pi)
* sigma) * np.exp(-r**2/(2.0*sigma**2))
nxx = 1000
rArr = np.linspace(0.0, r, nxx)
gauss = gaussFun(sig, rArr)
erf = 2.0*np.trapz(gauss, rArr)
return erf
def fracGauss(self, sig, r=0.15, pscale=None):
"""
For a given Gaussian PSF with sigma=sig,
derive the flux ratio ar the given radius r
Parameters:
sig: sigma of the Gauss PSF Function in arcsec
r: radius in arcsec
pscale: pixel scale
Return: the flux ratio
"""
if pscale == None:
pscale = self.pix_size
gaussx = galsim.Gaussian(flux=1.0, sigma=sig)
gaussImg = gaussx.drawImage(scale=pscale, method='no_pixel')
gaussImg = gaussImg.array
size = np.size(gaussImg, axis=0)
cxy = 0.5*(size-1)
flux, ferr, flag = sep.sum_circle(
gaussImg, [cxy], [cxy], [r/pscale], subpix=0)
return flux
def fwhmGauss(self, r=0.15, fr=0.8, pscale=None):
"""
Given a total flux ratio 'fr' within a fixed radius 'r',
estimate the fwhm of the Gaussian function
return the fwhm in arcsec
"""
if pscale == None:
pscale = self.pix_size
err = 1.0e-3
nxx = 100
sig = np.linspace(0.5*pscale, 1.0, nxx)
frA = np.zeros(nxx)
for i in range(nxx):
frA[i] = self.fracGauss(sig[i], r=r, pscale=pscale)
index = [i for i in range(nxx-1) if (fr-frA[i])
* (fr-frA[i+1]) <= 0.0][0]
while abs(frA[index]-fr) > 1.0e-3:
sig = np.linspace(sig[index], sig[index+1], nxx)
for i in range(nxx):
frA[i] = self.fracGauss(sig[i], r=r, pscale=pscale)
index = [i for i in range(
nxx-1) if (fr-frA[i])*(fr-frA[i+1]) <= 0.0][0]
fwhm = 2.35482*sig[index]
return fwhm
def get_PSF(self, pos_img, chip=None, bandpass=None, folding_threshold=5.e-3):
dx = pos_img.x - self.chip.cen_pix_x
dy = pos_img.y - self.chip.cen_pix_y
return self.PSFspin(dx, dy)
def PSFspin(self, x, y):
"""
The PSF profile at a given image position relative to the axis center
Parameters:
theta : spin angles in a given exposure in unit of [arcsecond]
dx, dy: relative position to the axis center in unit of [pixels]
Return:
Spinned PSF: g1, g2 and axis ratio 'a/b'
"""
a2Rad = np.pi/(60.0*60.0*180.0)
ff = self.sigGauss * 0.107 * (1000.0/10.0) # in unit of [pixels]
rc = np.sqrt(x*x + y*y)
cpix = rc*(self.sigSpin*a2Rad)
beta = (np.arctan2(y, x) + np.pi/2)
ell = cpix**2/(2.0*ff**2+cpix**2)
# ell *= 10.0
qr = np.sqrt((1.0+ell)/(1.0-ell))
# psfShape = galsim.Shear(e=ell, beta=beta)
# g1, g2 = psfShape.g1, psfShape.g2
# qr = np.sqrt((1.0+ell)/(1.0-ell))
# return ell, beta, qr
PSFshear = galsim.Shear(e=ell, beta=beta*galsim.radians)
return self.psf.shear(PSFshear), PSFshear
...@@ -12,14 +12,14 @@ import scipy.spatial as spatial ...@@ -12,14 +12,14 @@ import scipy.spatial as spatial
import galsim import galsim
import h5py import h5py
from ObservationSim.PSF.PSFModel import PSFModel from observation_sim.psf.PSFModel import PSFModel
NPSF = 900 #***# 30*30 NPSF = 900 # ***# 30*30
PixSizeInMicrons = 5. #***# in microns PixSizeInMicrons = 5. # ***# in microns
###find neighbors-KDtree### ### find neighbors-KDtree###
def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True): def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True):
""" """
find nearest neighbors by 2D-KDTree find nearest neighbors by 2D-KDTree
...@@ -38,7 +38,7 @@ def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True): ...@@ -38,7 +38,7 @@ def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True):
datay = py datay = py
tree = spatial.KDTree(list(zip(datax.ravel(), datay.ravel()))) tree = spatial.KDTree(list(zip(datax.ravel(), datay.ravel())))
dataq=[] dataq = []
rr = dr rr = dr
if OnlyDistance == True: if OnlyDistance == True:
dataq = tree.query_ball_point([tx, ty], rr) dataq = tree.query_ball_point([tx, ty], rr)
...@@ -51,7 +51,9 @@ def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True): ...@@ -51,7 +51,9 @@ def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True):
dataq = np.array(dataq)[ddSortindx[0:dn]] dataq = np.array(dataq)[ddSortindx[0:dn]]
return dataq return dataq
###find neighbors-hoclist### ### find neighbors-hoclist###
def hocBuild(partx, party, nhocx, nhocy, dhocx, dhocy): def hocBuild(partx, party, nhocx, nhocy, dhocx, dhocy):
if np.max(partx) > nhocx*dhocx: if np.max(partx) > nhocx*dhocx:
print('ERROR') print('ERROR')
...@@ -60,8 +62,8 @@ def hocBuild(partx, party, nhocx, nhocy, dhocx, dhocy): ...@@ -60,8 +62,8 @@ def hocBuild(partx, party, nhocx, nhocy, dhocx, dhocy):
print('ERROR') print('ERROR')
sys.exit() sys.exit()
npart = partx.size npart = partx.size
hoclist= np.zeros(npart, dtype=np.int32)-1 hoclist = np.zeros(npart, dtype=np.int32)-1
hoc = np.zeros([nhocy, nhocx], dtype=np.int32)-1 hoc = np.zeros([nhocy, nhocx], dtype=np.int32)-1
for ipart in range(npart): for ipart in range(npart):
ix = int(partx[ipart]/dhocx) ix = int(partx[ipart]/dhocx)
...@@ -70,18 +72,20 @@ def hocBuild(partx, party, nhocx, nhocy, dhocx, dhocy): ...@@ -70,18 +72,20 @@ def hocBuild(partx, party, nhocx, nhocy, dhocx, dhocy):
hoc[iy, ix] = ipart hoc[iy, ix] = ipart
return hoc, hoclist return hoc, hoclist
def hocFind(px, py, dhocx, dhocy, hoc, hoclist): def hocFind(px, py, dhocx, dhocy, hoc, hoclist):
ix = int(px/dhocx) ix = int(px/dhocx)
iy = int(py/dhocy) iy = int(py/dhocy)
neigh=[] neigh = []
it = hoc[iy, ix] it = hoc[iy, ix]
while it != -1: while it != -1:
neigh.append(it) neigh.append(it)
it = hoclist[it] it = hoclist[it]
return neigh return neigh
def findNeighbors_hoclist(px, py, tx=None,ty=None, dn=4, hoc=None, hoclist=None):
def findNeighbors_hoclist(px, py, tx=None, ty=None, dn=4, hoc=None, hoclist=None):
nhocy = nhocx = 20 nhocy = nhocx = 20
pxMin = np.min(px) pxMin = np.min(px)
...@@ -91,21 +95,21 @@ def findNeighbors_hoclist(px, py, tx=None,ty=None, dn=4, hoc=None, hoclist=None) ...@@ -91,21 +95,21 @@ def findNeighbors_hoclist(px, py, tx=None,ty=None, dn=4, hoc=None, hoclist=None)
dhocx = (pxMax - pxMin)/(nhocx-1) dhocx = (pxMax - pxMin)/(nhocx-1)
dhocy = (pyMax - pyMin)/(nhocy-1) dhocy = (pyMax - pyMin)/(nhocy-1)
partx = px - pxMin +dhocx/2 partx = px - pxMin + dhocx/2
party = py - pyMin +dhocy/2 party = py - pyMin + dhocy/2
if hoc is None: if hoc is None:
hoc, hoclist = hocBuild(partx, party, nhocx, nhocy, dhocx, dhocy) hoc, hoclist = hocBuild(partx, party, nhocx, nhocy, dhocx, dhocy)
return hoc, hoclist return hoc, hoclist
if hoc is not None: if hoc is not None:
tx = tx - pxMin +dhocx/2 tx = tx - pxMin + dhocx/2
ty = ty - pyMin +dhocy/2 ty = ty - pyMin + dhocy/2
itx = int(tx/dhocx) itx = int(tx/dhocx)
ity = int(ty/dhocy) ity = int(ty/dhocy)
ps = [-1, 0, 1] ps = [-1, 0, 1]
neigh=[] neigh = []
for ii in range(3): for ii in range(3):
for jj in range(3): for jj in range(3):
ix = itx + ps[ii] ix = itx + ps[ii]
...@@ -119,23 +123,23 @@ def findNeighbors_hoclist(px, py, tx=None,ty=None, dn=4, hoc=None, hoclist=None) ...@@ -119,23 +123,23 @@ def findNeighbors_hoclist(px, py, tx=None,ty=None, dn=4, hoc=None, hoclist=None)
if iy > nhocy-1: if iy > nhocy-1:
continue continue
#neightt = myUtil.hocFind(ppx, ppy, dhocx, dhocy, hoc, hoclist) # neightt = myUtil.hocFind(ppx, ppy, dhocx, dhocy, hoc, hoclist)
it = hoc[iy, ix] it = hoc[iy, ix]
while it != -1: while it != -1:
neigh.append(it) neigh.append(it)
it = hoclist[it] it = hoclist[it]
#neigh.append(neightt) # neigh.append(neightt)
#ll = [i for k in neigh for i in k] # ll = [i for k in neigh for i in k]
if dn != -1: if dn != -1:
ptx = np.array(partx[neigh]) ptx = np.array(partx[neigh])
pty = np.array(party[neigh]) pty = np.array(party[neigh])
dd = np.hypot(ptx-tx, pty-ty) dd = np.hypot(ptx-tx, pty-ty)
idx = np.argsort(dd) idx = np.argsort(dd)
neigh= np.array(neigh)[idx[0:dn]] neigh = np.array(neigh)[idx[0:dn]]
return neigh return neigh
###PSF-IDW### ### PSF-IDW###
def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=True, hoc=None, hoclist=None, PSFCentroidWgt=False): def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=True, hoc=None, hoclist=None, PSFCentroidWgt=False):
""" """
psf interpolation by IDW psf interpolation by IDW
...@@ -161,9 +165,11 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru ...@@ -161,9 +165,11 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru
if OnlyNeighbors == True: if OnlyNeighbors == True:
if hoc is None: if hoc is None:
neigh = findNeighbors(px, py, cen_col, cen_row, dr=5., dn=4, OnlyDistance=False) neigh = findNeighbors(px, py, cen_col, cen_row,
dr=5., dn=4, OnlyDistance=False)
if hoc is not None: if hoc is not None:
neigh = findNeighbors_hoclist(cen_col, cen_row, tx=px,ty=py, dn=4, hoc=hoc, hoclist=hoclist) neigh = findNeighbors_hoclist(
cen_col, cen_row, tx=px, ty=py, dn=4, hoc=hoc, hoclist=hoclist)
neighFlag = np.zeros(npsf) neighFlag = np.zeros(npsf)
neighFlag[neigh] = 1 neighFlag[neigh] = 1
...@@ -173,7 +179,8 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru ...@@ -173,7 +179,8 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru
if neighFlag[ipsf] != 1: if neighFlag[ipsf] != 1:
continue continue
dist = np.sqrt((ref_col - cen_col[ipsf])**2 + (ref_row - cen_row[ipsf])**2) dist = np.sqrt((ref_col - cen_col[ipsf])
** 2 + (ref_row - cen_row[ipsf])**2)
if IDWindex == 1: if IDWindex == 1:
psfWeight[ipsf] = dist psfWeight[ipsf] = dist
if IDWindex == 2: if IDWindex == 2:
...@@ -186,7 +193,7 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru ...@@ -186,7 +193,7 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru
psfWeight[ipsf] = 1./psfWeight[ipsf] psfWeight[ipsf] = 1./psfWeight[ipsf]
psfWeight /= np.sum(psfWeight) psfWeight /= np.sum(psfWeight)
psfMaker = np.zeros([ngy, ngx], dtype=np.float32) psfMaker = np.zeros([ngy, ngx], dtype=np.float32)
for ipsf in range(npsf): for ipsf in range(npsf):
if OnlyNeighbors == True: if OnlyNeighbors == True:
if neighFlag[ipsf] != 1: if neighFlag[ipsf] != 1:
...@@ -201,15 +208,14 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru ...@@ -201,15 +208,14 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru
return psfMaker return psfMaker
### define PSFInterp###
###define PSFInterp###
class PSFInterp(PSFModel): class PSFInterp(PSFModel):
def __init__(self, chip, npsf=NPSF, PSF_data=None, PSF_data_file=None, PSF_data_prefix="", sigSpin=0, psfRa=0.15, HocBuild=False, LOG_DEBUG=False): def __init__(self, chip, npsf=NPSF, PSF_data=None, PSF_data_file=None, PSF_data_prefix="", sigSpin=0, psfRa=0.15, HocBuild=False, LOG_DEBUG=False):
self.LOG_DEBUG = LOG_DEBUG self.LOG_DEBUG = LOG_DEBUG
if self.LOG_DEBUG: if self.LOG_DEBUG:
print('===================================================') print('===================================================')
print('DEBUG: psf module for csstSim ' \ print('DEBUG: psf module for csstSim '
+time.strftime("(%Y-%m-%d %H:%M:%S)", time.localtime()), flush=True) + time.strftime("(%Y-%m-%d %H:%M:%S)", time.localtime()), flush=True)
print('===================================================') print('===================================================')
self.sigSpin = sigSpin self.sigSpin = sigSpin
...@@ -221,53 +227,62 @@ class PSFInterp(PSFModel): ...@@ -221,53 +227,62 @@ class PSFInterp(PSFModel):
print('Error - PSF_data_file is None') print('Error - PSF_data_file is None')
sys.exit() sys.exit()
self.nwave= self._getPSFwave(self.iccd, PSF_data_file, PSF_data_prefix) self.nwave = self._getPSFwave(
self.iccd, PSF_data_file, PSF_data_prefix)
self.npsf = npsf self.npsf = npsf
self.PSF_data = self._loadPSF(self.iccd, PSF_data_file, PSF_data_prefix) self.PSF_data = self._loadPSF(
self.iccd, PSF_data_file, PSF_data_prefix)
if self.LOG_DEBUG: if self.LOG_DEBUG:
print('nwave-{:} on ccd-{:}::'.format(self.nwave, self.iccd), flush=True) print('nwave-{:} on ccd-{:}::'.format(self.nwave,
self.iccd), flush=True)
print('self.PSF_data ... ok', flush=True) print('self.PSF_data ... ok', flush=True)
print('Preparing self.[psfMat,cen_col,cen_row] for psfMaker ... ', end='', flush=True) print(
'Preparing self.[psfMat,cen_col,cen_row] for psfMaker ... ', end='', flush=True)
ngy, ngx = self.PSF_data[0][0]['psfMat'].shape
self.psfMat = np.zeros([self.nwave, self.npsf, ngy, ngx], dtype=np.float32) ngy, ngx = self.PSF_data[0][0]['psfMat'].shape
self.cen_col= np.zeros([self.nwave, self.npsf], dtype=np.float32) self.psfMat = np.zeros(
self.cen_row= np.zeros([self.nwave, self.npsf], dtype=np.float32) [self.nwave, self.npsf, ngy, ngx], dtype=np.float32)
self.hoc =[] self.cen_col = np.zeros([self.nwave, self.npsf], dtype=np.float32)
self.hoclist=[] self.cen_row = np.zeros([self.nwave, self.npsf], dtype=np.float32)
self.hoc = []
self.hoclist = []
for twave in range(self.nwave): for twave in range(self.nwave):
for tpsf in range(self.npsf): for tpsf in range(self.npsf):
self.psfMat[twave, tpsf, :, :] = self.PSF_data[twave][tpsf]['psfMat'] self.psfMat[twave, tpsf, :,
self.PSF_data[twave][tpsf]['psfMat'] = 0 ###free psfMat :] = self.PSF_data[twave][tpsf]['psfMat']
self.PSF_data[twave][tpsf]['psfMat'] = 0 # free psfMat
self.pixsize = self.PSF_data[twave][tpsf]['pixsize']*1e-3 ##mm self.pixsize = self.PSF_data[twave][tpsf]['pixsize']*1e-3 # mm
self.cen_col[twave, tpsf] = self.PSF_data[twave][tpsf]['image_x'] + self.PSF_data[twave][tpsf]['centroid_x'] self.cen_col[twave, tpsf] = self.PSF_data[twave][tpsf]['image_x'] + \
self.cen_row[twave, tpsf] = self.PSF_data[twave][tpsf]['image_y'] + self.PSF_data[twave][tpsf]['centroid_y'] self.PSF_data[twave][tpsf]['centroid_x']
self.cen_row[twave, tpsf] = self.PSF_data[twave][tpsf]['image_y'] + \
self.PSF_data[twave][tpsf]['centroid_y']
if HocBuild: if HocBuild:
#hoclist on twave for neighborsFinding # hoclist on twave for neighborsFinding
hoc,hoclist = findNeighbors_hoclist(self.cen_col[twave], self.cen_row[twave]) hoc, hoclist = findNeighbors_hoclist(
self.cen_col[twave], self.cen_row[twave])
self.hoc.append(hoc) self.hoc.append(hoc)
self.hoclist.append(hoclist) self.hoclist.append(hoclist)
if self.LOG_DEBUG: if self.LOG_DEBUG:
print('ok', flush=True) print('ok', flush=True)
def _getPSFwave(self, iccd, PSF_data_file, PSF_data_prefix): def _getPSFwave(self, iccd, PSF_data_file, PSF_data_prefix):
# fq = h5py.File(PSF_data_file+'/' +PSF_data_prefix +'psfCube_ccd{:}.h5'.format(iccd), 'r') # fq = h5py.File(PSF_data_file+'/' +PSF_data_prefix +'psfCube_ccd{:}.h5'.format(iccd), 'r')
fq = h5py.File(PSF_data_file+'/' +PSF_data_prefix +'psfCube_{:}.h5'.format(iccd), 'r') fq = h5py.File(PSF_data_file+'/' + PSF_data_prefix +
'psfCube_{:}.h5'.format(iccd), 'r')
nwave = len(fq.keys()) nwave = len(fq.keys())
fq.close() fq.close()
return nwave return nwave
def _loadPSF(self, iccd, PSF_data_file, PSF_data_prefix): def _loadPSF(self, iccd, PSF_data_file, PSF_data_prefix):
psfSet = [] psfSet = []
# fq = h5py.File(PSF_data_file+'/' +PSF_data_prefix +'psfCube_ccd{:}.h5'.format(iccd), 'r') # fq = h5py.File(PSF_data_file+'/' +PSF_data_prefix +'psfCube_ccd{:}.h5'.format(iccd), 'r')
fq = h5py.File(PSF_data_file+'/' +PSF_data_prefix +'psfCube_{:}.h5'.format(iccd), 'r') fq = h5py.File(PSF_data_file+'/' + PSF_data_prefix +
'psfCube_{:}.h5'.format(iccd), 'r')
for ii in range(self.nwave): for ii in range(self.nwave):
iwave = ii+1 iwave = ii+1
psfWave = [] psfWave = []
...@@ -276,30 +291,30 @@ class PSFInterp(PSFModel): ...@@ -276,30 +291,30 @@ class PSFInterp(PSFModel):
for jj in range(self.npsf): for jj in range(self.npsf):
ipsf = jj+1 ipsf = jj+1
psfInfo = {} psfInfo = {}
psfInfo['wavelength']= fq_iwave['wavelength'][()] psfInfo['wavelength'] = fq_iwave['wavelength'][()]
fq_iwave_ipsf = fq_iwave['psf_{:}'.format(ipsf)] fq_iwave_ipsf = fq_iwave['psf_{:}'.format(ipsf)]
psfInfo['pixsize'] = PixSizeInMicrons psfInfo['pixsize'] = PixSizeInMicrons
psfInfo['field_x'] = fq_iwave_ipsf['field_x'][()] psfInfo['field_x'] = fq_iwave_ipsf['field_x'][()]
psfInfo['field_y'] = fq_iwave_ipsf['field_y'][()] psfInfo['field_y'] = fq_iwave_ipsf['field_y'][()]
psfInfo['image_x'] = fq_iwave_ipsf['image_x'][()] psfInfo['image_x'] = fq_iwave_ipsf['image_x'][()]
psfInfo['image_y'] = fq_iwave_ipsf['image_y'][()] psfInfo['image_y'] = fq_iwave_ipsf['image_y'][()]
psfInfo['centroid_x']= fq_iwave_ipsf['cx'][()] psfInfo['centroid_x'] = fq_iwave_ipsf['cx'][()]
psfInfo['centroid_y']= fq_iwave_ipsf['cy'][()] psfInfo['centroid_y'] = fq_iwave_ipsf['cy'][()]
psfInfo['psfMat'] = fq_iwave_ipsf['psfMat'][()] psfInfo['psfMat'] = fq_iwave_ipsf['psfMat'][()]
psfWave.append(psfInfo) psfWave.append(psfInfo)
psfSet.append(psfWave) psfSet.append(psfWave)
fq.close() fq.close()
if self.LOG_DEBUG: if self.LOG_DEBUG:
print('psfSet has been loaded:', flush=True) print('psfSet has been loaded:', flush=True)
print('psfSet[iwave][ipsf][keys]:', psfSet[0][0].keys(), flush=True) print('psfSet[iwave][ipsf][keys]:',
psfSet[0][0].keys(), flush=True)
return psfSet return psfSet
def _findWave(self, bandpass): def _findWave(self, bandpass):
if isinstance(bandpass,int): if isinstance(bandpass, int):
twave = bandpass twave = bandpass
return twave return twave
...@@ -308,7 +323,6 @@ class PSFInterp(PSFModel): ...@@ -308,7 +323,6 @@ class PSFInterp(PSFModel):
if bandpass.blue_limit < bandwave and bandwave < bandpass.red_limit: if bandpass.blue_limit < bandwave and bandwave < bandpass.red_limit:
return twave return twave
return -1 return -1
def get_PSF(self, chip, pos_img, bandpass, galsimGSObject=True, findNeighMode='treeFind', folding_threshold=5.e-3, pointing_pa=0.0): def get_PSF(self, chip, pos_img, bandpass, galsimGSObject=True, findNeighMode='treeFind', folding_threshold=5.e-3, pointing_pa=0.0):
""" """
...@@ -323,7 +337,7 @@ class PSFInterp(PSFModel): ...@@ -323,7 +337,7 @@ class PSFInterp(PSFModel):
Returns: Returns:
PSF: A 'galsim.GSObject'. PSF: A 'galsim.GSObject'.
""" """
pixSize = np.rad2deg(self.pixsize*1e-3/28)*3600 #set psf pixsize pixSize = np.rad2deg(self.pixsize*1e-3/28)*3600 # set psf pixsize
# assert self.iccd == int(chip.getChipLabel(chipID=chip.chipID)), 'ERROR: self.iccd != chip.chipID' # assert self.iccd == int(chip.getChipLabel(chipID=chip.chipID)), 'ERROR: self.iccd != chip.chipID'
twave = self._findWave(bandpass) twave = self._findWave(bandpass)
...@@ -331,16 +345,18 @@ class PSFInterp(PSFModel): ...@@ -331,16 +345,18 @@ class PSFInterp(PSFModel):
print("!!!PSF bandpass does not match.") print("!!!PSF bandpass does not match.")
exit() exit()
PSFMat = self.psfMat[twave] PSFMat = self.psfMat[twave]
cen_col= self.cen_col[twave] cen_col = self.cen_col[twave]
cen_row= self.cen_row[twave] cen_row = self.cen_row[twave]
px = (pos_img.x - chip.cen_pix_x)*0.01 px = (pos_img.x - chip.cen_pix_x)*0.01
py = (pos_img.y - chip.cen_pix_y)*0.01 py = (pos_img.y - chip.cen_pix_y)*0.01
if findNeighMode == 'treeFind': if findNeighMode == 'treeFind':
imPSF = psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=True, PSFCentroidWgt=True) imPSF = psfMaker_IDW(px, py, PSFMat, cen_col, cen_row,
IDWindex=2, OnlyNeighbors=True, PSFCentroidWgt=True)
if findNeighMode == 'hoclistFind': if findNeighMode == 'hoclistFind':
assert(self.hoc != 0), 'hoclist should be built correctly!' assert (self.hoc != 0), 'hoclist should be built correctly!'
imPSF = psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=True, hoc=self.hoc[twave], hoclist=self.hoclist[twave], PSFCentroidWgt=True) imPSF = psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=True,
hoc=self.hoc[twave], hoclist=self.hoclist[twave], PSFCentroidWgt=True)
''' '''
############TEST: START ############TEST: START
...@@ -353,20 +369,21 @@ class PSFInterp(PSFModel): ...@@ -353,20 +369,21 @@ class PSFInterp(PSFModel):
''' '''
if galsimGSObject: if galsimGSObject:
imPSFt = np.zeros([257,257]) imPSFt = np.zeros([257, 257])
imPSFt[0:256, 0:256] = imPSF imPSFt[0:256, 0:256] = imPSF
# imPSFt[120:130, 0:256] = 1. # imPSFt[120:130, 0:256] = 1.
img = galsim.ImageF(imPSFt, scale=pixSize) img = galsim.ImageF(imPSFt, scale=pixSize)
gsp = galsim.GSParams(folding_threshold=folding_threshold) gsp = galsim.GSParams(folding_threshold=folding_threshold)
############TEST: START # TEST: START
# Use sheared PSF to test the PSF orientation # Use sheared PSF to test the PSF orientation
# self.psf = galsim.InterpolatedImage(img, gsparams=gsp).shear(g1=0.8, g2=0.) # self.psf = galsim.InterpolatedImage(img, gsparams=gsp).shear(g1=0.8, g2=0.)
############TEST: END # TEST: END
self.psf = galsim.InterpolatedImage(img, gsparams=gsp) self.psf = galsim.InterpolatedImage(img, gsparams=gsp)
wcs = chip.img.wcs.local(pos_img) wcs = chip.img.wcs.local(pos_img)
scale = galsim.PixelScale(0.074) scale = galsim.PixelScale(0.074)
self.psf = wcs.toWorld(scale.toImage(self.psf), image_pos=(pos_img)) self.psf = wcs.toWorld(scale.toImage(
self.psf), image_pos=(pos_img))
# return self.PSFspin(x=px/0.01, y=py/0.01) # return self.PSFspin(x=px/0.01, y=py/0.01)
return self.psf, galsim.Shear(e=0., beta=(np.pi/2)*galsim.radians) return self.psf, galsim.Shear(e=0., beta=(np.pi/2)*galsim.radians)
......
...@@ -4,6 +4,7 @@ PSF interpolation for CSST-Sim ...@@ -4,6 +4,7 @@ PSF interpolation for CSST-Sim
NOTE: [iccd, iwave, ipsf] are counted from 1 to n, but [tccd, twave, tpsf] are counted from 0 to n-1 NOTE: [iccd, iwave, ipsf] are counted from 1 to n, but [tccd, twave, tpsf] are counted from 0 to n-1
''' '''
import yaml
import sys import sys
import time import time
import copy import copy
...@@ -12,8 +13,9 @@ import scipy.spatial as spatial ...@@ -12,8 +13,9 @@ import scipy.spatial as spatial
import galsim import galsim
import h5py import h5py
from ObservationSim.PSF.PSFModel import PSFModel from observation_sim.instruments import Filter, FilterParam, Chip
from ObservationSim.Instrument.Chip import ChipUtils as chip_utils from observation_sim.psf.PSFModel import PSFModel
from observation_sim.instruments.chip import chip_utils
import os import os
from astropy.io import fits from astropy.io import fits
...@@ -21,12 +23,12 @@ from astropy.modeling.models import Gaussian2D ...@@ -21,12 +23,12 @@ from astropy.modeling.models import Gaussian2D
from scipy import signal from scipy import signal
LOG_DEBUG = False #***# LOG_DEBUG = False # ***#
NPSF = 900 #***# 30*30 NPSF = 900 # ***# 30*30
PixSizeInMicrons = 5. #***# in microns PIX_SIZE_MICRON = 5. # ***# in microns
###find neighbors-KDtree### ### find neighbors-KDtree###
# def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True): # def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True):
# """ # """
# find nearest neighbors by 2D-KDTree # find nearest neighbors by 2D-KDTree
...@@ -208,36 +210,35 @@ PixSizeInMicrons = 5. #***# in microns ...@@ -208,36 +210,35 @@ PixSizeInMicrons = 5. #***# in microns
# return psfMaker # return psfMaker
### define PSFInterp###
###define PSFInterp###
class PSFInterpSLS(PSFModel): class PSFInterpSLS(PSFModel):
def __init__(self, chip, filt,PSF_data_prefix="", sigSpin=0, psfRa=0.15, pix_size = 0.005): def __init__(self, chip, filt, PSF_data_prefix="", sigSpin=0, psfRa=0.15, pix_size=0.005):
if LOG_DEBUG: if LOG_DEBUG:
print('===================================================') print('===================================================')
print('DEBUG: psf module for csstSim ' \ print('DEBUG: psf module for csstSim '
+time.strftime("(%Y-%m-%d %H:%M:%S)", time.localtime()), flush=True) + time.strftime("(%Y-%m-%d %H:%M:%S)", time.localtime()), flush=True)
print('===================================================') print('===================================================')
self.sigSpin = sigSpin self.sigSpin = sigSpin
self.sigGauss = psfRa self.sigGauss = psfRa
self.grating_ids = chip_utils.getChipSLSGratingID(chip.chipID) self.grating_ids = chip_utils.getChipSLSGratingID(chip.chipID)
_,self.grating_type = chip.getChipFilter(chipID=chip.chipID) _, self.grating_type = chip.getChipFilter(chipID=chip.chipID)
self.data_folder = PSF_data_prefix self.data_folder = PSF_data_prefix
self.getPSFDataFromFile(filt) self.getPSFDataFromFile(filt)
self.pixsize = pix_size # um self.pixsize = pix_size # um
def getPSFDataFromFile(self, filt): def getPSFDataFromFile(self, filt):
gratingInwavelist = {'GU':0,'GV':1,'GI':2} gratingInwavelist = {'GU': 0, 'GV': 1, 'GI': 2}
grating_orders = ['0','1'] grating_orders = ['0', '1']
waveListFn = self.data_folder + '/wavelist.dat' waveListFn = self.data_folder + '/wavelist.dat'
wavelists = np.loadtxt(waveListFn) wavelists = np.loadtxt(waveListFn)
self.waveList = wavelists[:,gratingInwavelist[self.grating_type]] self.waveList = wavelists[:, gratingInwavelist[self.grating_type]]
bandranges = np.zeros([4,2]) bandranges = np.zeros([4, 2])
midBand = (self.waveList[0:3] + self.waveList[1:4])/2.*10000. midBand = (self.waveList[0:3] + self.waveList[1:4])/2.*10000.
bandranges[0,0] = filt.blue_limit bandranges[0, 0] = filt.blue_limit
bandranges[1:4,0] = midBand bandranges[1:4, 0] = midBand
bandranges[0:3, 1] = midBand bandranges[0:3, 1] = midBand
bandranges[3,1] = filt.red_limit bandranges[3, 1] = filt.red_limit
self.bandranges = bandranges self.bandranges = bandranges
...@@ -246,7 +247,7 @@ class PSFInterpSLS(PSFModel): ...@@ -246,7 +247,7 @@ class PSFInterpSLS(PSFModel):
for g_order in grating_orders: for g_order in grating_orders:
g_folder_order = g_folder + 'PSF_Order_' + g_order + '/' g_folder_order = g_folder + 'PSF_Order_' + g_order + '/'
grating_order_data = {} grating_order_data = {}
for bandi in [1,2,3,4]: for bandi in [1, 2, 3, 4]:
subBand_data = {} subBand_data = {}
subBand_data['bandrange'] = bandranges[bandi-1] subBand_data['bandrange'] = bandranges[bandi-1]
final_folder = g_folder_order + str(bandi) + '/' final_folder = g_folder_order + str(bandi) + '/'
...@@ -305,7 +306,7 @@ class PSFInterpSLS(PSFModel): ...@@ -305,7 +306,7 @@ class PSFInterpSLS(PSFModel):
# psfInfo['wavelength']= fq_iwave['wavelength'][()] # psfInfo['wavelength']= fq_iwave['wavelength'][()]
# #
# fq_iwave_ipsf = fq_iwave['psf_{:}'.format(ipsf)] # fq_iwave_ipsf = fq_iwave['psf_{:}'.format(ipsf)]
# psfInfo['pixsize'] = PixSizeInMicrons # psfInfo['pixsize'] = PIX_SIZE_MICRON
# psfInfo['field_x'] = fq_iwave_ipsf['field_x'][()] # psfInfo['field_x'] = fq_iwave_ipsf['field_x'][()]
# psfInfo['field_y'] = fq_iwave_ipsf['field_y'][()] # psfInfo['field_y'] = fq_iwave_ipsf['field_y'][()]
# psfInfo['image_x'] = fq_iwave_ipsf['image_x'][()] # psfInfo['image_x'] = fq_iwave_ipsf['image_x'][()]
...@@ -342,7 +343,7 @@ class PSFInterpSLS(PSFModel): ...@@ -342,7 +343,7 @@ class PSFInterpSLS(PSFModel):
offset = int(np.ceil(sigma * 3)) offset = int(np.ceil(sigma * 3))
g_size = 2 * offset + 1 g_size = 2 * offset + 1
m_cen = int(g_size / 2) m_cen = int(g_size / 2)
print('-----',g_size) print('-----', g_size)
g_PSF_ = Gaussian2D(1, m_cen, m_cen, sigma, sigma) g_PSF_ = Gaussian2D(1, m_cen, m_cen, sigma, sigma)
yp, xp = np.mgrid[0:g_size, 0:g_size] yp, xp = np.mgrid[0:g_size, 0:g_size]
g_PSF = g_PSF_(xp, yp) g_PSF = g_PSF_(xp, yp)
...@@ -351,8 +352,7 @@ class PSFInterpSLS(PSFModel): ...@@ -351,8 +352,7 @@ class PSFInterpSLS(PSFModel):
convImg = convImg/np.sum(convImg) convImg = convImg/np.sum(convImg)
return convImg return convImg
def get_PSF(self, chip, pos_img_local=[1000, 1000], bandNo=1, galsimGSObject=True, folding_threshold=5.e-3, g_order='A', grating_split_pos=3685):
def get_PSF(self, chip, pos_img_local = [1000,1000], bandNo = 1, galsimGSObject=True, folding_threshold=5.e-3, g_order = 'A', grating_split_pos=3685):
""" """
Get the PSF at a given image position Get the PSF at a given image position
...@@ -365,8 +365,9 @@ class PSFInterpSLS(PSFModel): ...@@ -365,8 +365,9 @@ class PSFInterpSLS(PSFModel):
Returns: Returns:
PSF: A 'galsim.GSObject'. PSF: A 'galsim.GSObject'.
""" """
order_IDs = {'A': '1', 'B': '0' ,'C': '0', 'D': '0', 'E': '0'} order_IDs = {'A': '1', 'B': '0', 'C': '0', 'D': '0', 'E': '0'}
contam_order_sigma = {'C':0.28032344707964174,'D':0.39900182912061344,'E':1.1988309797685412} #arcsec contam_order_sigma = {'C': 0.28032344707964174,
'D': 0.39900182912061344, 'E': 1.1988309797685412} # arcsec
x_start = chip.x_cen/chip.pix_size - chip.npix_x / 2. x_start = chip.x_cen/chip.pix_size - chip.npix_x / 2.
y_start = chip.y_cen/chip.pix_size - chip.npix_y / 2. y_start = chip.y_cen/chip.pix_size - chip.npix_y / 2.
# print(pos_img.x - x_start) # print(pos_img.x - x_start)
...@@ -382,7 +383,6 @@ class PSFInterpSLS(PSFModel): ...@@ -382,7 +383,6 @@ class PSFInterpSLS(PSFModel):
# if grating_order in ['-2','-1','2']: # if grating_order in ['-2','-1','2']:
# grating_order = '1' # grating_order = '1'
# if grating_order in ['0', '1']: # if grating_order in ['0', '1']:
psf_order = psf_data['order'+grating_order] psf_order = psf_data['order'+grating_order]
psf_order_b = psf_order['band'+str(bandNo)] psf_order_b = psf_order['band'+str(bandNo)]
...@@ -396,31 +396,34 @@ class PSFInterpSLS(PSFModel): ...@@ -396,31 +396,34 @@ class PSFInterpSLS(PSFModel):
px = pos_img.x*chip.pix_size px = pos_img.x*chip.pix_size
py = pos_img.y*chip.pix_size py = pos_img.y*chip.pix_size
dist2=(pos_p[:,1] - px)*(pos_p[:,1] - px) + (pos_p[:,0] - py)*(pos_p[:,0] - py) dist2 = (pos_p[:, 1] - px)*(pos_p[:, 1] - px) + \
temp_sort_dist = np.zeros([dist2.shape[0],2]) (pos_p[:, 0] - py)*(pos_p[:, 0] - py)
temp_sort_dist[:, 0] = np.arange(0, dist2.shape[0],1) temp_sort_dist = np.zeros([dist2.shape[0], 2])
temp_sort_dist[:, 0] = np.arange(0, dist2.shape[0], 1)
temp_sort_dist[:, 1] = dist2 temp_sort_dist[:, 1] = dist2
# print(temp_sort_dist) # print(temp_sort_dist)
dits2_sortlist = sorted(temp_sort_dist, key=lambda x:x[1]) dits2_sortlist = sorted(temp_sort_dist, key=lambda x: x[1])
# print(dits2_sortlist) # print(dits2_sortlist)
nearest4p = np.zeros([4,2]) nearest4p = np.zeros([4, 2])
pc_coeff_4p = np.zeros([pc_coeff.data.shape[0],4]) pc_coeff_4p = np.zeros([pc_coeff.data.shape[0], 4])
for i in np.arange(4): for i in np.arange(4):
smaller_ids = int(dits2_sortlist[i][0]) smaller_ids = int(dits2_sortlist[i][0])
nearest4p[i, 0] = pos_p[smaller_ids, 1] nearest4p[i, 0] = pos_p[smaller_ids, 1]
nearest4p[i, 1] = pos_p[smaller_ids, 0] nearest4p[i, 1] = pos_p[smaller_ids, 0]
pc_coeff_4p[:,i] = pc_coeff[:,smaller_ids] pc_coeff_4p[:, i] = pc_coeff[:, smaller_ids]
idw_dist = 1/(np.sqrt((px-nearest4p[:,0]) * (px-nearest4p[:,0]) + (py-nearest4p[:,1]) * (py-nearest4p[:,1]))) idw_dist = 1/(np.sqrt((px-nearest4p[:, 0]) * (px-nearest4p[:, 0]) + (
py-nearest4p[:, 1]) * (py-nearest4p[:, 1])))
coeff_int = np.zeros(pc_coeff.data.shape[0]) coeff_int = np.zeros(pc_coeff.data.shape[0])
for i in np.arange(4): for i in np.arange(4):
coeff_int = coeff_int + pc_coeff_4p[:,i]*idw_dist[i] coeff_int = coeff_int + pc_coeff_4p[:, i]*idw_dist[i]
coeff_int = coeff_int / np.sum(coeff_int) coeff_int = coeff_int / np.sum(coeff_int)
npc = 10 npc = 10
m_size = int(pcs.shape[0]**0.5) m_size = int(pcs.shape[0]**0.5)
PSF_int = np.dot(pcs[:,0:npc],coeff_int[0:npc]).reshape(m_size,m_size) PSF_int = np.dot(pcs[:, 0:npc], coeff_int[0:npc]
).reshape(m_size, m_size)
# PSF_int = PSF_int/np.sum(PSF_int) # PSF_int = PSF_int/np.sum(PSF_int)
PSF_int_trans = np.flipud(np.fliplr(PSF_int)) PSF_int_trans = np.flipud(np.fliplr(PSF_int))
...@@ -434,7 +437,6 @@ class PSFInterpSLS(PSFModel): ...@@ -434,7 +437,6 @@ class PSFInterpSLS(PSFModel):
# from astropy.io import fits # from astropy.io import fits
# fits.writeto(str(bandNo) + '_' + g_order+ '_psf_o.fits', PSF_int_trans) # fits.writeto(str(bandNo) + '_' + g_order+ '_psf_o.fits', PSF_int_trans)
# if g_order in ['C','D','E']: # if g_order in ['C','D','E']:
# g_simgma = contam_order_sigma[g_order]/pixel_size_arc # g_simgma = contam_order_sigma[g_order]/pixel_size_arc
# PSF_int_trans = self.convolveWithGauss(PSF_int_trans,g_simgma) # PSF_int_trans = self.convolveWithGauss(PSF_int_trans,g_simgma)
...@@ -459,24 +461,24 @@ class PSFInterpSLS(PSFModel): ...@@ -459,24 +461,24 @@ class PSFInterpSLS(PSFModel):
pixel_size_arc = np.rad2deg(self.pixsize * 1e-3 / 28) * 3600 pixel_size_arc = np.rad2deg(self.pixsize * 1e-3 / 28) * 3600
img = galsim.ImageF(PSF_int_trans, scale=pixel_size_arc) img = galsim.ImageF(PSF_int_trans, scale=pixel_size_arc)
gsp = galsim.GSParams(folding_threshold=folding_threshold) gsp = galsim.GSParams(folding_threshold=folding_threshold)
############TEST: START # TEST: START
# Use sheared PSF to test the PSF orientation # Use sheared PSF to test the PSF orientation
# self.psf = galsim.InterpolatedImage(img, gsparams=gsp).shear(g1=0.8, g2=0.) # self.psf = galsim.InterpolatedImage(img, gsparams=gsp).shear(g1=0.8, g2=0.)
############TEST: END # TEST: END
self.psf = galsim.InterpolatedImage(img, gsparams=gsp) self.psf = galsim.InterpolatedImage(img, gsparams=gsp)
# if g_order in ['C','D','E']: # if g_order in ['C','D','E']:
# add_psf = galsim.Gaussian(sigma=contam_order_sigma[g_order], flux=1.0) # add_psf = galsim.Gaussian(sigma=contam_order_sigma[g_order], flux=1.0)
# self.psf = galsim.Convolve(self.psf, add_psf) # self.psf = galsim.Convolve(self.psf, add_psf)
wcs = chip.img.wcs.local(pos_img) wcs = chip.img.wcs.local(pos_img)
scale = galsim.PixelScale(0.074) scale = galsim.PixelScale(0.074)
self.psf = wcs.toWorld(scale.toImage(self.psf), image_pos=(pos_img)) self.psf = wcs.toWorld(scale.toImage(
self.psf), image_pos=(pos_img))
# return self.PSFspin(x=px/0.01, y=py/0.01) # return self.PSFspin(x=px/0.01, y=py/0.01)
return self.psf, galsim.Shear(e=0., beta=(np.pi/2)*galsim.radians) return self.psf, galsim.Shear(e=0., beta=(np.pi/2)*galsim.radians)
return PSF_int_trans, PSF_int return PSF_int_trans, PSF_int
# pixSize = np.rad2deg(self.pixsize*1e-3/28)*3600 #set psf pixsize # pixSize = np.rad2deg(self.pixsize*1e-3/28)*3600 #set psf pixsize
# #
# # assert self.iccd == int(chip.getChipLabel(chipID=chip.chipID)), 'ERROR: self.iccd != chip.chipID' # # assert self.iccd == int(chip.getChipLabel(chipID=chip.chipID)), 'ERROR: self.iccd != chip.chipID'
...@@ -547,24 +549,23 @@ class PSFInterpSLS(PSFModel): ...@@ -547,24 +549,23 @@ class PSFInterpSLS(PSFModel):
# PSFshear = galsim.Shear(e=ell, beta=beta*galsim.radians) # PSFshear = galsim.Shear(e=ell, beta=beta*galsim.radians)
# return self.psf.shear(PSFshear), PSFshear # return self.psf.shear(PSFshear), PSFshear
from ObservationSim.Instrument import Filter, FilterParam, Chip
import yaml
if __name__ == '__main__': if __name__ == '__main__':
configfn = '/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_new_sim/csst-simulation/config/config_C6_dev.yaml' configfn = '/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_new_sim/csst-simulation/config/config_C6_dev.yaml'
with open(configfn, "r") as stream: with open(configfn, "r") as stream:
try: try:
config = yaml.safe_load(stream) config = yaml.safe_load(stream)
for key, value in config.items(): for key, value in config.items():
print (key + " : " + str(value)) print(key + " : " + str(value))
except yaml.YAMLError as exc: except yaml.YAMLError as exc:
print(exc) print(exc)
chip = Chip(chipID=1,config=config) chip = Chip(chipID=1, config=config)
filter_id, filter_type = chip.getChipFilter() filter_id, filter_type = chip.getChipFilter()
filt = Filter(filter_id=filter_id, filt = Filter(filter_id=filter_id,
filter_type=filter_type, filter_type=filter_type,
filter_param=FilterParam()) filter_param=FilterParam())
psf_i = PSFInterpSLS(chip, filt,PSF_data_prefix="/Volumes/EAGET/CSST_PSF_data/SLS_PSF_PCA_fp/") psf_i = PSFInterpSLS(
chip, filt, PSF_data_prefix="/Volumes/EAGET/CSST_PSF_data/SLS_PSF_PCA_fp/")
pos_img = galsim.PositionD(x=25155, y=-22060) pos_img = galsim.PositionD(x=25155, y=-22060)
psf_im = psf_i.get_PSF(chip, pos_img = pos_img, g_order = '1') psf_im = psf_i.get_PSF(chip, pos_img=pos_img, g_order='1')
import galsim
import sep
import numpy as np
from scipy.interpolate import interp1d
import pylab as pl
import os
import sys
class PSFModel(object):
def __init__(self, sigSpin=0., psfRa=0.15):
# TODO: what are the nesseary fields in PSFModel class?
pass
def PSFspin(self, psf, sigSpin, sigGauss, dx, dy):
"""
The PSF profile at a given image position relative to the axis center
Parameters:
theta : spin angles in a given exposure in unit of [arcsecond]
dx, dy: relative position to the axis center in unit of [pixels]
Return:
Spinned PSF: g1, g2 and axis ratio 'a/b'
"""
a2Rad = np.pi/(60.0*60.0*180.0)
ff = sigGauss * 0.107 * (1000.0/10.0) # in unit of [pixels]
rc = np.sqrt(dx*dx + dy*dy)
cpix = rc*(sigSpin*a2Rad)
beta = (np.arctan2(dy, dx) + np.pi/2)
ell = cpix**2/(2.0*ff**2+cpix**2)
# ell *= 10.0
qr = np.sqrt((1.0+ell)/(1.0-ell))
# psfShape = galsim.Shear(e=ell, beta=beta)
# g1, g2 = psfShape.g1, psfShape.g2
# qr = np.sqrt((1.0+ell)/(1.0-ell))
# return ell, beta, qr
PSFshear = galsim.Shear(e=ell, beta=beta*galsim.radians)
return psf.shear(PSFshear), PSFshear
import numpy as np import numpy as np
from ObservationSim.MockObject import FlatLED from observation_sim.mock_objects import FlatLED
import galsim import galsim
from astropy.time import Time from astropy.time import Time
...@@ -7,29 +7,34 @@ from datetime import datetime, timezone ...@@ -7,29 +7,34 @@ from datetime import datetime, timezone
import gc import gc
def add_LED_Flat(self, chip, filt, tel, pointing, catalog, obs_param): def add_LED_Flat(self, chip, filt, tel, pointing, catalog, obs_param):
if not hasattr(self, 'h_ext'): if not hasattr(self, 'h_ext'):
_, _ = self.prepare_headers(chip=chip, pointing=pointing) _, _ = self.prepare_headers(chip=chip, pointing=pointing)
chip_wcs = galsim.FitsWCS(header = self.h_ext) chip_wcs = galsim.FitsWCS(header=self.h_ext)
pf_map = np.zeros_like(chip.img.array) pf_map = np.zeros_like(chip.img.array)
if obs_param["LED_TYPE"] is not None: if obs_param["LED_TYPE"] is not None:
if len(obs_param["LED_TYPE"]) != 0: if len(obs_param["LED_TYPE"]) != 0:
print("LED OPEN--------") print("LED OPEN--------")
led_obj = FlatLED(chip, filt) led_obj = FlatLED(chip, filt)
led_flat, ledstat, letts = led_obj.drawObj_LEDFlat(led_type_list=obs_param["LED_TYPE"], exp_t_list=obs_param["LED_TIME"]) led_flat, ledstat, letts = led_obj.drawObj_LEDFlat(
led_type_list=obs_param["LED_TYPE"], exp_t_list=obs_param["LED_TIME"])
pf_map = led_flat pf_map = led_flat
self.updateHeaderInfo(header_flag='ext', keys = ['LEDSTAT'], values = [ledstat]) self.updateHeaderInfo(header_flag='ext', keys=[
self.updateHeaderInfo(header_flag='ext', keys = ['LEDT01','LEDT02','LEDT03','LEDT04','LEDT05','LEDT06','LEDT07','LEDT08','LEDT09','LEDT10','LEDT11','LEDT12','LEDT13','LEDT14'], values = letts) 'LEDSTAT'], values=[ledstat])
self.updateHeaderInfo(header_flag='ext', keys=['LEDT01', 'LEDT02', 'LEDT03', 'LEDT04', 'LEDT05', 'LEDT06',
'LEDT07', 'LEDT08', 'LEDT09', 'LEDT10', 'LEDT11', 'LEDT12', 'LEDT13', 'LEDT14'], values=letts)
if obs_param["shutter_effect"] == True: if obs_param["shutter_effect"] == True:
pf_map = pf_map * chip.shutter_img pf_map = pf_map * chip.shutter_img
pf_map = np.array(pf_map, dtype='float32') pf_map = np.array(pf_map, dtype='float32')
self.updateHeaderInfo(header_flag='ext', keys = ['SHTSTAT'], values = [True]) self.updateHeaderInfo(header_flag='ext', keys=[
'SHTSTAT'], values=[True])
else: else:
self.updateHeaderInfo(header_flag='ext', keys = ['SHTSTAT','SHTOPEN1','SHTCLOS0'], values = [True,self.h_ext['SHTCLOS1'],self.h_ext['SHTOPEN0']]) self.updateHeaderInfo(header_flag='ext', keys=['SHTSTAT', 'SHTOPEN1', 'SHTCLOS0'], values=[
True, self.h_ext['SHTCLOS1'], self.h_ext['SHTOPEN0']])
chip.img = chip.img + pf_map chip.img = chip.img + pf_map
...@@ -37,15 +42,18 @@ def add_LED_Flat(self, chip, filt, tel, pointing, catalog, obs_param): ...@@ -37,15 +42,18 @@ def add_LED_Flat(self, chip, filt, tel, pointing, catalog, obs_param):
datetime_obs = datetime.utcfromtimestamp(pointing.timestamp) datetime_obs = datetime.utcfromtimestamp(pointing.timestamp)
datetime_obs = datetime_obs.replace(tzinfo=timezone.utc) datetime_obs = datetime_obs.replace(tzinfo=timezone.utc)
t_obs = Time(datetime_obs) t_obs = Time(datetime_obs)
##ccd刷新2s,等待0.5s,开灯后等待0.5s,开始曝光 # ccd刷新2s,等待0.5s,开灯后等待0.5s,开始曝光
t_obs_renew = Time(t_obs.mjd - (2.) / 86400., format="mjd") t_obs_renew = Time(t_obs.mjd - (2.) / 86400., format="mjd")
t_obs_utc = datetime.utcfromtimestamp(np.round(datetime.utcfromtimestamp(t_obs_renew.unix).replace(tzinfo=timezone.utc).timestamp(), 1)) t_obs_utc = datetime.utcfromtimestamp(np.round(datetime.utcfromtimestamp(
self.updateHeaderInfo(header_flag='prim', keys = ['DATE-OBS'], values = [t_obs_utc.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-5]]) t_obs_renew.unix).replace(tzinfo=timezone.utc).timestamp(), 1))
self.updateHeaderInfo(header_flag='prim', keys=[
'DATE-OBS'], values=[t_obs_utc.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-5]])
#dark time : # dark time :
self.updateHeaderInfo(header_flag='ext', keys = ['DARKTIME'], values = [pointing.exp_time]) self.updateHeaderInfo(header_flag='ext', keys=[
'DARKTIME'], values=[pointing.exp_time])
gc.collect() gc.collect()
return chip, filt, tel, pointing return chip, filt, tel, pointing
\ No newline at end of file
import numpy as np import numpy as np
import galsim import galsim
from ObservationSim.Instrument.Chip import ChipUtils as chip_utils from observation_sim.instruments.chip import chip_utils
from ObservationSim.Instrument.Chip.libCTI.CTI_modeling import CTI_sim from observation_sim.instruments.chip.libCTI.CTI_modeling import CTI_sim
def add_brighter_fatter(self, chip, filt, tel, pointing, catalog, obs_param): def add_brighter_fatter(self, chip, filt, tel, pointing, catalog, obs_param):
chip.img = chip_utils.add_brighter_fatter(img=chip.img) chip.img = chip_utils.add_brighter_fatter(img=chip.img)
return chip, filt, tel, pointing return chip, filt, tel, pointing
def apply_CTE(self, chip, filt, tel, pointing, catalog, obs_param): def apply_CTE(self, chip, filt, tel, pointing, catalog, obs_param):
self.chip_output.Log_info(" Apply CTE Effect") self.chip_output.Log_info(" Apply CTE Effect")
### 2*8 -> 1*16 img-layout # 2*8 -> 1*16 img-layout
img = chip_utils.formatOutput(GSImage=chip.img) img = chip_utils.formatOutput(GSImage=chip.img)
chip.nsecy = 1 chip.nsecy = 1
chip.nsecx = 16 chip.nsecx = 16
...@@ -20,23 +22,26 @@ def apply_CTE(self, chip, filt, tel, pointing, catalog, obs_param): ...@@ -20,23 +22,26 @@ def apply_CTE(self, chip, filt, tel, pointing, catalog, obs_param):
dy = int(ny/chip.nsecy) dy = int(ny/chip.nsecy)
newimg = galsim.Image(nx, int(ny+chip.overscan_y), init_value=0) newimg = galsim.Image(nx, int(ny+chip.overscan_y), init_value=0)
for ichannel in range(16): for ichannel in range(16):
print('\n***add CTI effects: pointing-{:} chip-{:} channel-{:}***'.format(pointing.id, chip.chipID, ichannel+1)) print('\n***add CTI effects: pointing-{:} chip-{:} channel-{:}***'.format(
pointing.id, chip.chipID, ichannel+1))
noverscan, nsp, nmax = chip.overscan_y, 3, 10 noverscan, nsp, nmax = chip.overscan_y, 3, 10
beta, w, c = 0.478, 84700, 0 beta, w, c = 0.478, 84700, 0
t = np.array([0.74, 7.7, 37],dtype=np.float32) t = np.array([0.74, 7.7, 37], dtype=np.float32)
rho_trap = np.array([0.6, 1.6, 1.4],dtype=np.float32) rho_trap = np.array([0.6, 1.6, 1.4], dtype=np.float32)
trap_seeds = np.array([0, 1000, 10000],dtype=np.int32) + ichannel + chip.chipID*16 trap_seeds = np.array(
release_seed = 50 + ichannel + pointing.id*30 + chip.chipID*16 [0, 1000, 10000], dtype=np.int32) + ichannel + chip.chipID*16
newimg.array[:, 0+ichannel*dx:dx+ichannel*dx] = CTI_sim(img_arr[:, 0+ichannel*dx:dx+ichannel*dx],dx,dy,noverscan,nsp,nmax,beta,w,c,t,rho_trap,trap_seeds,release_seed) release_seed = 50 + ichannel + pointing.id*30 + chip.chipID*16
newimg.array[:, 0+ichannel*dx:dx+ichannel*dx] = CTI_sim(
img_arr[:, 0+ichannel*dx:dx+ichannel*dx], dx, dy, noverscan, nsp, nmax, beta, w, c, t, rho_trap, trap_seeds, release_seed)
newimg.wcs = img.wcs newimg.wcs = img.wcs
del img del img
img = newimg img = newimg
### 1*16 -> 2*8 img-layout # 1*16 -> 2*8 img-layout
chip.img = chip_utils.formatRevert(GSImage=img) chip.img = chip_utils.formatRevert(GSImage=img)
chip.nsecy = 2 chip.nsecy = 2
chip.nsecx = 8 chip.nsecx = 8
# [TODO] make overscan_y == 0 # [TODO] make overscan_y == 0
chip.overscan_y = 0 chip.overscan_y = 0
return chip, filt, tel, pointing return chip, filt, tel, pointing
\ No newline at end of file
from ObservationSim.Instrument.Chip import ChipUtils as chip_utils from observation_sim.instruments.chip import chip_utils
def add_cosmic_rays(self, chip, filt, tel, pointing, catalog, obs_param): def add_cosmic_rays(self, chip, filt, tel, pointing, catalog, obs_param):
self.chip_output.Log_info(" Adding Cosmic-Ray") self.chip_output.Log_info(" Adding Cosmic-Ray")
# Get exposure time # Get exposure time
if (obs_param) and ("exptime" in obs_param) and (obs_param["exptime"] is not None): if (obs_param) and ("exptime" in obs_param) and (obs_param["exptime"] is not None):
exptime = obs_param["exptime"] exptime = obs_param["exptime"]
...@@ -10,9 +11,9 @@ def add_cosmic_rays(self, chip, filt, tel, pointing, catalog, obs_param): ...@@ -10,9 +11,9 @@ def add_cosmic_rays(self, chip, filt, tel, pointing, catalog, obs_param):
exptime = pointing.exp_time exptime = pointing.exp_time
chip.img, crmap_gsimg, cr_event_num = chip_utils.add_cosmic_rays( chip.img, crmap_gsimg, cr_event_num = chip_utils.add_cosmic_rays(
img=chip.img, img=chip.img,
chip=chip, chip=chip,
exptime=exptime, exptime=exptime,
seed=self.overall_config["random_seeds"]["seed_CR"]+pointing.id*30+chip.chipID) seed=self.overall_config["random_seeds"]["seed_CR"]+pointing.id*30+chip.chipID)
# Save cosmic ray image # Save cosmic ray image
if (obs_param) and ("save_cosmic_img" in obs_param) and (obs_param["save_cosmic_img"] is not None): if (obs_param) and ("save_cosmic_img" in obs_param) and (obs_param["save_cosmic_img"] is not None):
...@@ -27,4 +28,4 @@ def add_cosmic_rays(self, chip, filt, tel, pointing, catalog, obs_param): ...@@ -27,4 +28,4 @@ def add_cosmic_rays(self, chip, filt, tel, pointing, catalog, obs_param):
project_cycle=self.overall_config["project_cycle"], project_cycle=self.overall_config["project_cycle"],
run_counter=self.overall_config["run_counter"] run_counter=self.overall_config["run_counter"]
) )
return chip, filt, tel, pointing return chip, filt, tel, pointing
\ No newline at end of file
...@@ -4,8 +4,8 @@ import psutil ...@@ -4,8 +4,8 @@ import psutil
import traceback import traceback
import numpy as np import numpy as np
import galsim import galsim
from ObservationSim._util import get_shear_field from observation_sim._util import get_shear_field
from ObservationSim.PSF import PSFGauss, FieldDistortion, PSFInterp, PSFInterpSLS from observation_sim.psf import PSFGauss, FieldDistortion, PSFInterp, PSFInterpSLS
from astropy.time import Time from astropy.time import Time
from datetime import datetime, timezone from datetime import datetime, timezone
......
from numpy.random import Generator, PCG64 from numpy.random import Generator, PCG64
from ObservationSim.Instrument.Chip import ChipUtils as chip_utils from observation_sim.instruments.chip import chip_utils
from ObservationSim.Instrument.Chip import Effects from observation_sim.instruments.chip import effects
def apply_PRNU(self, chip, filt, tel, pointing, catalog, obs_param): def apply_PRNU(self, chip, filt, tel, pointing, catalog, obs_param):
chip.img *= chip.prnu_img chip.img *= chip.prnu_img
if self.overall_config["output_setting"]["prnu_output"] == True: if self.overall_config["output_setting"]["prnu_output"] == True:
chip.prnu_img.write("%s/FlatImg_PRNU_%s.fits" % (self.chip_output.subdir, str(chip.chipID).rjust(2, '0'))) chip.prnu_img.write("%s/FlatImg_PRNU_%s.fits" %
(self.chip_output.subdir, str(chip.chipID).rjust(2, '0')))
return chip, filt, tel, pointing return chip, filt, tel, pointing
def add_poisson_and_dark(self, chip, filt, tel, pointing, catalog, obs_param): def add_poisson_and_dark(self, chip, filt, tel, pointing, catalog, obs_param):
# Add dark current & Poisson noise # Add dark current & Poisson noise
# Get exposure time # Get exposure time
...@@ -15,61 +18,68 @@ def add_poisson_and_dark(self, chip, filt, tel, pointing, catalog, obs_param): ...@@ -15,61 +18,68 @@ def add_poisson_and_dark(self, chip, filt, tel, pointing, catalog, obs_param):
exptime = obs_param["exptime"] exptime = obs_param["exptime"]
else: else:
exptime = pointing.exp_time exptime = pointing.exp_time
if obs_param["add_dark"] == True: if obs_param["add_dark"] == True:
chip.img, _ = chip_utils.add_poisson(img=chip.img, chip.img, _ = chip_utils.add_poisson(img=chip.img,
chip=chip, chip=chip,
exptime=pointing.exp_time, exptime=pointing.exp_time,
poisson_noise=chip.poisson_noise, poisson_noise=chip.poisson_noise,
InputDark=None) InputDark=None)
else: else:
chip.img, _ = chip_utils.add_poisson(img=chip.img, chip.img, _ = chip_utils.add_poisson(img=chip.img,
chip=self, chip=self,
exptime=exptime, exptime=exptime,
poisson_noise=chip.poisson_noise, poisson_noise=chip.poisson_noise,
dark_noise=0.) dark_noise=0.)
return chip, filt, tel, pointing return chip, filt, tel, pointing
def add_detector_defects(self, chip, filt, tel, pointing, catalog, obs_param): def add_detector_defects(self, chip, filt, tel, pointing, catalog, obs_param):
# Add Hot Pixels or/and Dead Pixels # Add Hot Pixels or/and Dead Pixels
rgbadpix = Generator(PCG64(int(self.overall_config["random_seeds"]["seed_defective"]+chip.chipID))) rgbadpix = Generator(
PCG64(int(self.overall_config["random_seeds"]["seed_defective"]+chip.chipID)))
badfraction = 5E-5*(rgbadpix.random()*0.5+0.7) badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
chip.img = Effects.DefectivePixels( chip.img = effects.DefectivePixels(
chip.img, chip.img,
IfHotPix=obs_param["hot_pixels"], IfHotPix=obs_param["hot_pixels"],
IfDeadPix=obs_param["dead_pixels"], IfDeadPix=obs_param["dead_pixels"],
fraction=badfraction, fraction=badfraction,
seed=self.overall_config["random_seeds"]["seed_defective"]+chip.chipID, biaslevel=0) seed=self.overall_config["random_seeds"]["seed_defective"]+chip.chipID, biaslevel=0)
# Apply Bad columns # Apply Bad columns
if obs_param["bad_columns"] == True: if obs_param["bad_columns"] == True:
chip.img = Effects.BadColumns(chip.img, chip.img = effects.BadColumns(chip.img,
seed=self.overall_config["random_seeds"]["seed_badcolumns"], seed=self.overall_config["random_seeds"]["seed_badcolumns"],
chipid=chip.chipID) chipid=chip.chipID)
return chip, filt, tel, pointing return chip, filt, tel, pointing
def add_nonlinearity(self, chip, filt, tel, pointing, catalog, obs_param): def add_nonlinearity(self, chip, filt, tel, pointing, catalog, obs_param):
self.chip_output.Log_info(" Applying Non-Linearity on the chip image") self.chip_output.Log_info(" Applying Non-Linearity on the chip image")
chip.img = Effects.NonLinearity(GSImage=chip.img, chip.img = effects.NonLinearity(GSImage=chip.img,
beta1=5.e-7, beta1=5.e-7,
beta2=0) beta2=0)
return chip, filt, tel, pointing return chip, filt, tel, pointing
def add_blooming(self, chip, filt, tel, pointing, catalog, obs_param): def add_blooming(self, chip, filt, tel, pointing, catalog, obs_param):
self.chip_output.Log_info(" Applying CCD Saturation & Blooming") self.chip_output.Log_info(" Applying CCD Saturation & Blooming")
chip.img = Effects.SaturBloom(GSImage=chip.img, chip.img = effects.SaturBloom(GSImage=chip.img,
nsect_x=1, nsect_x=1,
nsect_y=1, nsect_y=1,
fullwell=int(chip.full_well)) fullwell=int(chip.full_well))
return chip, filt, tel, pointing return chip, filt, tel, pointing
def add_bias(self, chip, filt, tel, pointing, catalog, obs_param): def add_bias(self, chip, filt, tel, pointing, catalog, obs_param):
self.chip_output.Log_info(" Adding Bias level and 16-channel non-uniformity") self.chip_output.Log_info(
" Adding Bias level and 16-channel non-uniformity")
if obs_param["bias_16channel"] == True: if obs_param["bias_16channel"] == True:
chip.img = Effects.AddBiasNonUniform16(chip.img, chip.img = effects.AddBiasNonUniform16(chip.img,
bias_level=float(chip.bias_level), bias_level=float(
nsecy = chip.nsecy, chip.bias_level),
nsecx=chip.nsecx, nsecy=chip.nsecy,
seed=self.overall_config["random_seeds"]["seed_biasNonUniform"]+chip.chipID) nsecx=chip.nsecx,
seed=self.overall_config["random_seeds"]["seed_biasNonUniform"]+chip.chipID)
elif obs_param["bias_16channel"] == False: elif obs_param["bias_16channel"] == False:
chip.img += self.bias_level chip.img += self.bias_level
return chip, filt, tel, pointing return chip, filt, tel, pointing
import numpy as np import numpy as np
import galsim import galsim
from ObservationSim.Straylight import calculateSkyMap_split_g from observation_sim.sky_background import calculateSkyMap_split_g
from ObservationSim.Instrument import FilterParam from observation_sim.instruments import FilterParam
from astropy.time import Time from astropy.time import Time
from datetime import datetime, timezone from datetime import datetime, timezone
def add_sky_background_sci(self, chip, filt, tel, pointing, catalog, obs_param): def add_sky_background_sci(self, chip, filt, tel, pointing, catalog, obs_param):
# Get exposure time # Get exposure time
if (obs_param) and ("exptime" in obs_param) and (obs_param["exptime"] is not None): if (obs_param) and ("exptime" in obs_param) and (obs_param["exptime"] is not None):
exptime = obs_param["exptime"] exptime = obs_param["exptime"]
else: else:
exptime = pointing.exp_time exptime = pointing.exp_time
flat_normal = np.ones_like(chip.img.array) flat_normal = np.ones_like(chip.img.array)
if obs_param["flat_fielding"] == True: if obs_param["flat_fielding"] == True:
flat_normal = flat_normal * chip.flat_img.array / np.mean(chip.flat_img.array) flat_normal = flat_normal * chip.flat_img.array / \
np.mean(chip.flat_img.array)
if obs_param["shutter_effect"] == True: if obs_param["shutter_effect"] == True:
flat_normal = flat_normal * chip.shutter_img flat_normal = flat_normal * chip.shutter_img
flat_normal = np.array(flat_normal, dtype='float32') flat_normal = np.array(flat_normal, dtype='float32')
self.updateHeaderInfo(header_flag='ext', keys = ['SHTSTAT'], values = [True]) self.updateHeaderInfo(header_flag='ext', keys=[
'SHTSTAT'], values=[True])
else: else:
self.updateHeaderInfo(header_flag='ext', keys = ['SHTSTAT','SHTOPEN1','SHTCLOS0'], values = [True,self.h_ext['SHTCLOS1'],self.h_ext['SHTOPEN0']]) self.updateHeaderInfo(header_flag='ext', keys=['SHTSTAT', 'SHTOPEN1', 'SHTCLOS0'], values=[
True, self.h_ext['SHTCLOS1'], self.h_ext['SHTOPEN0']])
if obs_param["enable_straylight_model"]: if obs_param["enable_straylight_model"]:
# Filter.sky_background, Filter.zodical_spec will be updated # Filter.sky_background, Filter.zodical_spec will be updated
filt.setFilterStrayLightPixel( filt.setFilterStrayLightPixel(
jtime = pointing.jdt, jtime=pointing.jdt,
sat_pos = np.array([pointing.sat_x, pointing.sat_y, pointing.sat_z]), sat_pos=np.array([pointing.sat_x, pointing.sat_y, pointing.sat_z]),
pointing_radec = np.array([pointing.ra,pointing.dec]), pointing_radec=np.array([pointing.ra, pointing.dec]),
sun_pos = np.array([pointing.sun_x, pointing.sun_y, pointing.sun_z])) sun_pos=np.array([pointing.sun_x, pointing.sun_y, pointing.sun_z]))
self.chip_output.Log_info("================================================") self.chip_output.Log_info(
self.chip_output.Log_info("sky background + stray light pixel flux value: %.5f"%(filt.sky_background)) "================================================")
self.chip_output.Log_info(
"sky background + stray light pixel flux value: %.5f" % (filt.sky_background))
if chip.survey_type == "photometric": if chip.survey_type == "photometric":
sky_map = filt.getSkyNoise(exptime = exptime) sky_map = filt.getSkyNoise(exptime=exptime)
sky_map = sky_map * np.ones_like(chip.img.array) * flat_normal sky_map = sky_map * np.ones_like(chip.img.array) * flat_normal
sky_map = galsim.Image(array=sky_map) sky_map = galsim.Image(array=sky_map)
else: else:
# chip.loadSLSFLATCUBE(flat_fn='flat_cube.fits') # chip.loadSLSFLATCUBE(flat_fn='flat_cube.fits')
sky_map = calculateSkyMap_split_g( sky_map = calculateSkyMap_split_g(
skyMap=flat_normal, skyMap=flat_normal,
blueLimit=filt.blue_limit, blueLimit=filt.blue_limit,
redLimit=filt.red_limit, redLimit=filt.red_limit,
conf=chip.sls_conf, conf=chip.sls_conf,
pixelSize=chip.pix_scale, pixelSize=chip.pix_scale,
isAlongY=0, isAlongY=0,
flat_cube=chip.flat_cube, flat_cube=chip.flat_cube,
zoldial_spec = filt.zodical_spec) zoldial_spec=filt.zodical_spec)
sky_map = (sky_map + filt.sky_background)*exptime sky_map = (sky_map + filt.sky_background)*exptime
# sky_map = sky_map * tel.pupil_area * obs_param["exptime"] # sky_map = sky_map * tel.pupil_area * obs_param["exptime"]
chip.img += sky_map chip.img += sky_map
return chip, filt, tel, pointing return chip, filt, tel, pointing
def add_sky_flat_calibration(self, chip, filt, tel, pointing, catalog, obs_param): def add_sky_flat_calibration(self, chip, filt, tel, pointing, catalog, obs_param):
if not hasattr(self, 'h_ext'): if not hasattr(self, 'h_ext'):
_, _ = self.prepare_headers(chip=chip, pointing=pointing) _, _ = self.prepare_headers(chip=chip, pointing=pointing)
chip_wcs = galsim.FitsWCS(header = self.h_ext) chip_wcs = galsim.FitsWCS(header=self.h_ext)
# Get exposure time # Get exposure time
if (obs_param) and ("exptime" in obs_param) and (obs_param["exptime"] is not None): if (obs_param) and ("exptime" in obs_param) and (obs_param["exptime"] is not None):
exptime = obs_param["exptime"] exptime = obs_param["exptime"]
else: else:
exptime = pointing.exp_time exptime = pointing.exp_time
skyback_level = obs_param["flat_level"] skyback_level = obs_param["flat_level"]
filter_param = FilterParam() filter_param = FilterParam()
...@@ -75,27 +82,33 @@ def add_sky_flat_calibration(self, chip, filt, tel, pointing, catalog, obs_param ...@@ -75,27 +82,33 @@ def add_sky_flat_calibration(self, chip, filt, tel, pointing, catalog, obs_param
flat_normal = np.ones_like(chip.img.array) flat_normal = np.ones_like(chip.img.array)
if obs_param["flat_fielding"] == True: if obs_param["flat_fielding"] == True:
flat_normal = flat_normal * chip.flat_img.array / np.mean(chip.flat_img.array) flat_normal = flat_normal * chip.flat_img.array / \
np.mean(chip.flat_img.array)
if obs_param["shutter_effect"] == True: if obs_param["shutter_effect"] == True:
flat_normal = flat_normal * chip.shutter_img flat_normal = flat_normal * chip.shutter_img
flat_normal = np.array(flat_normal, dtype='float32') flat_normal = np.array(flat_normal, dtype='float32')
if self.overall_config["output_setting"]["shutter_output"] == True: # output 16-bit shutter effect image with pixel value <=65535 # output 16-bit shutter effect image with pixel value <=65535
if self.overall_config["output_setting"]["shutter_output"] == True:
shutt_gsimg = galsim.ImageUS(chip.shutter_img*6E4) shutt_gsimg = galsim.ImageUS(chip.shutter_img*6E4)
shutt_gsimg.write("%s/ShutterEffect_%s_1.fits" % (self.chip_output.subdir, str(chip.chipID).rjust(2, '0'))) shutt_gsimg.write("%s/ShutterEffect_%s_1.fits" %
self.updateHeaderInfo(header_flag='ext', keys = ['SHTSTAT'], values = [True]) (self.chip_output.subdir, str(chip.chipID).rjust(2, '0')))
self.updateHeaderInfo(header_flag='ext', keys=[
'SHTSTAT'], values=[True])
else: else:
self.updateHeaderInfo(header_flag='ext', keys = ['SHTSTAT','SHTOPEN1','SHTCLOS0'], values = [True,self.h_ext['SHTCLOS1'],self.h_ext['SHTOPEN0']]) self.updateHeaderInfo(header_flag='ext', keys=['SHTSTAT', 'SHTOPEN1', 'SHTCLOS0'], values=[
True, self.h_ext['SHTCLOS1'], self.h_ext['SHTOPEN0']])
if chip.survey_type == "photometric": if chip.survey_type == "photometric":
sky_map = flat_normal * np.ones_like(chip.img.array) * norm_scaler * filter_param.param[chip.filter_type][5] / tel.pupil_area * exptime sky_map = flat_normal * np.ones_like(chip.img.array) * norm_scaler * \
filter_param.param[chip.filter_type][5] / tel.pupil_area * exptime
elif chip.survey_type == "spectroscopic": elif chip.survey_type == "spectroscopic":
# flat_normal = np.ones_like(chip.img.array) # flat_normal = np.ones_like(chip.img.array)
if obs_param["flat_fielding"] == True: if obs_param["flat_fielding"] == True:
flat_normal = flat_normal * chip.flat_img.array / np.mean(chip.flat_img.array) flat_normal = flat_normal * chip.flat_img.array / \
np.mean(chip.flat_img.array)
if obs_param["shutter_effect"] == True: if obs_param["shutter_effect"] == True:
flat_normal = flat_normal * chip.shutter_img flat_normal = flat_normal * chip.shutter_img
flat_normal = np.array(flat_normal, dtype='float32') flat_normal = np.array(flat_normal, dtype='float32')
sky_map = calculateSkyMap_split_g( sky_map = calculateSkyMap_split_g(
...@@ -107,36 +120,42 @@ def add_sky_flat_calibration(self, chip, filt, tel, pointing, catalog, obs_param ...@@ -107,36 +120,42 @@ def add_sky_flat_calibration(self, chip, filt, tel, pointing, catalog, obs_param
isAlongY=0, isAlongY=0,
flat_cube=chip.flat_cube) flat_cube=chip.flat_cube)
sky_map = sky_map * norm_scaler * exptime sky_map = sky_map * norm_scaler * exptime
chip.img += sky_map chip.img += sky_map
return chip, filt, tel, pointing return chip, filt, tel, pointing
def add_sky_background(self, chip, filt, tel, pointing, catalog, obs_param): def add_sky_background(self, chip, filt, tel, pointing, catalog, obs_param):
if not hasattr(self, 'h_ext'): if not hasattr(self, 'h_ext'):
_, _ = self.prepare_headers(chip=chip, pointing=pointing) _, _ = self.prepare_headers(chip=chip, pointing=pointing)
chip_wcs = galsim.FitsWCS(header = self.h_ext) chip_wcs = galsim.FitsWCS(header=self.h_ext)
if "flat_level" not in obs_param or "flat_level_filt" not in obs_param: if "flat_level" not in obs_param or "flat_level_filt" not in obs_param:
chip, filt, tel, pointing = self.add_sky_background_sci(chip, filt, tel, pointing, catalog, obs_param) chip, filt, tel, pointing = self.add_sky_background_sci(
chip, filt, tel, pointing, catalog, obs_param)
else: else:
if obs_param.get('flat_level') is None or obs_param.get('flat_level_filt')is None: if obs_param.get('flat_level') is None or obs_param.get('flat_level_filt') is None:
chip, filt, tel, pointing = self.add_sky_background_sci(chip, filt, tel, pointing, catalog, obs_param) chip, filt, tel, pointing = self.add_sky_background_sci(
chip, filt, tel, pointing, catalog, obs_param)
else: else:
chip, filt, tel, pointing = self.add_sky_flat_calibration(chip, filt, tel, pointing, catalog, obs_param) chip, filt, tel, pointing = self.add_sky_flat_calibration(
chip, filt, tel, pointing, catalog, obs_param)
# renew header info # renew header info
datetime_obs = datetime.utcfromtimestamp(pointing.timestamp) datetime_obs = datetime.utcfromtimestamp(pointing.timestamp)
datetime_obs = datetime_obs.replace(tzinfo=timezone.utc) datetime_obs = datetime_obs.replace(tzinfo=timezone.utc)
t_obs = Time(datetime_obs) t_obs = Time(datetime_obs)
##ccd刷新2s,等待0.5s,开始曝光
t_obs_renew = Time(t_obs.mjd - (2.+0.5) / 86400., format="mjd")
t_obs_utc = datetime.utcfromtimestamp(np.round(datetime.utcfromtimestamp(t_obs_renew.unix).replace(tzinfo=timezone.utc).timestamp(), 1)) # ccd刷新2s,等待0.5s,开始曝光
self.updateHeaderInfo(header_flag='prim', keys = ['DATE-OBS'], values = [t_obs_utc.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-5]]) t_obs_renew = Time(t_obs.mjd - (2.+0.5) / 86400., format="mjd")
#dark time : 曝光时间+刷新后等带时间0.5s+关闭快门时间1.5s+管快门后读出前等待0.5s t_obs_utc = datetime.utcfromtimestamp(np.round(datetime.utcfromtimestamp(
self.updateHeaderInfo(header_flag='ext', keys = ['DARKTIME'], values = [0.+0.0+0.0+pointing.exp_time]) t_obs_renew.unix).replace(tzinfo=timezone.utc).timestamp(), 1))
self.updateHeaderInfo(header_flag='prim', keys=[
'DATE-OBS'], values=[t_obs_utc.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-5]])
# dark time : 曝光时间+刷新后等带时间0.5s+关闭快门时间1.5s+管快门后读出前等待0.5s
self.updateHeaderInfo(header_flag='ext', keys=['DARKTIME'], values=[
0.+0.0+0.0+pointing.exp_time])
return chip, filt, tel, pointing return chip, filt, tel, pointing
\ No newline at end of file
from ObservationSim.Config.Header import generatePrimaryHeader, generateExtensionHeader from observation_sim.config.header import generatePrimaryHeader, generateExtensionHeader
def prepare_headers(self, chip, pointing): def prepare_headers(self, chip, pointing):
self.h_prim = generatePrimaryHeader( self.h_prim = generatePrimaryHeader(
xlen=chip.npix_x, xlen=chip.npix_x,
ylen=chip.npix_y, ylen=chip.npix_y,
pointing_id = pointing.obs_id, pointing_id=pointing.obs_id,
pointing_type_code = pointing.pointing_type_code, pointing_type_code=pointing.pointing_type_code,
ra=pointing.ra, ra=pointing.ra,
dec=pointing.dec, dec=pointing.dec,
pixel_scale=chip.pix_scale, pixel_scale=chip.pix_scale,
time_pt = pointing.timestamp, time_pt=pointing.timestamp,
exptime=pointing.exp_time, exptime=pointing.exp_time,
im_type=pointing.pointing_type, im_type=pointing.pointing_type,
sat_pos=[pointing.sat_x, pointing.sat_y, pointing.sat_z], sat_pos=[pointing.sat_x, pointing.sat_y, pointing.sat_z],
...@@ -19,32 +20,33 @@ def prepare_headers(self, chip, pointing): ...@@ -19,32 +20,33 @@ def prepare_headers(self, chip, pointing):
chip_name=str(chip.chipID).rjust(2, '0')) chip_name=str(chip.chipID).rjust(2, '0'))
self.h_ext = generateExtensionHeader( self.h_ext = generateExtensionHeader(
chip=chip, chip=chip,
xlen=chip.npix_x, xlen=chip.npix_x,
ylen=chip.npix_y, ylen=chip.npix_y,
ra=pointing.ra, ra=pointing.ra,
dec=pointing.dec, dec=pointing.dec,
pa=pointing.img_pa.deg, pa=pointing.img_pa.deg,
gain=chip.gain, gain=chip.gain,
readout=chip.read_noise, readout=chip.read_noise,
dark=chip.dark_noise, dark=chip.dark_noise,
saturation=90000, saturation=90000,
pixel_scale=chip.pix_scale, pixel_scale=chip.pix_scale,
pixel_size=chip.pix_size, pixel_size=chip.pix_size,
xcen=chip.x_cen, xcen=chip.x_cen,
ycen=chip.y_cen, ycen=chip.y_cen,
extName=pointing.pointing_type, extName=pointing.pointing_type,
timestamp = pointing.timestamp, timestamp=pointing.timestamp,
exptime = pointing.exp_time, exptime=pointing.exp_time,
readoutTime = chip.readout_time, readoutTime=chip.readout_time,
t_shutter_open = pointing.t_shutter_open, t_shutter_open=pointing.t_shutter_open,
t_shutter_close = pointing.t_shutter_close) t_shutter_close=pointing.t_shutter_close)
return self.h_prim, self.h_ext return self.h_prim, self.h_ext
def updateHeaderInfo(self,header_flag='prim', keys = ['key'], values = [0]):
def updateHeaderInfo(self, header_flag='prim', keys=['key'], values=[0]):
if header_flag == 'prim': if header_flag == 'prim':
for key,value in zip(keys, values): for key, value in zip(keys, values):
self.h_prim[key] = value self.h_prim[key] = value
if header_flag == 'ext': if header_flag == 'ext':
for key,value in zip(keys, values): for key, value in zip(keys, values):
self.h_ext[key] = value self.h_ext[key] = value
...@@ -2,66 +2,76 @@ import os ...@@ -2,66 +2,76 @@ import os
import galsim import galsim
import numpy as np import numpy as np
from astropy.io import fits from astropy.io import fits
from ObservationSim.Instrument.Chip import ChipUtils as chip_utils from observation_sim.instruments.chip import chip_utils
from ObservationSim.Instrument.Chip import Effects from observation_sim.instruments.chip import effects
from astropy.time import Time from astropy.time import Time
from datetime import datetime, timezone from datetime import datetime, timezone
def add_prescan_overscan(self, chip, filt, tel, pointing, catalog, obs_param): def add_prescan_overscan(self, chip, filt, tel, pointing, catalog, obs_param):
self.chip_output.Log_info("Apply pre/over-scan") self.chip_output.Log_info("Apply pre/over-scan")
chip.img = chip_utils.AddPreScan(GSImage=chip.img, chip.img = chip_utils.AddPreScan(GSImage=chip.img,
pre1=chip.prescan_x, pre1=chip.prescan_x,
pre2=chip.prescan_y, pre2=chip.prescan_y,
over1=chip.overscan_x, over1=chip.overscan_x,
over2=chip.overscan_y) over2=chip.overscan_y)
if obs_param["add_dark"] == True: if obs_param["add_dark"] == True:
ny = int(chip.npix_y/2) ny = int(chip.npix_y/2)
base_dark = (ny-1)*(chip.readout_time/ny)*chip.dark_noise base_dark = (ny-1)*(chip.readout_time/ny)*chip.dark_noise
chip.img.array[(chip.prescan_y+ny):-(chip.prescan_y+ny),:] = base_dark chip.img.array[(chip.prescan_y+ny):-(chip.prescan_y+ny), :] = base_dark
return chip, filt, tel, pointing return chip, filt, tel, pointing
def add_readout_noise(self, chip, filt, tel, pointing, catalog, obs_param): def add_readout_noise(self, chip, filt, tel, pointing, catalog, obs_param):
seed = int(self.overall_config["random_seeds"]["seed_readout"]) + pointing.id*30 + chip.chipID seed = int(self.overall_config["random_seeds"]
["seed_readout"]) + pointing.id*30 + chip.chipID
rng_readout = galsim.BaseDeviate(seed) rng_readout = galsim.BaseDeviate(seed)
readout_noise = galsim.GaussianNoise(rng=rng_readout, sigma=chip.read_noise) readout_noise = galsim.GaussianNoise(
rng=rng_readout, sigma=chip.read_noise)
chip.img.addNoise(readout_noise) chip.img.addNoise(readout_noise)
return chip, filt, tel, pointing return chip, filt, tel, pointing
def apply_gain(self, chip, filt, tel, pointing, catalog, obs_param): def apply_gain(self, chip, filt, tel, pointing, catalog, obs_param):
self.chip_output.Log_info(" Applying Gain") self.chip_output.Log_info(" Applying Gain")
if obs_param["gain_16channel"] == True: if obs_param["gain_16channel"] == True:
chip.img, chip.gain_channel = Effects.ApplyGainNonUniform16(chip.img, chip.img, chip.gain_channel = effects.ApplyGainNonUniform16(chip.img,
gain=chip.gain, gain=chip.gain,
nsecy = chip.nsecy, nsecy=chip.nsecy,
nsecx=chip.nsecx, nsecx=chip.nsecx,
seed=self.overall_config["random_seeds"]["seed_gainNonUniform"]+chip.chipID) seed=self.overall_config["random_seeds"]["seed_gainNonUniform"]+chip.chipID)
elif obs_param["gain_16channel"] == False: elif obs_param["gain_16channel"] == False:
chip.img /= chip.gain chip.img /= chip.gain
return chip, filt, tel, pointing return chip, filt, tel, pointing
def quantization_and_output(self, chip, filt, tel, pointing, catalog, obs_param): def quantization_and_output(self, chip, filt, tel, pointing, catalog, obs_param):
if not hasattr(self, 'h_ext'): if not hasattr(self, 'h_ext'):
_, _ = self.prepare_headers(chip=chip, pointing=pointing) _, _ = self.prepare_headers(chip=chip, pointing=pointing)
self.updateHeaderInfo(header_flag='ext', keys = ['SHTSTAT','SHTOPEN1','SHTCLOS0','SHTCLOS1','EXPTIME'], values = [False,self.h_ext['SHTOPEN0'],self.h_ext['SHTOPEN0'],self.h_ext['SHTOPEN0'],0.0]) self.updateHeaderInfo(header_flag='ext', keys=['SHTSTAT', 'SHTOPEN1', 'SHTCLOS0', 'SHTCLOS1', 'EXPTIME'], values=[
False, self.h_ext['SHTOPEN0'], self.h_ext['SHTOPEN0'], self.h_ext['SHTOPEN0'], 0.0])
# renew header info # renew header info
datetime_obs = datetime.utcfromtimestamp(pointing.timestamp) datetime_obs = datetime.utcfromtimestamp(pointing.timestamp)
datetime_obs = datetime_obs.replace(tzinfo=timezone.utc) datetime_obs = datetime_obs.replace(tzinfo=timezone.utc)
t_obs = Time(datetime_obs) t_obs = Time(datetime_obs)
##ccd刷新2s,等待0.5s,开灯后等待0.5s,开始曝光 # ccd刷新2s,等待0.5s,开灯后等待0.5s,开始曝光
t_obs_renew = Time(t_obs.mjd - 2. / 86400., format="mjd") t_obs_renew = Time(t_obs.mjd - 2. / 86400., format="mjd")
t_obs_utc = datetime.utcfromtimestamp(np.round(datetime.utcfromtimestamp(t_obs_renew.unix).replace(tzinfo=timezone.utc).timestamp(), 1)) t_obs_utc = datetime.utcfromtimestamp(np.round(datetime.utcfromtimestamp(
self.updateHeaderInfo(header_flag='prim', keys = ['DATE-OBS'], values = [t_obs_utc.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-5]]) t_obs_renew.unix).replace(tzinfo=timezone.utc).timestamp(), 1))
self.updateHeaderInfo(header_flag='prim', keys=[
'DATE-OBS'], values=[t_obs_utc.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-5]])
gains1 = list(chip.gain_channel[0:8]) gains1 = list(chip.gain_channel[0:8])
gains2 = list(chip.gain_channel[8:]) gains2 = list(chip.gain_channel[8:])
gains2.reverse() gains2.reverse()
gains = np.append(gains1,gains2) gains = np.append(gains1, gains2)
self.updateHeaderInfo(header_flag='ext', keys = ['GAIN01','GAIN02','GAIN03','GAIN04','GAIN05','GAIN06','GAIN07','GAIN08','GAIN09','GAIN10','GAIN11','GAIN12','GAIN13','GAIN14','GAIN15','GAIN16'], values = gains) self.updateHeaderInfo(header_flag='ext', keys=['GAIN01', 'GAIN02', 'GAIN03', 'GAIN04', 'GAIN05', 'GAIN06', 'GAIN07',
'GAIN08', 'GAIN09', 'GAIN10', 'GAIN11', 'GAIN12', 'GAIN13', 'GAIN14', 'GAIN15', 'GAIN16'], values=gains)
if obs_param["format_output"] == True: if obs_param["format_output"] == True:
self.chip_output.Log_info(" Apply 1*16 format") self.chip_output.Log_info(" Apply 1*16 format")
...@@ -73,20 +83,21 @@ def quantization_and_output(self, chip, filt, tel, pointing, catalog, obs_param) ...@@ -73,20 +83,21 @@ def quantization_and_output(self, chip, filt, tel, pointing, catalog, obs_param)
chip.img.replaceNegative(replace_value=0) chip.img.replaceNegative(replace_value=0)
chip.img.quantize() chip.img.quantize()
chip.img = galsim.Image(chip.img.array, dtype=np.uint16) chip.img = galsim.Image(chip.img.array, dtype=np.uint16)
fname = os.path.join(self.chip_output.subdir, self.h_prim['FILENAME'] + '.fits') fname = os.path.join(self.chip_output.subdir,
self.h_prim['FILENAME'] + '.fits')
f_name_size = 68 f_name_size = 68
if(len(self.h_prim['FILENAME'])>f_name_size): if (len(self.h_prim['FILENAME']) > f_name_size):
self.updateHeaderInfo(header_flag='prim', keys = ['FILENAME'], values = [self.h_prim['FILENAME'][0:f_name_size]]) self.updateHeaderInfo(header_flag='prim', keys=['FILENAME'], values=[
self.h_prim['FILENAME'][0:f_name_size]])
hdu1 = fits.PrimaryHDU(header=self.h_prim) hdu1 = fits.PrimaryHDU(header=self.h_prim)
self.updateHeaderInfo(header_flag='ext', keys = ['DATASECT'], values = [str(chip.img.array.shape[1]) + 'x' + str(chip.img.array.shape[0])]) self.updateHeaderInfo(header_flag='ext', keys=['DATASECT'], values=[
str(chip.img.array.shape[1]) + 'x' + str(chip.img.array.shape[0])])
hdu2 = fits.ImageHDU(chip.img.array, header=self.h_ext) hdu2 = fits.ImageHDU(chip.img.array, header=self.h_ext)
hdu2.header.comments["XTENSION"] = "image extension" hdu2.header.comments["XTENSION"] = "image extension"
hdu = fits.HDUList([hdu1, hdu2]) hdu = fits.HDUList([hdu1, hdu2])
hdu[0].add_datasum(when='data unit checksum') hdu[0].add_datasum(when='data unit checksum')
hdu[0].add_checksum(when='HDU checksum', override_datasum=True) hdu[0].add_checksum(when='HDU checksum', override_datasum=True)
......
from ObservationSim.MockObject.SpecDisperser import SpecDisperser from observation_sim.mock_objects.SpecDisperser import SpecDisperser
from ObservationSim.MockObject.SpecDisperser import rotate90 from observation_sim.mock_objects.SpecDisperser import rotate90
import galsim import galsim
import numpy as np import numpy as np
...@@ -20,10 +20,10 @@ except ImportError: ...@@ -20,10 +20,10 @@ except ImportError:
import importlib_resources as pkg_resources import importlib_resources as pkg_resources
###calculate sky map by sky SED # 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, 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, zoldial_spec = None): split_pos=3685, flat_cube=None, zoldial_spec=None):
# skyMap = np.ones([yLen, xLen], dtype='float32') # skyMap = np.ones([yLen, xLen], dtype='float32')
# #
# if isAlongY == 1: # if isAlongY == 1:
...@@ -45,19 +45,21 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s ...@@ -45,19 +45,21 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s
fImg = galsim.Image(fimg) fImg = galsim.Image(fimg)
try: try:
with pkg_resources.files('ObservationSim.Straylight.data.sky').joinpath(skyfn) as data_path: with pkg_resources.files('observation_sim.sky_background.data.sky').joinpath(skyfn) as data_path:
skySpec = np.loadtxt(data_path) skySpec = np.loadtxt(data_path)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Straylight.data.sky', skyfn) as data_path: with pkg_resources.path('observation_sim.sky_background.data.sky', skyfn) as data_path:
skySpec = np.loadtxt(data_path) skySpec = np.loadtxt(data_path)
# skySpec = np.loadtxt(skyfn) # skySpec = np.loadtxt(skyfn)
spec = Table(np.array([skySpec[:, 0], skySpec[:, 1]]).T, names=('WAVELENGTH', 'FLUX')) spec = Table(np.array([skySpec[:, 0], skySpec[:, 1]]
).T, names=('WAVELENGTH', 'FLUX'))
if zoldial_spec is not None: if zoldial_spec is not None:
deltL = 0.5 deltL = 0.5
lamb = np.arange(2000, 11000, deltL) lamb = np.arange(2000, 11000, deltL)
speci = interpolate.interp1d(zoldial_spec['WAVELENGTH'], zoldial_spec['FLUX']) speci = interpolate.interp1d(
zoldial_spec['WAVELENGTH'], zoldial_spec['FLUX'])
y = speci(lamb) y = speci(lamb)
# erg/s/cm2/A --> photo/s/m2/A # erg/s/cm2/A --> photo/s/m2/A
...@@ -65,7 +67,7 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s ...@@ -65,7 +67,7 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s
spec = Table(np.array([lamb, s_flux]).T, names=('WAVELENGTH', 'FLUX')) spec = Table(np.array([lamb, s_flux]).T, names=('WAVELENGTH', 'FLUX'))
if isAlongY == 0: if isAlongY == 0:
directParm = 0 directParm = 0
if isAlongY ==1: if isAlongY == 1:
directParm = 1 directParm = 1
if split_pos >= skyImg.array.shape[directParm]: if split_pos >= skyImg.array.shape[directParm]:
...@@ -90,25 +92,26 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s ...@@ -90,25 +92,26 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s
sub_x_end_arr = sub_x_start_arr + delt_x sub_x_end_arr = sub_x_start_arr + delt_x
sub_x_end_arr[-1] = min(sub_x_end_arr[-1], x_len) sub_x_end_arr[-1] = min(sub_x_end_arr[-1], x_len)
for i,k1 in enumerate(sub_y_start_arr): for i, k1 in enumerate(sub_y_start_arr):
sub_y_s = k1 sub_y_s = k1
sub_y_e = sub_y_end_arr[i] sub_y_e = sub_y_end_arr[i]
sub_y_center = (sub_y_s+sub_y_e)/2. sub_y_center = (sub_y_s+sub_y_e)/2.
for j,k2 in enumerate(sub_x_start_arr): for j, k2 in enumerate(sub_x_start_arr):
sub_x_s = k2 sub_x_s = k2
sub_x_e = sub_x_end_arr[j] sub_x_e = sub_x_end_arr[j]
skyImg_sub = galsim.Image(skyImg.array[sub_y_s:sub_y_e, sub_x_s:sub_x_e]) skyImg_sub = galsim.Image(
skyImg.array[sub_y_s:sub_y_e, sub_x_s:sub_x_e])
origin_sub = [sub_y_s, sub_x_s] origin_sub = [sub_y_s, sub_x_s]
sub_x_center = (sub_x_s + sub_x_e) / 2. sub_x_center = (sub_x_s + sub_x_e) / 2.
sdp = SpecDisperser(orig_img=skyImg_sub, xcenter=sub_x_center, ycenter=sub_y_center, origin=origin_sub, sdp = SpecDisperser(orig_img=skyImg_sub, xcenter=sub_x_center, ycenter=sub_y_center, origin=origin_sub,
tar_spec=spec, tar_spec=spec,
band_start=tbstart, band_end=tbend, band_start=tbstart, band_end=tbend,
conf=conf2, conf=conf2,
flat_cube=flat_cube, ignoreBeam=['D','E']) flat_cube=flat_cube, ignoreBeam=['D', 'E'])
spec_orders = sdp.compute_spec_orders() spec_orders = sdp.compute_spec_orders()
...@@ -141,9 +144,7 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s ...@@ -141,9 +144,7 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s
# if bounds.area() == 0: # if bounds.area() == 0:
# continue # continue
# fImg[bounds] = fImg[bounds] + ssImg[bounds] # fImg[bounds] = fImg[bounds] + ssImg[bounds]
else: else:
# skyImg1 = galsim.Image(skyImg.array[:, 0:split_pos]) # skyImg1 = galsim.Image(skyImg.array[:, 0:split_pos])
...@@ -165,32 +166,33 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s ...@@ -165,32 +166,33 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s
sub_y_start_arr = np.arange(0, y_len, delt_y) sub_y_start_arr = np.arange(0, y_len, delt_y)
sub_y_end_arr = sub_y_start_arr + delt_y sub_y_end_arr = sub_y_start_arr + delt_y
sub_y_end_arr[-1] = min(sub_y_end_arr[-1], y_len) sub_y_end_arr[-1] = min(sub_y_end_arr[-1], y_len)
delt_x = split_pos-0 delt_x = split_pos-0
sub_x_start_arr = np.arange(0, split_pos, delt_x) sub_x_start_arr = np.arange(0, split_pos, delt_x)
sub_x_end_arr = sub_x_start_arr + delt_x sub_x_end_arr = sub_x_start_arr + delt_x
sub_x_end_arr[-1] = min(sub_x_end_arr[-1], split_pos) sub_x_end_arr[-1] = min(sub_x_end_arr[-1], split_pos)
for i,k1 in enumerate(sub_y_start_arr): for i, k1 in enumerate(sub_y_start_arr):
sub_y_s = k1 sub_y_s = k1
sub_y_e = sub_y_end_arr[i] sub_y_e = sub_y_end_arr[i]
sub_y_center = (sub_y_s+sub_y_e)/2. sub_y_center = (sub_y_s+sub_y_e)/2.
for j,k2 in enumerate(sub_x_start_arr): for j, k2 in enumerate(sub_x_start_arr):
sub_x_s = k2 sub_x_s = k2
sub_x_e = sub_x_end_arr[j] sub_x_e = sub_x_end_arr[j]
# print(i,j,sub_y_s, sub_y_e,sub_x_s,sub_x_e) # print(i,j,sub_y_s, sub_y_e,sub_x_s,sub_x_e)
T1 = time.time() T1 = time.time()
skyImg_sub = galsim.Image(skyImg.array[sub_y_s:sub_y_e, sub_x_s:sub_x_e]) skyImg_sub = galsim.Image(
skyImg.array[sub_y_s:sub_y_e, sub_x_s:sub_x_e])
origin_sub = [sub_y_s, sub_x_s] origin_sub = [sub_y_s, sub_x_s]
sub_x_center = (sub_x_s + sub_x_e) / 2. sub_x_center = (sub_x_s + sub_x_e) / 2.
sdp = SpecDisperser(orig_img=skyImg_sub, xcenter=sub_x_center, ycenter=sub_y_center, origin=origin_sub, sdp = SpecDisperser(orig_img=skyImg_sub, xcenter=sub_x_center, ycenter=sub_y_center, origin=origin_sub,
tar_spec=spec, tar_spec=spec,
band_start=tbstart, band_end=tbend, band_start=tbstart, band_end=tbend,
conf=conf1, conf=conf1,
flat_cube=flat_cube) flat_cube=flat_cube)
spec_orders = sdp.compute_spec_orders() spec_orders = sdp.compute_spec_orders()
...@@ -204,10 +206,10 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s ...@@ -204,10 +206,10 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s
if bounds.area() == 0: if bounds.area() == 0:
continue continue
fImg[bounds] = fImg[bounds] + ssImg[bounds] fImg[bounds] = fImg[bounds] + ssImg[bounds]
T2 = time.time() T2 = time.time()
print('time: %s ms'% ((T2 - T1)*1000)) print('time: %s ms' % ((T2 - T1)*1000))
delt_x = x_len-split_pos delt_x = x_len-split_pos
sub_x_start_arr = np.arange(split_pos, x_len, delt_x) sub_x_start_arr = np.arange(split_pos, x_len, delt_x)
...@@ -224,18 +226,19 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s ...@@ -224,18 +226,19 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s
sub_x_s = k2 sub_x_s = k2
sub_x_e = sub_x_end_arr[j] sub_x_e = sub_x_end_arr[j]
# print(i,j,sub_y_s, sub_y_e,sub_x_s,sub_x_e) # print(i,j,sub_y_s, sub_y_e,sub_x_s,sub_x_e)
T1 = time.time() T1 = time.time()
skyImg_sub = galsim.Image(skyImg.array[sub_y_s:sub_y_e, sub_x_s:sub_x_e]) skyImg_sub = galsim.Image(
skyImg.array[sub_y_s:sub_y_e, sub_x_s:sub_x_e])
origin_sub = [sub_y_s, sub_x_s] origin_sub = [sub_y_s, sub_x_s]
sub_x_center = (sub_x_s + sub_x_e) / 2. sub_x_center = (sub_x_s + sub_x_e) / 2.
sdp = SpecDisperser(orig_img=skyImg_sub, xcenter=sub_x_center, ycenter=sub_y_center, origin=origin_sub, sdp = SpecDisperser(orig_img=skyImg_sub, xcenter=sub_x_center, ycenter=sub_y_center, origin=origin_sub,
tar_spec=spec, tar_spec=spec,
band_start=tbstart, band_end=tbend, band_start=tbstart, band_end=tbend,
conf=conf2, conf=conf2,
flat_cube=flat_cube) flat_cube=flat_cube)
spec_orders = sdp.compute_spec_orders() spec_orders = sdp.compute_spec_orders()
...@@ -251,17 +254,19 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s ...@@ -251,17 +254,19 @@ def calculateSkyMap_split_g(skyMap=None, blueLimit=4200, redLimit=6500, skyfn='s
fImg[bounds] = fImg[bounds] + ssImg[bounds] fImg[bounds] = fImg[bounds] + ssImg[bounds]
T2 = time.time() T2 = time.time()
print('time: %s ms'% ((T2 - T1)*1000)) print('time: %s ms' % ((T2 - T1)*1000))
if isAlongY == 1: if isAlongY == 1:
fimg, tmx, tmy = rotate90(array_orig=fImg.array, xc=0, yc=0, isClockwise=0) fimg, tmx, tmy = rotate90(
array_orig=fImg.array, xc=0, yc=0, isClockwise=0)
else: else:
fimg = fImg.array fimg = fImg.array
fimg = fimg * pixelSize * pixelSize fimg = fimg * pixelSize * pixelSize
return fimg return fimg
def calculateSkyMap(xLen=9232, yLen=9126, blueLimit=4200, redLimit=6500, def calculateSkyMap(xLen=9232, yLen=9126, blueLimit=4200, redLimit=6500,
skyfn='sky_emiss_hubble_50_50_A.dat', conf='', pixelSize=0.074, isAlongY=0): skyfn='sky_emiss_hubble_50_50_A.dat', conf='', pixelSize=0.074, isAlongY=0):
skyMap = np.ones([yLen, xLen], dtype='float32') skyMap = np.ones([yLen, xLen], dtype='float32')
...@@ -277,14 +282,15 @@ def calculateSkyMap(xLen=9232, yLen=9126, blueLimit=4200, redLimit=6500, ...@@ -277,14 +282,15 @@ def calculateSkyMap(xLen=9232, yLen=9126, blueLimit=4200, redLimit=6500,
fimg = np.zeros_like(skyMap) fimg = np.zeros_like(skyMap)
fImg = galsim.Image(fimg) fImg = galsim.Image(fimg)
try: try:
with pkg_resources.files('ObservationSim.Straylight.data.sky').joinpath(skyfn) as data_path: with pkg_resources.files('observation_sim.sky_background.data.sky').joinpath(skyfn) as data_path:
skySpec = np.loadtxt(data_path) skySpec = np.loadtxt(data_path)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Straylight.data.sky', skyfn) as data_path: with pkg_resources.path('observation_sim.sky_background.data.sky', skyfn) as data_path:
skySpec = np.loadtxt(data_path) skySpec = np.loadtxt(data_path)
# skySpec = np.loadtxt(skyfn) # skySpec = np.loadtxt(skyfn)
spec = Table(np.array([skySpec[:, 0], skySpec[:, 1]]).T, names=('WAVELENGTH', 'FLUX')) spec = Table(np.array([skySpec[:, 0], skySpec[:, 1]]
).T, names=('WAVELENGTH', 'FLUX'))
sdp = SpecDisperser(orig_img=skyImg, xcenter=skyImg.center.x, ycenter=skyImg.center.y, origin=[1, 1], sdp = SpecDisperser(orig_img=skyImg, xcenter=skyImg.center.x, ycenter=skyImg.center.y, origin=[1, 1],
tar_spec=spec, tar_spec=spec,
...@@ -303,10 +309,11 @@ def calculateSkyMap(xLen=9232, yLen=9126, blueLimit=4200, redLimit=6500, ...@@ -303,10 +309,11 @@ def calculateSkyMap(xLen=9232, yLen=9126, blueLimit=4200, redLimit=6500,
fImg[bounds] = fImg[bounds] + ssImg[bounds] fImg[bounds] = fImg[bounds] + ssImg[bounds]
if isAlongY == 1: if isAlongY == 1:
fimg, tmx, tmy = rotate90(array_orig=fImg.array, xc=0, yc=0, isClockwise=0) fimg, tmx, tmy = rotate90(
array_orig=fImg.array, xc=0, yc=0, isClockwise=0)
else: else:
fimg = fImg.array fimg = fImg.array
fimg = fimg * pixelSize * pixelSize fimg = fimg * pixelSize * pixelSize
return fimg return fimg
...@@ -15,270 +15,291 @@ except ImportError: ...@@ -15,270 +15,291 @@ except ImportError:
# Try backported to PY<37 'importlib_resources' # Try backported to PY<37 'importlib_resources'
import importlib_resources as pkg_resources import importlib_resources as pkg_resources
filterPivotWave = {'nuv':2875.5,'u':3629.6,'g':4808.4,'r':6178.2, 'i':7609.0, 'z':9012.9,'y':9627.9} filterPivotWave = {'nuv': 2875.5, 'u': 3629.6, 'g': 4808.4,
filterIndex = {'nuv':0,'u':1,'g':2,'r':3, 'i':4, 'z':5,'y':6} 'r': 6178.2, 'i': 7609.0, 'z': 9012.9, 'y': 9627.9}
filterCCD = {'nuv':'UV0','u':'UV0','g':'Astro_MB','r':'Astro_MB', 'i':'Basic_NIR', 'z':'Basic_NIR','y':'Basic_NIR'} filterIndex = {'nuv': 0, 'u': 1, 'g': 2, 'r': 3, 'i': 4, 'z': 5, 'y': 6}
bandRange = {'nuv':[2504.0,3230.0],'u':[3190.0,4039.0],'g':[3989.0,5498.0],'r':[5438.0,6956.0], 'i':[6886.0,8469.0], 'z':[8379.0,10855.0],'y':[9217.0, 10900.0], 'GU':[2550, 4000],'GV':[4000, 6200],'GI':[6200,10000]} filterCCD = {'nuv': 'UV0', 'u': 'UV0', 'g': 'Astro_MB',
'r': 'Astro_MB', 'i': 'Basic_NIR', 'z': 'Basic_NIR', 'y': 'Basic_NIR'}
bandRange = {'nuv': [2504.0, 3230.0], 'u': [3190.0, 4039.0], 'g': [3989.0, 5498.0], 'r': [5438.0, 6956.0], 'i': [
6886.0, 8469.0], 'z': [8379.0, 10855.0], 'y': [9217.0, 10900.0], 'GU': [2550, 4000], 'GV': [4000, 6200], 'GI': [6200, 10000]}
# Instrument_dir = '/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_C6/straylight/straylight/Instrument/' # Instrument_dir = '/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_C6/straylight/straylight/Instrument/'
SpecOrder = ['-2','-1','0','1','2'] SpecOrder = ['-2', '-1', '0', '1', '2']
filterMirrorEff = {'nuv': 0.54, 'u': 0.68, 'g': 0.8,
'r': 0.8, 'i': 0.8, 'z': 0.8, 'y': 0.8}
filterMirrorEff = {'nuv':0.54,'u':0.68,'g':0.8,'r':0.8, 'i':0.8, 'z':0.8,'y':0.8}
def transRaDec2D(ra, dec): def transRaDec2D(ra, dec):
x1 = np.cos(dec / 57.2957795) * np.cos(ra / 57.2957795); x1 = np.cos(dec / 57.2957795) * np.cos(ra / 57.2957795)
y1 = np.cos(dec / 57.2957795) * np.sin(ra / 57.2957795); y1 = np.cos(dec / 57.2957795) * np.sin(ra / 57.2957795)
z1 = np.sin(dec / 57.2957795); z1 = np.sin(dec / 57.2957795)
return np.array([x1, y1, z1]) return np.array([x1, y1, z1])
def getAngle132(x1 = 0, y1 = 0, z1 = 0, x2 = 0, y2 = 0, z2 = 0, x3 = 0, y3 = 0, z3 = 0):
def getAngle132(x1=0, y1=0, z1=0, x2=0, y2=0, z2=0, x3=0, y3=0, z3=0):
cosValue = 0;
angle = 0; cosValue = 0
angle = 0
x11 = x1-x3;
y11 = y1-y3; x11 = x1-x3
z11 = z1-z3; y11 = y1-y3
z11 = z1-z3
x22 = x2-x3;
y22 = y2-y3; x22 = x2-x3
z22 = z2-z3; y22 = y2-y3
z22 = z2-z3
tt = np.sqrt((x11*x11 + y11*y11 + z11* z11) * (x22*x22 + y22*y22 + z22*z22));
if(tt==0): tt = np.sqrt((x11*x11 + y11*y11 + z11 * z11)
return 0; * (x22*x22 + y22*y22 + z22*z22))
if (tt == 0):
cosValue = (x11*x22+y11*y22+z11*z22)/tt; return 0
if (cosValue > 1): cosValue = (x11*x22+y11*y22+z11*z22)/tt
cosValue = 1;
if (cosValue < -1): if (cosValue > 1):
cosValue = -1; cosValue = 1
angle = math.acos(cosValue); if (cosValue < -1):
return angle * 360 / (2 * math.pi); cosValue = -1
angle = math.acos(cosValue)
def calculateAnglePwithEarth(sat = np.array([0,0,0]), pointing = np.array([0,0,0]), sun = np.array([0,0,0])): return angle * 360 / (2 * math.pi)
def calculateAnglePwithEarth(sat=np.array([0, 0, 0]), pointing=np.array([0, 0, 0]), sun=np.array([0, 0, 0])):
modSat = np.sqrt(sat[0]*sat[0] + sat[1]*sat[1]+sat[2]*sat[2]) modSat = np.sqrt(sat[0]*sat[0] + sat[1]*sat[1]+sat[2]*sat[2])
modPoint = np.sqrt(pointing[0]*pointing[0] + pointing[1]*pointing[1] + pointing[2]*pointing[2]) modPoint = np.sqrt(pointing[0]*pointing[0] +
withLocalZenithAngle = (pointing[0] * sat[0] + pointing[1] * sat[1] + pointing[2] * sat[2]) / (modPoint*modSat) pointing[1]*pointing[1] + pointing[2]*pointing[2])
withLocalZenithAngle = (
pointing[0] * sat[0] + pointing[1] * sat[1] + pointing[2] * sat[2]) / (modPoint*modSat)
innerM_sat_sun = sat[0] * sun[0] + sat[1] * sun[1] + sat[2] * sun[2] innerM_sat_sun = sat[0] * sun[0] + sat[1] * sun[1] + sat[2] * sun[2]
cosAngle = innerM_sat_sun / (modSat * cons.au.value/1000) cosAngle = innerM_sat_sun / (modSat * cons.au.value/1000)
isInSunSide = 1 isInSunSide = 1
if (cosAngle < -0.3385737): #cos109.79 if (cosAngle < -0.3385737): # cos109.79
isInSunSide = -1; isInSunSide = -1
elif cosAngle >= -0.3385737 and cosAngle <= 0.3385737: elif cosAngle >= -0.3385737 and cosAngle <= 0.3385737:
isInSunSide = 0; isInSunSide = 0
return math.acos(withLocalZenithAngle)*180/math.pi,isInSunSide return math.acos(withLocalZenithAngle)*180/math.pi, isInSunSide
# /** # /**
# * *eCoor = ra, *eCoor+1 = dec # * *eCoor = ra, *eCoor+1 = dec
# */ # */
def Cartesian2Equatorial(carCoor = np.array([0,0,0])): def Cartesian2Equatorial(carCoor=np.array([0, 0, 0])):
eCoor = np.zeros(2) eCoor = np.zeros(2)
if (carCoor[0] > 0 and carCoor[1] >= 0): if (carCoor[0] > 0 and carCoor[1] >= 0):
eCoor[0] = math.atan(carCoor[1] / carCoor[0]) * 360 / (2 * math.pi) eCoor[0] = math.atan(carCoor[1] / carCoor[0]) * 360 / (2 * math.pi)
elif (carCoor[0] < 0): elif (carCoor[0] < 0):
eCoor[0] = (math.atan(carCoor[1] / carCoor[0]) + math.pi) * 360 / (2 * math.pi) eCoor[0] = (math.atan(carCoor[1] / carCoor[0]) +
math.pi) * 360 / (2 * math.pi)
elif (carCoor[0] > 0 and carCoor[1] < 0): elif (carCoor[0] > 0 and carCoor[1] < 0):
eCoor[0] = (math.atan(carCoor[1] / carCoor[0]) + 2 * math.pi) * 360 / (2 * math.pi) eCoor[0] = (math.atan(carCoor[1] / carCoor[0]) +
2 * math.pi) * 360 / (2 * math.pi)
elif (carCoor[0] == 0 and carCoor[1] < 0): elif (carCoor[0] == 0 and carCoor[1] < 0):
eCoor[0] = 270 eCoor[0] = 270
elif (carCoor[0] == 0 and carCoor[1] > 0): elif (carCoor[0] == 0 and carCoor[1] > 0):
eCoor[0] = 90 eCoor[0] = 90
eCoor[1] = math.atan(carCoor[2] / np.sqrt(carCoor[0] * carCoor[0] + carCoor[1] * carCoor[1])) * 360 / (2 * math.pi) eCoor[1] = math.atan(carCoor[2] / np.sqrt(carCoor[0] *
carCoor[0] + carCoor[1] * carCoor[1])) * 360 / (2 * math.pi)
return eCoor return eCoor
class Straylight(object): class Straylight(object):
def __init__(self, jtime = 2460843., sat_pos = np.array([0,0,0]), pointing_radec = np.array([0,0]), sun_pos = np.array([0,0,0])): def __init__(self, jtime=2460843., sat_pos=np.array([0, 0, 0]), pointing_radec=np.array([0, 0]), sun_pos=np.array([0, 0, 0])):
self.jtime = jtime self.jtime = jtime
self.sat = sat_pos self.sat = sat_pos
self.sun_pos = sun_pos self.sun_pos = sun_pos
self.equator = coord.SkyCoord(pointing_radec[0]*u.degree, pointing_radec[1]*u.degree,frame='icrs') self.equator = coord.SkyCoord(
pointing_radec[0]*u.degree, pointing_radec[1]*u.degree, frame='icrs')
self.ecliptic = self.equator.transform_to('barycentrictrueecliptic') self.ecliptic = self.equator.transform_to('barycentrictrueecliptic')
self.pointing = transRaDec2D(pointing_radec[0], pointing_radec[1]) self.pointing = transRaDec2D(pointing_radec[0], pointing_radec[1])
platForm = sys.platform platForm = sys.platform
if platForm == 'darwin': if platForm == 'darwin':
try: try:
with pkg_resources.files('ObservationSim.Straylight.lib').joinpath('libstraylight.dylib') as dllFn: with pkg_resources.files('observation_sim.sky_background.lib').joinpath('libstraylight.dylib') as dllFn:
self.slcdll = ctypes.CDLL(dllFn) self.slcdll = ctypes.CDLL(dllFn)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Straylight.lib', 'libstraylight.dylib') as dllFn: with pkg_resources.path('observation_sim.sky_background.lib', 'libstraylight.dylib') as dllFn:
self.slcdll = ctypes.CDLL(dllFn) self.slcdll = ctypes.CDLL(dllFn)
elif platForm == 'linux': elif platForm == 'linux':
try: try:
with pkg_resources.files('ObservationSim.Straylight.lib').joinpath('libstraylight.so') as dllFn: with pkg_resources.files('observation_sim.sky_background.lib').joinpath('libstraylight.so') as dllFn:
self.slcdll = ctypes.CDLL(dllFn) self.slcdll = ctypes.CDLL(dllFn)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Straylight.lib', 'libstraylight.so') as dllFn: with pkg_resources.path('observation_sim.sky_background.lib', 'libstraylight.so') as dllFn:
self.slcdll = ctypes.CDLL(dllFn) self.slcdll = ctypes.CDLL(dllFn)
# self.slcdll=ctypes.CDLL('./libstraylight.dylib') # self.slcdll=ctypes.CDLL('./libstraylight.dylib')
self.slcdll.Calculate.argtypes = [ctypes.c_double, ctypes.POINTER(ctypes.c_double), self.slcdll.Calculate.argtypes = [ctypes.c_double, ctypes.POINTER(ctypes.c_double),
ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(
ctypes.c_double),
ctypes.POINTER(ctypes.c_double), ctypes.c_char_p] ctypes.POINTER(ctypes.c_double), ctypes.c_char_p]
self.slcdll.PointSource.argtypes = [ctypes.c_double, ctypes.POINTER(ctypes.c_double), self.slcdll.PointSource.argtypes = [ctypes.c_double, ctypes.POINTER(ctypes.c_double),
ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(
ctypes.c_double),
ctypes.POINTER(ctypes.c_double), ctypes.c_char_p] ctypes.POINTER(ctypes.c_double), ctypes.c_char_p]
self.slcdll.EarthShine.argtypes = [ctypes.c_double, ctypes.POINTER(ctypes.c_double), self.slcdll.EarthShine.argtypes = [ctypes.c_double, ctypes.POINTER(ctypes.c_double),
ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(
ctypes.c_double),
ctypes.POINTER(ctypes.c_double)] ctypes.POINTER(ctypes.c_double)]
self.slcdll.Zodiacal.argtypes = [ctypes.c_double, ctypes.POINTER(ctypes.c_double), self.slcdll.Zodiacal.argtypes = [ctypes.c_double, ctypes.POINTER(ctypes.c_double),
ctypes.POINTER(ctypes.c_double)] ctypes.POINTER(ctypes.c_double)]
self.slcdll.ComposeY.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), self.slcdll.ComposeY.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double),
ctypes.POINTER(ctypes.c_double)] ctypes.POINTER(ctypes.c_double)]
self.slcdll.Init.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p] self.slcdll.Init.argtypes = [
ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p]
try: try:
with pkg_resources.files('ObservationSim.Straylight.lib').joinpath('DE405') as tFn: with pkg_resources.files('observation_sim.sky_background.lib').joinpath('DE405') as tFn:
self.deFn = tFn.as_uri()[7:] self.deFn = tFn.as_uri()[7:]
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Straylight.lib', 'DE405') as tFn: with pkg_resources.path('observation_sim.sky_background.lib', 'DE405') as tFn:
self.deFn = tFn.as_uri()[7:] self.deFn = tFn.as_uri()[7:]
try: try:
with pkg_resources.files('ObservationSim.Straylight.lib').joinpath('PST') as tFn: with pkg_resources.files('observation_sim.sky_background.lib').joinpath('PST') as tFn:
self.PSTFn = tFn.as_uri()[7:] self.PSTFn = tFn.as_uri()[7:]
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Straylight.lib', 'PST') as tFn: with pkg_resources.path('observation_sim.sky_background.lib', 'PST') as tFn:
self.PSTFn = tFn.as_uri()[7:] self.PSTFn = tFn.as_uri()[7:]
try: try:
with pkg_resources.files('ObservationSim.Straylight.lib').joinpath('R') as tFn: with pkg_resources.files('observation_sim.sky_background.lib').joinpath('R') as tFn:
self.RFn = tFn.as_uri()[7:] self.RFn = tFn.as_uri()[7:]
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Straylight.lib', 'R') as tFn: with pkg_resources.path('observation_sim.sky_background.lib', 'R') as tFn:
self.RFn = tFn.as_uri()[7:] self.RFn = tFn.as_uri()[7:]
try: try:
with pkg_resources.files('ObservationSim.Straylight.lib').joinpath('Zodiacal') as tFn: with pkg_resources.files('observation_sim.sky_background.lib').joinpath('Zodiacal') as tFn:
self.ZolFn = tFn.as_uri()[7:] self.ZolFn = tFn.as_uri()[7:]
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Straylight.lib', 'Zodiacal') as tFn: with pkg_resources.path('observation_sim.sky_background.lib', 'Zodiacal') as tFn:
self.ZolFn = tFn.as_uri()[7:] self.ZolFn = tFn.as_uri()[7:]
try: try:
with pkg_resources.files('ObservationSim.Straylight.lib').joinpath('BrightGaia_with_csst_mag') as tFn: with pkg_resources.files('observation_sim.sky_background.lib').joinpath('BrightGaia_with_csst_mag') as tFn:
self.brightStarTabFn = tFn.as_uri()[7:] self.brightStarTabFn = tFn.as_uri()[7:]
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Straylight.lib', 'BrightGaia_with_csst_mag') as tFn: with pkg_resources.path('observation_sim.sky_background.lib', 'BrightGaia_with_csst_mag') as tFn:
self.brightStarTabFn = tFn.as_uri()[7:] self.brightStarTabFn = tFn.as_uri()[7:]
print(self.deFn) print(self.deFn)
self.slcdll.Init(str.encode(self.deFn), str.encode(self.PSTFn), str.encode(self.RFn), str.encode(self.ZolFn)) self.slcdll.Init(str.encode(self.deFn), str.encode(
self.PSTFn), str.encode(self.RFn), str.encode(self.ZolFn))
def getFilterAndCCD_Q(self, filter = 'i'): def getFilterAndCCD_Q(self, filter='i'):
try: try:
with pkg_resources.files('ObservationSim.Instrument.data.ccd').joinpath(filterCCD[filter] + '.txt') as ccd_fn: with pkg_resources.files('observation_sim.instruments.data.ccd').joinpath(filterCCD[filter] + '.txt') as ccd_fn:
q_ccd_f = np.loadtxt(ccd_fn) q_ccd_f = np.loadtxt(ccd_fn)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Instrument.data.ccd', filterCCD[filter] + '.txt') as ccd_fn: with pkg_resources.path('observation_sim.instruments.data.ccd', filterCCD[filter] + '.txt') as ccd_fn:
q_ccd_f = np.loadtxt(ccd_fn) q_ccd_f = np.loadtxt(ccd_fn)
try: try:
with pkg_resources.files('ObservationSim.Instrument.data.filters').joinpath(filter + '.txt') as filter_fn: with pkg_resources.files('observation_sim.instruments.data.filters').joinpath(filter + '.txt') as filter_fn:
q_fil_f = np.loadtxt(filter_fn) q_fil_f = np.loadtxt(filter_fn)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Instrument.data.filters', filter + '.txt') as filter_fn: with pkg_resources.path('observation_sim.instruments.data.filters', filter + '.txt') as filter_fn:
q_fil_f = np.loadtxt(filter_fn) q_fil_f = np.loadtxt(filter_fn)
band_s = 2000 band_s = 2000
band_e = 11000 band_e = 11000
q_ccd_f[:,0] = q_ccd_f[:,0]*10 q_ccd_f[:, 0] = q_ccd_f[:, 0]*10
q_ccd = np.zeros([q_ccd_f.shape[0]+2,q_ccd_f.shape[1]]) q_ccd = np.zeros([q_ccd_f.shape[0]+2, q_ccd_f.shape[1]])
q_ccd[1:-1,:] = q_ccd_f q_ccd[1:-1, :] = q_ccd_f
q_ccd[0] = [band_s,0] q_ccd[0] = [band_s, 0]
q_ccd[-1] = [band_e,0] q_ccd[-1] = [band_e, 0]
q_fil = np.zeros([q_fil_f.shape[0]+2,q_fil_f.shape[1]]) q_fil = np.zeros([q_fil_f.shape[0]+2, q_fil_f.shape[1]])
q_fil[1:-1,:] = q_fil_f q_fil[1:-1, :] = q_fil_f
q_fil[0] = [band_s,0] q_fil[0] = [band_s, 0]
q_fil[-1] = [band_e,0] q_fil[-1] = [band_e, 0]
q_fil_i = interpolate.interp1d(q_fil[:, 0], q_fil[:, 1])
q_fil_i = interpolate.interp1d(q_fil[:,0], q_fil[:,1]) q_ccd_i = interpolate.interp1d(q_ccd[:, 0], q_ccd[:, 1])
q_ccd_i = interpolate.interp1d(q_ccd[:,0], q_ccd[:,1]) bands = np.arange(bandRange[filter][0], bandRange[filter][1], 0.5)
bands = np.arange(bandRange[filter][0], bandRange[filter][1],0.5)
q_ccd_fil = q_fil_i(bands)*q_ccd_i(bands) q_ccd_fil = q_fil_i(bands)*q_ccd_i(bands)
return np.trapz(q_ccd_fil, bands)/(bandRange[filter][1]-bandRange[filter][0]) return np.trapz(q_ccd_fil, bands)/(bandRange[filter][1]-bandRange[filter][0])
def calculateEarthShineFilter(self, filter = 'i', pixel_size_phy = 10 ): def calculateEarthShineFilter(self, filter='i', pixel_size_phy=10):
sat = (ctypes.c_double*3)() sat = (ctypes.c_double*3)()
sat[:] = self.sat sat[:] = self.sat
ob = (ctypes.c_double*3)() ob = (ctypes.c_double*3)()
ob[:]=self.pointing ob[:] = self.pointing
py1 = (ctypes.c_double*3)() py1 = (ctypes.c_double*3)()
py2 = (ctypes.c_double*3)() py2 = (ctypes.c_double*3)()
self.slcdll.ComposeY(ob,py1,py2) self.slcdll.ComposeY(ob, py1, py2)
earth_e1 = (ctypes.c_double*7)() earth_e1 = (ctypes.c_double*7)()
self.slcdll.EarthShine(self.jtime,sat,ob,py1,earth_e1) self.slcdll.EarthShine(self.jtime, sat, ob, py1, earth_e1)
earth_e2 = (ctypes.c_double*7)() earth_e2 = (ctypes.c_double*7)()
self.slcdll.EarthShine(self.jtime,sat,ob,py2,earth_e2) self.slcdll.EarthShine(self.jtime, sat, ob, py2, earth_e2)
band_earth_e1 = earth_e1[:][filterIndex[filter]] band_earth_e1 = earth_e1[:][filterIndex[filter]]
band_earth_e2 = earth_e2[:][filterIndex[filter]] band_earth_e2 = earth_e2[:][filterIndex[filter]]
q=self.getFilterAndCCD_Q(filter=filter) q = self.getFilterAndCCD_Q(filter=filter)
p_lambda = filterPivotWave[filter] p_lambda = filterPivotWave[filter]
c = cons.c.value c = cons.c.value
h = cons.h.value h = cons.h.value
pix_earth_e1 = band_earth_e1/(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q pix_earth_e1 = band_earth_e1 / \
pix_earth_e2 = band_earth_e2/(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q (h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q
pix_earth_e2 = band_earth_e2 / \
(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q
if pix_earth_e1< pix_earth_e2: if pix_earth_e1 < pix_earth_e2:
return pix_earth_e1, py1[:] return pix_earth_e1, py1[:]
else: else:
return pix_earth_e2, py2[:] return pix_earth_e2, py2[:]
""" """
calculate zodiacal call c++ program, seems to have some problem calculate zodiacal call c++ program, seems to have some problem
""" """
def calculateZodiacalFilter1(self, filter = 'i', pixel_size_phy = 10 ):
def calculateZodiacalFilter1(self, filter='i', pixel_size_phy=10):
sat = (ctypes.c_double*3)() sat = (ctypes.c_double*3)()
sat[:] = self.sat sat[:] = self.sat
ob = (ctypes.c_double*3)() ob = (ctypes.c_double*3)()
ob[:]=self.pointing ob[:] = self.pointing
zodical_e = (ctypes.c_double*7)() zodical_e = (ctypes.c_double*7)()
self.slcdll.Zodiacal(self.jtime,ob,zodical_e) self.slcdll.Zodiacal(self.jtime, ob, zodical_e)
ob1 = (ctypes.c_double*2)() ob1 = (ctypes.c_double*2)()
ob1[:] = np.array([self.ecliptic.lon.value, self.ecliptic.lat.value]) ob1[:] = np.array([self.ecliptic.lon.value, self.ecliptic.lat.value])
zodical_e1 = (ctypes.c_double*7)() zodical_e1 = (ctypes.c_double*7)()
self.slcdll.Zodiacal1(ob1,zodical_e1) self.slcdll.Zodiacal1(ob1, zodical_e1)
band_zodical_e = zodical_e[:][filterIndex[filter]] band_zodical_e = zodical_e[:][filterIndex[filter]]
q=self.getFilterAndCCD_Q(filter=filter) q = self.getFilterAndCCD_Q(filter=filter)
p_lambda = filterPivotWave[filter] p_lambda = filterPivotWave[filter]
c = cons.c.value c = cons.c.value
h = cons.h.value h = cons.h.value
pix_zodical_e = band_zodical_e/(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q pix_zodical_e = band_zodical_e / \
(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q
return pix_zodical_e, band_zodical_e return pix_zodical_e, band_zodical_e
""" """
calculate zodiacal use python calculate zodiacal use python
""" """
def calculateZodiacalFilter2(self,filter = 'i', aper = 2, pixelsize = 0.074, sun_pos = np.array([0,0,0])):
def calculateZodiacalFilter2(self, filter='i', aper=2, pixelsize=0.074, sun_pos=np.array([0, 0, 0])):
spec, v_mag = self.calculateZodicalSpec(longitude = self.ecliptic.lon.value, latitude = self.ecliptic.lat.value, sun_pos = sun_pos)
spec, v_mag = self.calculateZodicalSpec(
longitude=self.ecliptic.lon.value, latitude=self.ecliptic.lat.value, sun_pos=sun_pos)
# spec = self.calculateZodicalSpec(longitude = lon, latitude = lat) # spec = self.calculateZodicalSpec(longitude = lon, latitude = lat)
try: try:
with pkg_resources.files('ObservationSim.Instrument.data.throughputs').joinpath(filter + '_throughput.txt') as throughputFn: with pkg_resources.files('observation_sim.instruments.data.throughputs').joinpath(filter + '_throughput.txt') as throughputFn:
throughput = np.loadtxt(throughputFn) throughput = np.loadtxt(throughputFn)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Instrument.data.throughputs', filter + '_throughput.txt') as throughputFn: with pkg_resources.path('observation_sim.instruments.data.throughputs', filter + '_throughput.txt') as throughputFn:
throughput = np.loadtxt(throughputFn) throughput = np.loadtxt(throughputFn)
deltL = 0.5 deltL = 0.5
...@@ -294,61 +315,60 @@ class Straylight(object): ...@@ -294,61 +315,60 @@ class Straylight(object):
throughput_ = throughput_i(lamb) throughput_ = throughput_i(lamb)
sky_pix = np.trapz(flux*throughput_, lamb) * math.pi * aper*aper/4 * pixelsize * pixelsize sky_pix = np.trapz(flux*throughput_, lamb) * \
math.pi * aper*aper/4 * pixelsize * pixelsize
# sky_pix_e = np.trapz(y, lamb) * math.pi * aper*aper/4 * pixelsize * pixelsize/(10*10*1e-6*1e-6)*1e-7*1e4 # sky_pix_e = np.trapz(y, lamb) * math.pi * aper*aper/4 * pixelsize * pixelsize/(10*10*1e-6*1e-6)*1e-7*1e4
return sky_pix, v_mag#, sky_pix_e return sky_pix, v_mag # , sky_pix_e
def calculateStarLightFilter(self, filter = 'i', pointYaxis = np.array([1,1,1]), pixel_size_phy = 10 ): def calculateStarLightFilter(self, filter='i', pointYaxis=np.array([1, 1, 1]), pixel_size_phy=10):
sat = (ctypes.c_double*3)() sat = (ctypes.c_double*3)()
sat[:] = self.sat sat[:] = self.sat
ob = (ctypes.c_double*3)() ob = (ctypes.c_double*3)()
ob[:]=self.pointing ob[:] = self.pointing
py = (ctypes.c_double*3)() py = (ctypes.c_double*3)()
py[:] = pointYaxis py[:] = pointYaxis
q=self.getFilterAndCCD_Q(filter=filter) q = self.getFilterAndCCD_Q(filter=filter)
p_lambda = filterPivotWave[filter] p_lambda = filterPivotWave[filter]
c = cons.c.value c = cons.c.value
h = cons.h.value h = cons.h.value
star_e1 = (ctypes.c_double*7)() star_e1 = (ctypes.c_double*7)()
self.slcdll.PointSource(self.jtime,sat,ob,py,star_e1, str.encode(self.brightStarTabFn)) self.slcdll.PointSource(self.jtime, sat, ob, py,
star_e1, str.encode(self.brightStarTabFn))
band_star_e1 = star_e1[:][filterIndex[filter]] band_star_e1 = star_e1[:][filterIndex[filter]]
pix_star_e1 = band_star_e1/(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q pix_star_e1 = band_star_e1 / \
(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q
return pix_star_e1 return pix_star_e1
def calculateEarthshineGrating(self, grating = 'GU', pixel_size_phy = 10, normFilter = 'g', aper = 2, pixelsize = 0.074): def calculateEarthshineGrating(self, grating='GU', pixel_size_phy=10, normFilter='g', aper=2, pixelsize=0.074):
sat = (ctypes.c_double*3)() sat = (ctypes.c_double*3)()
sat[:] = self.sat sat[:] = self.sat
ob = (ctypes.c_double*3)() ob = (ctypes.c_double*3)()
ob[:]=self.pointing ob[:] = self.pointing
py1 = (ctypes.c_double*3)() py1 = (ctypes.c_double*3)()
py2 = (ctypes.c_double*3)() py2 = (ctypes.c_double*3)()
self.slcdll.ComposeY(ob,py1,py2) self.slcdll.ComposeY(ob, py1, py2)
earth_e1 = (ctypes.c_double*7)() earth_e1 = (ctypes.c_double*7)()
self.slcdll.EarthShine(self.jtime,sat,ob,py1,earth_e1) self.slcdll.EarthShine(self.jtime, sat, ob, py1, earth_e1)
earth_e2 = (ctypes.c_double*7)() earth_e2 = (ctypes.c_double*7)()
self.slcdll.EarthShine(self.jtime,sat,ob,py2,earth_e2) self.slcdll.EarthShine(self.jtime, sat, ob, py2, earth_e2)
# zodical_e = (ctypes.c_double*7)() # zodical_e = (ctypes.c_double*7)()
# self.slcdll.Zodiacal(self.jtime,ob,zodical_e) # self.slcdll.Zodiacal(self.jtime,ob,zodical_e)
band_earth_e1 = earth_e1[:][filterIndex[normFilter]] band_earth_e1 = earth_e1[:][filterIndex[normFilter]]
band_earth_e2 = earth_e2[:][filterIndex[normFilter]] band_earth_e2 = earth_e2[:][filterIndex[normFilter]]
band_earth_e = band_earth_e2 band_earth_e = band_earth_e2
py = py2[:] py = py2[:]
if band_earth_e1<band_earth_e2: if band_earth_e1 < band_earth_e2:
band_earth_e = band_earth_e1 band_earth_e = band_earth_e1
py = py1[:] py = py1[:]
# band_earth_e = np.min([band_earth_e1, band_earth_e2]) # band_earth_e = np.min([band_earth_e1, band_earth_e2])
...@@ -356,18 +376,20 @@ class Straylight(object): ...@@ -356,18 +376,20 @@ class Straylight(object):
# band_earth_e1 = 0 # band_earth_e1 = 0
# band_earth_e2 = 0 # band_earth_e2 = 0
# band_zodical_e = zodical_e[:][filterIndex[normFilter]] # band_zodical_e = zodical_e[:][filterIndex[normFilter]]
q=self.getFilterAndCCD_Q(filter=normFilter) q = self.getFilterAndCCD_Q(filter=normFilter)
p_lambda = filterPivotWave[normFilter] p_lambda = filterPivotWave[normFilter]
c = cons.c.value c = cons.c.value
h = cons.h.value h = cons.h.value
pix_earth_e = band_earth_e/(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q pix_earth_e = band_earth_e / \
(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q
# pix_earth_e2 = band_earth_e2/(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q # pix_earth_e2 = band_earth_e2/(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q
# pix_zodical_e = band_zodical_e/(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q # pix_zodical_e = band_zodical_e/(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q
# pix_earth_e = np.min([pix_earth_e1, pix_earth_e2]) # pix_earth_e = np.min([pix_earth_e1, pix_earth_e2])
earthshine_v, earthshine_spec = self.calculatEarthshineByHSTSpec(filter = normFilter, aper = aper, pixelsize = pixelsize) earthshine_v, earthshine_spec = self.calculatEarthshineByHSTSpec(
filter=normFilter, aper=aper, pixelsize=pixelsize)
lamb_earth = earthshine_spec['WAVELENGTH'] lamb_earth = earthshine_spec['WAVELENGTH']
flux_earth = earthshine_spec['FLUX']*pix_earth_e/earthshine_v flux_earth = earthshine_spec['FLUX']*pix_earth_e/earthshine_v
...@@ -375,30 +397,31 @@ class Straylight(object): ...@@ -375,30 +397,31 @@ class Straylight(object):
earth_v_grating = 0 earth_v_grating = 0
for s_order in SpecOrder: for s_order in SpecOrder:
try: try:
with pkg_resources.files('ObservationSim.Instrument.data.sls_conf').joinpath( with pkg_resources.files('observation_sim.instruments.data.sls_conf').joinpath(
grating + '.Throughput.' + s_order + 'st.fits') as thpFn: grating + '.Throughput.' + s_order + 'st.fits') as thpFn:
thp_ = Table.read(thpFn) thp_ = Table.read(thpFn)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Instrument.data.sls_conf', with pkg_resources.path('observation_sim.instruments.data.sls_conf',
grating + '.Throughput.' + s_order + 'st.fits') as thpFn: grating + '.Throughput.' + s_order + 'st.fits') as thpFn:
thp_ = Table.read(thpFn) thp_ = Table.read(thpFn)
thpFn_i = interpolate.interp1d(thp_['WAVELENGTH'], thp_['SENSITIVITY']) thpFn_i = interpolate.interp1d(
thp_['WAVELENGTH'], thp_['SENSITIVITY'])
thp = thpFn_i(lamb_earth) thp = thpFn_i(lamb_earth)
beamsEarth = np.trapz(flux_earth*thp,lamb_earth)* math.pi*aper*aper/4 * pixelsize * pixelsize beamsEarth = np.trapz(flux_earth*thp, lamb_earth) * \
math.pi*aper*aper/4 * pixelsize * pixelsize
earth_v_grating = earth_v_grating + beamsEarth earth_v_grating = earth_v_grating + beamsEarth
# print(beamsEarth) # print(beamsEarth)
# print(earthshine_v, pix_earth_e, earth_v_grating) # print(earthshine_v, pix_earth_e, earth_v_grating)
return earth_v_grating, py return earth_v_grating, py
def calculateStarLightGrating(self, grating = 'GU', pointYaxis = np.array([1,1,1]), pixel_size_phy = 10 ): def calculateStarLightGrating(self, grating='GU', pointYaxis=np.array([1, 1, 1]), pixel_size_phy=10):
sat = (ctypes.c_double*3)() sat = (ctypes.c_double*3)()
sat[:] = self.sat sat[:] = self.sat
ob = (ctypes.c_double*3)() ob = (ctypes.c_double*3)()
ob[:]=self.pointing ob[:] = self.pointing
py = (ctypes.c_double*3)() py = (ctypes.c_double*3)()
py[:] = pointYaxis py[:] = pointYaxis
...@@ -407,9 +430,9 @@ class Straylight(object): ...@@ -407,9 +430,9 @@ class Straylight(object):
c = cons.c.value c = cons.c.value
h = cons.h.value h = cons.h.value
star_e1 = (ctypes.c_double*7)() star_e1 = (ctypes.c_double*7)()
self.slcdll.PointSource(self.jtime,sat,ob,py,star_e1, str.encode(self.brightStarTabFn)) self.slcdll.PointSource(self.jtime, sat, ob, py,
star_e1, str.encode(self.brightStarTabFn))
filterPivotWaveList = np.zeros(7) filterPivotWaveList = np.zeros(7)
bandRangeList = np.zeros(7) bandRangeList = np.zeros(7)
...@@ -420,54 +443,54 @@ class Straylight(object): ...@@ -420,54 +443,54 @@ class Straylight(object):
filterMirrorEffList[i] = filterMirrorEff[filterNameList[i]] filterMirrorEffList[i] = filterMirrorEff[filterNameList[i]]
brange = bandRange[filterNameList[i]] brange = bandRange[filterNameList[i]]
bandRangeList[i] = brange[1] - brange[0] bandRangeList[i] = brange[1] - brange[0]
filterFlux_lamb = star_e1[:]/bandRangeList/filterMirrorEffList/(h*c/(filterPivotWaveList*1e-10)) filterFlux_lamb = star_e1[:]/bandRangeList / \
filterFlux_lambi = interpolate.interp1d(filterPivotWaveList,filterFlux_lamb,fill_value="extrapolate") filterMirrorEffList/(h*c/(filterPivotWaveList*1e-10))
filterFlux_lambi = interpolate.interp1d(
filterPivotWaveList, filterFlux_lamb, fill_value="extrapolate")
lamb_g = np.arange(bandRange[grating][0], bandRange[grating][1],1) lamb_g = np.arange(bandRange[grating][0], bandRange[grating][1], 1)
flux_g = filterFlux_lambi(lamb_g) flux_g = filterFlux_lambi(lamb_g)
# flux_total_g = np.trapz(flux_g,lamb_g) # flux_total_g = np.trapz(flux_g,lamb_g)
starLight_grating = 0 starLight_grating = 0
for s_order in SpecOrder: for s_order in SpecOrder:
try: try:
with pkg_resources.files('ObservationSim.Instrument.data.sls_conf').joinpath( with pkg_resources.files('observation_sim.instruments.data.sls_conf').joinpath(
grating + '.Throughput.' + s_order + 'st.fits') as thpFn: grating + '.Throughput.' + s_order + 'st.fits') as thpFn:
thp_ = Table.read(thpFn) thp_ = Table.read(thpFn)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Instrument.data.sls_conf', with pkg_resources.path('observation_sim.instruments.data.sls_conf',
grating + '.Throughput.' + s_order + 'st.fits') as thpFn: grating + '.Throughput.' + s_order + 'st.fits') as thpFn:
thp_ = Table.read(thpFn) thp_ = Table.read(thpFn)
thpFn_i = interpolate.interp1d(thp_['WAVELENGTH'], thp_['SENSITIVITY']) thpFn_i = interpolate.interp1d(
thp_['WAVELENGTH'], thp_['SENSITIVITY'])
thp = thpFn_i(lamb_g) thp = thpFn_i(lamb_g)
beamsZol = np.trapz(flux_g*thp,lamb_g)*pixel_size_phy*1e-6*pixel_size_phy*1e-6 beamsZol = np.trapz(flux_g*thp, lamb_g) * \
pixel_size_phy*1e-6*pixel_size_phy*1e-6
starLight_grating = starLight_grating + beamsZol starLight_grating = starLight_grating + beamsZol
# print(beamsZol) # print(beamsZol)
# band_star_e1 = star_e1[:][filterIndex[filter]] # band_star_e1 = star_e1[:][filterIndex[filter]]
# pix_star_e1 = band_star_e1/(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q # pix_star_e1 = band_star_e1/(h*c/(p_lambda*1e-10))*pixel_size_phy*1e-6*pixel_size_phy*1e-6*q
return starLight_grating
return starLight_grating
def calculatEarthshineByHSTSpec(self, filter='g', aper=2, pixelsize=0.074, s=2000, e=11000):
def calculatEarthshineByHSTSpec(self, filter = 'g', aper = 2, pixelsize = 0.074, s = 2000, e = 11000):
try: try:
with pkg_resources.files('ObservationSim.Straylight.data.sky').joinpath('earthShine.dat') as specFn: with pkg_resources.files('observation_sim.sky_background.data.sky').joinpath('earthShine.dat') as specFn:
spec = np.loadtxt(specFn) spec = np.loadtxt(specFn)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Straylight.data.sky', with pkg_resources.path('observation_sim.sky_background.data.sky',
'earthShine.dat') as specFn: 'earthShine.dat') as specFn:
spec = np.loadtxt(specFn) spec = np.loadtxt(specFn)
try: try:
with pkg_resources.files('ObservationSim.Instrument.data.throughputs').joinpath(filter + '_throughput.txt') as throughputFn: with pkg_resources.files('observation_sim.instruments.data.throughputs').joinpath(filter + '_throughput.txt') as throughputFn:
throughput = np.loadtxt(throughputFn) throughput = np.loadtxt(throughputFn)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Instrument.data.throughputs', filter + '_throughput.txt') as throughputFn: with pkg_resources.path('observation_sim.instruments.data.throughputs', filter + '_throughput.txt') as throughputFn:
throughput = np.loadtxt(throughputFn) throughput = np.loadtxt(throughputFn)
deltL = 0.5 deltL = 0.5
...@@ -482,7 +505,8 @@ class Straylight(object): ...@@ -482,7 +505,8 @@ class Straylight(object):
throughput_ = throughput_i(lamb) throughput_ = throughput_i(lamb)
sky_pix = np.trapz(flux*throughput_, lamb) * math.pi * aper*aper/4 * pixelsize * pixelsize sky_pix = np.trapz(flux*throughput_, lamb) * \
math.pi * aper*aper/4 * pixelsize * pixelsize
lamb = np.arange(s, e, deltL) lamb = np.arange(s, e, deltL)
speci = interpolate.interp1d(spec[:, 0], spec[:, 1]) speci = interpolate.interp1d(spec[:, 0], spec[:, 1])
...@@ -490,30 +514,31 @@ class Straylight(object): ...@@ -490,30 +514,31 @@ class Straylight(object):
# erg/s/cm2/A --> photo/s/m2/A # erg/s/cm2/A --> photo/s/m2/A
flux = y * lamb / (cons.h.value * cons.c.value) * 1e-13 flux = y * lamb / (cons.h.value * cons.c.value) * 1e-13
return sky_pix, Table(np.array([lamb, flux]).T,names=('WAVELENGTH', 'FLUX')) return sky_pix, Table(np.array([lamb, flux]).T, names=('WAVELENGTH', 'FLUX'))
def calculateZodicalSpec(self,longitude = 50, latitude = 60, sun_pos = np.array([0,0,0])): def calculateZodicalSpec(self, longitude=50, latitude=60, sun_pos=np.array([0, 0, 0])):
from scipy.interpolate import interp2d from scipy.interpolate import interp2d
from scipy.interpolate import griddata from scipy.interpolate import griddata
try: try:
with pkg_resources.files('ObservationSim.Straylight.data').joinpath('Zodiacal_map1.dat') as z_map_fn: with pkg_resources.files('observation_sim.sky_background.data').joinpath('Zodiacal_map1.dat') as z_map_fn:
ZL = np.loadtxt(z_map_fn) ZL = np.loadtxt(z_map_fn)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Straylight.data', with pkg_resources.path('observation_sim.sky_background.data',
'Zodiacal_map1.dat') as z_map_fn: 'Zodiacal_map1.dat') as z_map_fn:
ZL = np.loadtxt(z_map_fn) ZL = np.loadtxt(z_map_fn)
# zl_sh = ZL.shape # zl_sh = ZL.shape
# x = np.arange(0,zl_sh[1],1) # x = np.arange(0,zl_sh[1],1)
# y = np.arange(0,zl_sh[0],1) # y = np.arange(0,zl_sh[0],1)
x = ZL[0,1:] x = ZL[0, 1:]
y = ZL[1:,0] y = ZL[1:, 0]
X,Y = np.meshgrid(x,y) X, Y = np.meshgrid(x, y)
# f_sur = interp2d(X,Y,ZL,kind='linear') # f_sur = interp2d(X,Y,ZL,kind='linear')
sun_radec = Cartesian2Equatorial(sun_pos) sun_radec = Cartesian2Equatorial(sun_pos)
sun_eclip = coord.SkyCoord(sun_radec[0]*u.degree, sun_radec[1]*u.degree,frame='icrs') sun_eclip = coord.SkyCoord(
sun_radec[0]*u.degree, sun_radec[1]*u.degree, frame='icrs')
sun_equtor = sun_eclip.transform_to('barycentrictrueecliptic') sun_equtor = sun_eclip.transform_to('barycentrictrueecliptic')
longitude = longitude - (sun_equtor.lon*u.degree).value longitude = longitude - (sun_equtor.lon*u.degree).value
...@@ -526,15 +551,16 @@ class Straylight(object): ...@@ -526,15 +551,16 @@ class Straylight(object):
latitude = np.abs(latitude) latitude = np.abs(latitude)
lo = longitude lo = longitude
la = latitude la = latitude
zl = griddata((X.flatten(),Y.flatten()),ZL[1:,1:].flatten(),(la,lo), method='cubic').min() zl = griddata((X.flatten(), Y.flatten()),
ZL[1:, 1:].flatten(), (la, lo), method='cubic').min()
zl = zl*(math.pi*math.pi)/(180*180)/(3600*3600)*1e-4*1e7*1e-8*1e-4 zl = zl*(math.pi*math.pi)/(180*180)/(3600*3600)*1e-4*1e7*1e-8*1e-4
# print(zl , '\n') # print(zl , '\n')
try: try:
with pkg_resources.files('ObservationSim.Straylight.data.sky').joinpath('zodiacal.dat') as zodical_fn: with pkg_resources.files('observation_sim.sky_background.data.sky').joinpath('zodiacal.dat') as zodical_fn:
spec = np.loadtxt(zodical_fn) spec = np.loadtxt(zodical_fn)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Straylight.data.sky', with pkg_resources.path('observation_sim.sky_background.data.sky',
'zodiacal.dat') as zodical_fn: 'zodiacal.dat') as zodical_fn:
spec = np.loadtxt(zodical_fn) spec = np.loadtxt(zodical_fn)
...@@ -545,29 +571,37 @@ class Straylight(object): ...@@ -545,29 +571,37 @@ class Straylight(object):
v_mag = np.log10(f_ration)*(-2.5)+22.1 v_mag = np.log10(f_ration)*(-2.5)+22.1
# print("factor:", v_mag, lo, la) # print("factor:", v_mag, lo, la)
return Table(np.array([spec[:,0], spec[:,1]*f_ration]).T,names=('WAVELENGTH', 'FLUX')), v_mag return Table(np.array([spec[:, 0], spec[:, 1]*f_ration]).T, names=('WAVELENGTH', 'FLUX')), v_mag
def calculateStrayLightFilter(self, filter = 'i', pixel_size_phy = 10, pixel_scale = 0.074): def calculateStrayLightFilter(self, filter='i', pixel_size_phy=10, pixel_scale=0.074):
e1,py = self.calculateEarthShineFilter(filter = filter, pixel_size_phy = pixel_size_phy) e1, py = self.calculateEarthShineFilter(
e2, _ = self.calculateZodiacalFilter2(filter = filter, sun_pos=self.sun_pos, pixelsize = pixel_scale) filter=filter, pixel_size_phy=pixel_size_phy)
e3 = self.calculateStarLightFilter(filter = filter,pointYaxis = py, pixel_size_phy = pixel_size_phy) e2, _ = self.calculateZodiacalFilter2(
filter=filter, sun_pos=self.sun_pos, pixelsize=pixel_scale)
e3 = self.calculateStarLightFilter(
filter=filter, pointYaxis=py, pixel_size_phy=pixel_size_phy)
return e1+e2+e3 return e1+e2+e3
def calculateStrayLightGrating(self, grating = 'GI', pixel_size_phy = 10, normFilter_es = 'g'): def calculateStrayLightGrating(self, grating='GI', pixel_size_phy=10, normFilter_es='g'):
e1,py = self.calculateEarthshineGrating(grating = grating, pixel_size_phy = pixel_size_phy, normFilter = normFilter_es) e1, py = self.calculateEarthshineGrating(
e2 = self.calculateStarLightGrating(grating = grating, pointYaxis = py) grating=grating, pixel_size_phy=pixel_size_phy, normFilter=normFilter_es)
spec, _ = self.calculateZodicalSpec(longitude = self.ecliptic.lon.value, latitude = self.ecliptic.lat.value, sun_pos = self.sun_pos) e2 = self.calculateStarLightGrating(grating=grating, pointYaxis=py)
spec, _ = self.calculateZodicalSpec(
longitude=self.ecliptic.lon.value, latitude=self.ecliptic.lat.value, sun_pos=self.sun_pos)
return e1+e2, spec return e1+e2, spec
def testZodiacal(lon = 285.04312526255366, lat = 30.):
c_eclip = coord.SkyCoord(lon*u.degree, lat*u.degree,frame='barycentrictrueecliptic') def testZodiacal(lon=285.04312526255366, lat=30.):
c_eclip = coord.SkyCoord(lon*u.degree, lat*u.degree,
frame='barycentrictrueecliptic')
c_equtor = c_eclip.transform_to('icrs') c_equtor = c_eclip.transform_to('icrs')
sl = Straylight(jtime = 2459767.00354975, sat = np.array([]), radec = np.array([(c_equtor.ra*u.degree).value, (c_equtor.dec*u.degree).value])) sl = Straylight(jtime=2459767.00354975, sat=np.array([]), radec=np.array(
e_zol, v_mag = sl.calculateZodiacalFilter2(filter = 'i', sun_pos=np.array([-3.70939436e+07, 1.35334903e+08, 5.86673104e+07])) [(c_equtor.ra*u.degree).value, (c_equtor.dec*u.degree).value]))
e_zol, v_mag = sl.calculateZodiacalFilter2(filter='i', sun_pos=np.array(
[-3.70939436e+07, 1.35334903e+08, 5.86673104e+07]))
print(e_zol) print(e_zol)
# ju=2.4608437604166665e+06 # ju=2.4608437604166665e+06
...@@ -639,4 +673,3 @@ def testZodiacal(lon = 285.04312526255366, lat = 30.): ...@@ -639,4 +673,3 @@ def testZodiacal(lon = 285.04312526255366, lat = 30.):
# print(e1+e2,e1_+e3+e4,e5,e6) # print(e1+e2,e1_+e3+e4,e5,e6)
# #
# # print(e1,e2,e3,e4) # # print(e1,e2,e3,e4)
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