Commit 538b21ee authored by Zhang Xin's avatar Zhang Xin
Browse files

Merge branch 'develop' into 'master'

merge develop into master (for release v2.0)

See merge request csst_sim/csst-simulation!13
parents 2953a065 1c871e69
#!/bin/bash #!/bin/bash
#PBS -N SIMS #PBS -N SIMS
#PBS -l nodes=wcl-1:ppn=8+wcl-2:ppn=8+wcl-3:ppn=8+wcl-4:ppn=8+wcl-5:ppn=8+wcl-6:ppn=8 #PBS -l nodes=wcl-1:ppn=16+wcl-2:ppn=16+wcl-3:ppn=16+wcl-4:ppn=16+wcl-5:ppn=16+wcl-6:ppn=16
#PBS -u fangyuedong #PBS -u fangyuedong
###PBS -j oe ###PBS -j oe
cd $PBS_O_WORKDIR cd $PBS_O_WORKDIR
NP=32 NP=96
date date
echo $NP
# mpirun -np $NP python /public/home/fangyuedong/test/CSST/run_sim.py config_NGP.yaml -c /public/home/fangyuedong/test/CSST/config mpirun -np $NP python3 /share/home/fangyuedong/fgs_sim/csst-simulation/run_sim.py \
mpirun -np $NP python3 /share/home/fangyuedong/test_psf_rot/csst-simulation/run_sim.py config_NGP_dev.yaml -c /share/home/fangyuedong/test_psf_rot/csst-simulation/config --config_file config_NGP.yaml \
--catalog NGPCatalog \
-c /share/home/fangyuedong/fgs_sim/csst-simulation/config
#!/bin/bash
#PBS -N SIMS
#PBS -l nodes=wcl-1:ppn=12
###PBS -l nodes=wcl-1:ppn=24+wcl-2:ppn=24+wcl-3:ppn=24+wcl-4:ppn=24+wcl-5:ppn=24+wcl-6:ppn=24
#PBS -u fangyuedong
###PBS -j oe
cd $PBS_O_WORKDIR
NP=40
date
mpirun -np $NP python3 /share/home/fangyuedong/fgs_sim/csst-simulation/run_sim.py \
--config_file config_fgs.yaml \
--catalog FGS_Catalog \
-c /share/home/fangyuedong/fgs_sim/csst-simulation/config
...@@ -5,11 +5,12 @@ import os ...@@ -5,11 +5,12 @@ import os
import yaml import yaml
import shutil import shutil
import datetime import datetime
import importlib
import gc import gc
gc.enable() gc.enable()
def run_sim(Catalog): def run_sim():
""" """
Main method for simulation call. Main method for simulation call.
...@@ -63,7 +64,7 @@ def run_sim(Catalog): ...@@ -63,7 +64,7 @@ def run_sim(Catalog):
# "config['obs_setting']['np_cal']"" is the number of CAL pointings which will be # "config['obs_setting']['np_cal']"" is the number of CAL pointings which will be
# appended to the front. # appended to the front.
# NOTE: the implementation of gerenating time_stamps is temporary. # NOTE: the implementation of gerenating time_stamps is temporary.
pointing_list = generate_pointing_list(config=config, pointing_filename=config['pointing_file'], data_dir=config['pointing_dir']) pointing_list = generate_pointing_list(config=config, pointing_filename=config['obs_setting']['pointing_file'], data_dir=config['obs_setting']['pointing_dir'])
# Make the main output directories # Make the main output directories
run_dir = make_run_dirs(work_dir=config['work_dir'], run_name=config['run_name'], pointing_list=pointing_list) run_dir = make_run_dirs(work_dir=config['work_dir'], run_name=config['run_name'], pointing_list=pointing_list)
...@@ -82,7 +83,8 @@ def run_sim(Catalog): ...@@ -82,7 +83,8 @@ def run_sim(Catalog):
config_out.write("###############################################\n") config_out.write("###############################################\n")
# Initialize the simulation # Initialize the simulation
obs = Observation(config=config, Catalog=Catalog, work_dir=config['work_dir'], data_dir=config['data_dir']) catalog_module = importlib.import_module('Catalog.'+args.catalog)
obs = Observation(config=config, Catalog=catalog_module.Catalog, work_dir=config['work_dir'], data_dir=config['data_dir'])
# Run simulation # Run simulation
obs.runExposure_MPI_PointingList( obs.runExposure_MPI_PointingList(
...@@ -91,14 +93,4 @@ def run_sim(Catalog): ...@@ -91,14 +93,4 @@ def run_sim(Catalog):
chips=config["obs_setting"]["run_chips"]) chips=config["obs_setting"]["run_chips"])
if __name__=='__main__': if __name__=='__main__':
# To run with the example input catalog run_sim()
# from Catalog.Catalog_example import Catalog_example
# run_sim(Catalog=Catalog_example)
# # To run cycle-3 simulation
# from Catalog.C3Catalog import C3Catalog
# run_sim(Catalog=C3Catalog)
# To run calibration field NGP simulation
from Catalog.NGPCatalog import NGPCatalog
run_sim(Catalog=NGPCatalog)
...@@ -26,7 +26,7 @@ extensions = [ ...@@ -26,7 +26,7 @@ extensions = [
setup(name='CSSTSim', setup(name='CSSTSim',
version='1.0.5', version='2.0.0',
packages=find_packages(), packages=find_packages(),
install_requires=[ install_requires=[
'numpy>=1.18.5', 'numpy>=1.18.5',
...@@ -44,13 +44,15 @@ setup(name='CSSTSim', ...@@ -44,13 +44,15 @@ setup(name='CSSTSim',
package_data = { package_data = {
'ObservationSim.Astrometry.lib': ['libshao.so'], 'ObservationSim.Astrometry.lib': ['libshao.so'],
'ObservationSim.MockObject.data': ['*.dat'], 'ObservationSim.MockObject.data': ['*.dat'],
'ObservationSim.Instrument.data': ['*.txt', '*.dat'], 'ObservationSim.Instrument.data': ['*.txt', '*.dat', '*.json'],
'ObservationSim.Instrument.data.field_distortion': ['*.pickle'],
'ObservationSim.Instrument.data.ccd': ['*.txt'], 'ObservationSim.Instrument.data.ccd': ['*.txt'],
'ObservationSim.Instrument.data.filters': ['*.txt', '*.list', '*.dat'], 'ObservationSim.Instrument.data.filters': ['*.txt', '*.list', '*.dat'],
'ObservationSim.Instrument.data.throughputs': ['*.txt', '*.dat'], 'ObservationSim.Instrument.data.throughputs': ['*.txt', '*.dat'],
'ObservationSim.Instrument.data.sls_conf': ['*.conf', '*.fits'], 'ObservationSim.Instrument.data.sls_conf': ['*.conf', '*.fits'],
'ObservationSim.Instrument.data.flatCube': ['*.fits'], 'ObservationSim.Instrument.data.flatCube': ['*.fits'],
'Catalog.data': ['*.fits'], 'Catalog.data': ['*.fits'],
'ObservationSim.Config.Header':['*.header','*.lst'],
}, },
ext_modules = cythonize(extensions), ext_modules = cythonize(extensions),
) )
#!/bin/bash
date
python3 /share/home/fangyuedong/fgs_sim/csst-simulation/run_sim.py \
--config_file config_C6.yaml \
--catalog C6_Catalog \
-c /share/home/fangyuedong/fgs_sim/csst-simulation/config
#!/bin/bash
date
python3 /share/home/fangyuedong/fgs_sim/csst-simulation/run_sim.py \
--config_file config_fgs.yaml \
--catalog FGS_Catalog \
-c /share/home/fangyuedong/fgs_sim/csst-simulation/config
\ No newline at end of file
import unittest import unittest
from ObservationSim.MockObject.SpecDisperser import rotate90, SpecDisperser from ObservationSim.MockObject.SpecDisperser import rotate90, SpecDisperser
from ObservationSim.Config import ConfigDir, ReadConfig, ChipOutput from ObservationSim.Config import ChipOutput, Config
from ObservationSim.Instrument import Telescope, Chip, FilterParam, Filter, FocalPlane from ObservationSim.Instrument import Telescope, Chip, FilterParam, Filter, FocalPlane
from ObservationSim.MockObject import MockObject, Star from ObservationSim.MockObject import MockObject, Star
from ObservationSim.PSF import PSFGauss from ObservationSim.PSF import PSFGauss
...@@ -15,6 +15,36 @@ import matplotlib.pyplot as plt ...@@ -15,6 +15,36 @@ import matplotlib.pyplot as plt
from lmfit.models import LinearModel, GaussianModel from lmfit.models import LinearModel, GaussianModel
from ObservationSim.Config.Header import generateExtensionHeader
import math
import yaml
def getAngle132(x1=0, y1=0, z1=0, x2=0, y2=0, z2=0, x3=0, y3=0, z3=0):
cosValue = 0;
angle = 0;
x11 = x1 - x3;
y11 = y1 - y3;
z11 = z1 - z3;
x22 = x2 - x3;
y22 = y2 - y3;
z22 = z2 - z3;
tt = np.sqrt((x11 * x11 + y11 * y11 + z11 * z11) * (x22 * x22 + y22 * y22 + z22 * z22));
if (tt == 0):
return 0;
cosValue = (x11 * x22 + y11 * y22 + z11 * z22) / tt;
if (cosValue > 1):
cosValue = 1;
if (cosValue < -1):
cosValue = -1;
angle = math.acos(cosValue);
return angle * 360 / (2 * math.pi);
def fit_SingleGauss(xX, yX, contmX, iHa0): def fit_SingleGauss(xX, yX, contmX, iHa0):
background = LinearModel(prefix='line_') background = LinearModel(prefix='line_')
...@@ -25,7 +55,7 @@ def fit_SingleGauss(xX, yX, contmX, iHa0): ...@@ -25,7 +55,7 @@ def fit_SingleGauss(xX, yX, contmX, iHa0):
pars.update(gauss.make_params()) pars.update(gauss.make_params())
pars['g_center'].set(iHa0, min=iHa0 - 3, max=iHa0 + 3) pars['g_center'].set(iHa0, min=iHa0 - 3, max=iHa0 + 3)
pars['g_amplitude'].set(50, min=0) pars['g_amplitude'].set(50, min=0)
pars['g_sigma'].set(12, min=0.01) pars['g_sigma'].set(12, min=0.0001)
mod = gauss + background mod = gauss + background
init = mod.eval(pars, x=xX) init = mod.eval(pars, x=xX)
...@@ -54,7 +84,7 @@ def fit_SingleGauss(xX, yX, contmX, iHa0): ...@@ -54,7 +84,7 @@ def fit_SingleGauss(xX, yX, contmX, iHa0):
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): def produceObj(x,y,chip, ra, dec, pa):
pos_img = galsim.PositionD(chip.bound.xmin + x, chip.bound.ymin + y) pos_img = galsim.PositionD(chip.bound.xmin + x, chip.bound.ymin + y)
param = {} param = {}
...@@ -69,7 +99,22 @@ def produceObj(x,y,chip): ...@@ -69,7 +99,22 @@ def produceObj(x,y,chip):
obj = Star(param) obj = Star(param)
pos_img, offset, local_wcs = obj.getPosImg_Offset_WCS(img=chip.img, chip=chip) header_wcs = generateExtensionHeader(
xlen=chip.npix_x,
ylen=chip.npix_y,
ra=ra,
dec=dec,
pa=pa,
gain=chip.gain,
readout=chip.read_noise,
dark=chip.dark_noise,
saturation=90000,
psize=chip.pix_scale,
row_num=chip.rowID,
col_num=chip.colID,
extName='raw')
pos_img, offset, local_wcs, _ = obj.getPosImg_Offset_WCS(img=chip.img, chip=chip, img_header=header_wcs)
wave = np.arange(2500, 11000.5, 0.5) wave = np.arange(2500, 11000.5, 0.5)
# sedLen = wave.shape[0] # sedLen = wave.shape[0]
flux = pow(wave, -2) * 1e8 flux = pow(wave, -2) * 1e8
...@@ -346,28 +391,37 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -346,28 +391,37 @@ class TestSpecDisperse(unittest.TestCase):
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/"
path_dict = ConfigDir(work_dir=work_dir, data_dir=data_dir) configFn = '/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_C6/csst-simulation/config/config_C6.yaml'
config = ReadConfig(path_dict["config_file"]) normFilterFn = "/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_C6/csst-simulation/Catalog/data/SLOAN_SDSS.g.fits"
norm_star = Table.read(normFilterFn)
filter_param = FilterParam(filter_dir=path_dict["filter_dir"]) with open(configFn, "r") as stream:
focal_plane = FocalPlane(survey_type=config["survey_type"]) try:
chip = Chip(1, ccdEffCurve_dir=path_dict["ccd_dir"], CRdata_dir=path_dict["CRdata_dir"], config = yaml.safe_load(stream)
normalize_dir=path_dict["normalize_dir"], sls_dir=path_dict["sls_dir"], for key, value in config.items():
config=config) print(key + " : " + str(value))
except yaml.YAMLError as exc:
print(exc)
# config = Config.read_config(configFn)
# path_dict = Config.config_dir(config,work_dir=work_dir, data_dir=data_dir)
filter_param = FilterParam()
focal_plane = FocalPlane(survey_type=config["obs_setting"]["survey_type"])
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,
ccd_bandpass=chip.effCurve) ccd_bandpass=chip.effCurve)
tel = Telescope(optEffCurve_path=path_dict["mirror_file"]) tel = Telescope()
psf_model = PSFGauss(chip=chip) psf_model = PSFGauss(chip=chip)
wcs_fp = focal_plane.getTanWCS(config["ra_center"], config["dec_center"], config["image_rot"], chip.pix_scale) 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)
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) 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.drawObj_slitless( obj.drawObj_slitless(
tel=tel, tel=tel,
pos_img=pos_img, pos_img=pos_img,
...@@ -378,9 +432,9 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -378,9 +432,9 @@ class TestSpecDisperse(unittest.TestCase):
g1=0, g1=0,
g2=0, g2=0,
exptime=150, exptime=150,
normFilter=chip.normF_star) normFilter=norm_star)
obj, pos_img = produceObj(3685, 6500, chip) 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,
...@@ -391,9 +445,9 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -391,9 +445,9 @@ class TestSpecDisperse(unittest.TestCase):
g1=0, g1=0,
g2=0, g2=0,
exptime=150, exptime=150,
normFilter=chip.normF_star) normFilter=norm_star)
obj, pos_img = produceObj(5000, 2500, chip) 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,
...@@ -404,7 +458,7 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -404,7 +458,7 @@ class TestSpecDisperse(unittest.TestCase):
g1=0, g1=0,
g2=0, g2=0,
exptime=150, exptime=150,
normFilter=chip.normF_star) normFilter=norm_star)
print('Spec double disperse test') print('Spec double disperse test')
from astropy.io import fits from astropy.io import fits
...@@ -414,11 +468,208 @@ class TestSpecDisperse(unittest.TestCase): ...@@ -414,11 +468,208 @@ class TestSpecDisperse(unittest.TestCase):
# plt.imshow(chip.img.array) # plt.imshow(chip.img.array)
# plt.show() # plt.show()
def test_SLSImage_rotation(self):
from astropy.wcs import WCS
configFn = '/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_C6/csst-simulation/config/config_C6.yaml'
with open(configFn, "r") as stream:
try:
config = yaml.safe_load(stream)
for key, value in config.items():
print(key + " : " + str(value))
except yaml.YAMLError as exc:
print(exc)
chip = Chip(1, config=config)
ra=float(config["obs_setting"]["ra_center"])
dec=float(config["obs_setting"]["dec_center"])
pa=float(config["obs_setting"]["image_rot"])
header_wcs1 = generateExtensionHeader(
xlen=chip.npix_x,
ylen=chip.npix_y,
ra=ra,
dec=dec,
pa=pa,
gain=chip.gain,
readout=chip.read_noise,
dark=chip.dark_noise,
saturation=90000,
psize=chip.pix_scale,
row_num=chip.rowID,
col_num=chip.colID,
extName='raw', center_rot=0)
center = np.array([chip.npix_x / 2, chip.npix_y / 2])
h_wcs1 = WCS(header_wcs1)
x1, y1 = center + [100,0]
sky_1 = h_wcs1.pixel_to_world(x1,y1)
rot_angle = 1
header_wcs2 = generateExtensionHeader(
xlen=chip.npix_x,
ylen=chip.npix_y,
ra=ra,
dec=dec,
pa=pa,
gain=chip.gain,
readout=chip.read_noise,
dark=chip.dark_noise,
saturation=90000,
psize=chip.pix_scale,
row_num=chip.rowID,
col_num=chip.colID,
extName='raw', center_rot=rot_angle)
h_wcs2 = WCS(header_wcs2)
x2, y2 = h_wcs2.world_to_pixel(sky_1)
angle = getAngle132(x1,y1,0,x2,y2,0,center[0],center[1],0)
print(angle)
self.assertTrue(rot_angle - angle < np.abs(0.001))
rot_angle = 10
header_wcs2 = generateExtensionHeader(
xlen=chip.npix_x,
ylen=chip.npix_y,
ra=ra,
dec=dec,
pa=pa,
gain=chip.gain,
readout=chip.read_noise,
dark=chip.dark_noise,
saturation=90000,
psize=chip.pix_scale,
row_num=chip.rowID,
col_num=chip.colID,
extName='raw', center_rot=rot_angle)
h_wcs2 = WCS(header_wcs2)
x2, y2 = h_wcs2.world_to_pixel(sky_1)
angle = getAngle132(x1, y1, 0, x2, y2, 0, center[0], center[1], 0)
print(angle)
self.assertTrue(rot_angle - angle < np.abs(0.001))
rot_angle = 50
header_wcs2 = generateExtensionHeader(
xlen=chip.npix_x,
ylen=chip.npix_y,
ra=ra,
dec=dec,
pa=pa,
gain=chip.gain,
readout=chip.read_noise,
dark=chip.dark_noise,
saturation=90000,
psize=chip.pix_scale,
row_num=chip.rowID,
col_num=chip.colID,
extName='raw', center_rot=rot_angle)
h_wcs2 = WCS(header_wcs2)
x2, y2 = h_wcs2.world_to_pixel(sky_1)
angle = getAngle132(x1, y1, 0, x2, y2, 0, center[0], center[1], 0)
print(angle)
self.assertTrue(rot_angle - angle < np.abs(0.001))
chip = Chip(27, config=config)
ra = float(config["obs_setting"]["ra_center"])
dec = float(config["obs_setting"]["dec_center"])
pa = float(config["obs_setting"]["image_rot"])
header_wcs1 = generateExtensionHeader(
xlen=chip.npix_x,
ylen=chip.npix_y,
ra=ra,
dec=dec,
pa=pa,
gain=chip.gain,
readout=chip.read_noise,
dark=chip.dark_noise,
saturation=90000,
psize=chip.pix_scale,
row_num=chip.rowID,
col_num=chip.colID,
extName='raw', center_rot=0)
center = np.array([chip.npix_x / 2, chip.npix_y / 2])
h_wcs1 = WCS(header_wcs1)
x1, y1 = center + [100, 0]
sky_1 = h_wcs1.pixel_to_world(x1, y1)
rot_angle = 1
header_wcs2 = generateExtensionHeader(
xlen=chip.npix_x,
ylen=chip.npix_y,
ra=ra,
dec=dec,
pa=pa,
gain=chip.gain,
readout=chip.read_noise,
dark=chip.dark_noise,
saturation=90000,
psize=chip.pix_scale,
row_num=chip.rowID,
col_num=chip.colID,
extName='raw', center_rot=rot_angle)
h_wcs2 = WCS(header_wcs2)
x2, y2 = h_wcs2.world_to_pixel(sky_1)
angle = getAngle132(x1, y1, 0, x2, y2, 0, center[0], center[1], 0)
print(angle)
self.assertTrue(rot_angle - angle < np.abs(0.001))
rot_angle = 10
header_wcs2 = generateExtensionHeader(
xlen=chip.npix_x,
ylen=chip.npix_y,
ra=ra,
dec=dec,
pa=pa,
gain=chip.gain,
readout=chip.read_noise,
dark=chip.dark_noise,
saturation=90000,
psize=chip.pix_scale,
row_num=chip.rowID,
col_num=chip.colID,
extName='raw', center_rot=rot_angle)
h_wcs2 = WCS(header_wcs2)
x2, y2 = h_wcs2.world_to_pixel(sky_1)
angle = getAngle132(x1, y1, 0, x2, y2, 0, center[0], center[1], 0)
print(angle)
self.assertTrue(rot_angle - angle < np.abs(0.001))
rot_angle = 50
header_wcs2 = generateExtensionHeader(
xlen=chip.npix_x,
ylen=chip.npix_y,
ra=ra,
dec=dec,
pa=pa,
gain=chip.gain,
readout=chip.read_noise,
dark=chip.dark_noise,
saturation=90000,
psize=chip.pix_scale,
row_num=chip.rowID,
col_num=chip.colID,
extName='raw', center_rot=rot_angle)
h_wcs2 = WCS(header_wcs2)
x2, y2 = h_wcs2.world_to_pixel(sky_1)
angle = getAngle132(x1, y1, 0, x2, y2, 0, center[0], center[1], 0)
print(angle)
self.assertTrue(rot_angle - angle < np.abs(0.001))
if __name__ == '__main__': if __name__ == '__main__':
conff='/data/simudata/CSSOSDataProductsSims/data/CONF/CSST_GI2.conf' conff='/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_C6/csst-simulation/ObservationSim/Instrument/data/sls_conf/CSST_GI2.conf'
throughputf='/data/simudata/CSSOSDataProductsSims/data/CONF/GI.Throughput.1st.fits' throughputf='/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_C6/csst-simulation/ObservationSim/Instrument/data/sls_conf/GI.Throughput.1st.fits'
suit = unittest.TestSuite() suit = unittest.TestSuite()
case1 = TestSpecDisperse('test_Specdistperse1',conff,throughputf) case1 = TestSpecDisperse('test_Specdistperse1',conff,throughputf)
...@@ -429,6 +680,8 @@ if __name__ == '__main__': ...@@ -429,6 +680,8 @@ if __name__ == '__main__':
suit.addTest(case3) suit.addTest(case3)
case4 = TestSpecDisperse('test_double_disperse', conff, throughputf) case4 = TestSpecDisperse('test_double_disperse', conff, throughputf)
suit.addTest(case4) suit.addTest(case4)
case5 = TestSpecDisperse('test_SLSImage_rotation')
suit.addTest(case5)
unittest.TextTestRunner(verbosity=2).run(suit) unittest.TextTestRunner(verbosity=2).run(suit)
# runner = unittest.TextTestRunner() # runner = unittest.TextTestRunner()
......
import json
import os
import shutil
chip_filename = 'chip_definition.json'
# chip_list = {}
# chip_id = "39"
# chip_dict= {
# "chip_name": "FGS3-D1",
# "pix_size": 7.5e-3, # [mm]
# "pix_scale": 0.0555, # [arcsec/pix]
# "npix_x": 11264,
# "npix_y": 7680,
# "x_cen": -273.35, # [mm]
# "y_cen": 211.36, # [mm]
# "rotate_angle": 90. # [deg]
# }
# chip_list[chip_id] = chip_dict
def get_chip_row_col_main_fp(chip_id):
rowID = ((chip_id - 1) % 5) + 1
colID = 6 - ((chip_id - 1) // 5)
return rowID, colID
def get_chip_center_main_fp(chip_id, pixel_size=1e-2):
row, col = get_chip_row_col_main_fp(chip_id)
npix_x = 9216
npix_y = 9232
gx1, gx2 = (534, 1309)
gy = 898
nchip_x = 6
nchip_y = 5
xrem = 2*(col - 1) - (nchip_x - 1)
xcen = (npix_x//2 + gx1//2) * xrem
if chip_id >= 26 or chip_id == 21:
xcen = (npix_x//2 + gx1//2) * xrem - (gx2-gx1)
if chip_id <= 5 or chip_id == 10:
xcen = (npix_x//2 + gx1//2) * xrem + (gx2-gx1)
# ylim of a given CCD chip
yrem = (row - 1) - nchip_y // 2
ycen = (npix_y + gy) * yrem
return xcen * pixel_size, ycen * pixel_size
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"]
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_y = 9232
idx = chip_id_list.index(chip_id)
chip_name = filter_list[idx] + "-" + str(chip_label_list[idx])
xcen, ycen = get_chip_center_main_fp(chip_id, pixel_size)
row, col = get_chip_row_col_main_fp(chip_id)
rotate_angle = 0.
if filter_list[idx] in ['GU', 'GV', 'GI']:
rotate_angle = 1.
if col > 2:
rotate_angle = -1. * rotate_angle
chip_dict = {
"chip_name": chip_name,
"pix_size": 1e-2, # [mm]
"pix_scale": 0.074, # [arcsec/pix]
"npix_x": npix_x,
"npix_y": npix_y,
"x_cen": xcen, # [mm]
"y_cen": ycen, # [mm]
"rotate_angle": rotate_angle, # [deg]
"n_psf_samples": 900,
"dark_exptime": 300,
"flat_exptime": 150,
"readout_time": 40,
"df_strength": 2.3,
"bias_level": 500,
"gain": 1.1,
"full_well": 90000
}
return chip_dict
def set_fgs_chips(filepath):
with open(filepath, "r") as f:
data = json.load(f)
for i in range(12):
chip_id = str(31 + i)
data[chip_id]["dark_exptime"] = 300.
data[chip_id]["falt_exptime"] = 150.
data[chip_id]["readout_time"] = 0.01
data[chip_id]["df_strength"] = 2.3
data[chip_id]["bias_level"] = 2000.
data[chip_id]["gain"] = 1.
data[chip_id]["full_well"] = 90000
with open(filepath, "w") as f:
json.dump(data, f, indent=4)
def add_main_fp(filepath):
for i in range(30):
chip_id = i + 1
chip_dict = create_chip_dict_main_fp(chip_id)
add_dict_to_json(filepath, str(chip_id), chip_dict)
def add_dict_to_json(filepath, key, value):
with open(filepath, 'r') as f:
data = json.load(f)
data[key] = value
with open(filepath, "w") as f:
json.dump(data, f, indent=4)
if __name__=="__main__":
src = "../ObservationSim/Instrument/data/ccd/chip_definition.json"
shutil.copy(src, chip_filename)
add_main_fp(chip_filename)
set_fgs_chips(chip_filename)
\ No newline at end of file
# NAME:
# get_pointing
# PURPOSE:
# Return the pointing of CSST from a given [ra, dec]
# CALLING:
# pointing = findPointingbyChipID(chipID=tchip, ra=tra, dec=tdec)
# INPUTS:
# chipID - chip-# of CSST, int
# ra - Right ascension in decimal degrees, float
# dec- Declination in decimal degrees, float
# OUTPUTS:
# pointing - [ra_center, dec_center, image_rot]
# HISTORY:
# Written by Xin Zhang, 23 Apr. 2023
# Included by csst-simulation, C.W. 25 Apr. 2023
#
#
from tkinter.tix import INTEGER
import astropy.coordinates as coord
from astropy import units as u
from pylab import *
import numpy as np
import galsim
import math
# from numba import jit
class Chip(object):
def __init__(self, chipID):
self.chipID = chipID
self.nchip_x = 6
self.nchip_y = 5
self.npix_tot_x = 59516
self.npix_tot_y = 49752
self.npix_gap_x = (534, 1309)
self.npix_gap_y = 898
self.cen_pix_x = 0
self.cen_pix_y = 0
self.npix_x = 9216
self.npix_y = 9232
self.pix_scale = 0.074
def getTanWCS(self, ra, dec, img_rot, pix_scale = None, xcen=None, ycen=None, logger=None):
""" Get the WCS of the image mosaic using Gnomonic/TAN projection
Parameter:
ra, dec: float
(RA, Dec) of pointing of optical axis
img_rot: galsim Angle object
Rotation of image
pix_scale: float
Pixel size in unit of as/pix
Returns:
WCS of the focal plane
"""
if logger is not None:
logger.info(" Construct the wcs of the entire image mosaic using Gnomonic/TAN projection")
if (xcen == None) or (ycen == None):
xcen = self.cen_pix_x
ycen = self.cen_pix_y
if pix_scale == None:
pix_scale = self.pix_scale
dudx = -np.cos(img_rot.rad) * pix_scale
dudy = -np.sin(img_rot.rad) * pix_scale
dvdx = -np.sin(img_rot.rad) * pix_scale
dvdy = +np.cos(img_rot.rad) * pix_scale
# dudx = +np.sin(img_rot.rad) * pix_scale
# dudy = +np.cos(img_rot.rad) * pix_scale
# dvdx = -np.cos(img_rot.rad) * pix_scale
# dvdy = +np.sin(img_rot.rad) * pix_scale
moscen = galsim.PositionD(x=xcen, y=ycen)
sky_center = galsim.CelestialCoord(ra=ra*galsim.degrees, dec=dec*galsim.degrees)
affine = galsim.AffineTransform(dudx, dudy, dvdx, dvdy, origin=moscen)
WCS = galsim.TanWCS(affine, sky_center, units=galsim.arcsec)
return WCS
def getChipRowCol(self, chipID):
rowID = ((chipID - 1) % 5) + 1
colID = 6 - ((chipID - 1) // 5)
return rowID, colID
def getChipCenter(self):
"""Calculate the edges in pixel for a given CCD chip on the focal plane
NOTE: There are 5*4 CCD chips in the focus plane for photometric observation.
Parameters:
chipID: int
the index of the chip
Returns:
A galsim BoundsD object
"""
chipID = self.chipID
rowID, colID = self.getChipRowCol(chipID)
gx1, gx2 = self.npix_gap_x
gy = self.npix_gap_y
# xlim of a given CCD chip
xrem = 2*(colID - 1) - (self.nchip_x - 1)
xcen = (self.npix_x//2 + gx1//2) * xrem
if chipID >= 26 or chipID == 21:
xcen = (self.npix_x//2 + gx1//2) * xrem - (gx2-gx1)
if chipID <= 5 or chipID == 10:
xcen = (self.npix_x//2 + gx1//2) * xrem + (gx2-gx1)
# nx0 = xcen - self.npix_x//2 + 1
# nx1 = xcen + self.npix_x//2
# ylim of a given CCD chip
yrem = (rowID - 1) - self.nchip_y // 2
ycen = (self.npix_y + gy) * yrem
# ny0 = ycen - self.npix_y//2 + 1
# ny1 = ycen + self.npix_y//2
return galsim.PositionD(xcen, ycen)
def transRaDec2D(ra, dec):
x1 = np.cos(dec / 57.2957795) * np.cos(ra / 57.2957795);
y1 = np.cos(dec / 57.2957795) * np.sin(ra / 57.2957795);
z1 = np.sin(dec / 57.2957795);
return np.array([x1, y1, z1])
def getobsPA(ra, dec):
l1 = np.array([0,0,1])
l2 = transRaDec2D(ra, dec)
polar_ec = coord.SkyCoord(0*u.degree, 90*u.degree,frame='barycentrictrueecliptic')
polar_eq = polar_ec.transform_to('icrs')
# print(polar_eq.ra.value,polar_eq.dec.value)
polar_d = transRaDec2D(polar_eq.ra.value, polar_eq.dec.value)
l1l2cross = np.cross(l2,l1)
pdl2cross = np.cross(l2,polar_d)
angle = math.acos(np.dot(l1l2cross,pdl2cross)/(np.linalg.norm(l1l2cross)*np.linalg.norm(pdl2cross)))
angle = (angle)/math.pi*180
# if (ra>90 and ra< 270):
# angle=-angle
return angle
# @jit()
def getSelectPointingList(center = [60,-40], radius = 2):
points = np.loadtxt('sky.dat')
center = center#ra dec
radius = radius # degree
radii_dec = 1
radii_ra = 1/math.cos(math.pi*center[1]/180)
if radii_ra > 180:
radii_ra = 180
c_eclip = coord.SkyCoord(points[:,2]*u.degree, points[:,1]*u.degree,frame='barycentrictrueecliptic')
c_equtor = c_eclip.transform_to('icrs')
# print(np.min((c_equtor.ra*u.degree).value), np.max((c_equtor.ra*u.degree).value))
# c_equtor_sel = c_equtor
# points_sel = points
ra_range_lo = center[0]-radii_ra
ra_range_hi = center[0]+radii_ra
if ra_range_lo< 0:
ids1 = ((c_equtor.ra*u.degree).value<ra_range_hi) | ((c_equtor.ra*u.degree).value>360+ra_range_lo)
elif ra_range_hi > 360:
ids1 = ((c_equtor.ra*u.degree).value>ra_range_lo) | ((c_equtor.ra*u.degree).value<ra_range_hi-360)
else:
ids1 = ((c_equtor.ra*u.degree).value > ra_range_lo) & ((c_equtor.ra*u.degree).value < ra_range_hi)
dec_range_lo = center[1]-radii_dec
if center[1]-radii_dec < -90:
dec_range_lo = -90
dec_range_hi = center[1]+radii_dec
if center[1]+radii_dec > 90:
dec_range_hi = 90
ids3 = (c_equtor[ids1].dec*u.degree).value > dec_range_lo
ids4 = (c_equtor[ids1][ids3].dec*u.degree).value < dec_range_hi
num = points[ids1][ids3][ids4].shape[0]
p_result = np.zeros([num, 5])
i = 0
for p,p_ in zip(points[ids1][ids3][ids4],c_equtor[ids1][ids3][ids4]):
ra = (p_.ra*u.degree).value
dec = (p_.dec*u.degree).value
# print(ra, dec)
lon = p[2]
lat = p[1]
p_result[i,0] = ra
p_result[i,1] = dec
p_result[i,2] = lon
p_result[i,3] = lat
p_result[i,4] = getobsPA(ra, dec) + 90
i = i + 1
return p_result
def findPointingbyChipID(chipID = 8, ra = 60., dec = -40.):
"""_summary_
Args:
chipID (int, optional): Chip ID.
ra (_type_, optional): Chip center ra.
dec (_type_, optional): Chip center dec.
Returns:
_type_: [ra, dec, rotation angle]
"""
chip_center = [ra, dec]
p_list = getSelectPointingList(center = chip_center)
pchip = Chip(chipID)
p_num = p_list.shape[0]
max_value = 1000000000
min_d = max_value
r_ra = ra
r_dec = dec
r_rot = 0.
for i in np.arange(0,p_num,1):
ra_n = p_list[i,0]
dec_n = p_list[i,1]
rot = p_list[i,4]*galsim.degrees
chip_wcs = pchip.getTanWCS(ra_n, dec_n, rot)
c_center = pchip.getChipCenter()
c_world = chip_wcs.toWorld(c_center)
ra_s = c_world.ra.deg
dec_s = c_world.dec.deg
# print(ra, dec, ra_s, dec_s)
d = (ra_s - ra)*(ra_s - ra) + (dec_s - dec)*(dec_s - dec)
if d < min_d:
min_d = d
r_ra = ra_n
r_dec = dec_n
r_rot = rot.deg
if min_d == max_value:
print("RA:%f,Dec:%f不在指向范围内,请于巡天规划序列比对!!!!!"%(ra, dec))
return [r_ra, r_dec , r_rot]
if __name__ == "__main__":
tchip, tra, tdec = 8, 60., -40.
pointing = findPointingbyChipID(chipID=tchip, ra=tra, dec=tdec)
print("[ra_center, dec_center, image_rot]: ", pointing)
# NAME:
# indexFits_hdf5
# PURPOSE:
# Return a healpix indexed catalog from a set of Fits
# CALLING:
# write_StampsIndex(dir_cat=dir_temp)
# INPUTS:
# dir_cat - the directory of Fits catalog, "<dir_cat>/stampCats/*.fits"
# OUTPUTS:
# <dir_cat>/stampCatsIndex.hdf5
# OPTIONAL:
# test_fits(nfits=100, dir_cat=None) - generate a set of Fits by galsim gaussian
# HISTORY:
# Written by Chengliang Wei, 13 Apr. 2023
# Included by csst-simulation, C.W. 25 Apr. 2023
#
#
import os
import numpy as np
import astropy.io.fits as fitsio
import h5py
import healpy
import galsim
def test_fits(nfits=100, dir_cat=None):
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))
arr = gal.drawImage(nx=64, ny=64, scale=0.074).array
hdu = fitsio.PrimaryHDU()
hdu.data = arr
hdu.header.set('index', ifits)
hdu.header.set('ra', 60.+np.random.uniform(-0.2, 0.2))
hdu.header.set('dec', -40.+np.random.uniform(-0.2, 0.2))
hdu.header.set('mag_g', 22+np.random.uniform(-1, 1))
hdu.header.set('pixScale', 0.074)
fout=dir_cat+"stampCats/testStamp_{:}.fits".format(ifits)
if os.path.exists(fout):
os.remove(fout)
hdu.writeto(fout)
def write_StampsIndex(dir_cat=None, DEBUG=False):
MAXNUMBERINDEX = 10000
NSIDE = 128
fp = h5py.File(dir_cat+'stampCatsIndex.hdf5', 'w')
grp1 = fp.create_group('Stamps')
dataSet_Size = np.zeros(healpy.nside2npix(NSIDE), dtype=np.int64)
fitsList = os.listdir(dir_cat+'stampCats/') #获取fits文件列表
for istamp in range(len(fitsList)):
print(istamp, ': ', fitsList[istamp], end='\r')
hdu=fitsio.open(dir_cat+"stampCats/"+fitsList[istamp])
tra = hdu[0].header['RA']
tdec= hdu[0].header['DEC']
healpixID= healpy.ang2pix(NSIDE, tra, tdec, nest=False, lonlat=True)
if not(str(healpixID) in grp1):
grp2 = grp1.create_group(str(healpixID))
else:
grp2 = grp1[str(healpixID)]
if not('ra' in grp2):
dset_ra = grp2.create_dataset('ra', (0,), dtype='f16' , maxshape=(MAXNUMBERINDEX, ))
dset_dec= grp2.create_dataset('dec', (0,), dtype='f16', maxshape=(MAXNUMBERINDEX, ))
dt = h5py.special_dtype(vlen=str)
dset_fn = grp2.create_dataset('filename', (0,), dtype=dt, maxshape=(MAXNUMBERINDEX, ))
else:
dset_ra = grp2['ra']
dset_dec = grp2['dec']
dset_fn = grp2['filename']
dataSet_Size[healpixID] = dataSet_Size[healpixID]+1
grp2['ra'].resize((dataSet_Size[healpixID],))
grp2['dec'].resize((dataSet_Size[healpixID],))
grp2['filename'].resize((dataSet_Size[healpixID],))
dset_ra[dataSet_Size[healpixID]-1] = tra
dset_dec[dataSet_Size[healpixID]-1]= tdec
dset_fn[dataSet_Size[healpixID]-1]= fitsList[istamp]
fp.close()
if DEBUG:
print('\n')
ff = h5py.File(dir_cat+"stampCatsIndex.hdf5","r")
ss = 0
for kk in ff['Stamps'].keys():
print(kk, ff['Stamps'][kk]['ra'].size)
ss = ss+ff['Stamps'][kk]['ra'].size
print(ss)
if __name__ == '__main__':
dir_temp = "./Catalog_test/"
#test_fits(dir_cat=dir_temp)
write_StampsIndex(dir_cat=dir_temp)
This source diff could not be displayed because it is too large. You can view the blob instead.
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