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
#!/bin/bash
date
python3 /public/home/fangyuedong/project/csst_msc_sim/run_sim.py \
--config_file config_overall.yaml \
-c /public/home/fangyuedong/project/csst_msc_sim/config \
--catalog C9_Catalog
import os
import sys
from ObservationSim.Astrometry.Astrometry_util import on_orbit_obs_position
def readFits2List(fn):
from astropy.io import fits
if not os.path.exists(fn):
print("Can not find "+fn); return False
hdul=fits.open(fn)
data = hdul[1].data
ra_list = data['RA'].tolist()
dec_list = data['Dec'].tolist()
pmra_list = data['pmra'].tolist()
pmdec_list = data['pmdec'].tolist()
parallax_list = data['parallax'].tolist()
rv_list = [0.0 for i in range(len(ra_list))]
hdul.close()
return ra_list, dec_list, pmra_list, pmdec_list, rv_list, parallax_list
def usageExample(targets_fn, results_fn, x, y, z, vx, vy, vz, date_str, time_str):
if not os.path.exists(targets_fn):
print("Can not find " + targets_fn)
sys.exit(1)
ra_list, dec_list, pmra_list, pmdec_list, rv_list, parallax_list = readFits2List(targets_fn)
output_ra_list, output_dec_list = on_orbit_obs_position(ra_list, dec_list, pmra_list, \
pmdec_list, rv_list, parallax_list, len(ra_list), \
x, y, z, vx, vy, vz, "J2015.5", date_str, time_str, lib_path='./libshao.so')
f = open(results_fn, "w")
ll = list()
ll.append("n,date,time,ra,dec,pm_ra,pm_dec,rv,parallax,obs_ra,obs_dec\n")
for i in range(len(output_ra_list)):
ra_str = str(ra_list[i])
dec_str = str(dec_list[i])
pmra_str = str(pmra_list[i])
pmdec_str = str(pmdec_list[i])
rv_str = str(rv_list[i])
parallax_str = str(parallax_list[i])
ora_str = str(output_ra_list[i])
odec_str = str(output_dec_list[i])
l = str(i)+date_str+","+time_str+","+ra_str+","+dec_str+","+pmra_str+","+pmdec_str+","+rv_str+","+parallax_str+","+ora_str+","+odec_str+"\n"
ll.append(l)
f.writelines(ll)
f.close()
print("Process finished. Results save to "+results_fn)
def usageTips():
print("Usage 1: python3 ./shao_test.py")
print("Usage 2: python3 ./shao_test.py yyyy-MM-dd HH:mm:ss.ms Positon1_KM Positon2_KM Positon3_KM Velocity1_MK/S Velocity2_MK/S Velocity3_MK/S $PATH1/MMW_Gaia_Cluster_D20_SS_astrometry.fits $PATH2/results.csv")
print("Caution: Do no include space in path; Unit is KM or KM/S")
print("Example: python3 ./shao_test.py 2025-03-05 22:20:15.12 2347.766100 5132.421392 3726.591334 5.282357 4.644825 -3.074722 ./MMW_Gaia_Cluster_D20_SS_astrometry.fits ./results.csv")
if __name__ == "__main__":
args_value = sys.argv
if len(args_value) == 1:
usageExample("./MMW_Gaia_Cluster_D20_SS_astrometry.fits", "./results.csv", 2347.766100, 5132.421392, 3726.591334, 5.282357, 4.644825, -3.074722, "2025-03-05", "22:20:15.12"); sys.exit(1)
elif len(args_value) == 11:
date_str = args_value[1]
time_str = args_value[2]
x = float(args_value[3])
y = float(args_value[4])
z = float(args_value[5])
vx = float(args_value[6])
vy = float(args_value[7])
vz = float(args_value[8])
targets_fn = args_value[9]
results_fn = args_value[10]
if not os.path.exists(targets_fn):
print("Can not find " + targets_fn)
sys.exit(1)
usageExample(targets_fn, results_fn, x, y, z, vx, vy, vz, date_str, time_str)
else:
usageTips()
import unittest import unittest
import sys,os,math import sys
import os
import math
from itertools import islice from itertools import islice
import numpy as np import numpy as np
import copy import copy
...@@ -9,10 +11,9 @@ import galsim ...@@ -9,10 +11,9 @@ import galsim
import yaml import yaml
from astropy.io import fits from astropy.io import fits
from ObservationSim.Instrument import Chip, Filter, FilterParam, FocalPlane from observation_sim.instruments import Chip, Filter, FilterParam, FocalPlane
from ObservationSim.Instrument.Chip import ChipUtils as chip_utils from observation_sim.instruments.chip import chip_utils
#from ObservationSim.sim_steps import add_brighter_fatter_CTE from observation_sim.instruments.chip.libCTI.CTI_modeling import CTI_sim
from ObservationSim.Instrument.Chip.libCTI.CTI_modeling import CTI_sim
try: try:
import importlib.resources as pkg_resources import importlib.resources as pkg_resources
...@@ -23,14 +24,15 @@ except ImportError: ...@@ -23,14 +24,15 @@ except ImportError:
### test FUNCTION --- START ### ### test FUNCTION --- START ###
def add_brighter_fatter(img): def add_brighter_fatter(img):
#Inital dynamic lib # Inital dynamic lib
try: try:
with pkg_resources.files('ObservationSim.Instrument.Chip.libBF').joinpath("libmoduleBF.so") as lib_path: with pkg_resources.files('observation_sim.instruments.chip.libBF').joinpath("libmoduleBF.so") as lib_path:
lib_bf = ctypes.CDLL(lib_path) lib_bf = ctypes.CDLL(lib_path)
except AttributeError: except AttributeError:
with pkg_resources.path('ObservationSim.Instrument.Chip.libBF', "libmoduleBF.so") as lib_path: with pkg_resources.path('observation_sim.instruments.chip.libBF', "libmoduleBF.so") as lib_path:
lib_bf = ctypes.CDLL(lib_path) lib_bf = ctypes.CDLL(lib_path)
lib_bf.addEffects.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_float), ctypes.POINTER(ctypes.c_float), ctypes.c_int] lib_bf.addEffects.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.POINTER(
ctypes.c_float), ctypes.POINTER(ctypes.c_float), ctypes.c_int]
# Set bit flag # Set bit flag
bit_flag = 1 bit_flag = 1
...@@ -38,11 +40,11 @@ def add_brighter_fatter(img): ...@@ -38,11 +40,11 @@ def add_brighter_fatter(img):
nx, ny = img.array.shape nx, ny = img.array.shape
nn = nx * ny nn = nx * ny
arr_ima= (ctypes.c_float*nn)() arr_ima = (ctypes.c_float*nn)()
arr_imc= (ctypes.c_float*nn)() arr_imc = (ctypes.c_float*nn)()
arr_ima[:]= img.array.reshape(nn) arr_ima[:] = img.array.reshape(nn)
arr_imc[:]= np.zeros(nn) arr_imc[:] = np.zeros(nn)
lib_bf.addEffects(nx, ny, arr_ima, arr_imc, bit_flag) lib_bf.addEffects(nx, ny, arr_ima, arr_imc, bit_flag)
img.array[:, :] = np.reshape(arr_imc, [nx, ny]) img.array[:, :] = np.reshape(arr_imc, [nx, ny])
...@@ -50,20 +52,24 @@ def add_brighter_fatter(img): ...@@ -50,20 +52,24 @@ def add_brighter_fatter(img):
return img return img
### test FUNCTION --- END ### ### test FUNCTION --- END ###
def defineCCD(iccd, config_file): def defineCCD(iccd, config_file):
with open(config_file, "r") as stream: with open(config_file, "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=iccd, config=config) chip = Chip(chipID=iccd, config=config)
chip.img = galsim.ImageF(400, 200) #galsim.ImageF(chip.npix_x, chip.npix_y) # galsim.ImageF(chip.npix_x, chip.npix_y)
chip.img = galsim.ImageF(400, 200)
focal_plane = FocalPlane(chip_list=[iccd]) focal_plane = FocalPlane(chip_list=[iccd])
chip.img.wcs= focal_plane.getTanWCS(192.8595, 27.1283, -113.4333*galsim.degrees, chip.pix_scale) chip.img.wcs = focal_plane.getTanWCS(
192.8595, 27.1283, -113.4333*galsim.degrees, chip.pix_scale)
return chip return chip
def defineFilt(chip): def defineFilt(chip):
filter_param = FilterParam() filter_param = FilterParam()
filter_id, filter_type = chip.getChipFilter() filter_id, filter_type = chip.getChipFilter()
...@@ -79,11 +85,11 @@ def defineFilt(chip): ...@@ -79,11 +85,11 @@ def defineFilt(chip):
class detModule_coverage(unittest.TestCase): class detModule_coverage(unittest.TestCase):
def __init__(self, methodName='runTest'): def __init__(self, methodName='runTest'):
super(detModule_coverage, self).__init__(methodName) super(detModule_coverage, self).__init__(methodName)
##self.dataPath = "/public/home/chengliang/CSSOSDataProductsSims/csst-simulation/tests/UNIT_TEST_DATA" ##os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), 'csst_fz_gc1') # self.dataPath = "/public/home/chengliang/CSSOSDataProductsSims/csst-simulation/tests/UNIT_TEST_DATA" ##os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), 'csst_fz_gc1')
self.dataPath = os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), 'csst_msc_sim/csst_fz_msc') self.dataPath = os.path.join(
os.getenv('UNIT_TEST_DATA_ROOT'), 'csst_msc_sim/csst_fz_msc')
self.iccd = 1 self.iccd = 1
def test_add_brighter_fatter(self): def test_add_brighter_fatter(self):
config_file = os.path.join(self.dataPath, 'config_test.yaml') config_file = os.path.join(self.dataPath, 'config_test.yaml')
chip = defineCCD(self.iccd, config_file) chip = defineCCD(self.iccd, config_file)
...@@ -91,32 +97,31 @@ class detModule_coverage(unittest.TestCase): ...@@ -91,32 +97,31 @@ class detModule_coverage(unittest.TestCase):
print(chip.chipID) print(chip.chipID)
print(chip.cen_pix_x, chip.cen_pix_y) print(chip.cen_pix_x, chip.cen_pix_y)
#objA-lowSFB # objA-lowSFB
obj = galsim.Gaussian(sigma=0.2, flux=1000) obj = galsim.Gaussian(sigma=0.2, flux=1000)
arr = obj.drawImage(nx=64, ny=64, scale=0.074).array arr = obj.drawImage(nx=64, ny=64, scale=0.074).array
chip.img.array[(100-32):(100+32),(200-32):(200+32)] = arr[:,:] chip.img.array[(100-32):(100+32), (200-32):(200+32)] = arr[:, :]
img_old = copy.deepcopy(chip.img) img_old = copy.deepcopy(chip.img)
img_new = add_brighter_fatter(img=chip.img) img_new = add_brighter_fatter(img=chip.img)
arr1= img_old.array arr1 = img_old.array
arr2= img_new.array arr2 = img_new.array
deltaA_max = np.max(np.abs(arr2-arr1)) deltaA_max = np.max(np.abs(arr2-arr1))
print('deltaA-max:', np.max(np.abs(arr2-arr1))) print('deltaA-max:', np.max(np.abs(arr2-arr1)))
print('deltaA-min:', np.min(np.abs(arr2-arr1))) print('deltaA-min:', np.min(np.abs(arr2-arr1)))
#objB-highSFB # objB-highSFB
obj = galsim.Gaussian(sigma=0.2, flux=10000) obj = galsim.Gaussian(sigma=0.2, flux=10000)
arr = obj.drawImage(nx=64, ny=64, scale=0.074).array arr = obj.drawImage(nx=64, ny=64, scale=0.074).array
chip.img.array[(100-32):(100+32),(200-32):(200+32)] = arr[:,:] chip.img.array[(100-32):(100+32), (200-32):(200+32)] = arr[:, :]
img_old = copy.deepcopy(chip.img) img_old = copy.deepcopy(chip.img)
img_new = add_brighter_fatter(img=chip.img) img_new = add_brighter_fatter(img=chip.img)
arr3= img_old.array arr3 = img_old.array
arr4= img_new.array arr4 = img_new.array
deltaB_max = np.max(np.abs(arr4-arr3)) deltaB_max = np.max(np.abs(arr4-arr3))
print('deltaB-max:', np.max(np.abs(arr4-arr3))) print('deltaB-max:', np.max(np.abs(arr4-arr3)))
print('deltaB-min:', np.min(np.abs(arr4-arr3))) print('deltaB-min:', np.min(np.abs(arr4-arr3)))
self.assertTrue( deltaB_max > deltaA_max )
self.assertTrue(deltaB_max > deltaA_max)
def test_apply_CTE(self): def test_apply_CTE(self):
config_file = os.path.join(self.dataPath, 'config_test.yaml') config_file = os.path.join(self.dataPath, 'config_test.yaml')
...@@ -126,18 +131,21 @@ class detModule_coverage(unittest.TestCase): ...@@ -126,18 +131,21 @@ class detModule_coverage(unittest.TestCase):
print(chip.cen_pix_x, chip.cen_pix_y) print(chip.cen_pix_x, chip.cen_pix_y)
print(" Apply CTE Effect") print(" Apply CTE Effect")
nx,ny,noverscan,nsp,nmax = 4608,4616,84,3,10 nx, ny, noverscan, nsp, nmax = 4608, 4616, 84, 3, 10
ntotal = 4700 ntotal = 4700
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,100,1000],dtype=np.int32) trap_seeds = np.array([0, 100, 1000], dtype=np.int32)
release_seed = 500 release_seed = 500
image = fits.getdata(os.path.join(self.dataPath, "testCTE_image_before.fits")).astype(np.int32) image = fits.getdata(os.path.join(
#get_trap_map(trap_seeds,nx,ny,nmax,rho_trap,beta,c,".") self.dataPath, "testCTE_image_before.fits")).astype(np.int32)
#bin2fits("trap.bin",".",nsp,nx,ny,nmax) # get_trap_map(trap_seeds,nx,ny,nmax,rho_trap,beta,c,".")
image_cti = CTI_sim(image,nx,ny,noverscan,nsp,nmax,beta,w,c,t,rho_trap,trap_seeds,release_seed) # bin2fits("trap.bin",".",nsp,nx,ny,nmax)
fits.writeto(os.path.join(self.dataPath, "testCTE_image_after.fits"),data=image_cti,overwrite=True) image_cti = CTI_sim(image, nx, ny, noverscan, nsp, nmax,
beta, w, c, t, rho_trap, trap_seeds, release_seed)
fits.writeto(os.path.join(
self.dataPath, "testCTE_image_after.fits"), data=image_cti, overwrite=True)
if __name__ == '__main__': if __name__ == '__main__':
......
import unittest import unittest
import sys,os,math import sys
import os
import math
from itertools import islice from itertools import islice
import numpy as np import numpy as np
import galsim import galsim
import yaml import yaml
from ObservationSim.Instrument import Chip, Filter, FilterParam, FocalPlane from observation_sim.instruments import Chip, Filter, FilterParam, FocalPlane
from ObservationSim.PSF.PSFInterp import PSFInterp from observation_sim.psf.PSFInterp import PSFInterp
def defineCCD(iccd, config_file): def defineCCD(iccd, config_file):
with open(config_file, "r") as stream: with open(config_file, "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=iccd, config=config) chip = Chip(chipID=iccd, config=config)
chip.img = galsim.ImageF(chip.npix_x, chip.npix_y) chip.img = galsim.ImageF(chip.npix_x, chip.npix_y)
focal_plane = FocalPlane(chip_list=[iccd]) focal_plane = FocalPlane(chip_list=[iccd])
chip.img.wcs= focal_plane.getTanWCS(192.8595, 27.1283, -113.4333*galsim.degrees, chip.pix_scale) chip.img.wcs = focal_plane.getTanWCS(
192.8595, 27.1283, -113.4333*galsim.degrees, chip.pix_scale)
return chip return chip
def defineFilt(chip): def defineFilt(chip):
filter_param = FilterParam() filter_param = FilterParam()
filter_id, filter_type = chip.getChipFilter() filter_id, filter_type = chip.getChipFilter()
...@@ -39,7 +43,8 @@ def defineFilt(chip): ...@@ -39,7 +43,8 @@ def defineFilt(chip):
class PSFInterpModule_coverage(unittest.TestCase): class PSFInterpModule_coverage(unittest.TestCase):
def __init__(self, methodName='runTest'): def __init__(self, methodName='runTest'):
super(PSFInterpModule_coverage, self).__init__(methodName) super(PSFInterpModule_coverage, self).__init__(methodName)
self.dataPath = os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), 'csst_msc_sim/csst_fz_msc') self.dataPath = os.path.join(
os.getenv('UNIT_TEST_DATA_ROOT'), 'csst_msc_sim/csst_fz_msc')
self.iccd = 8 self.iccd = 8
def test_loadPSFSet(self): def test_loadPSFSet(self):
...@@ -48,23 +53,28 @@ class PSFInterpModule_coverage(unittest.TestCase): ...@@ -48,23 +53,28 @@ class PSFInterpModule_coverage(unittest.TestCase):
bandpass = defineFilt(chip) bandpass = defineFilt(chip)
print(chip.chipID) print(chip.chipID)
print(chip.cen_pix_x, chip.cen_pix_y) print(chip.cen_pix_x, chip.cen_pix_y)
pathTemp = self.dataPath #"/public/share/yangxuliu/CSSOSDataProductsSims/psfCube/set1_dynamic/" # "/public/share/yangxuliu/CSSOSDataProductsSims/psfCube/set1_dynamic/"
psfModel= PSFInterp(chip, npsf=900, PSF_data_file=pathTemp, PSF_data_prefix="", HocBuild=True, LOG_DEBUG=True) pathTemp = self.dataPath
psfModel = PSFInterp(chip, npsf=900, PSF_data_file=pathTemp,
x, y = 4096, 4096 #imgPos[iobj, :] # try get the PSF at some location (1234, 1234) on the chip PSF_data_prefix="", HocBuild=True, LOG_DEBUG=True)
# imgPos[iobj, :] # try get the PSF at some location (1234, 1234) on the chip
x, y = 4096, 4096
x = x+chip.bound.xmin x = x+chip.bound.xmin
y = y+chip.bound.ymin y = y+chip.bound.ymin
pos_img = galsim.PositionD(x, y) pos_img = galsim.PositionD(x, y)
psf,_ = psfModel.get_PSF(chip=chip, pos_img=pos_img, bandpass=0, galsimGSObject=True) psf, _ = psfModel.get_PSF(
psfA = psfModel.get_PSF(chip=chip, pos_img=pos_img, bandpass=bandpass[0], galsimGSObject=False) chip=chip, pos_img=pos_img, bandpass=0, galsimGSObject=True)
psfB = psfModel.get_PSF(chip=chip, pos_img=pos_img, findNeighMode='hoclistFind', bandpass=bandpass[0], galsimGSObject=False) psfA = psfModel.get_PSF(
chip=chip, pos_img=pos_img, bandpass=bandpass[0], galsimGSObject=False)
self.assertTrue( psf != None ) psfB = psfModel.get_PSF(
self.assertTrue( np.max(np.abs(psfA-psfB))<1e-6 ) chip=chip, pos_img=pos_img, findNeighMode='hoclistFind', bandpass=bandpass[0], galsimGSObject=False)
self.assertTrue(psf != None)
self.assertTrue(np.max(np.abs(psfA-psfB)) < 1e-6)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# #
#need add environment parameter UNIT_TEST_DATA_ROOT, link to "testData/" # need add environment parameter UNIT_TEST_DATA_ROOT, link to "testData/"
#linx and mac can run as follow, need modify the name of file directory # linx and mac can run as follow, need modify the name of file directory
#export UNIT_TEST_DATA_ROOT=/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_develop/csst-simulation/tests/testData # export UNIT_TEST_DATA_ROOT=/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_develop/csst-simulation/tests/testData
# #
import unittest import unittest
from ObservationSim.MockObject.SpecDisperser import rotate90, SpecDisperser from observation_sim.mock_objects.SpecDisperser import rotate90, SpecDisperser
from ObservationSim.Config import ChipOutput from observation_sim.config import ChipOutput
from ObservationSim.Instrument import Telescope, Chip, FilterParam, Filter, FocalPlane from observation_sim.instruments import Telescope, Chip, FilterParam, Filter, FocalPlane
from ObservationSim.MockObject import MockObject, Star from observation_sim.mock_objects import MockObject, Star
from ObservationSim.PSF import PSFGauss from observation_sim.psf import PSFGauss
import numpy as np import numpy as np
import galsim import galsim
...@@ -20,36 +20,37 @@ import matplotlib.pyplot as plt ...@@ -20,36 +20,37 @@ import matplotlib.pyplot as plt
from lmfit.models import LinearModel, GaussianModel from lmfit.models import LinearModel, GaussianModel
from ObservationSim.Config.Header import generateExtensionHeader from observation_sim.config.header import generateExtensionHeader
import math import math
import yaml import yaml
import os import os
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; cosValue = 0
angle = 0; angle = 0
x11 = x1 - x3; x11 = x1 - x3
y11 = y1 - y3; y11 = y1 - y3
z11 = z1 - z3; z11 = z1 - z3
x22 = x2 - x3; x22 = x2 - x3
y22 = y2 - y3; y22 = y2 - y3
z22 = z2 - z3; z22 = z2 - z3
tt = np.sqrt((x11 * x11 + y11 * y11 + z11 * z11) * (x22 * x22 + y22 * y22 + z22 * z22)); tt = np.sqrt((x11 * x11 + y11 * y11 + z11 * z11)
* (x22 * x22 + y22 * y22 + z22 * z22))
if (tt == 0): if (tt == 0):
return 0; return 0
cosValue = (x11 * x22 + y11 * y22 + z11 * z22) / tt; cosValue = (x11 * x22 + y11 * y22 + z11 * z22) / tt
if (cosValue > 1): if (cosValue > 1):
cosValue = 1; cosValue = 1
if (cosValue < -1): if (cosValue < -1):
cosValue = -1; cosValue = -1
angle = math.acos(cosValue); angle = math.acos(cosValue)
return angle * 360 / (2 * math.pi); return angle * 360 / (2 * math.pi)
def fit_SingleGauss(xX, yX, contmX, iHa0): def fit_SingleGauss(xX, yX, contmX, iHa0):
...@@ -71,26 +72,35 @@ def fit_SingleGauss(xX, yX, contmX, iHa0): ...@@ -71,26 +72,35 @@ def fit_SingleGauss(xX, yX, contmX, iHa0):
# print outX.params['g_center'] # print outX.params['g_center']
outX.fit_report(min_correl=0.25) outX.fit_report(min_correl=0.25)
# print(outX.fit_report(min_correl=0.25)) # print(outX.fit_report(min_correl=0.25))
line_slopeX = float(outX.fit_report(min_correl=0.25).split('line_slope:')[1].split('+/-')[0]) * contmX line_slopeX = float(outX.fit_report(min_correl=0.25).split(
'line_slope:')[1].split('+/-')[0]) * contmX
err_line_slopeX = float( err_line_slopeX = float(
outX.fit_report(min_correl=0.25).split('line_slope:')[1].split('+/-')[1].split('(')[0]) * contmX outX.fit_report(min_correl=0.25).split('line_slope:')[1].split('+/-')[1].split('(')[0]) * contmX
line_interceptX = float(outX.fit_report(min_correl=0.25).split('line_intercept:')[1].split('+/-')[0]) * contmX line_interceptX = float(outX.fit_report(min_correl=0.25).split(
'line_intercept:')[1].split('+/-')[0]) * contmX
err_line_interceptX = float( err_line_interceptX = float(
outX.fit_report(min_correl=0.25).split('line_intercept:')[1].split('+/-')[1].split('(')[0]) * contmX outX.fit_report(min_correl=0.25).split('line_intercept:')[1].split('+/-')[1].split('(')[0]) * contmX
sigmaX = float(outX.fit_report(min_correl=0.25).split('g_sigma:')[1].split('+/-')[0]) sigmaX = float(outX.fit_report(min_correl=0.25).split(
err_sigmaX = float(outX.fit_report(min_correl=0.25).split('g_sigma:')[1].split('+/-')[1].split('(')[0]) 'g_sigma:')[1].split('+/-')[0])
err_sigmaX = float(outX.fit_report(min_correl=0.25).split(
'g_sigma:')[1].split('+/-')[1].split('(')[0])
fwhmX = float(outX.fit_report(min_correl=0.25).split('g_fwhm:')[1].split('+/-')[0]) fwhmX = float(outX.fit_report(min_correl=0.25).split(
err_fwhmX = float(outX.fit_report(min_correl=0.25).split('g_fwhm:')[1].split('+/-')[1].split('(')[0]) 'g_fwhm:')[1].split('+/-')[0])
err_fwhmX = float(outX.fit_report(min_correl=0.25).split(
'g_fwhm:')[1].split('+/-')[1].split('(')[0])
centerX = float(outX.fit_report(min_correl=0.25).split('g_center:')[1].split('+/-')[0]) centerX = float(outX.fit_report(min_correl=0.25).split(
err_centerX = float(outX.fit_report(min_correl=0.25).split('g_center:')[1].split('+/-')[1].split('(')[0]) 'g_center:')[1].split('+/-')[0])
err_centerX = float(outX.fit_report(min_correl=0.25).split(
'g_center:')[1].split('+/-')[1].split('(')[0])
return sigmaX, err_sigmaX, fwhmX, err_fwhmX, centerX, err_centerX return sigmaX, err_sigmaX, fwhmX, err_fwhmX, centerX, err_centerX
def produceObj(x,y,chip, ra, dec, pa):
def produceObj(x, y, chip, ra, dec, pa):
pos_img = galsim.PositionD(x, y) pos_img = galsim.PositionD(x, y)
param = {} param = {}
...@@ -104,22 +114,22 @@ def produceObj(x,y,chip, ra, dec, pa): ...@@ -104,22 +114,22 @@ def produceObj(x,y,chip, ra, dec, pa):
obj = Star(param) obj = Star(param)
header_wcs = generateExtensionHeader(chip, header_wcs = generateExtensionHeader(chip,
xlen=chip.npix_x, xlen=chip.npix_x,
ylen=chip.npix_y, ylen=chip.npix_y,
ra=ra, ra=ra,
dec=dec, dec=dec,
pa=pa, pa=pa,
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,
row_num=chip.rowID, row_num=chip.rowID,
col_num=chip.colID, col_num=chip.colID,
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='SCI') extName='SCI')
chip_wcs = galsim.FitsWCS(header=header_wcs) chip_wcs = galsim.FitsWCS(header=header_wcs)
param["ra"] = chip_wcs.posToWorld(pos_img).ra.deg param["ra"] = chip_wcs.posToWorld(pos_img).ra.deg
...@@ -143,50 +153,56 @@ def produceObj(x,y,chip, ra, dec, pa): ...@@ -143,50 +153,56 @@ def produceObj(x,y,chip, ra, dec, pa):
class TestSpecDisperse(unittest.TestCase): class TestSpecDisperse(unittest.TestCase):
def __init__(self, methodName='runTest'): def __init__(self, methodName='runTest'):
super(TestSpecDisperse,self).__init__(methodName) super(TestSpecDisperse, self).__init__(methodName)
self.filePath('csst_msc_sim/test_sls_and_straylight') self.filePath('csst_msc_sim/test_sls_and_straylight')
# self.conff = conff # self.conff = conff
# self.throughputf = throughputf # self.throughputf = throughputf
def filePath(self, file_name): def filePath(self, file_name):
fn = os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), file_name) fn = os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), file_name)
self.conff= os.path.join(fn, 'CSST_GI2.conf') self.conff = os.path.join(fn, 'CSST_GI2.conf')
self.throughputf= os.path.join(fn, 'GI.Throughput.1st.fits') self.throughputf = os.path.join(fn, 'GI.Throughput.1st.fits')
self.testDir = fn self.testDir = fn
self.outDataFn = os.path.join(fn,'output') self.outDataFn = os.path.join(fn, 'output')
if os.path.isdir(self.outDataFn): if os.path.isdir(self.outDataFn):
pass pass
else: else:
os.mkdir(self.outDataFn) os.mkdir(self.outDataFn)
def test_rotate901(self): def test_rotate901(self):
m = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20],[21,22,23,24,25]]) m = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [
m1 = np.array([[21,16,11,6,1],[22,17,12,7,2],[23,18,13,8,3],[24,19,14,9,4],[25,20,15,10,5]]) 16, 17, 18, 19, 20], [21, 22, 23, 24, 25]])
m2 = np.array([[5,10,15,20,25],[4,9,14,19,24],[3,8,13,18,23],[2,7,12,17,22],[1,6,11,16,21]]) m1 = np.array([[21, 16, 11, 6, 1], [22, 17, 12, 7, 2], [
23, 18, 13, 8, 3], [24, 19, 14, 9, 4], [25, 20, 15, 10, 5]])
m2 = np.array([[5, 10, 15, 20, 25], [4, 9, 14, 19, 24], [
3, 8, 13, 18, 23], [2, 7, 12, 17, 22], [1, 6, 11, 16, 21]])
xc = 2 xc = 2
yc = 2 yc = 2
isClockwise = 0 isClockwise = 0
m1, xc1, yc1 = rotate90(array_orig=m, xc=xc, yc=yc, isClockwise=isClockwise) m1, xc1, yc1 = rotate90(array_orig=m, xc=xc,
yc=yc, isClockwise=isClockwise)
self.assertTrue(xc1-xc == 0) self.assertTrue(xc1-xc == 0)
self.assertTrue(yc1-yc == 0) self.assertTrue(yc1-yc == 0)
self.assertTrue(np.sum(m-m1) == 0) self.assertTrue(np.sum(m-m1) == 0)
def test_rotate902(self): def test_rotate902(self):
m = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20],[21,22,23,24,25]]) m = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [
m1 = np.array([[21,16,11,6,1],[22,17,12,7,2],[23,18,13,8,3],[24,19,14,9,4],[25,20,15,10,5]]) 16, 17, 18, 19, 20], [21, 22, 23, 24, 25]])
m2 = np.array([[5,10,15,20,25],[4,9,14,19,24],[3,8,13,18,23],[2,7,12,17,22],[1,6,11,16,21]]) m1 = np.array([[21, 16, 11, 6, 1], [22, 17, 12, 7, 2], [
23, 18, 13, 8, 3], [24, 19, 14, 9, 4], [25, 20, 15, 10, 5]])
m2 = np.array([[5, 10, 15, 20, 25], [4, 9, 14, 19, 24], [
3, 8, 13, 18, 23], [2, 7, 12, 17, 22], [1, 6, 11, 16, 21]])
xc = 2 xc = 2
yc = 2 yc = 2
isClockwise =1 isClockwise = 1
m1, xc1, yc1 = rotate90(array_orig=m, xc=xc, yc=yc, isClockwise=isClockwise) m1, xc1, yc1 = rotate90(array_orig=m, xc=xc,
yc=yc, isClockwise=isClockwise)
self.assertTrue(xc1-xc == 0) self.assertTrue(xc1-xc == 0)
self.assertTrue(yc1-yc == 0) self.assertTrue(yc1-yc == 0)
self.assertTrue(np.sum(m-m2) == 0) self.assertTrue(np.sum(m-m2) == 0)
def test_Specdistperse1(self): def test_Specdistperse1(self):
star = galsim.Gaussian(fwhm=0.39) star = galsim.Gaussian(fwhm=0.39)
...@@ -236,7 +252,8 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -236,7 +252,8 @@ class TestSpecDisperse(unittest.TestCase):
ids = wave_pix < 9700 ids = wave_pix < 9700
ids1 = wave_pix[ids] > 6500 ids1 = wave_pix[ids] > 6500
print('Spec disperse flux test') print('Spec disperse flux test')
self.assertTrue(np.mean((wave_flux[ids][ids1] - sed_i(wave_pix[ids][ids1]))/sed_i(wave_pix[ids][ids1]))<0.004) self.assertTrue(np.mean(
(wave_flux[ids][ids1] - sed_i(wave_pix[ids][ids1]))/sed_i(wave_pix[ids][ids1])) < 0.004)
# plt.figure() # plt.figure()
# plt.plot(wave_pix, wave_flux) # plt.plot(wave_pix, wave_flux)
# plt.plot(sed['WAVELENGTH'], sed['FLUX']) # plt.plot(sed['WAVELENGTH'], sed['FLUX'])
...@@ -299,14 +316,17 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -299,14 +316,17 @@ class TestSpecDisperse(unittest.TestCase):
input_em_lam = 6600 input_em_lam = 6600
ids = wave_pix < input_em_lam+200 ids = wave_pix < input_em_lam+200
ids1 = wave_pix[ids] > input_em_lam-200 ids1 = wave_pix[ids] > input_em_lam-200
deltLamda_pix = (max(wave_pix[ids][ids1]) - min(wave_pix[ids][ids1])) / (wave_pix[ids][ids1].shape[0] - 1) deltLamda_pix = (max(
_, _, fwhmx, fwhmx_err, center, center_err = fit_SingleGauss(wave_pix[ids][ids1], wave_flux[ids][ids1], 1.0, 6600) wave_pix[ids][ids1]) - min(wave_pix[ids][ids1])) / (wave_pix[ids][ids1].shape[0] - 1)
_, _, fwhmx, fwhmx_err, center, center_err = fit_SingleGauss(
wave_pix[ids][ids1], wave_flux[ids][ids1], 1.0, 6600)
print('Emission line position and shape test') print('Emission line position and shape test')
self.assertTrue(input_em_lam-center < deltLamda_pix) self.assertTrue(input_em_lam-center < deltLamda_pix)
# print(fwhmx/deltLamda_pix*pix_scale - psf_fwhm) # print(fwhmx/deltLamda_pix*pix_scale - psf_fwhm)
self.assertTrue(fwhmx/deltLamda_pix*pix_scale - psf_fwhm < np.abs(0.02)) self.assertTrue(fwhmx/deltLamda_pix*pix_scale -
psf_fwhm < np.abs(0.02))
# print('error is ',np.mean((wave_flux[ids][ids1] - sed_i(wave_pix[ids][ids1]))/sed_i(wave_pix[ids][ids1]))) # print('error is ',np.mean((wave_flux[ids][ids1] - sed_i(wave_pix[ids][ids1]))/sed_i(wave_pix[ids][ids1])))
# self.assertTrue(np.mean((wave_flux[ids][ids1] - sed_i(wave_pix[ids][ids1]))/sed_i(wave_pix[ids][ids1]))<0.004) # self.assertTrue(np.mean((wave_flux[ids][ids1] - sed_i(wave_pix[ids][ids1]))/sed_i(wave_pix[ids][ids1]))<0.004)
# plt.figure() # plt.figure()
...@@ -356,7 +376,6 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -356,7 +376,6 @@ class TestSpecDisperse(unittest.TestCase):
for i in range(sh[1]): for i in range(sh[1]):
spec_pix[i] = sum(Aimg[:, i]) spec_pix[i] = sum(Aimg[:, i])
wave_flux = np.zeros(wave_pix.shape[0]) wave_flux = np.zeros(wave_pix.shape[0])
for i in np.arange(1, wave_pix.shape[0] - 1): for i in np.arange(1, wave_pix.shape[0] - 1):
w = wave_pix[i] w = wave_pix[i]
...@@ -414,14 +433,12 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -414,14 +433,12 @@ class TestSpecDisperse(unittest.TestCase):
plt.legend(['one spec', 'split in 8000 A']) plt.legend(['one spec', 'split in 8000 A'])
plt.show() plt.show()
def test_double_disperse(self): def test_double_disperse(self):
# work_dir = "/public/home/fangyuedong/CSST_unittest/CSST/test/" # work_dir = "/public/home/fangyuedong/CSST_unittest/CSST/test/"
# data_dir = "/Volumes/Extreme SSD/SimData/" # data_dir = "/Volumes/Extreme SSD/SimData/"
# data_dir = "/data/simudata/CSSOSDataProductsSims/data/" # data_dir = "/data/simudata/CSSOSDataProductsSims/data/"
configFn = os.path.join(self.testDir, 'config_C6.yaml') configFn = os.path.join(self.testDir, 'config_C6.yaml')
normFilterFn = os.path.join(self.testDir, 'SLOAN_SDSS.g.fits') normFilterFn = os.path.join(self.testDir, 'SLOAN_SDSS.g.fits')
norm_star = Table.read(normFilterFn) norm_star = Table.read(normFilterFn)
with open(configFn, "r") as stream: with open(configFn, "r") as stream:
try: try:
...@@ -431,9 +448,9 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -431,9 +448,9 @@ class TestSpecDisperse(unittest.TestCase):
except yaml.YAMLError as exc: except yaml.YAMLError as exc:
print(exc) print(exc)
filter_param = FilterParam() filter_param = FilterParam()
focal_plane = FocalPlane(survey_type=config["obs_setting"]["survey_type"]) focal_plane = FocalPlane(
survey_type=config["obs_setting"]["survey_type"])
chip = Chip(1, config=config) chip = Chip(1, config=config)
filter_id, filter_type = chip.getChipFilter() filter_id, filter_type = chip.getChipFilter()
filt = Filter(filter_id=filter_id, filter_type=filter_type, filter_param=filter_param, filt = Filter(filter_id=filter_id, filter_type=filter_type, filter_param=filter_param,
...@@ -442,13 +459,14 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -442,13 +459,14 @@ class TestSpecDisperse(unittest.TestCase):
psf_model = PSFGauss(chip=chip) psf_model = PSFGauss(chip=chip)
wcs_fp = focal_plane.getTanWCS(float(config["obs_setting"]["ra_center"]), float(
wcs_fp = focal_plane.getTanWCS(float(config["obs_setting"]["ra_center"]), float(config["obs_setting"]["dec_center"]), float(config["obs_setting"]["image_rot"]) * galsim.degrees, chip.pix_scale) config["obs_setting"]["dec_center"]), float(config["obs_setting"]["image_rot"]) * galsim.degrees, chip.pix_scale)
chip.img = galsim.ImageF(chip.npix_x, chip.npix_y) chip.img = galsim.ImageF(chip.npix_x, chip.npix_y)
chip.img.setOrigin(chip.bound.xmin, chip.bound.ymin) chip.img.setOrigin(chip.bound.xmin, chip.bound.ymin)
chip.img.wcs = wcs_fp chip.img.wcs = wcs_fp
obj, pos_img = produceObj(2000,4500, chip,float(config["obs_setting"]["ra_center"]), float(config["obs_setting"]["dec_center"]), float(config["obs_setting"]["image_rot"])) obj, pos_img = produceObj(2000, 4500, chip, float(config["obs_setting"]["ra_center"]), float(
config["obs_setting"]["dec_center"]), float(config["obs_setting"]["image_rot"]))
# print(pos_img,chip.pix_scale) # print(pos_img,chip.pix_scale)
obj.drawObj_slitless( obj.drawObj_slitless(
tel=tel, tel=tel,
...@@ -462,7 +480,8 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -462,7 +480,8 @@ class TestSpecDisperse(unittest.TestCase):
exptime=150, exptime=150,
normFilter=norm_star) normFilter=norm_star)
obj, pos_img = produceObj(3685, 6500, chip,float(config["obs_setting"]["ra_center"]), float(config["obs_setting"]["dec_center"]), float(config["obs_setting"]["image_rot"])) obj, pos_img = produceObj(3685, 6500, chip, float(config["obs_setting"]["ra_center"]), float(
config["obs_setting"]["dec_center"]), float(config["obs_setting"]["image_rot"]))
obj.drawObj_slitless( obj.drawObj_slitless(
tel=tel, tel=tel,
pos_img=pos_img, pos_img=pos_img,
...@@ -475,7 +494,8 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -475,7 +494,8 @@ class TestSpecDisperse(unittest.TestCase):
exptime=150, exptime=150,
normFilter=norm_star) normFilter=norm_star)
obj, pos_img = produceObj(5000, 2500, chip, float(config["obs_setting"]["ra_center"]), float(config["obs_setting"]["dec_center"]), float(config["obs_setting"]["image_rot"])) obj, pos_img = produceObj(5000, 2500, chip, float(config["obs_setting"]["ra_center"]), float(
config["obs_setting"]["dec_center"]), float(config["obs_setting"]["image_rot"]))
obj.drawObj_slitless( obj.drawObj_slitless(
tel=tel, tel=tel,
pos_img=pos_img, pos_img=pos_img,
...@@ -490,7 +510,8 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -490,7 +510,8 @@ class TestSpecDisperse(unittest.TestCase):
print('Spec double disperse test') print('Spec double disperse test')
from astropy.io import fits from astropy.io import fits
fits.writeto(os.path.join(self.outDataFn,'test_sls_doubleDisp.fits'),chip.img.array, overwrite = True) fits.writeto(os.path.join(
self.outDataFn, 'test_sls_doubleDisp.fits'), chip.img.array, overwrite=True)
# plt.figure() # plt.figure()
# plt.imshow(chip.img.array) # plt.imshow(chip.img.array)
...@@ -498,7 +519,7 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -498,7 +519,7 @@ class TestSpecDisperse(unittest.TestCase):
def test_SLSImage_rotation(self): def test_SLSImage_rotation(self):
from astropy.wcs import WCS from astropy.wcs import WCS
configFn = os.path.join(self.testDir,'config_C6.yaml') configFn = os.path.join(self.testDir, 'config_C6.yaml')
with open(configFn, "r") as stream: with open(configFn, "r") as stream:
try: try:
...@@ -509,71 +530,71 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -509,71 +530,71 @@ class TestSpecDisperse(unittest.TestCase):
print(exc) print(exc)
chip = Chip(1, config=config) chip = Chip(1, config=config)
ra=float(config["obs_setting"]["ra_center"]) ra = float(config["obs_setting"]["ra_center"])
dec=float(config["obs_setting"]["dec_center"]) dec = float(config["obs_setting"]["dec_center"])
pa=float(config["obs_setting"]["image_rot"]) pa = float(config["obs_setting"]["image_rot"])
chip.rotate_angle = 0 chip.rotate_angle = 0
header_wcs1 = generateExtensionHeader(chip, header_wcs1 = generateExtensionHeader(chip,
xlen=chip.npix_x, xlen=chip.npix_x,
ylen=chip.npix_y, ylen=chip.npix_y,
ra=ra, ra=ra,
dec=dec, dec=dec,
pa=pa, pa=pa,
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,
row_num=chip.rowID, row_num=chip.rowID,
col_num=chip.colID, col_num=chip.colID,
extName='raw') extName='raw')
center = np.array([chip.npix_x / 2, chip.npix_y / 2]) center = np.array([chip.npix_x / 2, chip.npix_y / 2])
h_wcs1 = WCS(header_wcs1) h_wcs1 = WCS(header_wcs1)
x1, y1 = center + [100,0] x1, y1 = center + [100, 0]
sky_1 = h_wcs1.pixel_to_world(x1,y1) sky_1 = h_wcs1.pixel_to_world(x1, y1)
chip = Chip(1, config=config) chip = Chip(1, config=config)
rot_angle = 1 rot_angle = 1
chip.rotate_angle = rot_angle chip.rotate_angle = rot_angle
header_wcs2 = generateExtensionHeader(chip, header_wcs2 = generateExtensionHeader(chip,
xlen=chip.npix_x, xlen=chip.npix_x,
ylen=chip.npix_y, ylen=chip.npix_y,
ra=ra, ra=ra,
dec=dec, dec=dec,
pa=pa, pa=pa,
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,
row_num=chip.rowID, row_num=chip.rowID,
col_num=chip.colID, col_num=chip.colID,
extName='raw') extName='raw')
h_wcs2 = WCS(header_wcs2) h_wcs2 = WCS(header_wcs2)
x2, y2 = h_wcs2.world_to_pixel(sky_1) x2, y2 = h_wcs2.world_to_pixel(sky_1)
angle = getAngle132(x1,y1,0,x2,y2,0,center[0],center[1],0) angle = getAngle132(x1, y1, 0, x2, y2, 0, center[0], center[1], 0)
# print("rotation angle:" ,rot_angle ,chip.rotate_angle, angle) # print("rotation angle:" ,rot_angle ,chip.rotate_angle, angle)
# self.assertTrue(rot_angle - angle < np.abs(0.001)) # self.assertTrue(rot_angle - angle < np.abs(0.001))
rot_angle = 10 rot_angle = 10
chip.rotate_angle = rot_angle chip.rotate_angle = rot_angle
header_wcs2 = generateExtensionHeader(chip, header_wcs2 = generateExtensionHeader(chip,
xlen=chip.npix_x, xlen=chip.npix_x,
ylen=chip.npix_y, ylen=chip.npix_y,
ra=ra, ra=ra,
dec=dec, dec=dec,
pa=pa, pa=pa,
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,
row_num=chip.rowID, row_num=chip.rowID,
col_num=chip.colID, col_num=chip.colID,
extName='raw') extName='raw')
h_wcs2 = WCS(header_wcs2) h_wcs2 = WCS(header_wcs2)
x2, y2 = h_wcs2.world_to_pixel(sky_1) x2, y2 = h_wcs2.world_to_pixel(sky_1)
...@@ -584,19 +605,19 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -584,19 +605,19 @@ class TestSpecDisperse(unittest.TestCase):
rot_angle = 50 rot_angle = 50
chip.rotate_angle = rot_angle chip.rotate_angle = rot_angle
header_wcs2 = generateExtensionHeader(chip, header_wcs2 = generateExtensionHeader(chip,
xlen=chip.npix_x, xlen=chip.npix_x,
ylen=chip.npix_y, ylen=chip.npix_y,
ra=ra, ra=ra,
dec=dec, dec=dec,
pa=pa, pa=pa,
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,
row_num=chip.rowID, row_num=chip.rowID,
col_num=chip.colID, col_num=chip.colID,
extName='raw') extName='raw')
h_wcs2 = WCS(header_wcs2) h_wcs2 = WCS(header_wcs2)
x2, y2 = h_wcs2.world_to_pixel(sky_1) x2, y2 = h_wcs2.world_to_pixel(sky_1)
...@@ -604,7 +625,6 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -604,7 +625,6 @@ class TestSpecDisperse(unittest.TestCase):
# print(rot_angle - angle) # print(rot_angle - angle)
self.assertTrue(rot_angle - angle < np.abs(0.001)) self.assertTrue(rot_angle - angle < np.abs(0.001))
chip = Chip(27, config=config) chip = Chip(27, config=config)
ra = float(config["obs_setting"]["ra_center"]) ra = float(config["obs_setting"]["ra_center"])
...@@ -612,19 +632,19 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -612,19 +632,19 @@ class TestSpecDisperse(unittest.TestCase):
pa = float(config["obs_setting"]["image_rot"]) pa = float(config["obs_setting"]["image_rot"])
chip.rotate_angle = 0 chip.rotate_angle = 0
header_wcs1 = generateExtensionHeader(chip, header_wcs1 = generateExtensionHeader(chip,
xlen=chip.npix_x, xlen=chip.npix_x,
ylen=chip.npix_y, ylen=chip.npix_y,
ra=ra, ra=ra,
dec=dec, dec=dec,
pa=pa, pa=pa,
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,
row_num=chip.rowID, row_num=chip.rowID,
col_num=chip.colID, col_num=chip.colID,
extName='raw') extName='raw')
center = np.array([chip.npix_x / 2, chip.npix_y / 2]) center = np.array([chip.npix_x / 2, chip.npix_y / 2])
h_wcs1 = WCS(header_wcs1) h_wcs1 = WCS(header_wcs1)
...@@ -634,19 +654,19 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -634,19 +654,19 @@ class TestSpecDisperse(unittest.TestCase):
rot_angle = 1 rot_angle = 1
chip.rotate_angle = rot_angle chip.rotate_angle = rot_angle
header_wcs2 = generateExtensionHeader(chip, header_wcs2 = generateExtensionHeader(chip,
xlen=chip.npix_x, xlen=chip.npix_x,
ylen=chip.npix_y, ylen=chip.npix_y,
ra=ra, ra=ra,
dec=dec, dec=dec,
pa=pa, pa=pa,
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,
row_num=chip.rowID, row_num=chip.rowID,
col_num=chip.colID, col_num=chip.colID,
extName='raw') extName='raw')
h_wcs2 = WCS(header_wcs2) h_wcs2 = WCS(header_wcs2)
x2, y2 = h_wcs2.world_to_pixel(sky_1) x2, y2 = h_wcs2.world_to_pixel(sky_1)
...@@ -657,19 +677,19 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -657,19 +677,19 @@ class TestSpecDisperse(unittest.TestCase):
rot_angle = 10 rot_angle = 10
chip.rotate_angle = rot_angle chip.rotate_angle = rot_angle
header_wcs2 = generateExtensionHeader(chip, header_wcs2 = generateExtensionHeader(chip,
xlen=chip.npix_x, xlen=chip.npix_x,
ylen=chip.npix_y, ylen=chip.npix_y,
ra=ra, ra=ra,
dec=dec, dec=dec,
pa=pa, pa=pa,
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,
row_num=chip.rowID, row_num=chip.rowID,
col_num=chip.colID, col_num=chip.colID,
extName='raw') extName='raw')
h_wcs2 = WCS(header_wcs2) h_wcs2 = WCS(header_wcs2)
x2, y2 = h_wcs2.world_to_pixel(sky_1) x2, y2 = h_wcs2.world_to_pixel(sky_1)
...@@ -680,19 +700,19 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -680,19 +700,19 @@ class TestSpecDisperse(unittest.TestCase):
rot_angle = 50 rot_angle = 50
chip.rotate_angle = rot_angle chip.rotate_angle = rot_angle
header_wcs2 = generateExtensionHeader(chip, header_wcs2 = generateExtensionHeader(chip,
xlen=chip.npix_x, xlen=chip.npix_x,
ylen=chip.npix_y, ylen=chip.npix_y,
ra=ra, ra=ra,
dec=dec, dec=dec,
pa=pa, pa=pa,
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,
row_num=chip.rowID, row_num=chip.rowID,
col_num=chip.colID, col_num=chip.colID,
extName='raw') extName='raw')
h_wcs2 = WCS(header_wcs2) h_wcs2 = WCS(header_wcs2)
x2, y2 = h_wcs2.world_to_pixel(sky_1) x2, y2 = h_wcs2.world_to_pixel(sky_1)
...@@ -701,11 +721,9 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -701,11 +721,9 @@ class TestSpecDisperse(unittest.TestCase):
self.assertTrue(rot_angle - angle < np.abs(0.001)) self.assertTrue(rot_angle - angle < np.abs(0.001))
if __name__ == '__main__': if __name__ == '__main__':
os.environ['UNIT_TEST_DATA_ROOT']="/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_develop/csst-simulation/tests/testData" os.environ['UNIT_TEST_DATA_ROOT'] = "/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_develop/csst-simulation/tests/testData"
testDir = os.getenv('UNIT_TEST_DATA_ROOT') testDir = os.getenv('UNIT_TEST_DATA_ROOT')
# conff= os.path.join(testDir, 'CSST_GI2.conf') # conff= os.path.join(testDir, 'CSST_GI2.conf')
# throughputf= os.path.join(testDir, 'GI.Throughput.1st.fits') # throughputf= os.path.join(testDir, 'GI.Throughput.1st.fits')
...@@ -723,4 +741,4 @@ if __name__ == '__main__': ...@@ -723,4 +741,4 @@ if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(suit) unittest.TextTestRunner(verbosity=2).run(suit)
# runner = unittest.TextTestRunner() # runner = unittest.TextTestRunner()
# runner.run(suit) # runner.run(suit)
\ No newline at end of file
# #
#need add environment parameter UNIT_TEST_DATA_ROOT, link to "testData/" # need add environment parameter UNIT_TEST_DATA_ROOT, link to "testData/"
#linx and mac can run as follow, need modify the name of file directory # linx and mac can run as follow, need modify the name of file directory
#export UNIT_TEST_DATA_ROOT=/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_develop/csst-simulation/tests/testData # export UNIT_TEST_DATA_ROOT=/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_develop/csst-simulation/tests/testData
# #
import unittest import unittest
from ObservationSim.Straylight import Straylight from observation_sim.sky_background import Straylight
import numpy as np import numpy as np
import math import math
...@@ -17,8 +17,10 @@ import matplotlib.pyplot as plt ...@@ -17,8 +17,10 @@ import matplotlib.pyplot as plt
import os import os
hubbleAverZodiacal = {'nuv':0.0035,'u':0.0163,'g':0.1109,'r':0.1471,'i':0.1568,'z':0.0953,'y':0.0283} hubbleAverZodiacal = {'nuv': 0.0035, 'u': 0.0163, 'g': 0.1109,
hubbleAverEarthShine = {'nuv':0.00024,'u':0.0051,'g':0.0506,'r':0.0591,'i':0.0568,'z':0.0315,'y':0.0090} 'r': 0.1471, 'i': 0.1568, 'z': 0.0953, 'y': 0.0283}
hubbleAverEarthShine = {'nuv': 0.00024, 'u': 0.0051, 'g': 0.0506,
'r': 0.0591, 'i': 0.0568, 'z': 0.0315, 'y': 0.0090}
# 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);
...@@ -28,63 +30,69 @@ hubbleAverEarthShine = {'nuv':0.00024,'u':0.0051,'g':0.0506,'r':0.0591,'i':0.056 ...@@ -28,63 +30,69 @@ hubbleAverEarthShine = {'nuv':0.00024,'u':0.0051,'g':0.0506,'r':0.0591,'i':0.056
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; cosValue = 0
angle = 0; angle = 0
x11 = x1 - x3; x11 = x1 - x3
y11 = y1 - y3; y11 = y1 - y3
z11 = z1 - z3; z11 = z1 - z3
x22 = x2 - x3; x22 = x2 - x3
y22 = y2 - y3; y22 = y2 - y3
z22 = z2 - z3; z22 = z2 - z3
tt = np.sqrt((x11 * x11 + y11 * y11 + z11 * z11) * (x22 * x22 + y22 * y22 + z22 * z22)); tt = np.sqrt((x11 * x11 + y11 * y11 + z11 * z11)
* (x22 * x22 + y22 * y22 + z22 * z22))
if (tt == 0): if (tt == 0):
return 0; return 0
cosValue = (x11 * x22 + y11 * y22 + z11 * z22) / tt; cosValue = (x11 * x22 + y11 * y22 + z11 * z22) / tt
if (cosValue > 1): if (cosValue > 1):
cosValue = 1; cosValue = 1
if (cosValue < -1): if (cosValue < -1):
cosValue = -1; cosValue = -1
angle = math.acos(cosValue); angle = math.acos(cosValue)
return angle * 360 / (2 * math.pi); 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])):
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
class TestStraylight(unittest.TestCase): class TestStraylight(unittest.TestCase):
def __init__(self,methodName='runTest', filter = 'i', grating = "GI"): def __init__(self, methodName='runTest', filter='i', grating="GI"):
super(TestStraylight,self).__init__(methodName) super(TestStraylight, self).__init__(methodName)
# print(file_name) # print(file_name)
# fn = os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), file_name) # fn = os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), file_name)
# self.pointingData = np.loadtxt(os.path.join(fn, 'Straylight_test.dat'), dtype=np.double) # self.pointingData = np.loadtxt(os.path.join(fn, 'Straylight_test.dat'), dtype=np.double)
self.filePath('csst_msc_sim/test_sls_and_straylight') self.filePath('csst_msc_sim/test_sls_and_straylight')
self.filter = filter self.filter = filter
self.grating = grating self.grating = grating
def filePath(self, file_name): def filePath(self, file_name):
fn = os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), file_name) fn = os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), file_name)
self.pointingData = np.loadtxt(os.path.join(fn, 'Straylight_test.dat'), dtype=np.double) self.pointingData = np.loadtxt(os.path.join(
fn, 'Straylight_test.dat'), dtype=np.double)
def test_EarthShineFilter(self): def test_EarthShineFilter(self):
d_sh = self.pointingData.shape d_sh = self.pointingData.shape
sl_e_pix = np.zeros([d_sh[0],3],dtype=np.double) sl_e_pix = np.zeros([d_sh[0], 3], dtype=np.double)
for i in np.arange(d_sh[0]): for i in np.arange(d_sh[0]):
# if i > 50: # if i > 50:
...@@ -92,17 +100,19 @@ class TestStraylight(unittest.TestCase): ...@@ -92,17 +100,19 @@ class TestStraylight(unittest.TestCase):
ju = self.pointingData[i, 5] ju = self.pointingData[i, 5]
# pointing = transRaDec2D(self.pointingData[i, 0], self.pointingData[i, 1]) # pointing = transRaDec2D(self.pointingData[i, 0], self.pointingData[i, 1])
# print(ju, pointing, surveylist[i,3:9]) # print(ju, pointing, surveylist[i,3:9])
sl = Straylight(jtime=ju, sat_pos=self.pointingData[i, 6:9], pointing_radec=np.array([self.pointingData[i, 0], self.pointingData[i, 1]]),sun_pos=self.pointingData[i,9:12]) sl = Straylight(jtime=ju, sat_pos=self.pointingData[i, 6:9], pointing_radec=np.array(
[self.pointingData[i, 0], self.pointingData[i, 1]]), sun_pos=self.pointingData[i, 9:12])
e1, py = sl.calculateEarthShineFilter(filter=self.filter) e1, py = sl.calculateEarthShineFilter(filter=self.filter)
earthZenithAngle, isInSunSide = calculateAnglePwithEarth(sat=self.pointingData[i, 6:9], pointing= sl.pointing, sun=self.pointingData[i,9:12]) earthZenithAngle, isInSunSide = calculateAnglePwithEarth(
sat=self.pointingData[i, 6:9], pointing=sl.pointing, sun=self.pointingData[i, 9:12])
# e2, _ = sl.calculateZodiacalFilter2(filter='i', sun_pos=sl.sun_pos) # e2, _ = sl.calculateZodiacalFilter2(filter='i', sun_pos=sl.sun_pos)
# e3 = sl.calculateStarLightFilter(filter='i', pointYaxis=py) # e3 = sl.calculateStarLightFilter(filter='i', pointYaxis=py)
# e_all = sl.calculateStrayLightFilter(filter='i') # e_all = sl.calculateStrayLightFilter(filter='i')
# s_pix, spec = sl.calculateStrayLightGrating(grating='GI') # s_pix, spec = sl.calculateStrayLightGrating(grating='GI')
sl_e_pix[i,0] = e1 sl_e_pix[i, 0] = e1
sl_e_pix[i, 1] = earthZenithAngle sl_e_pix[i, 1] = earthZenithAngle
sl_e_pix[i, 2] = isInSunSide sl_e_pix[i, 2] = isInSunSide
median = np.median(sl_e_pix[:,0]) median = np.median(sl_e_pix[:, 0])
print(' average Earthshine %s: %e' % (self.filter, median)) print(' average Earthshine %s: %e' % (self.filter, median))
self.assertTrue(median-hubbleAverEarthShine[self.filter] < 0.1) self.assertTrue(median-hubbleAverEarthShine[self.filter] < 0.1)
plt.figure() plt.figure()
...@@ -117,27 +127,29 @@ class TestStraylight(unittest.TestCase): ...@@ -117,27 +127,29 @@ class TestStraylight(unittest.TestCase):
def test_ZodiacalFilter(self): def test_ZodiacalFilter(self):
d_sh = self.pointingData.shape d_sh = self.pointingData.shape
sl_e_pix = np.zeros([d_sh[0],2],dtype=np.double) sl_e_pix = np.zeros([d_sh[0], 2], dtype=np.double)
for i in np.arange(d_sh[0]): for i in np.arange(d_sh[0]):
ju = self.pointingData[i, 5] ju = self.pointingData[i, 5]
sl = Straylight(jtime=ju, sat_pos=self.pointingData[i, 6:9], pointing_radec=np.array([self.pointingData[i, 0], self.pointingData[i, 1]]),sun_pos=self.pointingData[i,9:12]) sl = Straylight(jtime=ju, sat_pos=self.pointingData[i, 6:9], pointing_radec=np.array(
e1, _ = sl.calculateZodiacalFilter2(filter=self.filter, sun_pos=sl.sun_pos) [self.pointingData[i, 0], self.pointingData[i, 1]]), sun_pos=self.pointingData[i, 9:12])
sl_e_pix[i,0] = e1 e1, _ = sl.calculateZodiacalFilter2(
sl_e_pix[i,1] = getAngle132(x1=self.pointingData[i,9], y1=self.pointingData[i,10], z1=self.pointingData[i,11], x2=sl.pointing[0], filter=self.filter, sun_pos=sl.sun_pos)
y2=sl.pointing[1], z2=sl.pointing[2], x3=0, y3=0, z3=0) sl_e_pix[i, 0] = e1
sl_e_pix[i, 1] = getAngle132(x1=self.pointingData[i, 9], y1=self.pointingData[i, 10], z1=self.pointingData[i, 11], x2=sl.pointing[0],
y2=sl.pointing[1], z2=sl.pointing[2], x3=0, y3=0, z3=0)
plt.figure() plt.figure()
plt.plot(sl_e_pix[:, 0], sl_e_pix[:, 1], 'r.') plt.plot(sl_e_pix[:, 0], sl_e_pix[:, 1], 'r.')
plt.xlabel('straylight-zodiacal(e-/pixel/s)') plt.xlabel('straylight-zodiacal(e-/pixel/s)')
plt.ylabel('Angle between pointing and sun(degree)') plt.ylabel('Angle between pointing and sun(degree)')
plt.show() plt.show()
median = np.median(sl_e_pix[:,0]) median = np.median(sl_e_pix[:, 0])
print(' average Zodiacal %s: %f' % (self.filter, median)) print(' average Zodiacal %s: %f' % (self.filter, median))
self.assertTrue(median-hubbleAverZodiacal[self.filter] < 0.1) self.assertTrue(median-hubbleAverZodiacal[self.filter] < 0.1)
def test_StarFilter(self): def test_StarFilter(self):
d_sh = self.pointingData.shape d_sh = self.pointingData.shape
sl_e_pix = np.zeros(d_sh[0],dtype=np.double) sl_e_pix = np.zeros(d_sh[0], dtype=np.double)
tnum = 10 tnum = 10
for i in np.arange(tnum): for i in np.arange(tnum):
...@@ -146,20 +158,21 @@ class TestStraylight(unittest.TestCase): ...@@ -146,20 +158,21 @@ class TestStraylight(unittest.TestCase):
ju = self.pointingData[i, 5] ju = self.pointingData[i, 5]
# pointing = transRaDec2D(self.pointingData[i, 0], self.pointingData[i, 1]) # pointing = transRaDec2D(self.pointingData[i, 0], self.pointingData[i, 1])
# print(ju, pointing, surveylist[i,3:9]) # print(ju, pointing, surveylist[i,3:9])
sl = Straylight(jtime=ju, sat_pos=self.pointingData[i, 6:9], pointing_radec=np.array([self.pointingData[i, 0], self.pointingData[i, 1]]),sun_pos=self.pointingData[i,9:12]) sl = Straylight(jtime=ju, sat_pos=self.pointingData[i, 6:9], pointing_radec=np.array(
[self.pointingData[i, 0], self.pointingData[i, 1]]), sun_pos=self.pointingData[i, 9:12])
e1, py = sl.calculateEarthShineFilter(filter=self.filter) e1, py = sl.calculateEarthShineFilter(filter=self.filter)
# e2, _ = sl.calculateZodiacalFilter2(filter='i', sun_pos=sl.sun_pos) # e2, _ = sl.calculateZodiacalFilter2(filter='i', sun_pos=sl.sun_pos)
e3 = sl.calculateStarLightFilter(filter=self.filter, pointYaxis=py) e3 = sl.calculateStarLightFilter(filter=self.filter, pointYaxis=py)
# e_all = sl.calculateStrayLightFilter(filter='i') # e_all = sl.calculateStrayLightFilter(filter='i')
# s_pix, spec = sl.calculateStrayLightGrating(grating='GI') # s_pix, spec = sl.calculateStrayLightGrating(grating='GI')
sl_e_pix[i] = e3 sl_e_pix[i] = e3
median = np.median(sl_e_pix[0:tnum]) median = np.median(sl_e_pix[0:tnum])
print(' average Earthshine %s: %e' % (self.filter, median)) print(' average Earthshine %s: %e' % (self.filter, median))
self.assertTrue(median-hubbleAverEarthShine[self.filter] < 0.2) self.assertTrue(median-hubbleAverEarthShine[self.filter] < 0.2)
def test_GratingStraylight(self): def test_GratingStraylight(self):
d_sh = self.pointingData.shape d_sh = self.pointingData.shape
sl_e_pix = np.zeros(d_sh[0],dtype=np.double) sl_e_pix = np.zeros(d_sh[0], dtype=np.double)
tnum = 10 tnum = 10
for i in np.arange(tnum): for i in np.arange(tnum):
...@@ -168,7 +181,8 @@ class TestStraylight(unittest.TestCase): ...@@ -168,7 +181,8 @@ class TestStraylight(unittest.TestCase):
ju = self.pointingData[i, 5] ju = self.pointingData[i, 5]
# pointing = transRaDec2D(self.pointingData[i, 0], self.pointingData[i, 1]) # pointing = transRaDec2D(self.pointingData[i, 0], self.pointingData[i, 1])
# print(ju, pointing, surveylist[i,3:9]) # print(ju, pointing, surveylist[i,3:9])
sl = Straylight(jtime=ju, sat_pos=self.pointingData[i, 6:9], pointing_radec=np.array([self.pointingData[i, 0], self.pointingData[i, 1]]),sun_pos=self.pointingData[i,9:12]) sl = Straylight(jtime=ju, sat_pos=self.pointingData[i, 6:9], pointing_radec=np.array(
[self.pointingData[i, 0], self.pointingData[i, 1]]), sun_pos=self.pointingData[i, 9:12])
# e1, py = sl.calculateEarthShineFilter(filter=self.filter) # e1, py = sl.calculateEarthShineFilter(filter=self.filter)
# e2, _ = sl.calculateZodiacalFilter2(filter='i', sun_pos=sl.sun_pos) # e2, _ = sl.calculateZodiacalFilter2(filter='i', sun_pos=sl.sun_pos)
# e3 = sl.calculateStarLightFilter(filter=self.filter, pointYaxis=py) # e3 = sl.calculateStarLightFilter(filter=self.filter, pointYaxis=py)
...@@ -179,18 +193,15 @@ class TestStraylight(unittest.TestCase): ...@@ -179,18 +193,15 @@ class TestStraylight(unittest.TestCase):
plt.plot(spec['WAVELENGTH'], spec['FLUX'], 'r') plt.plot(spec['WAVELENGTH'], spec['FLUX'], 'r')
plt.xlabel('WAVELENGTH') plt.xlabel('WAVELENGTH')
plt.ylabel('F$\lambda$(erg/s/cm2/A/arcsec2)') plt.ylabel('F$\lambda$(erg/s/cm2/A/arcsec2)')
plt.xlim(2000,10000) plt.xlim(2000, 10000)
plt.show() plt.show()
median = np.median(sl_e_pix[0:tnum]) median = np.median(sl_e_pix[0:tnum])
print(' average Earthshine %s: %e' % (self.grating, median)) print(' average Earthshine %s: %e' % (self.grating, median))
self.assertTrue(median < 0.8) self.assertTrue(median < 0.8)
if __name__ == '__main__': if __name__ == '__main__':
os.environ['UNIT_TEST_DATA_ROOT']="/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_develop/csst-simulation/tests/testData" os.environ['UNIT_TEST_DATA_ROOT'] = "/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_develop/csst-simulation/tests/testData"
# suit = unittest.TestSuite() # suit = unittest.TestSuite()
# case1 = TestStraylight('test_EarthShineFilter', filter = 'i') # case1 = TestStraylight('test_EarthShineFilter', filter = 'i')
...@@ -201,4 +212,4 @@ if __name__ == '__main__': ...@@ -201,4 +212,4 @@ if __name__ == '__main__':
# suit.addTest(case3) # suit.addTest(case3)
# case4 = TestStraylight('test_GratingStraylight', grating = 'GI') # case4 = TestStraylight('test_GratingStraylight', grating = 'GI')
# suit.addTest(case4) # suit.addTest(case4)
# unittest.TextTestRunner(verbosity=2).run(suit) # unittest.TextTestRunner(verbosity=2).run(suit)
\ No newline at end of file
import unittest
import os
import sys
from astropy.time import Time
from datetime import datetime
from observation_sim.astrometry.Astrometry_util import on_orbit_obs_position
class TestAstrometry(unittest.TestCase):
def __init__(self, methodName='runTest'):
super(TestAstrometry, self).__init__(methodName)
# self.dataPath = os.path.join(
# os.getenv('UNIT_TEST_DATA_ROOT'), 'csst_msc_sim/csst_fz_msc')
def test_astrometry_method(self):
ra_list = [300.061827]
dec_list = [-60.132741]
pmra_list = [0.]
pmdec_list = [0.]
rv_list = [0.]
parallax_list = [1e-9]
sat_x = 5227.7501
sat_y = -1521.2218
sat_z = -4007.7662
sat_vx = 0.13581745522969868
sat_vy = 7.233066646238058
sat_vz = -2.5770060087052116
dt = datetime.utcfromtimestamp(
Time(2461865.75468577, format='jd').unix)
date_str = dt.date().isoformat()
time_str = dt.time().isoformat()
ra_arr, dec_arr = on_orbit_obs_position(
input_ra_list=ra_list,
input_dec_list=dec_list,
input_pmra_list=pmra_list,
input_pmdec_list=pmdec_list,
input_rv_list=rv_list,
input_parallax_list=parallax_list,
input_nstars=len(ra_list),
input_x=sat_x,
input_y=sat_y,
input_z=sat_z,
input_vx=sat_vx,
input_vy=sat_vy,
input_vz=sat_vz,
input_epoch="J2000",
input_date_str=date_str,
input_time_str=time_str
)
print(ra_arr[0], dec_arr[0])
self.assertTrue(ra_arr[0] != ra_list[0])
self.assertTrue(dec_arr[0] != dec_list[0])
if __name__ == '__main__':
unittest.main()
import unittest import unittest
import sys,os,math import sys
import os
import math
from itertools import islice from itertools import islice
import numpy as np import numpy as np
import galsim import galsim
import yaml import yaml
from ObservationSim.Instrument import Chip, Filter, FilterParam, FocalPlane from observation_sim.instruments import Chip, Filter, FilterParam, FocalPlane
#from ObservationSim.Instrument.Chip import ChipUtils as chip_utils
### test FUNCTION --- START ### ### test FUNCTION --- START ###
def get_base_img(img, chip, read_noise, readout_time, dark_noise, exptime=150., InputDark=None): def get_base_img(img, chip, read_noise, readout_time, dark_noise, exptime=150., InputDark=None):
if InputDark == None: if InputDark == None:
# base_level = read_noise**2 + dark_noise*(exptime+0.5*readout_time) # base_level = read_noise**2 + dark_noise*(exptime+0.5*readout_time)
## base_level = dark_noise*(exptime+0.5*readout_time) # base_level = dark_noise*(exptime+0.5*readout_time)
base_level = dark_noise*(exptime) base_level = dark_noise*(exptime)
base_img1 = base_level * np.ones_like(img.array) base_img1 = base_level * np.ones_like(img.array)
else: else:
...@@ -25,8 +28,8 @@ def get_base_img(img, chip, read_noise, readout_time, dark_noise, exptime=150., ...@@ -25,8 +28,8 @@ def get_base_img(img, chip, read_noise, readout_time, dark_noise, exptime=150.,
arr = np.broadcast_to(arr, (ny, nx)) arr = np.broadcast_to(arr, (ny, nx))
base_img2 = np.zeros_like(img.array) base_img2 = np.zeros_like(img.array)
base_img2[:ny, :] = arr base_img2[:ny, :] = arr
base_img2[ny:, :] = arr[::-1,:] base_img2[ny:, :] = arr[::-1, :]
base_img2[:,:] = base_img2[:,:]*(readout_time/ny)*dark_noise base_img2[:, :] = base_img2[:, :]*(readout_time/ny)*dark_noise
return base_img1+base_img2 return base_img1+base_img2
### test FUNCTION --- END ### ### test FUNCTION --- END ###
...@@ -35,16 +38,18 @@ def defineCCD(iccd, config_file): ...@@ -35,16 +38,18 @@ def defineCCD(iccd, config_file):
with open(config_file, "r") as stream: with open(config_file, "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=iccd, config=config) chip = Chip(chipID=iccd, config=config)
chip.img = galsim.ImageF(chip.npix_x, chip.npix_y) chip.img = galsim.ImageF(chip.npix_x, chip.npix_y)
focal_plane = FocalPlane(chip_list=[iccd]) focal_plane = FocalPlane(chip_list=[iccd])
chip.img.wcs= focal_plane.getTanWCS(192.8595, 27.1283, -113.4333*galsim.degrees, chip.pix_scale) chip.img.wcs = focal_plane.getTanWCS(
192.8595, 27.1283, -113.4333*galsim.degrees, chip.pix_scale)
return chip return chip
def defineFilt(chip): def defineFilt(chip):
filter_param = FilterParam() filter_param = FilterParam()
filter_id, filter_type = chip.getChipFilter() filter_id, filter_type = chip.getChipFilter()
...@@ -60,7 +65,8 @@ def defineFilt(chip): ...@@ -60,7 +65,8 @@ def defineFilt(chip):
class detModule_coverage(unittest.TestCase): class detModule_coverage(unittest.TestCase):
def __init__(self, methodName='runTest'): def __init__(self, methodName='runTest'):
super(detModule_coverage, self).__init__(methodName) super(detModule_coverage, self).__init__(methodName)
self.dataPath = os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), 'csst_msc_sim/csst_fz_msc') self.dataPath = os.path.join(
os.getenv('UNIT_TEST_DATA_ROOT'), 'csst_msc_sim/csst_fz_msc')
self.iccd = 1 self.iccd = 1
def test_add_dark(self): def test_add_dark(self):
...@@ -70,16 +76,19 @@ class detModule_coverage(unittest.TestCase): ...@@ -70,16 +76,19 @@ class detModule_coverage(unittest.TestCase):
print(chip.chipID) print(chip.chipID)
print(chip.cen_pix_x, chip.cen_pix_y) print(chip.cen_pix_x, chip.cen_pix_y)
exptime=150. exptime = 150.
base_img = get_base_img(img=chip.img, chip=chip, read_noise=chip.read_noise, readout_time=chip.readout_time, dark_noise=chip.dark_noise, exptime=exptime, InputDark=None) base_img = get_base_img(img=chip.img, chip=chip, read_noise=chip.read_noise,
readout_time=chip.readout_time, dark_noise=chip.dark_noise, exptime=exptime, InputDark=None)
ny = int(chip.npix_y/2) ny = int(chip.npix_y/2)
self.assertTrue( np.abs(np.max(base_img) - (exptime*chip.dark_noise+(ny-1)*(chip.readout_time/ny)*chip.dark_noise )) < 1e-6 ) self.assertTrue(np.abs(np.max(base_img) - (exptime*chip.dark_noise +
self.assertTrue( np.min(base_img) == 3 ) (ny-1)*(chip.readout_time/ny)*chip.dark_noise)) < 1e-6)
self.assertTrue(np.min(base_img) == 3)
base_img = get_base_img(img=chip.img, chip=chip, read_noise=chip.read_noise, readout_time=chip.readout_time, dark_noise=chip.dark_noise, exptime=150., InputDark="testTag") base_img = get_base_img(img=chip.img, chip=chip, read_noise=chip.read_noise,
self.assertTrue( np.abs(np.max(base_img) - ((ny-1)*(chip.readout_time/ny)*chip.dark_noise )) < 1e-6 ) readout_time=chip.readout_time, dark_noise=chip.dark_noise, exptime=150., InputDark="testTag")
self.assertTrue(np.abs(np.max(base_img) - ((ny-1) *
(chip.readout_time/ny)*chip.dark_noise)) < 1e-6)
if __name__ == '__main__': if __name__ == '__main__':
......
import unittest import unittest
import numpy as np import numpy as np
from ObservationSim.Instrument.Chip import Effects from observation_sim.instruments.chip import effects
import galsim import galsim
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import os,sys,math,copy import os
import sys
import math
import copy
from numpy.random import Generator, PCG64 from numpy.random import Generator, PCG64
import warnings import warnings
from astropy.io import fits from astropy.io import fits
...@@ -13,20 +16,20 @@ warnings.filterwarnings("ignore", '.*Numba.*',) ...@@ -13,20 +16,20 @@ warnings.filterwarnings("ignore", '.*Numba.*',)
width = 9216 width = 9216
height = 9232 height = 9232
class DetTest(unittest.TestCase): class DetTest(unittest.TestCase):
def __init__(self, methodName='runTest'): def __init__(self, methodName='runTest'):
super(DetTest,self).__init__(methodName) super(DetTest, self).__init__(methodName)
self.filePath('csst_msc_sim/test_sls_and_straylight') self.filePath('csst_msc_sim/test_sls_and_straylight')
def filePath(self, file_name): def filePath(self, file_name):
self.datafn = os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), file_name) self.datafn = os.path.join(os.getenv('UNIT_TEST_DATA_ROOT'), file_name)
self.outDataFn = os.path.join(self.datafn,'output') self.outDataFn = os.path.join(self.datafn, 'output')
if os.path.isdir(self.outDataFn): if os.path.isdir(self.outDataFn):
pass pass
else: else:
os.mkdir(self.outDataFn) os.mkdir(self.outDataFn)
def test_prnu(self): def test_prnu(self):
''' '''
...@@ -35,13 +38,14 @@ class DetTest(unittest.TestCase): ...@@ -35,13 +38,14 @@ class DetTest(unittest.TestCase):
print('PRNU Test:') print('PRNU Test:')
sigma = 0.01 sigma = 0.01
seed = 20210911 seed = 20210911
prnuimg = Effects.PRNU_Img(width, height, sigma=sigma, seed=seed) prnuimg = effects.PRNU_Img(width, height, sigma=sigma, seed=seed)
meanval, stdval = np.mean(prnuimg.array), np.std(prnuimg.array) meanval, stdval = np.mean(prnuimg.array), np.std(prnuimg.array)
print(' Mean & STDDEV of PRNU image are %6.4f & %6.4f.' % (meanval, stdval)) print(' Mean & STDDEV of PRNU image are %6.4f & %6.4f.' %
(meanval, stdval))
print(' PRNU Image Array:') print(' PRNU Image Array:')
print(' ',prnuimg.array) print(' ', prnuimg.array)
self.assertTrue(np.abs(meanval-1)<1e-6) self.assertTrue(np.abs(meanval-1) < 1e-6)
self.assertTrue(np.abs(stdval-sigma)<0.002) self.assertTrue(np.abs(stdval-sigma) < 0.002)
print('\nUnit test for PRNU has been passed.') print('\nUnit test for PRNU has been passed.')
del prnuimg del prnuimg
...@@ -50,15 +54,17 @@ class DetTest(unittest.TestCase): ...@@ -50,15 +54,17 @@ class DetTest(unittest.TestCase):
Test add dark current to image. Expected result: an image with dark current 3.4 e- and noise=1.844 e-. Test add dark current to image. Expected result: an image with dark current 3.4 e- and noise=1.844 e-.
''' '''
rng_poisson = galsim.BaseDeviate(20210911) rng_poisson = galsim.BaseDeviate(20210911)
dark_noise = galsim.DeviateNoise(galsim.PoissonDeviate(rng_poisson, 0.02*(150+0.5*40))) dark_noise = galsim.DeviateNoise(
img = galsim.Image(200,200,dtype=np.float32, init_value=0) galsim.PoissonDeviate(rng_poisson, 0.02*(150+0.5*40)))
print('Initial Mean & STD = %6.3f & %6.3f' % (np.mean(img.array), np.std(img.array))) img = galsim.Image(200, 200, dtype=np.float32, init_value=0)
print('Initial Mean & STD = %6.3f & %6.3f' %
(np.mean(img.array), np.std(img.array)))
img.addNoise(dark_noise) img.addNoise(dark_noise)
meanval = np.mean(img.array) meanval = np.mean(img.array)
stdval = np.std(img.array) stdval = np.std(img.array)
print('Dark added Mean & STD = %6.3f & %6.3f' % (meanval, stdval)) print('Dark added Mean & STD = %6.3f & %6.3f' % (meanval, stdval))
self.assertTrue(np.abs(meanval-3.4)<0.05) self.assertTrue(np.abs(meanval-3.4) < 0.05)
self.assertTrue(np.abs(stdval-1.844)<0.02) self.assertTrue(np.abs(stdval-1.844) < 0.02)
print('\nUnit test for dark current has been passed.') print('\nUnit test for dark current has been passed.')
del img del img
...@@ -66,149 +72,161 @@ class DetTest(unittest.TestCase): ...@@ -66,149 +72,161 @@ class DetTest(unittest.TestCase):
''' '''
Test saturation and bleeding. Expected result: an image with bleeding effect. Test saturation and bleeding. Expected result: an image with bleeding effect.
''' '''
img = galsim.Image(500,500,dtype=np.float32) img = galsim.Image(500, 500, dtype=np.float32)
star = galsim.Gaussian(flux=60e5,fwhm=3) star = galsim.Gaussian(flux=60e5, fwhm=3)
img = star.drawImage(image=img,center=(150,200)) img = star.drawImage(image=img, center=(150, 200))
# gal = galsim.Sersic(n=1, half_light_radius=3,flux=50e5) # gal = galsim.Sersic(n=1, half_light_radius=3,flux=50e5)
# img = gal.drawImage(image=img,center=(350,300)) # img = gal.drawImage(image=img,center=(350,300))
img.addNoise(galsim.GaussianNoise(sigma=7)) img.addNoise(galsim.GaussianNoise(sigma=7))
# plt.imshow(img.array) # plt.imshow(img.array)
# plt.show() # plt.show()
filename1 = os.path.join(self.outDataFn,'test_satu_initimg.fits') filename1 = os.path.join(self.outDataFn, 'test_satu_initimg.fits')
img.write(filename1) img.write(filename1)
newimg = Effects.SaturBloom(img, fullwell=9e4) newimg = effects.SaturBloom(img, fullwell=9e4)
# plt.imshow(newimg.array) # plt.imshow(newimg.array)
# plt.show() # plt.show()
filename2 = os.path.join(self.outDataFn,'test_satu_bleedimg.fits') filename2 = os.path.join(self.outDataFn, 'test_satu_bleedimg.fits')
newimg.write(filename2) newimg.write(filename2)
del img,newimg, star del img, newimg, star
def test_nonlinear(self): def test_nonlinear(self):
''' '''
Test non-linear effect. Expected result: an image with non-linearity effect. Test non-linear effect. Expected result: an image with non-linearity effect.
''' '''
imgarr = np.arange(1,9e4,4).reshape((150,150)) imgarr = np.arange(1, 9e4, 4).reshape((150, 150))
img = galsim.Image(copy.deepcopy(imgarr)) img = galsim.Image(copy.deepcopy(imgarr))
filename1 = os.path.join(self.outDataFn,'test_nonlinear_initimg.fits') filename1 = os.path.join(self.outDataFn, 'test_nonlinear_initimg.fits')
img.write(filename1) img.write(filename1)
newimg = Effects.NonLinearity(img, beta1=5E-7, beta2=0) newimg = effects.NonLinearity(img, beta1=5E-7, beta2=0)
filename2 = os.path.join(self.outDataFn,'test_nonlinear_finalimg.fits') filename2 = os.path.join(
self.outDataFn, 'test_nonlinear_finalimg.fits')
newimg.write(filename2) newimg.write(filename2)
plt.scatter(imgarr.flatten(), newimg.array.flatten(), s=2, alpha=0.5) plt.scatter(imgarr.flatten(), newimg.array.flatten(), s=2, alpha=0.5)
plt.plot([-1e3,9e4],[-1e3,9e4],color='black', lw=1, ls='--') plt.plot([-1e3, 9e4], [-1e3, 9e4], color='black', lw=1, ls='--')
plt.xlabel('input (e-)') plt.xlabel('input (e-)')
plt.ylabel('output (e-)') plt.ylabel('output (e-)')
plt.savefig(os.path.join(self.outDataFn,'test_nonlinearity.png'), dpi=200) plt.savefig(os.path.join(self.outDataFn,
'test_nonlinearity.png'), dpi=200)
plt.show() plt.show()
del img,newimg,imgarr del img, newimg, imgarr
def test_badpixel_HtrDtr(self): def test_badpixel_HtrDtr(self):
img = galsim.Image(500,500,init_value=1000) img = galsim.Image(500, 500, init_value=1000)
rgbadpix = Generator(PCG64(20210911)) rgbadpix = Generator(PCG64(20210911))
badfraction = 5E-5*(rgbadpix.random()*0.5+0.7) badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
img = Effects.DefectivePixels(img, IfHotPix=True, IfDeadPix=True, fraction=badfraction, seed=20210911, biaslevel=0) img = effects.DefectivePixels(
img.write(os.path.join(self.outDataFn,'test_badpixel_HtrDtr.fits')) img, IfHotPix=True, IfDeadPix=True, fraction=badfraction, seed=20210911, biaslevel=0)
img.write(os.path.join(self.outDataFn, 'test_badpixel_HtrDtr.fits'))
del img del img
def test_badpixel_HfsDtr(self): def test_badpixel_HfsDtr(self):
img = galsim.Image(500,500,init_value=1000) img = galsim.Image(500, 500, init_value=1000)
rgbadpix = Generator(PCG64(20210911)) rgbadpix = Generator(PCG64(20210911))
badfraction = 5E-5*(rgbadpix.random()*0.5+0.7) badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
img = Effects.DefectivePixels(img, IfHotPix=False, IfDeadPix=True, fraction=badfraction, seed=20210911, biaslevel=0) img = effects.DefectivePixels(
img.write(os.path.join(self.outDataFn,'test_badpixel_HfsDtr.fits')) img, IfHotPix=False, IfDeadPix=True, fraction=badfraction, seed=20210911, biaslevel=0)
img.write(os.path.join(self.outDataFn, 'test_badpixel_HfsDtr.fits'))
del img del img
def test_badpixel_HtrDfs(self): def test_badpixel_HtrDfs(self):
img = galsim.Image(500,500,init_value=1000) img = galsim.Image(500, 500, init_value=1000)
rgbadpix = Generator(PCG64(20210911)) rgbadpix = Generator(PCG64(20210911))
badfraction = 5E-5*(rgbadpix.random()*0.5+0.7) badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
img = Effects.DefectivePixels(img, IfHotPix=True, IfDeadPix=False, fraction=badfraction, seed=20210911, biaslevel=0) img = effects.DefectivePixels(
img.write(os.path.join(self.outDataFn,'test_badpixel_HtrDfs.fits')) img, IfHotPix=True, IfDeadPix=False, fraction=badfraction, seed=20210911, biaslevel=0)
img.write(os.path.join(self.outDataFn, 'test_badpixel_HtrDfs.fits'))
del img del img
def test_badpixel_HfsDfs(self): def test_badpixel_HfsDfs(self):
img = galsim.Image(500,500,init_value=1000) img = galsim.Image(500, 500, init_value=1000)
rgbadpix = Generator(PCG64(20210911)) rgbadpix = Generator(PCG64(20210911))
badfraction = 5E-5*(rgbadpix.random()*0.5+0.7) badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
img = Effects.DefectivePixels(img, IfHotPix=False, IfDeadPix=False, fraction=badfraction, seed=20210911, biaslevel=0) img = effects.DefectivePixels(
img.write(os.path.join(self.outDataFn,'test_badpixel_HfsDfs.fits')) img, IfHotPix=False, IfDeadPix=False, fraction=badfraction, seed=20210911, biaslevel=0)
img.write(os.path.join(self.outDataFn, 'test_badpixel_HfsDfs.fits'))
del img del img
def test_badlines(self): def test_badlines(self):
img = galsim.Image(500,500,init_value=-1000) img = galsim.Image(500, 500, init_value=-1000)
img.addNoise(galsim.GaussianNoise(sigma=7)) img.addNoise(galsim.GaussianNoise(sigma=7))
newimg = Effects.BadColumns(copy.deepcopy(img), seed=20210911) newimg = effects.BadColumns(copy.deepcopy(img), seed=20210911)
newimg.write(os.path.join(self.outDataFn,'test_badlines.fits')) newimg.write(os.path.join(self.outDataFn, 'test_badlines.fits'))
del newimg,img del newimg, img
# def test_cte(self): # def test_cte(self):
# img = galsim.Image(200,200,init_value=1000) # img = galsim.Image(200,200,init_value=1000)
# img.array[50,80] = 1e4 # img.array[50,80] = 1e4
# img.array[150,150] = 3e4 # img.array[150,150] = 3e4
# newimgcol = Effects.CTE_Effect(copy.deepcopy(img),direction='column') # newimgcol = effects.CTE_Effect(copy.deepcopy(img),direction='column')
# newimgrow = Effects.CTE_Effect(copy.deepcopy(img),direction='row') # newimgrow = effects.CTE_Effect(copy.deepcopy(img),direction='row')
# newimgcol.write(os.path.join(self.outDataFn,'test_ctecol.fits')) # newimgcol.write(os.path.join(self.outDataFn,'test_ctecol.fits'))
# newimgrow.write(os.path.join(self.outDataFn,'test_cterow.fits')) # newimgrow.write(os.path.join(self.outDataFn,'test_cterow.fits'))
# del img,newimgcol,newimgrow # del img,newimgcol,newimgrow
def test_readnoise(self): def test_readnoise(self):
img = galsim.Image(200,200,init_value=1000) img = galsim.Image(200, 200, init_value=1000)
seed = 20210911 seed = 20210911
rng_readout = galsim.BaseDeviate(seed) rng_readout = galsim.BaseDeviate(seed)
readout_noise = galsim.GaussianNoise(rng=rng_readout, sigma=5) readout_noise = galsim.GaussianNoise(rng=rng_readout, sigma=5)
img.addNoise(readout_noise) img.addNoise(readout_noise)
img.write(os.path.join(self.outDataFn,'test_readnoise.fits')) img.write(os.path.join(self.outDataFn, 'test_readnoise.fits'))
stdval = np.std(img.array) stdval = np.std(img.array)
self.assertTrue(np.abs(stdval-5)<0.01*5) self.assertTrue(np.abs(stdval-5) < 0.01*5)
print('\nUnit test for readout noise has been passed.') print('\nUnit test for readout noise has been passed.')
del img del img
def test_addbias(self): def test_addbias(self):
img = galsim.Image(200,200,init_value=0) img = galsim.Image(200, 200, init_value=0)
img = Effects.AddBiasNonUniform16(img,bias_level=500, nsecy = 2, nsecx=8,seed=20210911) img = effects.AddBiasNonUniform16(
img, bias_level=500, nsecy=2, nsecx=8, seed=20210911)
img.write('./output/test_addbias.fits') img.write('./output/test_addbias.fits')
del img del img
def test_apply16gains(self): def test_apply16gains(self):
img = galsim.Image(500,500,init_value=100) img = galsim.Image(500, 500, init_value=100)
img,_ = Effects.ApplyGainNonUniform16(img, gain=1.5, nsecy=2, nsecx=8, seed=202102) img, _ = effects.ApplyGainNonUniform16(
img.write(os.path.join(self.outDataFn,'test_apply16gains.fits')) img, gain=1.5, nsecy=2, nsecx=8, seed=202102)
img.write(os.path.join(self.outDataFn, 'test_apply16gains.fits'))
rightedge = int(500/8)*8 rightedge = int(500/8)*8
print('gain=%6.2f' % 1.5) print('gain=%6.2f' % 1.5)
meanimg = np.mean(img.array[:,:rightedge]) meanimg = np.mean(img.array[:, :rightedge])
sigmaimg = np.std(img.array[:,:rightedge]) sigmaimg = np.std(img.array[:, :rightedge])
print('mean, sigma = %6.2f, %6.2f' % (meanimg,sigmaimg)) print('mean, sigma = %6.2f, %6.2f' % (meanimg, sigmaimg))
self.assertTrue(np.abs(meanimg-100/1.5)<1) self.assertTrue(np.abs(meanimg-100/1.5) < 1)
self.assertTrue(np.abs(sigmaimg/meanimg-0.01)<0.001) self.assertTrue(np.abs(sigmaimg/meanimg-0.01) < 0.001)
print('\nUnit test for applying 16 channel gains has been passed.') print('\nUnit test for applying 16 channel gains has been passed.')
del img del img
def test_cosmicray(self): def test_cosmicray(self):
attachedSizes = np.loadtxt(os.path.join(self.datafn,'wfc-cr-attachpixel.dat')) attachedSizes = np.loadtxt(os.path.join(
cr_map,_ = Effects.produceCR_Map( self.datafn, 'wfc-cr-attachpixel.dat'))
xLen=500, yLen=500, exTime=150+0.5*40, cr_map, _ = effects.produceCR_Map(
cr_pixelRatio=0.003*(1+0.5*40/150), xLen=500, yLen=500, exTime=150+0.5*40,
gain=1, attachedSizes=attachedSizes, seed=20210911) cr_pixelRatio=0.003*(1+0.5*40/150),
gain=1, attachedSizes=attachedSizes, seed=20210911)
crimg = galsim.Image(cr_map) crimg = galsim.Image(cr_map)
crimg.write(os.path.join(self.outDataFn,'test_cosmicray.fits')) crimg.write(os.path.join(self.outDataFn, 'test_cosmicray.fits'))
del cr_map,crimg del cr_map, crimg
def test_shutter(self): def test_shutter(self):
img = galsim.Image(5000,5000,init_value=1000) img = galsim.Image(5000, 5000, init_value=1000)
shuttimg = Effects.ShutterEffectArr(img, t_exp=150, t_shutter=1.3, dist_bearing=735, dt=1E-3) # shutter effect normalized image for this chip # shutter effect normalized image for this chip
shuttimg = effects.ShutterEffectArr(
img, t_exp=150, t_shutter=1.3, dist_bearing=735, dt=1E-3)
img *= shuttimg img *= shuttimg
img.write(os.path.join(self.outDataFn,'test_shutter.fits')) img.write(os.path.join(self.outDataFn, 'test_shutter.fits'))
del img del img
def test_vignette(self): def test_vignette(self):
img = galsim.Image(2000,2000,init_value=1000) img = galsim.Image(2000, 2000, init_value=1000)
print(img.bounds) print(img.bounds)
# # img.bounds = galsim.BoundsI(1, width, 1, height) # # img.bounds = galsim.BoundsI(1, width, 1, height)
img.setOrigin(10000,10000) img.setOrigin(10000, 10000)
flat_img = Effects.MakeFlatSmooth(img.bounds,20210911) flat_img = effects.MakeFlatSmooth(img.bounds, 20210911)
flat_normal = flat_img / np.mean(flat_img.array) flat_normal = flat_img / np.mean(flat_img.array)
flat_normal.write(os.path.join(self.outDataFn,'test_vignette.fits')) flat_normal.write(os.path.join(self.outDataFn, 'test_vignette.fits'))
del flat_img,img,flat_normal del flat_img, img, flat_normal
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
\ No newline at end of file
import unittest
import numpy as np
import galsim
import os
import sys
from astropy.table import Table
from scipy import interpolate
import pickle
class test_field_distortion(unittest.TestCase):
def __init__(self, methodName="runTest"):
super(test_field_distortion, self).__init__(methodName)
self.dataMainPath = os.path.join(
os.getenv("UNIT_TEST_DATA_ROOT"), "csst_msc_sim/field_distortion"
)
self.dataInputPath = os.path.join(self.dataMainPath, "input_catalog")
self.fdModelName = "FieldDistModel_v2.0_test.pickle"
def test_fd_model(self):
cat_dir = self.dataInputPath
model_dir = self.dataMainPath
model_date = "2024-05-08"
model_name = self.fdModelName
field_distortion_model(
cat_dir,
model_dir,
poly_degree=4,
model_date=model_date,
model_name=model_name,
)
def test_fd_apply(self):
model_name = self.fdModelName
model_dir = self.dataMainPath
cat_dir = self.dataMainPath
field_distortion_apply(
model_name, model_dir, cat_dir, ra_cen=60.0, dec_cen=-40.0, img_rot=0.0
)
def ccdParam():
"""
Basic CCD size and noise parameters.
"""
# CCD size
xt, yt = 59516, 49752
x0, y0 = 9216, 9232
xgap, ygap = (534, 1309), 898
xnchip, ynchip = 6, 5
ccdSize = xt, yt, x0, y0, xgap, ygap, xnchip, ynchip
# other parameters
readNoise = 5.0 # e/pix
darkNoise = 0.02 # e/pix/s
pixel_scale = 0.074 # pixel scale
gain = 1.0
ccdBase = readNoise, darkNoise, pixel_scale, gain
return ccdSize, ccdBase
def chipLim(chip):
ccdSize, ccdBase = ccdParam()
xt, yt, x0, y0, gx, gy, xnchip, ynchip = ccdSize
gx1, gx2 = gx
rowID = ((chip - 1) % 5) + 1
colID = 6 - ((chip - 1) // 5)
xrem = 2 * (colID - 1) - (xnchip - 1)
xcen = (x0 // 2 + gx1 // 2) * xrem
if chip <= 5 or chip == 10:
xcen = (x0 // 2 + gx1 // 2) * xrem + (gx2 - gx1)
if chip >= 26 or chip == 21:
xcen = (x0 // 2 + gx1 // 2) * xrem - (gx2 - gx1)
nx0 = xcen - x0 // 2 + 1
nx1 = xcen + x0 // 2
yrem = (rowID - 1) - ynchip // 2
ycen = (y0 + gy) * yrem
ny0 = ycen - y0 // 2 + 1
ny1 = ycen + y0 // 2
return nx0, nx1, ny0, ny1
def chip_filter(nchip):
"""
return filter name of a given chip
"""
filtype = ["nuv", "u", "g", "r", "i", "z", "y"]
# updated configurations
# if nchip>24 or nchip<7: raise ValueError("!!! Chip ID: [7,24]")
if nchip in [6, 15, 16, 25]:
filter_name = "y"
if nchip in [11, 20]:
filter_name = "z"
if nchip in [7, 24]:
filter_name = "i"
if nchip in [14, 17]:
filter_name = "u"
if nchip in [9, 22]:
filter_name = "r"
if nchip in [12, 13, 18, 19]:
filter_name = "nuv"
if nchip in [8, 23]:
filter_name = "g"
filter_id = filtype.index(filter_name)
return filter_id, filter_name
def skyLim(wcs, x0, x1, y0, y1):
"""
The sky coverage of a single exposure image
"""
r2d = 180.0 / np.pi
# xt, yt, x0, y0, gx, gy, xnchip, ynchip = ccdSize()
s1 = wcs.toWorld(galsim.PositionD(x0, y0))
s2 = wcs.toWorld(galsim.PositionD(x0, y1))
s3 = wcs.toWorld(galsim.PositionD(x1, y0))
s4 = wcs.toWorld(galsim.PositionD(x1, y1))
ra = [s1.ra.rad * r2d, s2.ra.rad * r2d, s3.ra.rad * r2d, s4.ra.rad * r2d]
dec = [s1.dec.rad * r2d, s2.dec.rad * r2d, s3.dec.rad * r2d, s4.dec.rad * r2d]
return min(ra), max(ra), min(dec), max(dec)
def wcsMain(imgRotation=0.0, raCenter=0.0, decCenter=0.0):
ccdSize, ccdBase = ccdParam()
xsize, ysize, _, _, _, _, _, _ = ccdSize
_, _, pixelScale, _ = ccdBase
xmcen, ymcen = 0.0, 0.0
imrot = imgRotation * galsim.degrees
racen = raCenter * galsim.degrees
deccen = decCenter * galsim.degrees
# define the wcs
dudx = -np.cos(imrot.rad) * pixelScale
dudy = +np.sin(imrot.rad) * pixelScale
dvdx = -np.sin(imrot.rad) * pixelScale
dvdy = -np.cos(imrot.rad) * pixelScale
moscen = galsim.PositionD(x=xmcen, y=ymcen)
skyCenter = galsim.CelestialCoord(ra=racen, dec=deccen)
affine = galsim.AffineTransform(dudx, dudy, dvdx, dvdy, origin=moscen)
wcs = galsim.TanWCS(affine, skyCenter, units=galsim.arcsec)
return wcs
# FD model
def field_distortion_model(
cat_dir,
model_dir,
poly_degree=4,
model_date="2024-05-08",
model_name="FieldDistModel_v2.0_test.pickle",
):
# default parameter setup
nccd, nwave, npsf = 30, 4, 30 * 30
# load a CSST-like wcs
wcs = wcsMain()
cd11, cd12 = wcs.cd[0, 0], wcs.cd[0, 1]
cd21, cd22 = wcs.cd[1, 0], wcs.cd[1, 1]
xmcen, ymcen = wcs.crpix
# obtain the interpolation model
fdFunList = {}
fdFunList["date"] = model_date
for iwave in range(1, nwave + 1):
# if iwave!=1: continue
iwaveKey = "wave%d" % iwave
# first construct the global interpolation
xwList, ywList = [], []
xdList, ydList = [], []
fdFunList[iwaveKey] = {}
for iccd in range(1, nccd + 1):
# if iccd!=9: continue
iccdKey = "ccd" + str("0%d" % (iccd))[-2:]
# load PSF data
ipsfDatn = os.path.join(cat_dir, "ccd%d_%s.dat" % (iccd, iwaveKey))
ipsfDat = Table.read(ipsfDatn, format="ascii")
for ipsf in range(1, npsf + 1):
# if ipsf!=2: continue
xField = ipsfDat["field_x"][ipsf - 1]
yField = ipsfDat["field_y"][ipsf - 1]
# image coordinate with field distortion
xImage = 100.0 * (
ipsfDat["image_x"][ipsf - 1] + ipsfDat["centroid_x"][ipsf - 1]
)
yImage = 100.0 * (
ipsfDat["image_y"][ipsf - 1] + ipsfDat["centroid_y"][ipsf - 1]
)
# image coordinate only with wcs projection
xwcs = (cd12 * yField - cd22 * xField) / (
cd12 * cd21 - cd11 * cd22
) + xmcen
ywcs = (cd21 * xField - cd11 * yField) / (
cd12 * cd21 - cd11 * cd22
) + ymcen
xwList += [xwcs]
ywList += [ywcs]
xdList += [xImage]
ydList += [yImage]
# global interpolation
xImageFun = interpolate.SmoothBivariateSpline(
xwList, ywList, xdList, kx=poly_degree, ky=poly_degree
)
yImageFun = interpolate.SmoothBivariateSpline(
xwList, ywList, ydList, kx=poly_degree, ky=poly_degree
)
fdFunList[iwaveKey] = {
"xImagePos": xImageFun,
"yImagePos": yImageFun,
"interpLimit": [
np.min(xwList),
np.max(xwList),
np.min(ywList),
np.max(ywList),
],
}
# construct the residual interpolation
fdFunList[iwaveKey]["residual"] = {}
for iccd in range(1, nccd + 1):
# if iccd!=1: continue
iccdKey = "ccd" + str("0%d" % (iccd))[-2:]
# open the ditortion data
ipsfDatn = os.path.join(cat_dir, "ccd%d_%s.dat" % (iccd, iwaveKey))
ipsfDat = Table.read(ipsfDatn, format="ascii")
ixwList, iywList = [], []
idxList, idyList = [], []
for ipsf in range(1, npsf + 1):
# if ipsf!=1: continue
print(
"^_^ loading: iccd-{:} iwave-{:} ipsf-{:}".format(iccd, iwave, ipsf)
)
xField = ipsfDat["field_x"][ipsf - 1]
yField = ipsfDat["field_y"][ipsf - 1]
xImage = 100.0 * (
ipsfDat["image_x"][ipsf - 1] + ipsfDat["centroid_x"][ipsf - 1]
)
yImage = 100.0 * (
ipsfDat["image_y"][ipsf - 1] + ipsfDat["centroid_y"][ipsf - 1]
)
# image coordinate only with wcs projection
xwcs = (cd12 * yField - cd22 * xField) / (
cd12 * cd21 - cd11 * cd22
) + xmcen
ywcs = (cd21 * xField - cd11 * yField) / (
cd12 * cd21 - cd11 * cd22
) + ymcen
ixPred = xImageFun(xwcs, ywcs)[0][0]
iyPred = yImageFun(xwcs, ywcs)[0][0]
idx = xImage - ixPred
idy = yImage - iyPred
# print(idx, idy)
ixwList += [xwcs]
iywList += [ywcs]
idxList += [idx]
idyList += [idy]
# interpolation
xResFun = interpolate.SmoothBivariateSpline(
ixwList, iywList, idxList, kx=poly_degree, ky=poly_degree
)
yResFun = interpolate.SmoothBivariateSpline(
ixwList, iywList, idyList, kx=poly_degree, ky=poly_degree
)
fdFunList[iwaveKey]["residual"][iccdKey] = {
"xResidual": xResFun,
"yResidual": yResFun,
"interpLimit": [
np.min(ixwList),
np.max(ixwList),
np.min(iywList),
np.max(iywList),
],
}
# save the interpolation functions
model_name_full = os.path.join(model_dir, model_name)
with open(model_name_full, "wb") as out:
pickle.dump(fdFunList, out, pickle.HIGHEST_PROTOCOL)
return
def field_distortion_apply(
model_name, model_dir, cat_dir, ra_cen=60.0, dec_cen=-40.0, img_rot=0.0
):
# CCD and observation
ccdSize, ccdBase = ccdParam()
xsize, ysize, xchip, ychip, xgap, ygap, xnchip, ynchip = ccdSize
nchip = xnchip * ynchip
#################################################
xmcen, ymcen = 0.0, 0.0
#################################################
badchip = list(range(1, 6)) + list(range(26, 31)) + [10, 21]
# define the wcs of the image mosaic
print(
"^_^ Construct the wcs of the entire image mosaic using Gnomonic/TAN projection"
)
wcs = wcsMain(imgRotation=img_rot, raCenter=ra_cen, decCenter=dec_cen)
#################################################
# load the field distortion model
model_name_full = os.path.join(model_dir, model_name)
with open(model_name_full, "rb") as f:
fdModel = pickle.load(f)
#################################################
raLow, raUp, decLow, decUp = skyLim(
wcs, -xsize // 2 + 1, xsize // 2, -ysize // 2 + 1, ysize // 2
)
dra = (raUp - raLow) * np.cos(dec_cen * np.pi / 180.0)
ddec = decUp - decLow
print(
" Image pixel size: %d*%d; center: (Ra, Dec)=(%.3f, %.3f)."
% (xsize, ysize, ra_cen, dec_cen)
)
print(" Field of Veiw: %.2f * %.2f deg^2." % (dra, ddec))
# filters and corresponding bounds in the image mosaic
fbound = {}
print(" Model the filter distributions in the image mosaic ...")
stats = {}
for i in range(nchip):
chip_id = i + 1
if chip_id in badchip:
continue
cx0, cx1, cy0, cy1 = chipLim(chip_id)
chip_bound = galsim.BoundsD(cx0 - 1, cx1 - 1, cy0 - 1, cy1 - 1)
chip_filter_id, chip_filt = chip_filter(chip_id)
# print "^_^ CHIP %d, Filter %s"%(chip_id,chip_filter)
fbound[chip_id] = [chip_filter_id, chip_filt, chip_bound]
stats[chip_id] = [0, 0, 0]
# generate object grid
ra_input = np.arange(ra_cen - 1.0, ra_cen + 1.0, 0.00125)
dec_input = np.arange(dec_cen - 1.0, dec_cen + 1.0, 0.00125)
nobj = len(ra_input) * len(dec_input)
crdCat = np.zeros((nobj, 2))
cid = 0
for id1 in range(len(ra_input)):
ira = ra_input[id1]
for id2 in range(len(dec_input)):
idec = dec_input[id2]
crdCat[cid, :] = ira, idec
cid += 1
print("^_^ Total %d objects are generaged" % nobj)
# main program
for i in range(nchip):
# if i not in [6]: continue
if i + 1 in badchip:
continue
filtidk, filtnmk, boundk = fbound[i + 1]
idStr = str("0%d" % (i + 1))[-2:]
###################################################################
# 1) Use global field distortion model: FieldDistModelGlobal_v2.0.pickle
ifdModel = fdModel["wave1"]
irsModel = fdModel["wave1"]["residual"]["ccd" + idStr]
xLowI, xUpI, yLowI, yUpI = ifdModel["interpLimit"]
xlLowI, xlUpI, ylLowI, ylUpI = irsModel["interpLimit"]
# field distortion model along x/y-axis
ixfdModel = ifdModel["xImagePos"]
iyfdModel = ifdModel["yImagePos"]
ixrsModel = irsModel["xResidual"]
iyrsModel = irsModel["yResidual"]
# first-order derivatives of the global field distortion model
ifx_dx = ixfdModel.partial_derivative(1, 0)
ifx_dy = ixfdModel.partial_derivative(0, 1)
ify_dx = iyfdModel.partial_derivative(1, 0)
ify_dy = iyfdModel.partial_derivative(0, 1)
# first-order derivatives of the residual field distortion model
irx_dx = ixrsModel.partial_derivative(1, 0)
irx_dy = ixrsModel.partial_derivative(0, 1)
iry_dx = iyrsModel.partial_derivative(1, 0)
iry_dy = iyrsModel.partial_derivative(0, 1)
###################################################################
# construct the image mosaic firstly
xorigin, yorigin = xmcen - boundk.xmin, ymcen - boundk.ymin
print(" Construct the chip mosaic ...")
fimage = galsim.ImageF(xchip, ychip)
fimage.setOrigin(boundk.xmin, boundk.ymin)
fimage.wcs = wcs
raLow, raUp, decLow, decUp = skyLim(
wcs, boundk.xmin, boundk.xmax, boundk.ymin, boundk.ymax
)
dra = (raUp - raLow) * np.cos(dec_cen * np.pi / 180.0)
ddec = decUp - decLow
print(" Image coverage: %.2f * %.2f arcmin^2." % (dra * 60.0, ddec * 60.0))
# enlarge the sky coverage in order to catch the galaxies at the chip edge
raLow -= 0.2 / 60.0
decLow -= 0.2 / 60.0
raUp += 0.2 / 60.0
decUp += 0.2 / 60.0
print(
" Range: RA=[%.4f, %.4f]; DEC=[%.4f, %.4f]"
% (raLow, raUp, decLow, decUp)
)
# generate the galaxy and star images
catxxn = os.path.join(
cat_dir, "csst_mainfocus_field_distortion_ccd%s_%s.cat" % (idStr, filtnmk)
)
hdrxx = "#id_obj id_chip filter ra_true dec_ture x_image_ture y_image_ture x_image y_image g1_fd g2_fd\n"
fmtxx = "%8d %3d %4s %12.6f %12.6f %13.6f %13.6f %13.6f %13.6f %9.5f %9.5f\n"
catxx = open(catxxn, "w")
catxx.write(hdrxx)
oidxx = 0
for k in range(nobj):
# if k != 0: continue
# input galaxy parameters
rak = crdCat[k, 0]
deck = crdCat[k, 1]
# reject objects out of the image
if (rak - raLow) * (rak - raUp) > 0.0 or (deck - decLow) * (
deck - decUp
) > 0.0:
continue
world_pos = galsim.CelestialCoord(
ra=rak * galsim.degrees, dec=deck * galsim.degrees
)
image_pos = fimage.wcs.toImage(world_pos)
xk_true = image_pos.x
yk_true = image_pos.y
#################################################################
# field distortion
if (xLowI - xk_true) * (xUpI - xk_true) > 0 or (yLowI - yk_true) * (
yUpI - yk_true
) > 0:
continue
xk = ixfdModel(xk_true, yk_true)[0][0]
yk = iyfdModel(xk_true, yk_true)[0][0]
# global offset correction
if (xlLowI - xk) * (xlUpI - xk) > 0 or (ylLowI - yk) * (ylUpI - yk) > 0:
continue
dxk = ixrsModel(xk, yk)[0][0]
dyk = iyrsModel(xk, yk)[0][0]
xk = xk + dxk
yk = yk + dyk
# field distortion induced ellipticity
ix_dx = ifx_dx(xk, yk) + irx_dx(xk, yk)
ix_dy = ifx_dy(xk, yk) + irx_dy(xk, yk)
iy_dx = ify_dx(xk, yk) + iry_dx(xk, yk)
iy_dy = ify_dy(xk, yk) + iry_dy(xk, yk)
g1k_fd = 0.0 + (iy_dy - ix_dx) / (iy_dy + ix_dx)
g2k_fd = 0.0 - (iy_dx + ix_dy) / (iy_dy + ix_dx)
#################################################################
dxk_true, dyk_true = xk_true - xmcen, yk_true - ymcen
xLock_true, yLock_true = dxk_true + xorigin + 1.0, dyk_true + yorigin + 1.0
dxk, dyk = xk - xmcen, yk - ymcen
xLock, yLock = dxk + xorigin + 1.0, dyk + yorigin + 1.0
if (xLock_true < 0) or (xLock_true > xchip):
continue
if (yLock_true < 0) or (yLock_true > ychip):
continue
if (xLock < 0) or (xLock > xchip):
continue
if (yLock < 0) or (yLock > ychip):
continue
linexx = fmtxx % (
k + 1,
i + 1,
filtnmk.lower(),
rak,
deck,
xLock_true,
yLock_true,
xLock,
yLock,
g1k_fd[0][0],
g2k_fd[0][0],
)
catxx.write(linexx)
catxx.close()
return
if __name__ == "__main__":
unittest.main()
import unittest import unittest
import os import os
import galsim import galsim
from ObservationSim.Instrument import FocalPlane, Chip from observation_sim.instruments import FocalPlane, Chip
class TestFocalPlane(unittest.TestCase): class TestFocalPlane(unittest.TestCase):
...@@ -20,12 +20,12 @@ class TestFocalPlane(unittest.TestCase): ...@@ -20,12 +20,12 @@ class TestFocalPlane(unittest.TestCase):
def test_fp_method(self): def test_fp_method(self):
wcs = self.focal_plane.getTanWCS( wcs = self.focal_plane.getTanWCS(
192.8595, 0., 0.*galsim.degrees, 0.0074) 192.8595, 0., 0.*galsim.degrees, 0.074)
sky_coverage = self.focal_plane.getSkyCoverage( sky_coverage = self.focal_plane.getSkyCoverage(
wcs, x0=-1, x1=0, y0=-1, y1=0) wcs, x0=-1, x1=0, y0=-1, y1=0)
print(sky_coverage.area()) print(sky_coverage.area())
self.assertTrue(abs(sky_coverage.area() - 0.0074**2/(3600.**2)) < 1e13) self.assertTrue(abs(sky_coverage.area() - 0.074**2/(3600.**2)) < 1e13)
if __name__ == '__main_': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -15,12 +15,12 @@ import copy ...@@ -15,12 +15,12 @@ import copy
from astropy.cosmology import FlatLambdaCDM from astropy.cosmology import FlatLambdaCDM
from astropy import constants from astropy import constants
from astropy import units as U from astropy import units as U
from ObservationSim.MockObject._util import getObservedSED from observation_sim.mock_objects._util import getObservedSED
from ObservationSim.MockObject import CatalogBase, Galaxy from observation_sim.mock_objects import CatalogBase, Galaxy
from ObservationSim.Instrument import Chip, Filter, FilterParam, FocalPlane from observation_sim.instruments import Chip, Filter, FilterParam, FocalPlane
from ObservationSim.PSF.PSFInterp import PSFInterp from observation_sim.psf.PSFInterp import PSFInterp
from ObservationSim.MockObject._util import integrate_sed_bandpass, getNormFactorForSpecWithABMAG, getABMAG from observation_sim.mock_objects._util import integrate_sed_bandpass, getNormFactorForSpecWithABMAG, getABMAG
class Catalog(CatalogBase): class Catalog(CatalogBase):
......
...@@ -6,8 +6,7 @@ import numpy as np ...@@ -6,8 +6,7 @@ import numpy as np
import galsim import galsim
import yaml import yaml
from ObservationSim.Instrument import Chip, Filter, FilterParam, FocalPlane from observation_sim.instruments import Chip, Filter, FilterParam, FocalPlane
#from ObservationSim.Instrument.Chip import ChipUtils as chip_utils
### test FUNCTION --- START ### ### test FUNCTION --- START ###
def AddPreScan(GSImage, pre1=27, pre2=4, over1=71, over2=80, nsecy = 2, nsecx=8): def AddPreScan(GSImage, pre1=27, pre2=4, over1=71, over2=80, nsecy = 2, nsecx=8):
......
...@@ -14,17 +14,19 @@ chip_filename = 'chip_definition.json' ...@@ -14,17 +14,19 @@ chip_filename = 'chip_definition.json'
# "npix_y": 7680, # "npix_y": 7680,
# "x_cen": -273.35, # [mm] # "x_cen": -273.35, # [mm]
# "y_cen": 211.36, # [mm] # "y_cen": 211.36, # [mm]
# "rotate_angle": 90. # [deg] # "rotate_angle": 90. # [deg]
# } # }
# chip_list[chip_id] = chip_dict # chip_list[chip_id] = chip_dict
def get_chip_row_col_main_fp(chip_id): def get_chip_row_col_main_fp(chip_id):
rowID = ((chip_id - 1) % 5) + 1 rowID = ((chip_id - 1) % 5) + 1
colID = 6 - ((chip_id - 1) // 5) colID = 6 - ((chip_id - 1) // 5)
return rowID, colID return rowID, colID
def get_chip_center_main_fp(chip_id, pixel_size=1e-2): def get_chip_center_main_fp(chip_id, pixel_size=1e-2):
row, col = get_chip_row_col_main_fp(chip_id) row, col = get_chip_row_col_main_fp(chip_id)
npix_x = 9216 npix_x = 9216
npix_y = 9232 npix_y = 9232
...@@ -39,16 +41,20 @@ def get_chip_center_main_fp(chip_id, pixel_size=1e-2): ...@@ -39,16 +41,20 @@ def get_chip_center_main_fp(chip_id, pixel_size=1e-2):
xcen = (npix_x//2 + gx1//2) * xrem - (gx2-gx1) xcen = (npix_x//2 + gx1//2) * xrem - (gx2-gx1)
if chip_id <= 5 or chip_id == 10: if chip_id <= 5 or chip_id == 10:
xcen = (npix_x//2 + gx1//2) * xrem + (gx2-gx1) xcen = (npix_x//2 + gx1//2) * xrem + (gx2-gx1)
# ylim of a given CCD chip # ylim of a given CCD chip
yrem = (row - 1) - nchip_y // 2 yrem = (row - 1) - nchip_y // 2
ycen = (npix_y + gy) * yrem ycen = (npix_y + gy) * yrem
return xcen * pixel_size, ycen * pixel_size return xcen * pixel_size, ycen * pixel_size
def create_chip_dict_main_fp(chip_id, pixel_size=1e-2): def create_chip_dict_main_fp(chip_id, pixel_size=1e-2):
filter_list = ["GV", "GI", "y", "z", "y", "GI", "GU", "r", "u", "NUV", "i", "GV", "GU", "g", "NUV", "NUV", "g", "GU", "GV", "i", "NUV", "u", "r", "GU", "GI", "y", "z", "y", "GI", "GV"] filter_list = ["GV", "GI", "y", "z", "y", "GI", "GU", "r", "u", "NUV", "i", "GV", "GU", "g",
chip_label_list = [3,3,3,1,1,1,3,2,2,1,1,1,4,2,3,2,1,1,4,2,4,1,1,2,4,2,2,4,2,2] "NUV", "NUV", "g", "GU", "GV", "i", "NUV", "u", "r", "GU", "GI", "y", "z", "y", "GI", "GV"]
chip_id_list = [26, 21, 16, 11, 6, 1, 27, 22, 17, 12, 7, 2, 28, 23, 18, 13, 8, 3, 29, 24, 19, 14, 9, 4, 30, 25, 20, 15, 10, 5] chip_label_list = [3, 3, 3, 1, 1, 1, 3, 2, 2, 1, 1, 1,
4, 2, 3, 2, 1, 1, 4, 2, 4, 1, 1, 2, 4, 2, 2, 4, 2, 2]
chip_id_list = [26, 21, 16, 11, 6, 1, 27, 22, 17, 12, 7, 2, 28,
23, 18, 13, 8, 3, 29, 24, 19, 14, 9, 4, 30, 25, 20, 15, 10, 5]
npix_x = 9216 npix_x = 9216
npix_y = 9232 npix_y = 9232
idx = chip_id_list.index(chip_id) idx = chip_id_list.index(chip_id)
...@@ -63,10 +69,10 @@ def create_chip_dict_main_fp(chip_id, pixel_size=1e-2): ...@@ -63,10 +69,10 @@ def create_chip_dict_main_fp(chip_id, pixel_size=1e-2):
chip_dict = { chip_dict = {
"chip_name": chip_name, "chip_name": chip_name,
"pix_size": 1e-2, # [mm] "pix_size": 1e-2, # [mm]
"pix_scale": 0.074, # [arcsec/pix] "pix_scale": 0.074, # [arcsec/pix]
"npix_x": npix_x, "npix_x": npix_x,
"npix_y": npix_y, "npix_y": npix_y,
"x_cen": xcen, # [mm] "x_cen": xcen, # [mm]
"y_cen": ycen, # [mm] "y_cen": ycen, # [mm]
"rotate_angle": rotate_angle, # [deg] "rotate_angle": rotate_angle, # [deg]
"n_psf_samples": 900, "n_psf_samples": 900,
...@@ -80,6 +86,7 @@ def create_chip_dict_main_fp(chip_id, pixel_size=1e-2): ...@@ -80,6 +86,7 @@ def create_chip_dict_main_fp(chip_id, pixel_size=1e-2):
} }
return chip_dict return chip_dict
def set_fgs_chips(filepath): def set_fgs_chips(filepath):
with open(filepath, "r") as f: with open(filepath, "r") as f:
data = json.load(f) data = json.load(f)
...@@ -94,7 +101,7 @@ def set_fgs_chips(filepath): ...@@ -94,7 +101,7 @@ def set_fgs_chips(filepath):
data[chip_id]["full_well"] = 90000 data[chip_id]["full_well"] = 90000
with open(filepath, "w") as f: with open(filepath, "w") as f:
json.dump(data, f, indent=4) json.dump(data, f, indent=4)
def add_main_fp(filepath): def add_main_fp(filepath):
for i in range(30): for i in range(30):
...@@ -102,6 +109,7 @@ def add_main_fp(filepath): ...@@ -102,6 +109,7 @@ def add_main_fp(filepath):
chip_dict = create_chip_dict_main_fp(chip_id) chip_dict = create_chip_dict_main_fp(chip_id)
add_dict_to_json(filepath, str(chip_id), chip_dict) add_dict_to_json(filepath, str(chip_id), chip_dict)
def add_dict_to_json(filepath, key, value): def add_dict_to_json(filepath, key, value):
with open(filepath, 'r') as f: with open(filepath, 'r') as f:
data = json.load(f) data = json.load(f)
...@@ -109,8 +117,9 @@ def add_dict_to_json(filepath, key, value): ...@@ -109,8 +117,9 @@ def add_dict_to_json(filepath, key, value):
with open(filepath, "w") as f: with open(filepath, "w") as f:
json.dump(data, f, indent=4) json.dump(data, f, indent=4)
if __name__=="__main__":
src = "../ObservationSim/Instrument/data/ccd/chip_definition.json" if __name__ == "__main__":
src = "../observation_sim/instruments/data/ccd/chip_definition.json"
shutil.copy(src, chip_filename) shutil.copy(src, chip_filename)
add_main_fp(chip_filename) add_main_fp(chip_filename)
set_fgs_chips(chip_filename) set_fgs_chips(chip_filename)
\ No newline at end of file
import os import os
import numpy as np import numpy as np
import ObservationSim.PSF.PSFInterp as PSFInterp import observation_sim.psf.PSFInterp as PSFInterp
from ObservationSim.Instrument import Chip, Filter, FilterParam from observation_sim.instruments import Chip, Filter, FilterParam
import yaml import yaml
import galsim import galsim
import astropy.io.fits as fitsio import astropy.io.fits as fitsio
# Setup PATH # Setup PATH
SIMPATH = "/share/simudata/CSSOSDataProductsSims/data/CSSTSimImage_C8/testRun_FGS" SIMPATH = "/share/simudata/CSSOSDataProductsSims/data/CSSTSimImage_C8/testRun_FGS"
config_filename= SIMPATH+"/config_C6_fits.yaml" config_filename = SIMPATH+"/config_C6_fits.yaml"
cat_filename = SIMPATH+"/MSC_00000000/MSC_10106100000000_chip_40_filt_FGS.cat" cat_filename = SIMPATH+"/MSC_00000000/MSC_10106100000000_chip_40_filt_FGS.cat"
# Read cat file # Read cat file
catFn = open(cat_filename,"r") catFn = open(cat_filename, "r")
line = catFn.readline() line = catFn.readline()
print(cat_filename,'\n',line) print(cat_filename, '\n', line)
imgPos = [] imgPos = []
chipID = -1 chipID = -1
for line in catFn: for line in catFn:
line = line.strip() line = line.strip()
columns = line.split() columns = line.split()
if chipID == -1: if chipID == -1:
chipID = int(columns[1]) chipID = int(columns[1])
else: else:
...@@ -37,41 +37,46 @@ with open(config_filename, "r") as stream: ...@@ -37,41 +37,46 @@ with open(config_filename, "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)
# Setup Chip # Setup Chip
chip = Chip(chipID=chipID, config=config) chip = Chip(chipID=chipID, config=config)
print('chip.bound::', chip.bound.xmin, chip.bound.xmax, chip.bound.ymin, chip.bound.ymax) print('chip.bound::', chip.bound.xmin, chip.bound.xmax,
chip.bound.ymin, chip.bound.ymax)
for iobj in range(nobj): for iobj in range(nobj):
print("\nget psf for iobj-", iobj, '\t', 'bandpass:', end=" ", flush=True) print("\nget psf for iobj-", iobj, '\t', 'bandpass:', end=" ", flush=True)
# Setup Position on focalplane # Setup Position on focalplane
x, y = imgPos[iobj, :] # try get the PSF at some location (1234, 1234) on the chip # try get the PSF at some location (1234, 1234) on the chip
x, y = imgPos[iobj, :]
x = x+chip.bound.xmin x = x+chip.bound.xmin
y = y+chip.bound.ymin y = y+chip.bound.ymin
pos_img = galsim.PositionD(x, y) pos_img = galsim.PositionD(x, y)
# Setup sub-bandpass # Setup sub-bandpass
# (There are 4 sub-bandpasses for each PSF sample) # (There are 4 sub-bandpasses for each PSF sample)
filter_param = FilterParam() filter_param = FilterParam()
filter_id, filter_type = chip.getChipFilter() filter_id, filter_type = chip.getChipFilter()
filt = Filter( filt = Filter(
filter_id=filter_id, filter_id=filter_id,
filter_type=filter_type, filter_type=filter_type,
filter_param=filter_param, filter_param=filter_param,
ccd_bandpass=chip.effCurve) ccd_bandpass=chip.effCurve)
bandpass_list = filt.bandpass_sub_list bandpass_list = filt.bandpass_sub_list
for i in range(len(bandpass_list)): for i in range(len(bandpass_list)):
print(i, end=" ", flush=True) print(i, end=" ", flush=True)
bandpass = bandpass_list[i] # say you want to access the PSF for the sub-bandpass at the blue end for that chip # say you want to access the PSF for the sub-bandpass at the blue end for that chip
bandpass = bandpass_list[i]
# Get corresponding PSF model # Get corresponding PSF model
psf_model = PSFInterp(chip=chip, npsf=100, PSF_data_file=config["psf_setting"]["psf_dir"]) psf_model = PSFInterp(chip=chip, npsf=100,
psf = psf_model.get_PSF(chip=chip, pos_img=pos_img, bandpass=bandpass, galsimGSObject=False) PSF_data_file=config["psf_setting"]["psf_dir"])
psf = psf_model.get_PSF(
chip=chip, pos_img=pos_img, bandpass=bandpass, galsimGSObject=False)
if True: if True:
fn = "psf_{:}.{:}.{:}.fits".format(chipID, iobj, i) fn = "psf_{:}.{:}.{:}.fits".format(chipID, iobj, i)
if fn != None: if fn != None:
...@@ -81,6 +86,3 @@ for iobj in range(nobj): ...@@ -81,6 +86,3 @@ for iobj in range(nobj):
hdu.data = psf hdu.data = psf
hdu.header.set('pixScale', 5) hdu.header.set('pixScale', 5)
hdu.writeto(fn) hdu.writeto(fn)
...@@ -26,7 +26,8 @@ import galsim ...@@ -26,7 +26,8 @@ import galsim
def test_fits(nfits=100, dir_cat=None): def test_fits(nfits=100, dir_cat=None):
for ifits in range(nfits): for ifits in range(nfits):
gal = galsim.Gaussian(sigma=np.random.uniform(0.2, 0.3)).shear(g1=np.random.uniform(-0.5, 0.5), g2=np.random.uniform(-0.5, 0.5)) gal = galsim.Gaussian(sigma=np.random.uniform(0.2, 0.3)).shear(
g1=np.random.uniform(-0.5, 0.5), g2=np.random.uniform(-0.5, 0.5))
arr = gal.drawImage(nx=64, ny=64, scale=0.074).array arr = gal.drawImage(nx=64, ny=64, scale=0.074).array
hdu = fitsio.PrimaryHDU() hdu = fitsio.PrimaryHDU()
...@@ -38,41 +39,44 @@ def test_fits(nfits=100, dir_cat=None): ...@@ -38,41 +39,44 @@ def test_fits(nfits=100, dir_cat=None):
hdu.header.set('mag_g', 22+np.random.uniform(-1, 1)) hdu.header.set('mag_g', 22+np.random.uniform(-1, 1))
hdu.header.set('pixScale', 0.074) hdu.header.set('pixScale', 0.074)
fout=dir_cat+"stampCats/testStamp_{:}.fits".format(ifits) fout = dir_cat+"stampCats/testStamp_{:}.fits".format(ifits)
if os.path.exists(fout): if os.path.exists(fout):
os.remove(fout) os.remove(fout)
hdu.writeto(fout) hdu.writeto(fout)
def write_StampsIndex(dir_cat=None, DEBUG=False): def write_StampsIndex(dir_cat=None, DEBUG=False):
MAXNUMBERINDEX = 10000 MAXNUMBERINDEX = 10000
NSIDE = 128 NSIDE = 128
fp = h5py.File(dir_cat+'stampCatsIndex.hdf5', 'w') fp = h5py.File(dir_cat+'stampCatsIndex.hdf5', 'w')
grp1 = fp.create_group('Stamps') grp1 = fp.create_group('Stamps')
dataSet_Size = np.zeros(healpy.nside2npix(NSIDE), dtype=np.int64) dataSet_Size = np.zeros(healpy.nside2npix(NSIDE), dtype=np.int64)
fitsList = os.listdir(dir_cat+'stampCats/') #获取fits文件列表 fitsList = os.listdir(dir_cat+'stampCats/') # 获取fits文件列表
for istamp in range(len(fitsList)): for istamp in range(len(fitsList)):
print(istamp, ': ', fitsList[istamp], end='\r') print(istamp, ': ', fitsList[istamp], end='\r')
hdu=fitsio.open(dir_cat+"stampCats/"+fitsList[istamp]) hdu = fitsio.open(dir_cat+"stampCats/"+fitsList[istamp])
tra = hdu[0].header['RA'] tra = hdu[0].header['RA']
tdec= hdu[0].header['DEC'] tdec = hdu[0].header['DEC']
healpixID= healpy.ang2pix(NSIDE, tra, tdec, nest=False, lonlat=True) healpixID = healpy.ang2pix(NSIDE, tra, tdec, nest=False, lonlat=True)
if not(str(healpixID) in grp1): if not (str(healpixID) in grp1):
grp2 = grp1.create_group(str(healpixID)) grp2 = grp1.create_group(str(healpixID))
else: else:
grp2 = grp1[str(healpixID)] grp2 = grp1[str(healpixID)]
if not('ra' in grp2): if not ('ra' in grp2):
dset_ra = grp2.create_dataset('ra', (0,), dtype='f16' , maxshape=(MAXNUMBERINDEX, )) dset_ra = grp2.create_dataset(
dset_dec= grp2.create_dataset('dec', (0,), dtype='f16', maxshape=(MAXNUMBERINDEX, )) 'ra', (0,), dtype='f16', maxshape=(MAXNUMBERINDEX, ))
dset_dec = grp2.create_dataset(
'dec', (0,), dtype='f16', maxshape=(MAXNUMBERINDEX, ))
dt = h5py.special_dtype(vlen=str) dt = h5py.special_dtype(vlen=str)
dset_fn = grp2.create_dataset('filename', (0,), dtype=dt, maxshape=(MAXNUMBERINDEX, )) dset_fn = grp2.create_dataset(
'filename', (0,), dtype=dt, maxshape=(MAXNUMBERINDEX, ))
else: else:
dset_ra = grp2['ra'] dset_ra = grp2['ra']
dset_dec = grp2['dec'] dset_dec = grp2['dec']
dset_fn = grp2['filename'] dset_fn = grp2['filename']
...@@ -82,13 +86,13 @@ def write_StampsIndex(dir_cat=None, DEBUG=False): ...@@ -82,13 +86,13 @@ def write_StampsIndex(dir_cat=None, DEBUG=False):
grp2['filename'].resize((dataSet_Size[healpixID],)) grp2['filename'].resize((dataSet_Size[healpixID],))
dset_ra[dataSet_Size[healpixID]-1] = tra dset_ra[dataSet_Size[healpixID]-1] = tra
dset_dec[dataSet_Size[healpixID]-1]= tdec dset_dec[dataSet_Size[healpixID]-1] = tdec
dset_fn[dataSet_Size[healpixID]-1]= fitsList[istamp] dset_fn[dataSet_Size[healpixID]-1] = fitsList[istamp]
fp.close() fp.close()
if DEBUG: if DEBUG:
print('\n') print('\n')
ff = h5py.File(dir_cat+"stampCatsIndex.hdf5","r") ff = h5py.File(dir_cat+"stampCatsIndex.hdf5", "r")
ss = 0 ss = 0
for kk in ff['Stamps'].keys(): for kk in ff['Stamps'].keys():
print(kk, ff['Stamps'][kk]['ra'].size) print(kk, ff['Stamps'][kk]['ra'].size)
...@@ -98,6 +102,5 @@ def write_StampsIndex(dir_cat=None, DEBUG=False): ...@@ -98,6 +102,5 @@ def write_StampsIndex(dir_cat=None, DEBUG=False):
if __name__ == '__main__': if __name__ == '__main__':
dir_temp = "./Catalog_test/" dir_temp = "./Catalog_test/"
#test_fits(dir_cat=dir_temp) # test_fits(dir_cat=dir_temp)
write_StampsIndex(dir_cat=dir_temp) write_StampsIndex(dir_cat=dir_temp)
# NOTE: This is a stand-alone function, meaning that you do not need # NOTE: This is a stand-alone function, meaning that you do not need
# to install the entire CSST image simulation pipeline. # to install the entire CSST image simulation pipeline.
# For a given object's coordinate (Ra, Dec), the function will predict # For a given object's coordinate (Ra, Dec), the function will predict
# the object's image position and corresponding filter in the focal plane # the object's image position and corresponding filter in the focal plane
# under a specified CSST pointing centered at (rap, decp). # under a specified CSST pointing centered at (rap, decp).
import galsim import galsim
import numpy as np import numpy as np
import argparse import argparse
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import os, sys import os
import sys
def focalPlaneInf(ra_target, dec_target, ra_point, dec_point, image_rot=-113.4333, figout="zTargetOnCCD.pdf"): def focalPlaneInf(ra_target, dec_target, ra_point, dec_point, image_rot=-113.4333, figout="zTargetOnCCD.pdf"):
""" """
...@@ -37,60 +39,71 @@ def focalPlaneInf(ra_target, dec_target, ra_point, dec_point, image_rot=-113.433 ...@@ -37,60 +39,71 @@ def focalPlaneInf(ra_target, dec_target, ra_point, dec_point, image_rot=-113.433
or type >> python TargetLocationCheck.py ra_target dec_target ra_point dec_point -image_rot=floatNum or type >> python TargetLocationCheck.py ra_target dec_target ra_point dec_point -image_rot=floatNum
or type >> python TargetLocationCheck.py ra_target dec_target ra_point dec_point -image_rot=floatNum -figout=FigureName or type >> python TargetLocationCheck.py ra_target dec_target ra_point dec_point -image_rot=floatNum -figout=FigureName
""" """
print("^_^ Input target coordinate: [Ra, Dec] = [%10.6f, %10.6f]"%(ra_target,dec_target)) print("^_^ Input target coordinate: [Ra, Dec] = [%10.6f, %10.6f]" % (
print("^_^ Input telescope pointing center: [Ra, Dec] = [%10.6f, %10.6f]"%(ra_point,dec_point)) ra_target, dec_target))
print("^_^ Input camera orientation: %12.6f degree(s)"%image_rot) print("^_^ Input telescope pointing center: [Ra, Dec] = [%10.6f, %10.6f]" % (
ra_point, dec_point))
print("^_^ Input camera orientation: %12.6f degree(s)" % image_rot)
print(" ") print(" ")
# load ccd parameters # load ccd parameters
xsize, ysize, xchip, ychip, xgap, ygap, xnchip, ynchip = ccdParam() xsize, ysize, xchip, ychip, xgap, ygap, xnchip, ynchip = ccdParam()
print("^_^ Pixel range of focal plane: x = [%5d, %5d], y = [%5d, %5d]"%(-xsize/2,xsize/2,-ysize/2,ysize/2)) print("^_^ Pixel range of focal plane: x = [%5d, %5d], y = [%5d, %5d]" % (
# wcs -xsize/2, xsize/2, -ysize/2, ysize/2))
wcs = getTanWCS(ra_point, dec_point, image_rot, pix_scale=0.074) # wcs
skyObj = galsim.CelestialCoord(ra=ra_target*galsim.degrees,dec=dec_target*galsim.degrees) wcs = getTanWCS(ra_point, dec_point, image_rot, pix_scale=0.074)
pixObj = wcs.toImage(skyObj) skyObj = galsim.CelestialCoord(
ra=ra_target*galsim.degrees, dec=dec_target*galsim.degrees)
pixObj = wcs.toImage(skyObj)
xpixObj = pixObj.x xpixObj = pixObj.x
ypixObj = pixObj.y ypixObj = pixObj.y
print("^_^ Image position of target: [xImage, yImage] = [%9.3f, %9.3f]"%(xpixObj,ypixObj)) print("^_^ Image position of target: [xImage, yImage] = [%9.3f, %9.3f]" % (
xpixObj, ypixObj))
# first determine if the target is in the focal plane # first determine if the target is in the focal plane
xin = (xpixObj+xsize/2)*(xpixObj-xsize/2) xin = (xpixObj+xsize/2)*(xpixObj-xsize/2)
yin = (ypixObj+ysize/2)*(ypixObj-ysize/2) yin = (ypixObj+ysize/2)*(ypixObj-ysize/2)
if xin>0 or yin>0: raise ValueError("!!! Input target is out of the focal plane") if xin > 0 or yin > 0:
raise ValueError("!!! Input target is out of the focal plane")
# second determine the location of the target # second determine the location of the target
trigger = False trigger = False
for i in range(30): for i in range(30):
ichip = i+1 ichip = i+1
ischip = str("0%d"%ichip)[-2:] ischip = str("0%d" % ichip)[-2:]
fId, fType = getChipFilter(ichip) fId, fType = getChipFilter(ichip)
ix0, ix1, iy0, iy1 = getChipLim(ichip) ix0, ix1, iy0, iy1 = getChipLim(ichip)
ixin = (xpixObj-ix0)*(xpixObj-ix1) ixin = (xpixObj-ix0)*(xpixObj-ix1)
iyin = (ypixObj-iy0)*(ypixObj-iy1) iyin = (ypixObj-iy0)*(ypixObj-iy1)
if ixin<=0 and iyin<=0: if ixin <= 0 and iyin <= 0:
trigger = True trigger = True
idx = xpixObj - ix0 idx = xpixObj - ix0
idy = ypixObj - iy0 idy = ypixObj - iy0
print(" ---------------------------------------------") print(" ---------------------------------------------")
print(" ** Target locates in CHIP#%s with filter %s **"%(ischip,fType)) print(" ** Target locates in CHIP#%s with filter %s **" %
print(" ** Target position in the chip: [x, y] = [%7.2f, %7.2f]"%(idx, idy)) (ischip, fType))
print(
" ** Target position in the chip: [x, y] = [%7.2f, %7.2f]" % (idx, idy))
print(" ---------------------------------------------") print(" ---------------------------------------------")
break break
if not trigger: print("^|^ Target locates in CCD gap") if not trigger:
print("^|^ Target locates in CCD gap")
# show the figure # show the figure
print(" Target on CCD layout is saved into %s"%figout) print(" Target on CCD layout is saved into %s" % figout)
ccdLayout(xpixObj, ypixObj, figout=figout) ccdLayout(xpixObj, ypixObj, figout=figout)
return return
def ccdParam(): def ccdParam():
xt, yt = 59516, 49752 xt, yt = 59516, 49752
x0, y0 = 9216, 9232 x0, y0 = 9216, 9232
xgap, ygap = (534,1309), 898 xgap, ygap = (534, 1309), 898
xnchip, ynchip = 6, 5 xnchip, ynchip = 6, 5
ccdSize = xt, yt, x0, y0, xgap, ygap, xnchip, ynchip ccdSize = xt, yt, x0, y0, xgap, ygap, xnchip, ynchip
return ccdSize return ccdSize
def getTanWCS(ra, dec, img_rot, pix_scale=0.074): def getTanWCS(ra, dec, img_rot, pix_scale=0.074):
""" """
Get the WCS of the image mosaic using Gnomonic/TAN projection Get the WCS of the image mosaic using Gnomonic/TAN projection
...@@ -105,40 +118,53 @@ def getTanWCS(ra, dec, img_rot, pix_scale=0.074): ...@@ -105,40 +118,53 @@ def getTanWCS(ra, dec, img_rot, pix_scale=0.074):
WCS of the focal plane WCS of the focal plane
""" """
xcen, ycen = 0, 0 xcen, ycen = 0, 0
img_rot = img_rot * galsim.degrees img_rot = img_rot * galsim.degrees
dudx = -np.cos(img_rot.rad) * pix_scale dudx = -np.cos(img_rot.rad) * pix_scale
dudy = -np.sin(img_rot.rad) * pix_scale dudy = -np.sin(img_rot.rad) * pix_scale
dvdx = -np.sin(img_rot.rad) * pix_scale dvdx = -np.sin(img_rot.rad) * pix_scale
dvdy = +np.cos(img_rot.rad) * pix_scale dvdy = +np.cos(img_rot.rad) * pix_scale
moscen = galsim.PositionD(x=xcen, y=ycen) moscen = galsim.PositionD(x=xcen, y=ycen)
sky_center = galsim.CelestialCoord(ra=ra*galsim.degrees, dec=dec*galsim.degrees) sky_center = galsim.CelestialCoord(
affine = galsim.AffineTransform(dudx, dudy, dvdx, dvdy, origin=moscen) ra=ra*galsim.degrees, dec=dec*galsim.degrees)
WCS = galsim.TanWCS(affine, sky_center, units=galsim.arcsec) affine = galsim.AffineTransform(dudx, dudy, dvdx, dvdy, origin=moscen)
WCS = galsim.TanWCS(affine, sky_center, units=galsim.arcsec)
return WCS return WCS
def getChipFilter(chipID): def getChipFilter(chipID):
""" """
Return the filter index and type for a given chip #(chipID) Return the filter index and type for a given chip #(chipID)
""" """
filter_type_list = ["nuv","u", "g", "r", "i","z","y","GU", "GV", "GI"] filter_type_list = ["nuv", "u", "g", "r", "i", "z", "y", "GU", "GV", "GI"]
# TODO: maybe a more elegent way other than hard coded? # TODO: maybe a more elegent way other than hard coded?
# e.g. use something like a nested dict: # e.g. use something like a nested dict:
if chipID in [6, 15, 16, 25]: filter_type = "y" if chipID in [6, 15, 16, 25]:
if chipID in [11, 20]: filter_type = "z" filter_type = "y"
if chipID in [7, 24]: filter_type = "i" if chipID in [11, 20]:
if chipID in [14, 17]: filter_type = "u" filter_type = "z"
if chipID in [9, 22]: filter_type = "r" if chipID in [7, 24]:
if chipID in [12, 13, 18, 19]: filter_type = "nuv" filter_type = "i"
if chipID in [8, 23]: filter_type = "g" if chipID in [14, 17]:
if chipID in [1, 10, 21, 30]: filter_type = "GI" filter_type = "u"
if chipID in [2, 5, 26, 29]: filter_type = "GV" if chipID in [9, 22]:
if chipID in [3, 4, 27, 28]: filter_type = "GU" filter_type = "r"
if chipID in [12, 13, 18, 19]:
filter_type = "nuv"
if chipID in [8, 23]:
filter_type = "g"
if chipID in [1, 10, 21, 30]:
filter_type = "GI"
if chipID in [2, 5, 26, 29]:
filter_type = "GV"
if chipID in [3, 4, 27, 28]:
filter_type = "GU"
filter_id = filter_type_list.index(filter_type) filter_id = filter_type_list.index(filter_type)
return filter_id, filter_type return filter_id, filter_type
def getChipLim(chipID): def getChipLim(chipID):
""" """
Calculate the edges in pixel for a given CCD chip on the focal plane Calculate the edges in pixel for a given CCD chip on the focal plane
...@@ -173,20 +199,22 @@ def getChipLim(chipID): ...@@ -173,20 +199,22 @@ def getChipLim(chipID):
return nx0-1, nx1-1, ny0-1, ny1-1 return nx0-1, nx1-1, ny0-1, ny1-1
def ccdLayout(xpixTar, ypixTar, figout="ccdLayout.pdf"): def ccdLayout(xpixTar, ypixTar, figout="ccdLayout.pdf"):
fig = plt.figure(figsize=(10.0,8.0)) fig = plt.figure(figsize=(10.0, 8.0))
ax = fig.add_axes([0.1,0.1,0.80,0.80]) ax = fig.add_axes([0.1, 0.1, 0.80, 0.80])
# plot the layout of the ccd distribution # plot the layout of the ccd distribution
for i in range(30): for i in range(30):
ichip = i+1 ichip = i+1
fId, fType = getChipFilter(ichip) fId, fType = getChipFilter(ichip)
ischip = str("0%d"%ichip)[-2:] ischip = str("0%d" % ichip)[-2:]
ix0, ix1, iy0, iy1 = getChipLim(ichip) ix0, ix1, iy0, iy1 = getChipLim(ichip)
ax.plot([ix0,ix1],[iy0,iy0],"k-", linewidth=2.5) ax.plot([ix0, ix1], [iy0, iy0], "k-", linewidth=2.5)
ax.plot([ix0,ix1],[iy1,iy1],"k-", linewidth=2.5) ax.plot([ix0, ix1], [iy1, iy1], "k-", linewidth=2.5)
ax.plot([ix0,ix0],[iy0,iy1],"k-", linewidth=2.5) ax.plot([ix0, ix0], [iy0, iy1], "k-", linewidth=2.5)
ax.plot([ix1,ix1],[iy0,iy1],"k-", linewidth=2.5) ax.plot([ix1, ix1], [iy0, iy1], "k-", linewidth=2.5)
ax.text(ix0+500,iy0+1500,"%s#%s"%(fType, ischip), fontsize=12, color="grey") ax.text(ix0+500, iy0+1500, "%s#%s" %
(fType, ischip), fontsize=12, color="grey")
ax.plot(xpixTar, ypixTar, "r*", ms=12) ax.plot(xpixTar, ypixTar, "r*", ms=12)
ax.set_xlabel("$X\,[\mathrm{pixels}]$", fontsize=20) ax.set_xlabel("$X\,[\mathrm{pixels}]$", fontsize=20)
ax.set_ylabel("$Y\,[\mathrm{pixels}]$", fontsize=20) ax.set_ylabel("$Y\,[\mathrm{pixels}]$", fontsize=20)
...@@ -194,6 +222,7 @@ def ccdLayout(xpixTar, ypixTar, figout="ccdLayout.pdf"): ...@@ -194,6 +222,7 @@ def ccdLayout(xpixTar, ypixTar, figout="ccdLayout.pdf"):
ax.axis('off') ax.axis('off')
plt.savefig(figout) plt.savefig(figout)
def parseArguments(): def parseArguments():
# Create argument parser # Create argument parser
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
...@@ -203,7 +232,7 @@ def parseArguments(): ...@@ -203,7 +232,7 @@ def parseArguments():
parser.add_argument("dec_target", type=float) parser.add_argument("dec_target", type=float)
parser.add_argument("ra_point", type=float) parser.add_argument("ra_point", type=float)
parser.add_argument("dec_point", type=float) parser.add_argument("dec_point", type=float)
# Optional arguments # Optional arguments
parser.add_argument("-image_rot", type=float, default=-113.4333) parser.add_argument("-image_rot", type=float, default=-113.4333)
parser.add_argument("-figout", type=str, default="zTargetOnCCD.pdf") parser.add_argument("-figout", type=str, default="zTargetOnCCD.pdf")
...@@ -213,10 +242,11 @@ def parseArguments(): ...@@ -213,10 +242,11 @@ def parseArguments():
return args return args
if __name__ == "__main__": if __name__ == "__main__":
# Parse the arguments # Parse the arguments
args = parseArguments() args = parseArguments()
# Run function # Run function
focalPlaneInf(args.ra_target, args.dec_target, args.ra_point, args.dec_point, args.image_rot, args.figout) focalPlaneInf(args.ra_target, args.dec_target, args.ra_point,
args.dec_point, args.image_rot, args.figout)
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