From 3d2380f0b1fedf1942faba8d180b9e7692e270c6 Mon Sep 17 00:00:00 2001 From: yan Date: Fri, 25 Oct 2024 15:01:45 +0800 Subject: [PATCH] update --- csst_mci_sim/CTI/CTI.py | 68 +- csst_mci_sim/csst_mci_sim.py | 7363 +++++++++-------- csst_mci_sim/earthshine.py | 6 +- .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 187 bytes csst_mci_sim/straylight.py | 2 +- csst_mci_sim/support/MCIinstrumentModel.py | 24 +- .../MCIinstrumentModel.cpython-311.pyc | Bin 1792 -> 0 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 188 -> 0 bytes .../__pycache__/cosmicrays.cpython-311.pyc | Bin 12483 -> 0 bytes .../__pycache__/logger.cpython-311.pyc | Bin 1483 -> 0 bytes .../support/__pycache__/sed.cpython-311.pyc | Bin 11181 -> 0 bytes .../support/__pycache__/shao.cpython-311.pyc | Bin 8274 -> 0 bytes csst_mci_sim/support/cosmicrays.py | 92 +- csst_mci_sim/support/logger.py | 11 +- csst_mci_sim/support/sed.py | 150 +- csst_mci_sim/support/shao.py | 135 +- csst_mci_sim/zodiacal.py | 23 +- tests/test_mci_sim.py | 170 +- tests/test_zodiacal.py | 2 +- 19 files changed, 4455 insertions(+), 3591 deletions(-) create mode 100644 csst_mci_sim/mci_so/__pycache__/__init__.cpython-311.pyc delete mode 100644 csst_mci_sim/support/__pycache__/MCIinstrumentModel.cpython-311.pyc delete mode 100644 csst_mci_sim/support/__pycache__/__init__.cpython-311.pyc delete mode 100644 csst_mci_sim/support/__pycache__/cosmicrays.cpython-311.pyc delete mode 100644 csst_mci_sim/support/__pycache__/logger.cpython-311.pyc delete mode 100644 csst_mci_sim/support/__pycache__/sed.cpython-311.pyc delete mode 100644 csst_mci_sim/support/__pycache__/shao.cpython-311.pyc diff --git a/csst_mci_sim/CTI/CTI.py b/csst_mci_sim/CTI/CTI.py index 3abb3d8..d25aa4b 100644 --- a/csst_mci_sim/CTI/CTI.py +++ b/csst_mci_sim/CTI/CTI.py @@ -15,7 +15,7 @@ parameters in parallel and serial direction. import numpy as np -#CDM03bidir +# CDM03bidir class CDM03bidir(): """ Class to run CDM03 CTI model, class Fortran routine to perform the actual CDM03 calculations. @@ -27,6 +27,7 @@ class CDM03bidir(): :param log: instance to Python logging :type log: logging instance """ + def __init__(self, settings, data, log=None): """ Class constructor. @@ -39,48 +40,50 @@ class CDM03bidir(): :type log: logging instance """ self.data = data - self.values = dict(quads=(0,1,2,3), xsize=2048, ysize=2066, dob=0.0, rdose=8.0e9) + self.values = dict(quads=(0, 1, 2, 3), xsize=2048, + ysize=2066, dob=0.0, rdose=8.0e9) self.values.update(settings) self.log = log self._setupLogger() - #default CDM03 settings + # default CDM03 settings self.params = dict(beta_p=0.6, beta_s=0.6, fwc=200000., vth=1.168e7, vg=6.e-11, t=20.48e-3, sfwc=730000., svg=1.0e-10, st=5.0e-6, parallel=1., serial=0.0) - #update with inputs + # update with inputs self.params.update(self.values) - #read in trap information - trapdata = np.loadtxt(self.values['dir_path']+self.values['paralleltrapfile']) + # read in trap information + trapdata = np.loadtxt( + self.values['dir_path']+self.values['paralleltrapfile']) if trapdata.ndim > 1: self.nt_p = trapdata[:, 0] self.sigma_p = trapdata[:, 1] self.taur_p = trapdata[:, 2] else: - #only one trap species + # only one trap species self.nt_p = [trapdata[0],] self.sigma_p = [trapdata[1],] self.taur_p = [trapdata[2],] - trapdata = np.loadtxt(self.values['dir_path']+self.values['serialtrapfile']) + trapdata = np.loadtxt( + self.values['dir_path']+self.values['serialtrapfile']) if trapdata.ndim > 1: self.nt_s = trapdata[:, 0] self.sigma_s = trapdata[:, 1] self.taur_s = trapdata[:, 2] else: - #only one trap species + # only one trap species self.nt_s = [trapdata[0],] self.sigma_s = [trapdata[1],] self.taur_s = [trapdata[2],] - #scale thibaut's values + # scale thibaut's values if 'thibaut' in self.values['parallelTrapfile']: - self.nt_p /= 0.576 #thibaut's values traps / pixel - self.sigma_p *= 1.e4 #thibaut's values in m**2 + self.nt_p /= 0.576 # thibaut's values traps / pixel + self.sigma_p *= 1.e4 # thibaut's values in m**2 if 'thibaut' in self.values['serialTrapfile']: - self.nt_s *= 0.576 #thibaut's values traps / pixel #should be division? - self.sigma_s *= 1.e4 #thibaut's values in m**2 - + self.nt_s *= 0.576 # thibaut's values traps / pixel #should be division? + self.sigma_s *= 1.e4 # thibaut's values in m**2 def _setupLogger(self): """ @@ -90,7 +93,6 @@ class CDM03bidir(): # if self.log is None: # self.logger = False - def applyRadiationDamage(self, data, iquadrant=0): """ Apply radian damage based on FORTRAN CDM03 model. The method assumes that @@ -127,10 +129,10 @@ class CDM03bidir(): array will be laid out in memory in C-style (row-major order). :return: image that has been run through the CDM03 model - :rtype: ndarray - """"" - #return data - + :rtype: ndarray """"" + + # return data + iflip = iquadrant / 2 jflip = iquadrant % 2 @@ -154,24 +156,22 @@ class CDM03bidir(): self.log.info('jflip=%i' % jflip) ################################################################################# -###modify - #sys.path.append('../so') - +# modify + # sys.path.append('../so') + # from ifs_so.cdm03.cpython-38-x86_64-linux-gnu import cdm03bidir # import cdm03bidir from .mci_so import cdm03bidir - + CTIed = cdm03bidir.cdm03(np.asfortranarray(data), - jflip, iflip, - self.values['dob'], self.values['rdose'], - self.nt_p, self.sigma_p, self.taur_p, - self.nt_s, self.sigma_s, self.taur_s, - params, - [data.shape[0], data.shape[1], len(self.nt_p), len(self.nt_s), len(self.params)]) - - + jflip, iflip, + self.values['dob'], self.values['rdose'], + self.nt_p, self.sigma_p, self.taur_p, + self.nt_s, self.sigma_s, self.taur_s, + params, + [data.shape[0], data.shape[1], len(self.nt_p), len(self.nt_s), len(self.params)]) + return np.asanyarray(CTIed) - + ################################################################################################################# ################################################################################################################# - diff --git a/csst_mci_sim/csst_mci_sim.py b/csst_mci_sim/csst_mci_sim.py index 39c8fe2..19e91b8 100644 --- a/csst_mci_sim/csst_mci_sim.py +++ b/csst_mci_sim/csst_mci_sim.py @@ -1,12 +1,38 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# from scipy.integrate import simps +import math +import sys +import os +from astropy import units as u +from astropy.io import fits +from astropy.table import Table +from tqdm import tqdm +import numpy as np +from astropy.coordinates import get_sun +from astropy.time import Time +from datetime import datetime, timedelta +import pandas as pd +import galsim +import configparser as ConfigParser +from scipy import ndimage +from astropy.coordinates import SkyCoord +from scipy import interpolate +from scipy.signal import fftconvolve +import pandas +import ctypes +import astropy.coordinates as coord +from scipy.interpolate import interp1d +import ipy.spatial as spatial +# import sc +# from matplotlib import pyplot as plt +#from joblib import Parallel, delayed + """ Created on Mon Oct 18 09:38:35 2021 - @author: yan, zhaojun""" - """ The CSST MCI Image Simulator ============================================= @@ -20,12 +46,9 @@ The approximate sequence of events in the simulator is as follows: plate scale and pixel scale, exposure time etc.). #. Read in another file containing charge trap definitions (for CTI modelling). #. Read in a file defining the cosmic rays (trail lengths and cumulative distributions). - - + # + # #. Loop over the number of exposures to co-add and for each object in the object catalog: - - - #. Apply a multiplicative flat-field map to emulate pixel-to-pixel non-uniformity [optional]. #. Add cosmic ray tracks onto the CCD with random positions but known distribution [optional]. @@ -42,8 +65,8 @@ The approximate sequence of events in the simulator is as follows: #. Add a given bias level and discretise the counts (the output is going to be in 16bit unsigned integers). #. Finally the simulated image is converted to a FITS file, a WCS is assigned and the output is saved to the current working directory. - - # add galaxy lensing effect to self.information['lensing'], set this parameter in .config file; update@24.10.16 + # + # add galaxy lensing effect to self.information['lensing'], set this parameter in .config file; update@24.10.16 .. Warning:: The code is still work in progress and new features are being added. The code has been tested, but nevertheless bugs may be lurking in corners, so @@ -51,54 +74,34 @@ The approximate sequence of events in the simulator is as follows: Contact Information: zhaojunyan@shao.ac.cn - -------- +######## +------ """ -import galsim -import pandas as pd -#from scipy.integrate import simps -from datetime import datetime, timedelta -from astropy.time import Time -from astropy.coordinates import get_sun -import numpy as np -from tqdm import tqdm -from astropy.table import Table -from astropy.io import fits -from astropy import units as u -import os, sys, math -import configparser as ConfigParser -#from matplotlib import pyplot as plt -from scipy import ndimage ###################### try: from support import logger as lg from support import cosmicrays from support import shao - from support import sed + from support import sed from support import MCIinstrumentModel from mci_so import cdm03bidir - -except: +except: from .support import logger as lg from .support import cosmicrays from .support import shao - from .support import sed + from .support import sed from .support import MCIinstrumentModel from .mci_so import cdm03bidir #################################################### -#from joblib import Parallel, delayed -from astropy.coordinates import SkyCoord -from scipy import interpolate -from scipy.signal import fftconvolve -import pandas -import ctypes -import astropy.coordinates as coord -from scipy.interpolate import interp1d - ########################### functions ######################### +def get_file_extension(filename): + # 使用os.path.splitext()函数分割文件名和扩展名 + file_name, extension = os.path.splitext(filename) + return extension +########################################################## """ Charge Transfer Inefficiency @@ -114,10 +117,8 @@ parameters in parallel and serial direction. :version: 0.35 """ -import numpy as np - -#CDM03bidir +# CDM03bidir class CDM03bidir(): """ Class to run CDM03 CTI model, class Fortran routine to perform the actual CDM03 calculations. @@ -129,6 +130,7 @@ class CDM03bidir(): :param log: instance to Python logging :type log: logging instance """ + def __init__(self, settings, data, log=None): """ Class constructor. @@ -141,48 +143,50 @@ class CDM03bidir(): :type log: logging instance """ self.data = data - self.values = dict(quads=(0,1,2,3), xsize=2048, ysize=2066, dob=0.0, rdose=8.0e9) + self.values = dict(quads=(0, 1, 2, 3), xsize=2048, + ysize=2066, dob=0.0, rdose=8.0e9) self.values.update(settings) self.log = log self._setupLogger() - #default CDM03 settings + # default CDM03 settings self.params = dict(beta_p=0.6, beta_s=0.6, fwc=200000., vth=1.168e7, vg=6.e-11, t=20.48e-3, sfwc=730000., svg=1.0e-10, st=5.0e-6, parallel=1., serial=0.0) - #update with inputs + # update with inputs self.params.update(self.values) - #read in trap information - trapdata = np.loadtxt(self.values['dir_path']+self.values['paralleltrapfile']) + # read in trap information + trapdata = np.loadtxt( + self.values['dir_path']+self.values['paralleltrapfile']) if trapdata.ndim > 1: self.nt_p = trapdata[:, 0] self.sigma_p = trapdata[:, 1] self.taur_p = trapdata[:, 2] else: - #only one trap species + # only one trap species self.nt_p = [trapdata[0],] self.sigma_p = [trapdata[1],] self.taur_p = [trapdata[2],] - trapdata = np.loadtxt(self.values['dir_path']+self.values['serialtrapfile']) + trapdata = np.loadtxt( + self.values['dir_path']+self.values['serialtrapfile']) if trapdata.ndim > 1: self.nt_s = trapdata[:, 0] self.sigma_s = trapdata[:, 1] self.taur_s = trapdata[:, 2] else: - #only one trap species + # only one trap species self.nt_s = [trapdata[0],] self.sigma_s = [trapdata[1],] self.taur_s = [trapdata[2],] - #scale thibaut's values + # scale thibaut's values if 'thibaut' in self.values['parallelTrapfile']: - self.nt_p /= 0.576 #thibaut's values traps / pixel - self.sigma_p *= 1.e4 #thibaut's values in m**2 + self.nt_p /= 0.576 # thibaut's values traps / pixel + self.sigma_p *= 1.e4 # thibaut's values in m**2 if 'thibaut' in self.values['serialTrapfile']: - self.nt_s *= 0.576 #thibaut's values traps / pixel #should be division? - self.sigma_s *= 1.e4 #thibaut's values in m**2 - + self.nt_s *= 0.576 # thibaut's values traps / pixel #should be division? + self.sigma_s *= 1.e4 # thibaut's values in m**2 def _setupLogger(self): """ @@ -192,7 +196,6 @@ class CDM03bidir(): # if self.log is None: # self.logger = False - def applyRadiationDamage(self, data, iquadrant=0): """ Apply radian damage based on FORTRAN CDM03 model. The method assumes that @@ -229,10 +232,10 @@ class CDM03bidir(): array will be laid out in memory in C-style (row-major order). :return: image that has been run through the CDM03 model - :rtype: ndarray - """"" - #return data - + :rtype: ndarray """"" + + # return data + iflip = iquadrant / 2 jflip = iquadrant % 2 @@ -257,18 +260,16 @@ class CDM03bidir(): ################################################################################# - CTIed = cdm03bidir.cdm03(np.asfortranarray(data), - jflip, iflip, - self.values['dob'], self.values['rdose'], - self.nt_p, self.sigma_p, self.taur_p, - self.nt_s, self.sigma_s, self.taur_s, - params, - [data.shape[0], data.shape[1], len(self.nt_p), len(self.nt_s), len(self.params)]) - - + jflip, iflip, + self.values['dob'], self.values['rdose'], + self.nt_p, self.sigma_p, self.taur_p, + self.nt_s, self.sigma_s, self.taur_s, + params, + [data.shape[0], data.shape[1], len(self.nt_p), len(self.nt_s), len(self.params)]) + return np.asanyarray(CTIed) - + ################################################################################################################# ################################################################################################################# @@ -282,7 +283,9 @@ def transRaDec2D(ra, dec): ############################################################################### ################################################################ -def ill2flux(E,path): + + +def ill2flux(E, path): # use template from sky_bkg (background_spec_hst.dat) filename = path+'MCI_inputData/refs/background_spec_hst.dat' @@ -313,15 +316,18 @@ def ill2flux(E,path): ############################################################## + def earth_angle(time_jd, x_sat, y_sat, z_sat, ra_obj, dec_obj): ra_sat = np.arctan2(y_sat, x_sat) / np.pi * 180 dec_sat = np.arctan2(z_sat, np.sqrt(x_sat**2+y_sat**2)) / np.pi * 180 - radec_sat = SkyCoord(ra=ra_sat*u.degree, dec=dec_sat*u.degree, frame='gcrs') + radec_sat = SkyCoord(ra=ra_sat*u.degree, + dec=dec_sat*u.degree, frame='gcrs') lb_sat = radec_sat.transform_to('geocentrictrueecliptic') # get the obj location - radec_obj = SkyCoord(ra=ra_obj*u.degree, dec=dec_obj*u.degree, frame='gcrs') + radec_obj = SkyCoord(ra=ra_obj*u.degree, + dec=dec_obj*u.degree, frame='gcrs') lb_obj = radec_obj.transform_to('geocentrictrueecliptic') # calculate the angle between sub-satellite point and the earth side @@ -338,6 +344,7 @@ def earth_angle(time_jd, x_sat, y_sat, z_sat, ra_obj, dec_obj): return angle ####################################### + def CCDnonLinearityModel(data, beta=6e-7): """ @@ -349,50 +356,58 @@ def CCDnonLinearityModel(data, beta=6e-7): :rtype: float or ndarray """ out = data-beta*data**2 - + return out -#############################################################33333 +# 33333 + class StrayLight(object): - def __init__(self, path, jtime = 2460843., sat = np.array([0,0,0]), radec = np.array([0,0])): + def __init__(self, path, jtime=2460843., sat=np.array([0, 0, 0]), radec=np.array([0, 0])): self.path = path self.jtime = jtime self.sat = sat - self.equator = coord.SkyCoord(radec[0]*u.degree, radec[1]*u.degree,frame='icrs') + self.equator = coord.SkyCoord( + radec[0]*u.degree, radec[1]*u.degree, frame='icrs') self.ecliptic = self.equator.transform_to('barycentrictrueecliptic') self.pointing = transRaDec2D(radec[0], radec[1]) - self.slcdll = ctypes.CDLL(self.path+'MCI_inputData/refs/libstraylight.so') #dylib + self.slcdll = ctypes.CDLL( + self.path+'MCI_inputData/refs/libstraylight.so') # dylib self.slcdll.Calculate.argtypes = [ctypes.c_double, ctypes.POINTER(ctypes.c_double), - ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), - ctypes.POINTER(ctypes.c_double), ctypes.c_char_p] - - self.slcdll.PointSource.argtypes = [ctypes.c_double ,ctypes.POINTER(ctypes.c_double), - ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double), - ctypes.POINTER(ctypes.c_double), ctypes.c_char_p] - - self.slcdll.EarthShine.argtypes = [ctypes.c_double ,ctypes.POINTER(ctypes.c_double), - ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), - ctypes.POINTER(ctypes.c_double)] - - self.slcdll.Zodiacal.argtypes = [ctypes.c_double ,ctypes.POINTER(ctypes.c_double), - ctypes.POINTER(ctypes.c_double)] + ctypes.POINTER(ctypes.c_double), ctypes.POINTER( + ctypes.c_double), + ctypes.POINTER(ctypes.c_double), ctypes.c_char_p] + + self.slcdll.PointSource.argtypes = [ctypes.c_double, ctypes.POINTER(ctypes.c_double), + ctypes.POINTER(ctypes.c_double), ctypes.POINTER( + ctypes.c_double), + ctypes.POINTER(ctypes.c_double), ctypes.c_char_p] + + self.slcdll.EarthShine.argtypes = [ctypes.c_double, ctypes.POINTER(ctypes.c_double), + ctypes.POINTER(ctypes.c_double), ctypes.POINTER( + ctypes.c_double), + ctypes.POINTER(ctypes.c_double)] + + self.slcdll.Zodiacal.argtypes = [ctypes.c_double, ctypes.POINTER(ctypes.c_double), + ctypes.POINTER(ctypes.c_double)] self.slcdll.ComposeY.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), - ctypes.POINTER(ctypes.c_double)] - self.slcdll.Init.argtypes=[ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p] + ctypes.POINTER(ctypes.c_double)] + self.slcdll.Init.argtypes = [ + ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p] self.deFn = self.path+"MCI_inputData/refs/DE405" self.PSTFn = self.path+"MCI_inputData/refs/PST" self.RFn = self.path+"MCI_inputData/refs/R" - self.ZolFn =self.path+"MCI_inputData/refs/Zodiacal" + self.ZolFn = self.path+"MCI_inputData/refs/Zodiacal" self.brightStarTabFn = self.path+"MCI_inputData/refs/BrightGaia_with_csst_mag" - self.slcdll.Init(str.encode(self.deFn),str.encode(self.PSTFn),str.encode(self.RFn),str.encode(self.ZolFn)) - + self.slcdll.Init(str.encode(self.deFn), str.encode( + self.PSTFn), str.encode(self.RFn), str.encode(self.ZolFn)) def caculateStarLightFilter(self, filter='i'): - - filterIndex = {'nuv':0,'u':1,'g':2,'r':3, 'i':4, 'z':5,'y':6} + + filterIndex = {'nuv': 0, 'u': 1, 'g': 2, + 'r': 3, 'i': 4, 'z': 5, 'y': 6} sat = (ctypes.c_double*3)() sat[:] = self.sat @@ -404,9 +419,11 @@ class StrayLight(object): self.slcdll.ComposeY(ob, py1, py2) star_e1 = (ctypes.c_double*7)() - self.slcdll.PointSource(self.jtime, sat, ob, py1, star_e1, str.encode(self.brightStarTabFn)) + self.slcdll.PointSource(self.jtime, sat, ob, py1, + star_e1, str.encode(self.brightStarTabFn)) star_e2 = (ctypes.c_double*7)() - self.slcdll.PointSource(self.jtime, sat, ob, py2, star_e2, str.encode(self.brightStarTabFn)) + self.slcdll.PointSource(self.jtime, sat, ob, py2, + star_e2, str.encode(self.brightStarTabFn)) band_star_e1 = star_e1[:][filterIndex[filter]] band_star_e2 = star_e2[:][filterIndex[filter]] @@ -414,8 +431,9 @@ class StrayLight(object): return max(band_star_e1, band_star_e2) def caculateEarthShineFilter(self, filter='i'): - - filterIndex = {'nuv':0,'u':1,'g':2,'r':3, 'i':4, 'z':5,'y':6} + + filterIndex = {'nuv': 0, 'u': 1, 'g': 2, + 'r': 3, 'i': 4, 'z': 5, 'y': 6} sat = (ctypes.c_double*3)() sat[:] = self.sat ob = (ctypes.c_double*3)() @@ -426,8 +444,9 @@ class StrayLight(object): self.slcdll.ComposeY(ob, py1, py2) earth_e1 = (ctypes.c_double*7)() - self.slcdll.EarthShine(self.jtime, sat, ob, py1, earth_e1) # e[7]代表7个波段的照度 - + self.slcdll.EarthShine(self.jtime, sat, ob, py1, + earth_e1) # e[7]代表7个波段的照度 + earth_e2 = (ctypes.c_double*7)() self.slcdll.EarthShine(self.jtime, sat, ob, py2, earth_e2) @@ -435,78 +454,89 @@ class StrayLight(object): band_earth_e2 = earth_e2[:][filterIndex[filter]] return max(band_earth_e1, band_earth_e2) - -############################################################################### + ############################################################################### ############################################################################### +############################################################################### + def make_c_coor(fov, step): """ Draw the mesh grids for a fov * fov box with given step . """ - - nc=int(fov/step) - - bs=fov + + nc = int(fov/step) + + bs = fov ds = bs / nc xx01 = np.linspace(-bs / 2.0, bs / 2.0 - ds, nc) + 0.5 * ds xx02 = np.linspace(-bs / 2.0, bs / 2.0 - ds, nc) + 0.5 * ds xg2, xg1 = np.meshgrid(xx01, xx02) return xg1, xg2 -############################################################################## +############################################################################## ############################################################################## - -#datetime to mjd + +# datetime to mjd + + def time2mjd(dateT): - t0=datetime(1858,11,17,0,0,0,0) # - mjd=(dateT-t0).days - mjd_s=dateT.hour*3600.0+dateT.minute*60.0+dateT.second+dateT.microsecond/1000000.0 + t0 = datetime(1858, 11, 17, 0, 0, 0, 0) # + mjd = (dateT-t0).days + mjd_s = dateT.hour*3600.0+dateT.minute*60.0 + \ + dateT.second+dateT.microsecond/1000000.0 return mjd+mjd_s/86400.0 + def time2jd(dateT): - t0=datetime(1858,11,17,0,0,0,0) # - mjd=(dateT-t0).days - mjd_s=dateT.hour*3600.0+dateT.minute*60.0+dateT.second+dateT.microsecond/1000000.0 + t0 = datetime(1858, 11, 17, 0, 0, 0, 0) # + mjd = (dateT-t0).days + mjd_s = dateT.hour*3600.0+dateT.minute*60.0 + \ + dateT.second+dateT.microsecond/1000000.0 return mjd+mjd_s/86400.0++2400000.5 - -#mjd to datetime + +# mjd to datetime + + def mjd2time(mjd): - t0=datetime(1858,11,17,0,0,0,0) # + t0 = datetime(1858, 11, 17, 0, 0, 0, 0) return t0+timedelta(days=mjd) + def jd2time(jd): - mjd=jd2mjd(jd) + mjd = jd2mjd(jd) return mjd2time(mjd) - -#mjd to jd + +# mjd to jd # def mjd2jd(mjd): # return mjd+2400000.5 + def jd2mjd(jd): return jd-2400000.5 + def dt2hmd(dt): - ## dt is datetime - hour=dt.hour - minute=dt.minute - second=dt.second - if hour<10: - str_h='0'+str(hour) + ## dt is datetime + hour = dt.hour + minute = dt.minute + second = dt.second + if hour < 10: + str_h = '0'+str(hour) else: - str_h=str(hour) - - if minute<10: - str_m='0'+str(minute) + str_h = str(hour) + + if minute < 10: + str_m = '0'+str(minute) else: - str_m=str(minute) - - if second<10: - str_d='0'+str(second+dt.microsecond*1e-6) + str_m = str(minute) + + if second < 10: + str_d = '0'+str(second+dt.microsecond*1e-6) else: - str_d=str(second+dt.microsecond*1e-6) - + str_d = str(second+dt.microsecond*1e-6) + return str_h+':'+str_m+':'+str_d ############################################################################### @@ -515,75 +545,82 @@ def dt2hmd(dt): def deg2HMS(ra0, dec0): '''convert deg to ra's HMS and dec's DMS''' c = SkyCoord(ra=ra0*u.degree, dec=dec0*u.degree) - ss=c.to_string('hmsdms') - - ## print(ss) - - for k in range(5,len(ss)-1): - - if ss[k]=='s': - s_idx=k - - if ss[k]=='d': - d_idx=k - - if ss[k]=='m': - m_idx=k - - if c.ra.hms.s<10 and c.ra.hms.s>0.1: - temp=str(c.ra.hms.s) - ra_ss='0'+temp[:3] - if c.ra.hms.s>10: - temp=str(c.ra.hms.s) - ra_ss=temp[:4] - - if c.ra.hms.s<0.1: - temp=str(c.ra.hms.s) - ra_ss='00.0' - - dms_d=ss[s_idx+2:d_idx] - dms_m=ss[d_idx+1:m_idx] - dms_s=ss[m_idx+1:m_idx+3] - - hhmmss=ss[0:2]+ss[3:5]+ra_ss + ss = c.to_string('hmsdms') + + # print(ss) + + for k in range(5, len(ss)-1): + + if ss[k] == 's': + s_idx = k + + if ss[k] == 'd': + d_idx = k + + if ss[k] == 'm': + m_idx = k + + if c.ra.hms.s < 10 and c.ra.hms.s > 0.1: + temp = str(c.ra.hms.s) + ra_ss = '0'+temp[:3] + if c.ra.hms.s > 10: + temp = str(c.ra.hms.s) + ra_ss = temp[:4] + + if c.ra.hms.s < 0.1: + temp = str(c.ra.hms.s) + ra_ss = '00.0' + + dms_d = ss[s_idx+2:d_idx] + dms_m = ss[d_idx+1:m_idx] + dms_s = ss[m_idx+1:m_idx+3] + + hhmmss = ss[0:2]+ss[3:5]+ra_ss return hhmmss+dms_d+dms_m+dms_s ############################################################################### ############################################################################### ############################################################################# -#### distortion function +# distortion function -def distortField(ra, dec, ch): - ###% ra ,dec are the idea position in arcsec , and the center position is ra=0, dec=0 +def distortField(ra, dec, ch): + # % ra ,dec are the idea position in arcsec , and the center position is ra=0, dec=0 '''MCI geometry distortion effect in channel G R and I''' - distortA=dict() - - distortB=dict() - - distortA['g']=np.array([0.000586224851462036,0.999778507355332,-0.000377391397200834,-4.40403573019393e-06,0.000147444528630966,-1.93281825050268e-06,5.73520238714447e-07,-1.05194725549731e-08,7.55124671251098e-07,-3.85623216175251e-09,-1.36254798567168e-11,1.36983654024573e-09,-4.53104347730230e-11,1.50641840169747e-09,-1.05226890727366e-11,1.06471556810228e-12,-1.42299485385165e-16,5.90008722878028e-12,2.36749977009538e-17,4.11061448730916e-12,3.39287277469805e-17]) - distortB['g']=np.array([1.00113878750680,-0.000495107770623867,0.999162436209357,9.67138672907941e-05,-3.88808001621361e-06,0.000267940195644359,-3.03504629416955e-09,7.59508802931395e-07,-1.13952684052500e-08,9.58672893217047e-07,2.96397490595616e-10,-3.01506961685930e-11,2.22570315950441e-09,-4.26077028191289e-11,2.07336026666512e-09,1.71450079597168e-16,2.94455108664049e-12,8.18246797239659e-17,8.32235684990184e-12,1.05203957047210e-17,5.58541337682320e-12]) - - distortA['r']=np.array([0.000530712822898294,0.999814397089242,-0.000366783811357609,-1.08650906916023e-05,0.000146500108063480,-4.48994291741769e-06,5.66992328511032e-07,-2.10826363791224e-08,7.51050898843171e-07,-7.74459106063614e-09,-5.78712436084704e-11,1.36389366137393e-09,-9.50057131576629e-11,1.49666815592076e-09,-2.16074939825761e-11,2.07124539578673e-12,-1.32787329448528e-13,5.78542850850562e-12,-5.82328830750271e-14,4.04881815088026e-12,2.46095156355282e-15]) - distortB['r']=np.array([1.00110972320988,-0.000483253233767592,0.999181377618578,9.60316928622784e-05,-9.06574382424422e-06,0.000266147076486786,-6.64513480754565e-09,7.53794491639207e-07,-2.25340150955077e-08,9.53032549996219e-07,2.93844965469408e-10,-6.80521155195455e-11,2.21272371816576e-09,-9.13097728847483e-11,2.06225316601308e-09,9.41096324034730e-14,3.00253083795091e-12,-1.40935245750903e-13,8.27122551593984e-12,-2.41500808188601e-13,5.52074803508046e-12]) - - distortA['i']=np.array([0.000532645905256854,0.999813271238129,-0.000366606839338804,-1.06782246147986e-05,0.000146529811926289,-4.54488847969004e-06,5.68028930846942e-07,-2.11055358580630e-08,7.51187628288423e-07,-7.93885390157909e-09,-5.63104333653064e-11,1.36559362569725e-09,-9.64353839395137e-11,1.50231201562648e-09,-2.04159956020294e-11,1.91408535007684e-12,-7.46369323634455e-14,5.86071470639700e-12,-1.65328163262914e-13,4.07648238374705e-12,3.40880674871652e-14]) - distortB['i']=np.array([1.00111276400037,-0.000484310769918440,0.999180286636823,9.61240720951134e-05,-8.76526511019577e-06,0.000266192433565878,-6.59462433108999e-09,7.54391611102465e-07,-2.30957980169170e-08,9.53612393886641e-07,2.95558631849358e-10,-7.08307092409029e-11,2.21952307845185e-09,-9.03816603147003e-11,2.06450141393973e-09,-3.77836686311826e-14,3.13358046393416e-12,-5.20417845240954e-14,8.24487152802918e-12,-1.17846469609206e-13,5.35830020655191e-12]) - - x=ra/0.05*10/1000 # convert ra in arcsec to mm - - y=dec/0.05*10/1000 # convert ra in arcsec to mm - - dd=np.array([1, x, y, x*x, x*y, y*y, x**3, x**2*y, x*y**2, y**3, x**4, x**3*y, x**2*y**2, x*y**3, y**4, x**5, x**4*y, x**3*y**2, x**2*y**3 , x*y**4, y**5]) - - xc= np.dot(distortA[ch],dd) - yc= np.dot(distortB[ch],dd) - - distortRa =xc*1000/10*0.05-0.00265 - - distortDec=yc*1000/10*0.05-5.0055 - + distortA = dict() + + distortB = dict() + + distortA['g'] = np.array([0.000586224851462036, 0.999778507355332, -0.000377391397200834, -4.40403573019393e-06, 0.000147444528630966, -1.93281825050268e-06, 5.73520238714447e-07, -1.05194725549731e-08, 7.55124671251098e-07, -3.85623216175251e-09, - + 1.36254798567168e-11, 1.36983654024573e-09, -4.53104347730230e-11, 1.50641840169747e-09, -1.05226890727366e-11, 1.06471556810228e-12, -1.42299485385165e-16, 5.90008722878028e-12, 2.36749977009538e-17, 4.11061448730916e-12, 3.39287277469805e-17]) + distortB['g'] = np.array([1.00113878750680, -0.000495107770623867, 0.999162436209357, 9.67138672907941e-05, -3.88808001621361e-06, 0.000267940195644359, -3.03504629416955e-09, 7.59508802931395e-07, -1.13952684052500e-08, 9.58672893217047e-07, + 2.96397490595616e-10, -3.01506961685930e-11, 2.22570315950441e-09, -4.26077028191289e-11, 2.07336026666512e-09, 1.71450079597168e-16, 2.94455108664049e-12, 8.18246797239659e-17, 8.32235684990184e-12, 1.05203957047210e-17, 5.58541337682320e-12]) + + distortA['r'] = np.array([0.000530712822898294, 0.999814397089242, -0.000366783811357609, -1.08650906916023e-05, 0.000146500108063480, -4.48994291741769e-06, 5.66992328511032e-07, -2.10826363791224e-08, 7.51050898843171e-07, -7.74459106063614e-09, - + 5.78712436084704e-11, 1.36389366137393e-09, -9.50057131576629e-11, 1.49666815592076e-09, -2.16074939825761e-11, 2.07124539578673e-12, -1.32787329448528e-13, 5.78542850850562e-12, -5.82328830750271e-14, 4.04881815088026e-12, 2.46095156355282e-15]) + distortB['r'] = np.array([1.00110972320988, -0.000483253233767592, 0.999181377618578, 9.60316928622784e-05, -9.06574382424422e-06, 0.000266147076486786, -6.64513480754565e-09, 7.53794491639207e-07, -2.25340150955077e-08, 9.53032549996219e-07, + 2.93844965469408e-10, -6.80521155195455e-11, 2.21272371816576e-09, -9.13097728847483e-11, 2.06225316601308e-09, 9.41096324034730e-14, 3.00253083795091e-12, -1.40935245750903e-13, 8.27122551593984e-12, -2.41500808188601e-13, 5.52074803508046e-12]) + + distortA['i'] = np.array([0.000532645905256854, 0.999813271238129, -0.000366606839338804, -1.06782246147986e-05, 0.000146529811926289, -4.54488847969004e-06, 5.68028930846942e-07, -2.11055358580630e-08, 7.51187628288423e-07, -7.93885390157909e-09, - + 5.63104333653064e-11, 1.36559362569725e-09, -9.64353839395137e-11, 1.50231201562648e-09, -2.04159956020294e-11, 1.91408535007684e-12, -7.46369323634455e-14, 5.86071470639700e-12, -1.65328163262914e-13, 4.07648238374705e-12, 3.40880674871652e-14]) + distortB['i'] = np.array([1.00111276400037, -0.000484310769918440, 0.999180286636823, 9.61240720951134e-05, -8.76526511019577e-06, 0.000266192433565878, -6.59462433108999e-09, 7.54391611102465e-07, -2.30957980169170e-08, 9.53612393886641e-07, + 2.95558631849358e-10, -7.08307092409029e-11, 2.21952307845185e-09, -9.03816603147003e-11, 2.06450141393973e-09, -3.77836686311826e-14, 3.13358046393416e-12, -5.20417845240954e-14, 8.24487152802918e-12, -1.17846469609206e-13, 5.35830020655191e-12]) + + x = ra/0.05*10/1000 # convert ra in arcsec to mm + + y = dec/0.05*10/1000 # convert ra in arcsec to mm + + dd = np.array([1, x, y, x*x, x*y, y*y, x**3, x**2*y, x*y**2, y**3, x**4, x**3*y, + x**2*y**2, x*y**3, y**4, x**5, x**4*y, x**3*y**2, x**2*y**3, x*y**4, y**5]) + + xc = np.dot(distortA[ch], dd) + yc = np.dot(distortB[ch], dd) + + distortRa = xc*1000/10*0.05-0.00265 + + distortDec = yc*1000/10*0.05-5.0055 + return distortRa, distortDec ##################################################################################### @@ -620,7 +657,7 @@ def distortField(ra, dec, ch): # ------- # pixel_position:list with two np.array # such as [array([124.16937605, 99. , 99. ]), -# array([ 97.52378661, 99. , 100.50014483])] +# array([ 97.52378661, 99. , 100.50014483])] # """ # theta_r = rotsky / 180 * np.pi # w = WCS(naxis=2) @@ -640,24 +677,27 @@ def distortField(ra, dec, ch): ############################################################################### + def cal_pos(center_ra, center_dec, rotTel, rotSky, sRa, sDec): -# ''' center_ra: telescope pointing in ra direction, unit: degree -# center_dec: telescope pointing in dec direction, unit: degree -# rotTel: telescope totation in degree -# rotSky: telescope rotation in degree -# sRa: source ra in arcsec -# sDec: source dec in arcsec + # ''' center_ra: telescope pointing in ra direction, unit: degree + # center_dec: telescope pointing in dec direction, unit: degree + # rotTel: telescope totation in degree + # rotSky: telescope rotation in degree + # sRa: source ra in arcsec + # sDec: source dec in arcsec - boresight = galsim.CelestialCoord(ra=-center_ra*galsim.degrees, dec=center_dec*galsim.degrees) + boresight = galsim.CelestialCoord( + ra=-center_ra*galsim.degrees, dec=center_dec*galsim.degrees) - q = rotTel - rotSky + q = rotTel - rotSky cq, sq = np.cos(q), np.sin(q) - jac = [cq, -sq, sq, cq] - affine = galsim.AffineTransform(*jac) - wcs = galsim.TanWCS(affine, boresight, units=galsim.arcsec) - objCoord = galsim.CelestialCoord(ra =-sRa*galsim.arcsec, dec=sDec*galsim.arcsec) - field_pos = wcs.toImage(objCoord) - return -field_pos.x, field_pos.y ## return the field position + jac = [cq, -sq, sq, cq] + affine = galsim.AffineTransform(*jac) + wcs = galsim.TanWCS(affine, boresight, units=galsim.arcsec) + objCoord = galsim.CelestialCoord( + ra=-sRa*galsim.arcsec, dec=sDec*galsim.arcsec) + field_pos = wcs.toImage(objCoord) + return -field_pos.x, field_pos.y # return the field position ##################################################################################### @@ -676,14 +716,15 @@ def cal_pos(center_ra, center_dec, rotTel, rotSky, sRa, sDec): # shape=np.zeros(2,dtype=int) # shape[0]=int(size[0]/sample) # shape[1]=int(size[1]/sample) - + # sh = shape[0], a.shape[0] // shape[0], shape[1], a.shape[1] // shape[1] - + # return a.reshape(sh).sum(-1).sum(1) ##################################################################### ######################################################### + def centroid(data): ''' calculate the centroid of the input two-dimentional image data @@ -700,10 +741,10 @@ def centroid(data): ''' ### from scipy import ndimage - cy,cx=ndimage.center_of_mass(data) + cy, cx = ndimage.center_of_mass(data) return cx, cy -############################################################################### +############################################################################### ############################################################################### @@ -712,9 +753,9 @@ def centroid(data): PSF interpolation for MCI_sim ''' -import scipy.spatial as spatial ###find neighbors-KDtree ### + def findNeighbors(tx, ty, px, py, dn=5): """ find nearest neighbors by 2D-KDTree @@ -732,12 +773,14 @@ def findNeighbors(tx, ty, px, py, dn=5): datax = px datay = py tree = spatial.KDTree(list(zip(datax.ravel(), datay.ravel()))) - indexq=[] + indexq = [] dist, indexq = tree.query([tx, ty], dn) return indexq ############################################################################### ###PSF-IDW### + + def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, dn=5, IDWindex=3, OnlyNeighbors=True): """ psf interpolation by IDW @@ -754,25 +797,26 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, dn=5, IDWindex=3, OnlyNeighbo """ minimum_psf_weight = 1e-8 - ref_col = px ### target position in x - ref_row = py ### target position in y + ref_col = px # target position in x + ref_row = py # target position in y + + ngy, ngx = PSFMat[:, :, 0, 0].shape # PSF data size - ngy, ngx = PSFMat[:, :, 0, 0].shape ### PSF data size - #################################### ####### my code ###### psfWeight = np.zeros([dn]) if OnlyNeighbors == True: - + neigh = findNeighbors(px, py, cen_col, cen_row, dn) - + ####################################################################### for ipsf in range(len(neigh)): - idx=neigh[ipsf] - dist = np.sqrt((ref_col - cen_col[idx])**2 + (ref_row - cen_row[idx])**2) - + idx = neigh[ipsf] + dist = np.sqrt((ref_col - cen_col[idx]) + ** 2 + (ref_row - cen_row[idx])**2) + if IDWindex == 1: psfWeight[ipsf] = dist if IDWindex == 2: @@ -783,37 +827,37 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, dn=5, IDWindex=3, OnlyNeighbo psfWeight[ipsf] = dist**4 if IDWindex == 5: psfWeight[ipsf] = dist**5 - + psfWeight[ipsf] = max(psfWeight[ipsf], minimum_psf_weight) psfWeight[ipsf] = 1./psfWeight[ipsf] - - ##################################3 - + + # 3 + psfWeight /= np.sum(psfWeight) - psfMaker = np.zeros([ngy, ngx, 7 ], dtype=np.float32) - + psfMaker = np.zeros([ngy, ngx, 7], dtype=np.float32) + ######################################################### for waven in range(7): - + for ipsf in range(len(neigh)): - - idx=neigh[ipsf] - - iPSFMat = PSFMat[:, :, waven,idx].copy() - + + idx = neigh[ipsf] + + iPSFMat = PSFMat[:, :, waven, idx].copy() + ipsfWeight = psfWeight[ipsf] - + psfMaker[:, :, waven] += iPSFMat * ipsfWeight - + psfMaker[:, :, waven] /= np.nansum(psfMaker[:, :, waven]) - - + return psfMaker ############################################################################### -############################################################################### ############################################################################### +############################################################################### + class MCIsimulator(): """ @@ -825,7 +869,7 @@ class MCIsimulator(): self.image_g g channel self.image_r r channel self.image_i i channel - + :param opts: OptionParser instance :type opts: OptionParser instance @@ -839,13 +883,13 @@ class MCIsimulator(): :type opts: OptionParser instance """ self.configfile = configfile - self.section = 'TEST' #####simulation section; + self.section = 'TEST' # simulation section; self.information = MCIinstrumentModel.MCIinformation() - - #update settings with defaults + + # update settings with defaults self.information.update(dict(quadrant=int(0), ccdx=int(0), - ccdy=int(0), + ccdy=int(0), ccdxgap=1.643, ccdygap=8.116, xsize=2000, @@ -855,36 +899,36 @@ class MCIsimulator(): dark=0.001, exptime=300.0, readouttime=4., - rdose=8.0e9, + rdose=8.0e9, ghostCutoff=22.0, ghostratio=5.e-5, - coveringfraction=0.05, #CR: + coveringfraction=0.05, # CR: # cosmicraylengths =self.information['dir_path']+'MCI_inputData/data/cdf_cr_length.dat', - # cosmicraydistance=self.information['dir_path']+'MCI_inputData/data/cdf_cr_total.dat', + # cosmicraydistance=self.information['dir_path']+'MCI_inputData/data/cdf_cr_total.dat', # parallelTrapfile =self.information['dir_path']+'MCI_inputData/data/cdm_euclid_parallel.dat', # serialTrapfile =self.information['dir_path']+'MCI_inputData/data/cdm_euclid_serial.dat', mode='same')) - + #################################################### ############################################################################### - def readConfigs(self,simnumber,source): + def readConfigs(self, simnumber, source): """ Reads the config file information using configParser and sets up a logger. """ self.config = ConfigParser.RawConfigParser() - - if simnumber==1: + + if simnumber == 1: print('beging config file name : ') - print(self.configfile) - - #self.config.readfp(open(self.configfile)) + print(self.configfile) + + # self.config.readfp(open(self.configfile)) self.config.read_file(open(self.configfile)) - - + ########################################################################### + def processConfigs(self): """ Processes configuration information and save the information to a dictionary self.information. @@ -893,7 +937,7 @@ class MCIsimulator(): support.MCIinstrumentModel.VISinformation(). Any of the defaults can be overwritten by providing a config file with a correct field name. """ - #parse options and update the information dictionary + # parse options and update the information dictionary options = self.config.options(self.section) settings = {} for option in options: @@ -901,91 +945,102 @@ class MCIsimulator(): settings[option] = self.config.getint(self.section, option) except ValueError: try: - settings[option] = self.config.getfloat(self.section, option) + settings[option] = self.config.getfloat( + self.section, option) except ValueError: settings[option] = self.config.get(self.section, option) self.information.update(settings) - #ghost ratio can be in engineering format, so getfloat does not capture it... - self.information['ghostratio'] = float(self.config.get(self.section, 'ghostRatio')) + # ghost ratio can be in engineering format, so getfloat does not capture it... + self.information['ghostratio'] = float( + self.config.get(self.section, 'ghostRatio')) ################################################################################################### ################################################################################################## - - #booleans to control the flow - - self.cosmicRays = self.config.getboolean(self.section, 'cosmicRays') - self.darknoise = self.config.getboolean(self.section, 'darknoise') - self.cosmetics = self.config.getboolean(self.section, 'cosmetics') - self.radiationDamage = self.config.getboolean(self.section, 'radiationDamage') - self.bleeding = self.config.getboolean(self.section, 'bleeding') - self.overscans = self.config.getboolean(self.section, 'overscans') - self.nonlinearity = self.config.getboolean(self.section, 'nonlinearity') - self.readoutNoise = self.config.getboolean(self.section, 'readoutNoise') - self.skyback = self.config.getboolean(self.section, 'skyback') - self.TianceEffect = self.config.getboolean(self.section, 'TianceEffect') - self.intscale = self.config.getboolean(self.section, 'intscale') - self.ghosts = self.config.getboolean(self.section, 'ghosts') - self.shutterEffect =self.config.getboolean(self.section, 'shutterEffect') - self.flatfieldM =self.config.getboolean(self.section, 'flatfieldm') - self.PRNUeffect =self.config.getboolean(self.section, 'PRNUeffect') - self.appFatt =self.config.getboolean(self.section, 'appFatt') - self.sky_shift_rot =self.config.getboolean(self.section, 'sky_shift_rot') - self.distortion =self.config.getboolean(self.section, 'distortion') - self.sim_star =self.config.getboolean(self.section, 'sim_star') - self.sim_galaxy =self.config.getboolean(self.section, 'sim_galaxy') - - self.save_starpsf =self.config.getboolean(self.section, 'save_starpsf') - self.save_cosmicrays =self.config.getboolean(self.section, 'save_cosmicrays') - self.lensing =self.config.getboolean(self.section, 'lensing') - - ###############################################3################################# - self.booleans = dict(cosmicRays =self.cosmicRays, - darknoise =self.darknoise, - cosmetics =self.cosmetics, + + # booleans to control the flow + + self.cosmicRays = self.config.getboolean(self.section, 'cosmicRays') + self.darknoise = self.config.getboolean(self.section, 'darknoise') + self.cosmetics = self.config.getboolean(self.section, 'cosmetics') + self.radiationDamage = self.config.getboolean( + self.section, 'radiationDamage') + self.bleeding = self.config.getboolean(self.section, 'bleeding') + self.overscans = self.config.getboolean(self.section, 'overscans') + self.nonlinearity = self.config.getboolean( + self.section, 'nonlinearity') + self.readoutNoise = self.config.getboolean( + self.section, 'readoutNoise') + self.skyback = self.config.getboolean(self.section, 'skyback') + self.TianceEffect = self.config.getboolean( + self.section, 'TianceEffect') + self.intscale = self.config.getboolean(self.section, 'intscale') + self.ghosts = self.config.getboolean(self.section, 'ghosts') + self.shutterEffect = self.config.getboolean( + self.section, 'shutterEffect') + self.flatfieldM = self.config.getboolean(self.section, 'flatfieldm') + self.PRNUeffect = self.config.getboolean(self.section, 'PRNUeffect') + self.appFatt = self.config.getboolean(self.section, 'appFatt') + self.sky_shift_rot = self.config.getboolean( + self.section, 'sky_shift_rot') + self.distortion = self.config.getboolean(self.section, 'distortion') + self.sim_star = self.config.getboolean(self.section, 'sim_star') + self.sim_galaxy = self.config.getboolean(self.section, 'sim_galaxy') + + self.save_starpsf = self.config.getboolean( + self.section, 'save_starpsf') + self.save_cosmicrays = self.config.getboolean( + self.section, 'save_cosmicrays') + self.lensing = self.config.getboolean(self.section, 'lensing') + + ###############################################3################################# + self.booleans = dict(cosmicRays=self.cosmicRays, + darknoise=self.darknoise, + cosmetics=self.cosmetics, radiationDamage=self.radiationDamage, - bleeding =self.bleeding, - overscans =self.overscans, - nonlinearity =self.nonlinearity, - readoutNoise =self.readoutNoise, - skyback =self.skyback, - TianceEffect =self.TianceEffect, - intscale =self.intscale, - ghosts =self.ghosts , - shutterEffect =self.shutterEffect, - flatfieldM =self.flatfieldM, - PRNUeffect =self.PRNUeffect, - appFatt =self.appFatt , - sky_shift_rot =self.sky_shift_rot, - distortion =self.distortion, - sim_star =self.sim_star, - sim_galaxy =self.sim_galaxy, - save_starpsf =self.save_starpsf, - save_cosmicrays =self.save_cosmicrays , - lensing =self.lensing ) - ##################################################################### - - - + bleeding=self.bleeding, + overscans=self.overscans, + nonlinearity=self.nonlinearity, + readoutNoise=self.readoutNoise, + skyback=self.skyback, + TianceEffect=self.TianceEffect, + intscale=self.intscale, + ghosts=self.ghosts, + shutterEffect=self.shutterEffect, + flatfieldM=self.flatfieldM, + PRNUeffect=self.PRNUeffect, + appFatt=self.appFatt, + sky_shift_rot=self.sky_shift_rot, + distortion=self.distortion, + sim_star=self.sim_star, + sim_galaxy=self.sim_galaxy, + save_starpsf=self.save_starpsf, + save_cosmicrays=self.save_cosmicrays, + lensing=self.lensing) + ##################################################################### + return - - ############################################################################## + + ############################################################################## ############################################################################### def _createEmpty(self): """ Creates and empty array of a given x and y size full of zeros. add g r i channel images; - + Creates lensing parameters; - - """ - self.image_g=np.zeros((self.information['ysize'], self.information['xsize']), dtype=float) - self.image_r=np.zeros((self.information['ysize'], self.information['xsize']), dtype=float) - self.image_i=np.zeros((self.information['ysize'], self.information['xsize']), dtype=float) + + """ + self.image_g = np.zeros( + (self.information['ysize'], self.information['xsize']), dtype=float) + self.image_r = np.zeros( + (self.information['ysize'], self.information['xsize']), dtype=float) + self.image_i = np.zeros( + (self.information['ysize'], self.information['xsize']), dtype=float) return - + ############################################################################### ############################################################################## def _loadGhostModel(self): @@ -997,9 +1052,9 @@ class MCIsimulator(): distance to the ghost from y=0 is appropriate (given current knowledge, about 750 VIS pixels). """ - self.ghostOffsetX=self.information['ghostoffsetx'] - self.ghostOffsetY=self.information['ghostoffsety'] - + self.ghostOffsetX = self.information['ghostoffsetx'] + self.ghostOffsetY = self.information['ghostoffsety'] + self.ghostMax = self.information['ghostratio'] self.log.info('Maximum in the ghost model %e' % self.ghostMax) return @@ -1014,42 +1069,44 @@ class MCIsimulator(): self.log.info('Reading in cosmic ray information from %s and %s' % (self.information['cosmicraylengths'], self.information['cosmicraydistance'])) - crLengths = np.loadtxt(self.information['dir_path']+self.information['cosmicraylengths']) - crDists = np.loadtxt(self.information['dir_path']+self.information['cosmicraydistance']) + crLengths = np.loadtxt( + self.information['dir_path']+self.information['cosmicraylengths']) + crDists = np.loadtxt( + self.information['dir_path']+self.information['cosmicraydistance']) self.cr = dict(cr_u=crLengths[:, 0], cr_cdf=crLengths[:, 1], cr_cdfn=np.shape(crLengths)[0], cr_v=crDists[:, 0], cr_cde=crDists[:, 1], cr_cden=np.shape(crDists)[0]) - + return ############################################################################### ############################################################################### - def configure(self,simnumber,sourcein,dir_path,result_path): + def configure(self, simnumber, sourcein, dir_path, result_path): """ Configures the simulator with input information and creates and empty array to which the final image will be build on. """ - self.readConfigs(simnumber,sourcein) - + self.readConfigs(simnumber, sourcein) + self.processConfigs() - + self._createEmpty() - - self.information['dir_path']=dir_path - - self.information['result_path']=result_path - self.source=sourcein - + self.information['dir_path'] = dir_path + + self.information['result_path'] = result_path + + self.source = sourcein + ##print('print information:', self.information) - + ########################################################################### - - now=datetime.utcnow() - #data_time=now.strftime("%Y-%m-%d-%H-%M-%S") - result_day=now.strftime("%Y-%m-%d") - + + now = datetime.utcnow() + # data_time=now.strftime("%Y-%m-%d-%H-%M-%S") + result_day = now.strftime("%Y-%m-%d") + # if self.information['dir_path'] =='/nfsdata/share/simulation-unittest/mci_sim/': # self.result_path = self.information['dir_path'] +'mci_sim_result/'+result_day # else: @@ -1061,12 +1118,13 @@ class MCIsimulator(): # self.result_path = '../MCI_simResult/'+self.source+"_"+result_day # else: # self.result_path = '/data/mcisimdata/'+result_day - + print(self.information['result_path']) - - self.result_path = self.information['result_path']+self.source+"_"+result_day - - if os.path.isdir(self.result_path)==False: + + self.result_path = self.information['result_path'] + \ + self.source+"_"+result_day + + if os.path.isdir(self.result_path) == False: os.mkdir(self.result_path) os.mkdir(self.result_path+'/cali_Data') os.mkdir(self.result_path+'/log_Data') @@ -1074,63 +1132,69 @@ class MCIsimulator(): os.mkdir(self.result_path+'/ori_Sky') os.mkdir(self.result_path+'/sky_Data') os.mkdir(self.result_path+'/PSF_Data') - - - now=datetime.utcnow() - - data_time=now.strftime("%Y-%m-%d-%H-%M-%S") - - print('simnumber', simnumber) - self.log = lg.setUpLogger(self.result_path+'/log_Data/MCIsim_'+self.source+'_'+data_time+'_Num_'+str(simnumber)+'.log') - + now = datetime.utcnow() + + data_time = now.strftime("%Y-%m-%d-%H-%M-%S") + + print('simnumber', simnumber) + + self.log = lg.setUpLogger(self.result_path+'/log_Data/MCIsim_' + + self.source+'_'+data_time+'_Num_'+str(simnumber)+'.log') self.log.info('-------STARTING A NEW SIMULATION------------') - + for key, value in self.information.items(): self.log.info('%s = %s' % (key, value)) - - - self.log.info('The exposure order is %i ' % simnumber ) - - #load instrument model, these values are also stored in the FITS header - - self.information['G_filters']=["F275W", "F280N","NUV", "WU", "CBU", "F343N", "u", "F373N", "F395N", "F336W"] - self.information['R_filters']=["F487N", "F502N", "CBV", "r", "F656N", "F658N", "F467M", "F555W", "F606W", "F673N"] - self.information['I_filters']=["z", "y", "F815N", "CBI", "F925N", "F960M", "F968N", "F845M" ,"F850LP" ,"F814W"] - - #### load telescope efficiency data - - self.tel_eff=np.load(self.information['dir_path']+'MCI_inputData/tel_eff/tel_eff.npy',allow_pickle=True).item() - - #### load MCI filter data - self.filterP=np.load(self.information['dir_path']+'MCI_inputData/MCI_filters/mci_filterPWTC.npy',allow_pickle=True).item() - + + self.log.info('The exposure order is %i ' % simnumber) + + # load instrument model, these values are also stored in the FITS header + + self.information['G_filters'] = ["F275W", "F280N", "NUV", + "WU", "CBU", "F343N", "u", "F373N", "F395N", "F336W"] + self.information['R_filters'] = ["F487N", "F502N", "CBV", "r", + "F656N", "F658N", "F467M", "F555W", "F606W", "F673N"] + self.information['I_filters'] = ["z", "y", "F815N", + "CBI", "F925N", "F960M", "F968N", "F845M", "F850LP", "F814W"] + + # load telescope efficiency data + + self.tel_eff = np.load( + self.information['dir_path']+'MCI_inputData/tel_eff/tel_eff.npy', allow_pickle=True).item() + + # load MCI filter data + self.filterP = np.load( + self.information['dir_path']+'MCI_inputData/MCI_filters/mci_filterPWTC.npy', allow_pickle=True).item() + return - + ################################################################################ def load_filter_PSF(self): - ##### load filter PSF in three channels ,G , R and I + # load filter PSF in three channels ,G , R and I ### # load filter name in three channels from information - self.filter_g=self.information['filter_g'] - self.filter_r=self.information['filter_r'] - self.filter_i=self.information['filter_i'] - - self.filter_psf=dict() - - filtername=self.filter_g - self.filter_psf['g']=np.load(self.information['dir_path']+'MCI_inputData/PSF/'+filtername+'_PSF.npy', allow_pickle=True).item() - - filtername=self.filter_r - self.filter_psf['r']=np.load(self.information['dir_path']+'MCI_inputData/PSF/'+filtername+'_PSF.npy', allow_pickle=True).item() - - filtername=self.filter_i - self.filter_psf['i']=np.load(self.information['dir_path']+'MCI_inputData/PSF/'+filtername+'_PSF.npy', allow_pickle=True).item() - - return - -############################################################################################### + self.filter_g = self.information['filter_g'] + self.filter_r = self.information['filter_r'] + self.filter_i = self.information['filter_i'] + + self.filter_psf = dict() + + filtername = self.filter_g + self.filter_psf['g'] = np.load( + self.information['dir_path']+'MCI_inputData/PSF/'+filtername+'_PSF.npy', allow_pickle=True).item() + + filtername = self.filter_r + self.filter_psf['r'] = np.load( + self.information['dir_path']+'MCI_inputData/PSF/'+filtername+'_PSF.npy', allow_pickle=True).item() + + filtername = self.filter_i + self.filter_psf['i'] = np.load( + self.information['dir_path']+'MCI_inputData/PSF/'+filtername+'_PSF.npy', allow_pickle=True).item() + + return + +############################################################################################### def get_PSF(self, px, py, ch): """ @@ -1143,745 +1207,829 @@ class MCIsimulator(): Returns: PSF: PSF array at given 7 wavelength and at target position """ - PSFMat = self.filter_psf[ch]['psf_mat'] - cen_col= self.filter_psf[ch]['psf_field_X'] - cen_row= self.filter_psf[ch]['psf_field_Y'] + PSFMat = self.filter_psf[ch]['psf_mat'] + cen_col = self.filter_psf[ch]['psf_field_X'] + cen_row = self.filter_psf[ch]['psf_field_Y'] imPSF = psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2) - + return imPSF ############################################################################### -############################################################################### - - def cal_SED_photons(self, flux): - ## flux_arr, input flux array with unit of 1e-17 erg/s/A/cm^2 +############################################################################### + + def cal_SED_photons(self, flux): + # flux_arr, input flux array with unit of 1e-17 erg/s/A/cm^2 + + # set the wavelenth for MCI from 250nm to 1100nm + wave = np.linspace(2500, 10000, 8501) + wave = wave/10 - wave = np.linspace(2500,10000,8501) # set the wavelenth for MCI from 250nm to 1100nm - wave=wave/10 - # calcutle photons from original spec cube data, # data: input data, two-dimentional, unit : 1e-17 erg/s/A/cm^2 - - planckh= 6.62620*10**-27 # % erg s; - cc=2.99792458*10**17 # in nm/s - telarea=3.1415926*100*100 # in cm^2,望远镜聚光面积�? - fluxlam=1e-17*(flux) # convert original unit to unit of erg/s/A/cm^2 - # wave in nm ;; - ephoton=planckh*cc/wave # single photon energy in erg/photon; cc与lambda单位需要一致; - - Nphoton =fluxlam/ephoton*telarea*self.information['exptime'] # in unit of photons - - #### load telescope efficiency data - teleff=dict() - teleff['g']=self.tel_eff['G'] ### fisrt colunmm is wavelength in nm - teleff['r']=self.tel_eff['R'] ### second colunmm is efficiency - teleff['i']=self.tel_eff['I'] - ##### - - ft=dict() - ft['g']=self.filter_g - ft['r']=self.filter_r - ft['i']=self.filter_i - - + + planckh = 6.62620*10**-27 # % erg s; + cc = 2.99792458*10**17 # in nm/s + telarea = 3.1415926*100*100 # in cm^2,望远镜聚光面积�? + # convert original unit to unit of erg/s/A/cm^2 + fluxlam = 1e-17*(flux) + # wave in nm ;; + # single photon energy in erg/photon; cc与lambda单位需要一致; + ephoton = planckh*cc/wave + + Nphoton = fluxlam/ephoton*telarea * \ + self.information['exptime'] # in unit of photons + + # load telescope efficiency data + teleff = dict() + teleff['g'] = self.tel_eff['G'] # fisrt colunmm is wavelength in nm + teleff['r'] = self.tel_eff['R'] # second colunmm is efficiency + teleff['i'] = self.tel_eff['I'] + ##### + + ft = dict() + ft['g'] = self.filter_g + ft['r'] = self.filter_r + ft['i'] = self.filter_i + # load filter name in three channels - ft_wave=dict() - ft_wave['g']=self.filterP[ft['g']]['wave_nm'] - ft_wave['r']=self.filterP[ft['r']]['wave_nm'] - ft_wave['i']=self.filterP[ft['i']]['wave_nm'] - - ft_eff=dict() - ft_eff['g']=self.filterP[ft['g']]['throughout'] - ft_eff['r']=self.filterP[ft['r']]['throughout'] - ft_eff['i']=self.filterP[ft['i']]['throughout'] - - chlist=['g','r','i'] - - Sumphoton=dict() - PSF_eff_weight=dict() - + ft_wave = dict() + ft_wave['g'] = self.filterP[ft['g']]['wave_nm'] + ft_wave['r'] = self.filterP[ft['r']]['wave_nm'] + ft_wave['i'] = self.filterP[ft['i']]['wave_nm'] + + ft_eff = dict() + ft_eff['g'] = self.filterP[ft['g']]['throughout'] + ft_eff['r'] = self.filterP[ft['r']]['throughout'] + ft_eff['i'] = self.filterP[ft['i']]['throughout'] + + chlist = ['g', 'r', 'i'] + + Sumphoton = dict() + PSF_eff_weight = dict() + for k in range(3): - ch=chlist[k] - tel_wavearr=teleff[ch][:,0] - tel_effarr =teleff[ch][:,1] - tel_effnew=np.interp(wave, tel_wavearr, tel_effarr) - - ft_wavearr=ft_wave[ch] - ft_effarr =ft_eff[ch] - ft_effnew =np.interp(wave, ft_wavearr, ft_effarr) - - - #### SED flux*filter_flux*tel_eff - eff_arr=Nphoton*ft_effnew*tel_effnew - - Sumphoton[ch]=np.sum(eff_arr) - - iwave=self.filter_psf[ch]['psf_iwave'][:] ### seven wavelength for the seleced filter - - psf_coeff =np.interp(iwave, wave, eff_arr) - - if psf_coeff.sum()==0: - psf_coeff=1.0/7*np.ones(7) - else: - psf_coeff=psf_coeff/psf_coeff.sum() - - PSF_eff_weight[ch]=psf_coeff - - return Sumphoton, PSF_eff_weight + ch = chlist[k] + tel_wavearr = teleff[ch][:, 0] + tel_effarr = teleff[ch][:, 1] + tel_effnew = np.interp(wave, tel_wavearr, tel_effarr) - ################################################## -############################################################################### - - def cal_sky_noise(self): - ####### add earthshine ####### + ft_wavearr = ft_wave[ch] + ft_effarr = ft_eff[ch] + ft_effnew = np.interp(wave, ft_wavearr, ft_effarr) + + # SED flux*filter_flux*tel_eff + eff_arr = Nphoton*ft_effnew*tel_effnew + + Sumphoton[ch] = np.sum(eff_arr) + + # seven wavelength for the seleced filter + iwave = self.filter_psf[ch]['psf_iwave'][:] + + psf_coeff = np.interp(iwave, wave, eff_arr) + + if psf_coeff.sum() == 0: + psf_coeff = 1.0/7*np.ones(7) + else: + psf_coeff = psf_coeff/psf_coeff.sum() + + PSF_eff_weight[ch] = psf_coeff + + return Sumphoton, PSF_eff_weight + + ################################################## +############################################################################### + + def cal_sky_noise(self): ####### add earthshine ####### - #self.earthshine_wave # A - #self.earthshine_flux # erg/s/cm^2/A/arcsec^2 - - wave = np.linspace(2500,11000, 8501) # set the wavelenth for MCI from 250nm to 1100nm - - skynoise_flux=self.earthshine_flux+self.zodiacal_flux # erg/s/cm^2/A/arcsec^2 - - - wave=wave/10 - - # data: input data, two-dimentional, unit : 1e-17 erg/s/A/cm^2 - planckh= 6.62620*10**-27 # % erg s; - cc=2.99792458*10**17 # in nm/s - telarea=3.1415926*100*100 # in cm^2, - ephoton=planckh*cc/wave # in erg/photon, - Nphoton_flux =skynoise_flux/ephoton*telarea*0.05*0.05*self.information['exptime'] # each pixel will have the photons in unit of photons/s/A - - #### load telescope efficiency data - teleff=dict() - teleff['g']=self.tel_eff['G'] ### fisrt colunmm is wavelength in nm - teleff['r']=self.tel_eff['R'] ### second colunmm is efficiency - teleff['i']=self.tel_eff['I'] - ##### - - ft=dict() - ft['g']=self.filter_g - ft['r']=self.filter_r - ft['i']=self.filter_i - + ####### add earthshine ####### + # self.earthshine_wave # A + # self.earthshine_flux # erg/s/cm^2/A/arcsec^2 + + # set the wavelenth for MCI from 250nm to 1100nm + wave = np.linspace(2500, 11000, 8501) + + skynoise_flux = self.earthshine_flux+self.zodiacal_flux # erg/s/cm^2/A/arcsec^2 + + wave = wave/10 + + # data: input data, two-dimentional, unit : 1e-17 erg/s/A/cm^2 + planckh = 6.62620*10**-27 # % erg s; + cc = 2.99792458*10**17 # in nm/s + telarea = 3.1415926*100*100 # in cm^2, + ephoton = planckh*cc/wave # in erg/photon, + # each pixel will have the photons in unit of photons/s/A + Nphoton_flux = skynoise_flux/ephoton*telarea * \ + 0.05*0.05*self.information['exptime'] + + # load telescope efficiency data + teleff = dict() + teleff['g'] = self.tel_eff['G'] # fisrt colunmm is wavelength in nm + teleff['r'] = self.tel_eff['R'] # second colunmm is efficiency + teleff['i'] = self.tel_eff['I'] + ##### + + ft = dict() + ft['g'] = self.filter_g + ft['r'] = self.filter_r + ft['i'] = self.filter_i + # load filter name in three channels - ft_wave=dict() - ft_wave['g']=self.filterP[ft['g']]['wave_nm'] - ft_wave['r']=self.filterP[ft['r']]['wave_nm'] - ft_wave['i']=self.filterP[ft['i']]['wave_nm'] - - ft_eff=dict() - ft_eff['g']=self.filterP[ft['g']]['throughout'] - ft_eff['r']=self.filterP[ft['r']]['throughout'] - ft_eff['i']=self.filterP[ft['i']]['throughout'] - - chlist=['g','r','i'] - - self.Sky_Noise=dict() + ft_wave = dict() + ft_wave['g'] = self.filterP[ft['g']]['wave_nm'] + ft_wave['r'] = self.filterP[ft['r']]['wave_nm'] + ft_wave['i'] = self.filterP[ft['i']]['wave_nm'] + + ft_eff = dict() + ft_eff['g'] = self.filterP[ft['g']]['throughout'] + ft_eff['r'] = self.filterP[ft['r']]['throughout'] + ft_eff['i'] = self.filterP[ft['i']]['throughout'] + + chlist = ['g', 'r', 'i'] + + self.Sky_Noise = dict() - for k in range(3): - ch=chlist[k] - tel_wavearr=teleff[ch][:,0] - tel_effarr =teleff[ch][:,1] - tel_effnew=np.interp(wave, tel_wavearr, tel_effarr) - - ft_wavearr=ft_wave[ch] - ft_effarr =ft_eff[ch] - ft_effnew =np.interp(wave, ft_wavearr, ft_effarr) - - self.Sky_Noise[ch]=np.sum(Nphoton_flux*ft_effnew*tel_effnew) - - return self.Sky_Noise + ch = chlist[k] + tel_wavearr = teleff[ch][:, 0] + tel_effarr = teleff[ch][:, 1] + tel_effnew = np.interp(wave, tel_wavearr, tel_effarr) + + ft_wavearr = ft_wave[ch] + ft_effarr = ft_eff[ch] + ft_effnew = np.interp(wave, ft_wavearr, ft_effarr) + + self.Sky_Noise[ch] = np.sum(Nphoton_flux*ft_effnew*tel_effnew) + + return self.Sky_Noise ################################################## ############################################################################## - def cal_StarSED_img(self): + def cal_StarSED_img(self): ##################### - - pixelscale=self.information['pixel_size'] ## arcsec, pixel scale size - ghostOffsetX =self.information['ghostoffsetx'] - ghostOffsetY=self.information['ghostoffsety'] - ghostMx=self.information['ghostratio'] - rotTelPos=self.information['rotTelPos'] - rotSkyPos=self.information['rotSkyPos'] - - theta = rotTelPos - rotSkyPos - - ############ load star data catlog ##################### - starcat='selection_MACSJ0744.9 3927_20230517_concat.csv' - - ##starcat='selection_20230517_concat.fits' - ################################################### - - self.log.info('Stat catlog file name is %s' % (starcat)) - - ########################################## - df2=pandas.read_csv(self.information['dir_path']+'MCI_inputData/star_input/'+starcat) + pixelscale = self.information['pixel_size'] # arcsec, pixel scale size + ghostOffsetX = self.information['ghostoffsetx'] + ghostOffsetY = self.information['ghostoffsety'] + ghostMx = self.information['ghostratio'] + + rotTelPos = self.information['rotTelPos'] + rotSkyPos = self.information['rotSkyPos'] + + theta = rotTelPos - rotSkyPos + + ############ load star data catlog ##################### + # 'selection_MACSJ0744.9 3927_20230517_concat.csv' + starcat = self.information['starcat'] + + if get_file_extension(starcat) == '.csv': + + # starcat='selection_20230517_concat.fits' + ################################################### + + self.log.info('Stat catlog file name is %s' % (starcat)) + + ########################################## + df2 = pandas.read_csv( + self.information['dir_path']+'MCI_inputData/star_input/'+starcat) + + df3 = df2[(abs(df2['ra_gaia']-df2['ra_gaia'].mean()) < 400/3600.0) + & (abs(df2['dec_gaia']-df2['dec_gaia'].mean()) < 400/3600.0)] + + df3.index = range(len(df3)) + + ################################################### + + # np.save('umag.npy', df3['umag'] ) + self.star = df3 + + del df2, df3 + + self.information['ra_obj'] = self.star['ra_gaia'].mean() + self.information['dec_obj'] = self.star['dec_gaia'].mean() + nsrcs = len(self.star['ra_gaia']) + + if get_file_extension(starcat) == '.fits': + + self.log.info('Stat catlog file name is %s' % (starcat)) + + df0 = fits.open( + self.information['dir_path']+'/MCI_inputData/star_input/'+starcat) + + self.star = df0[1].data + + self.information['ra_obj'] = self.star['ra'].mean() + self.information['dec_obj'] = self.star['dec'].mean() + nsrcs = len(self.star['ra']) + + ################################## - df3=df2[ (abs(df2['ra_gaia']-df2['ra_gaia'].mean())<400/3600.0) & (abs(df2['dec_gaia']-df2['dec_gaia'].mean())<400/3600.0) ] - - df3.index = range(len(df3)) - - ################################################### - - # np.save('umag.npy', df3['umag'] ) - self.star=df3 - - del df2,df3 - - self.information['ra_obj'] = self.star['ra_gaia'].mean() - self.information['dec_obj'] = self.star['dec_gaia'].mean() - - self.information['star_ra'] = self.information['ra_obj'] - self.information['star_dec']= self.information['dec_obj'] - - center_ra =self.information['T_disRa'] +self.information['ra_obj'] - center_dec=self.information['T_disDec'] +self.information['dec_obj'] - - self.information['ra_pnt0'] =center_ra - self.information['dec_pnt0']=center_dec - - channel=['g','r','i'] + self.information['star_dec'] = self.information['dec_obj'] + + center_ra = self.information['T_disRa'] + self.information['ra_obj'] + center_dec = self.information['T_disDec'] + self.information['dec_obj'] + + self.information['ra_pnt0'] = center_ra + self.information['dec_pnt0'] = center_dec + + channel = ['g', 'r', 'i'] ####################################################################### - #################### cal_PSF_array ################################# - - + #################### cal_PSF_array ################################# + if self.save_starpsf: - + self.log.info('calculate and save star PSF data......') - - primary_g=fits.PrimaryHDU() - PSF_g=fits.HDUList([primary_g]) - - primary_r=fits.PrimaryHDU() - PSF_r=fits.HDUList([primary_r]) - - primary_i=fits.PrimaryHDU() - PSF_i=fits.HDUList([primary_i]) - - fov=0.05*min(self.information['xsize'],self.information['ysize']) - - dec_arr,ra_arr=make_c_coor(fov,25) - - k=0; - - ####################################################################### + + primary_g = fits.PrimaryHDU() + PSF_g = fits.HDUList([primary_g]) + + primary_r = fits.PrimaryHDU() + PSF_r = fits.HDUList([primary_r]) + + primary_i = fits.PrimaryHDU() + PSF_i = fits.HDUList([primary_i]) + + fov = 0.05*min(self.information['xsize'], + self.information['ysize']) + + dec_arr, ra_arr = make_c_coor(fov, 25) + + k = 0 + + ####################################################################### for ii in range(len(ra_arr)): for jj in range(len(ra_arr)): - - ################################################################## - - galRa = ra_arr[ii,jj] +center_ra*3600 # ra of PFS, arcsecond - galDec = dec_arr[ii,jj]+center_dec*3600 # dec of PSF, arcsecond - - fsx,fsy=cal_pos(center_ra,center_dec, rotTelPos, rotSkyPos, galRa, galDec) - + + ################################################################## + + galRa = ra_arr[ii, jj] + center_ra * \ + 3600 # ra of PFS, arcsecond + galDec = dec_arr[ii, jj]+center_dec * \ + 3600 # dec of PSF, arcsecond + + fsx, fsy = cal_pos(center_ra, center_dec, + rotTelPos, rotSkyPos, galRa, galDec) + ############# do field distottion ########## - - if self.distortion: - - for i in range(3): - ch=channel[i] - fpx,fpy=distortField(fsx, fsy, ch) - + + if self.distortion: + + for i in range(3): + ch = channel[i] + fpx, fpy = distortField(fsx, fsy, ch) + else: - - fpx=fsx - fpy=fsy - - ################################################################### - - psf=dict() - + + fpx = fsx + fpy = fsy + + ################################################################### + + psf = dict() + for i in range(3): - - ch=channel[i] - - psfmat=self.get_PSF(fpx, fpy, ch) - - temp=0 - + + ch = channel[i] + + psfmat = self.get_PSF(fpx, fpy, ch) + + temp = 0 + for iwave in range(7): - temp=temp+1/7.0*psfmat[:,:,iwave] - - temp=temp/temp.sum() - - ####rotate the PSF data - if abs(theta.deg)>0: - psf[ch]=ndimage.rotate(temp, theta.deg, order=1, reshape=False) # here we choose reshape=False, the rotated image will + temp = temp+1/7.0*psfmat[:, :, iwave] + + temp = temp/temp.sum() + + # rotate the PSF data + if abs(theta.deg) > 0: + # here we choose reshape=False, the rotated image will + psf[ch] = ndimage.rotate( + temp, theta.deg, order=1, reshape=False) else: - psf[ch]=temp + psf[ch] = temp ################################### - - hdu_g=fits.ImageHDU(psf['g']) - hdu_g.header['ra'] = ra_arr[ii,jj] - hdu_g.header['dec'] = dec_arr[ii,jj] - hdu_g.header['rot_deg']=-theta.deg + + hdu_g = fits.ImageHDU(psf['g']) + hdu_g.header['ra'] = ra_arr[ii, jj] + hdu_g.header['dec'] = dec_arr[ii, jj] + hdu_g.header['rot_deg'] = -theta.deg PSF_g.append(hdu_g) ################################### - hdu_r=fits.ImageHDU(psf['r']) - hdu_r.header['ra'] = ra_arr[ii,jj] - hdu_r.header['dec'] = dec_arr[ii,jj] - hdu_r.header['rot_deg']=-theta.deg + hdu_r = fits.ImageHDU(psf['r']) + hdu_r.header['ra'] = ra_arr[ii, jj] + hdu_r.header['dec'] = dec_arr[ii, jj] + hdu_r.header['rot_deg'] = -theta.deg PSF_r.append(hdu_r) ################################### - hdu_i=fits.ImageHDU(psf['i']) - hdu_i.header['ra'] = ra_arr[ii,jj] - hdu_i.header['dec']= dec_arr[ii,jj] - hdu_i.header['rot_deg']=-theta.deg + hdu_i = fits.ImageHDU(psf['i']) + hdu_i.header['ra'] = ra_arr[ii, jj] + hdu_i.header['dec'] = dec_arr[ii, jj] + hdu_i.header['rot_deg'] = -theta.deg PSF_i.append(hdu_i) ################################### del hdu_g del hdu_r del hdu_i - k=k+1 - + k = k+1 + ############################################ - file_g=self.result_path+'/PSF_Data/'+'PSF_sim_No.'+str(self.information['simnumber'])+'_C1.fits' - PSF_g.writeto(file_g,overwrite=True) - - file_r=self.result_path+'/PSF_Data/'+'PSF_sim_No.'+str(self.information['simnumber'])+'_C2.fits' - PSF_r.writeto(file_r,overwrite=True) - - file_i=self.result_path+'/PSF_Data/'+'PSF_sim_No.'+str(self.information['simnumber'])+'_C3.fits' - PSF_i.writeto(file_i,overwrite=True) - + file_g = self.result_path+'/PSF_Data/'+'PSF_sim_No.' + \ + str(self.information['simnumber'])+'_C1.fits' + PSF_g.writeto(file_g, overwrite=True) + + file_r = self.result_path+'/PSF_Data/'+'PSF_sim_No.' + \ + str(self.information['simnumber'])+'_C2.fits' + PSF_r.writeto(file_r, overwrite=True) + + file_i = self.result_path+'/PSF_Data/'+'PSF_sim_No.' + \ + str(self.information['simnumber'])+'_C3.fits' + PSF_i.writeto(file_i, overwrite=True) + del PSF_g del PSF_r del PSF_i self.log.info('finish save star PSF data......') - + ########## finish save PSF fits ########################################## ############################################################################ - nsrcs=len(self.star['ra_gaia']) - self.log.info('load star catlog successfully') - - ################################################################## - obj=dict() - obj['g']=np.zeros(3) - obj['r']=np.zeros(3) - obj['i']=np.zeros(3) - - fullimg=dict() - star_input=dict() - star_input['g']=np.zeros((nsrcs,3)) - star_input['r']=np.zeros((nsrcs,3)) - star_input['i']=np.zeros((nsrcs,3)) - - star_output=dict() - star_output['g']=np.zeros((nsrcs,3)) - star_output['r']=np.zeros((nsrcs,3)) - star_output['i']=np.zeros((nsrcs,3)) - - final_image=dict() - - final_image['g'] = galsim.ImageF(int(self.information['xsize']), int(self.information['ysize'])) - final_image['r'] = galsim.ImageF(int(self.information['xsize']), int(self.information['ysize'])) - final_image['i'] = galsim.ImageF(int(self.information['xsize']), int(self.information['ysize'])) - - final_image['g'].setOrigin(0,0) - final_image['r'].setOrigin(0,0) - final_image['i'].setOrigin(0,0) + ################################################################## + obj = dict() + obj['g'] = np.zeros(3) + obj['r'] = np.zeros(3) + obj['i'] = np.zeros(3) + + fullimg = dict() + star_input = dict() + star_input['g'] = np.zeros((nsrcs, 3)) + star_input['r'] = np.zeros((nsrcs, 3)) + star_input['i'] = np.zeros((nsrcs, 3)) + + star_output = dict() + star_output['g'] = np.zeros((nsrcs, 3)) + star_output['r'] = np.zeros((nsrcs, 3)) + star_output['i'] = np.zeros((nsrcs, 3)) + + final_image = dict() + + final_image['g'] = galsim.ImageF( + int(self.information['xsize']), int(self.information['ysize'])) + final_image['r'] = galsim.ImageF( + int(self.information['xsize']), int(self.information['ysize'])) + final_image['i'] = galsim.ImageF( + int(self.information['xsize']), int(self.information['ysize'])) + + final_image['g'].setOrigin(0, 0) + final_image['r'].setOrigin(0, 0) + final_image['i'].setOrigin(0, 0) ####################################################################### - nlayccd = 0 - - ############################################ - - ra = self.information['ra_pnt0'] - dec = self.information['dec_pnt0'] - - time_jd=time2jd(self.dt) - - x_sat=float(self.orbit_pars[self.orbit_exp_num,1]) - y_sat=float(self.orbit_pars[self.orbit_exp_num,2]) - z_sat=float(self.orbit_pars[self.orbit_exp_num,3]) - - wave0, zodi0 = self.zodiacal(ra, dec, self.TianCe_day) # erg/s/cm^2/A/arcsec^2 - + nlayccd = 0 + + ############################################ + + ra = self.information['ra_pnt0'] + dec = self.information['dec_pnt0'] + + time_jd = time2jd(self.dt) + + x_sat = float(self.orbit_pars[self.orbit_exp_num, 1]) + y_sat = float(self.orbit_pars[self.orbit_exp_num, 2]) + z_sat = float(self.orbit_pars[self.orbit_exp_num, 3]) + + wave0, zodi0 = self.zodiacal( + ra, dec, self.TianCe_day) # erg/s/cm^2/A/arcsec^2 + self.log.info('dir_path:') self.log.info(self.information['dir_path']) - - + # EarthShine from straylight - sl = StrayLight(self.information['dir_path'],jtime=time_jd, sat=np.array([x_sat, y_sat, z_sat]), radec=np.array([(ra*u.degree).value, (dec*u.degree).value])) + sl = StrayLight(self.information['dir_path'], jtime=time_jd, sat=np.array( + [x_sat, y_sat, z_sat]), radec=np.array([(ra*u.degree).value, (dec*u.degree).value])) earth_e = sl.caculateEarthShineFilter(filter='r') - star_e = sl.caculateStarLightFilter(filter='r') + star_e = sl.caculateStarLightFilter(filter='r') angle_earth = earth_angle(time_jd, x_sat, y_sat, z_sat, ra, dec) - + if angle_earth < 0: earth_e = 0 - - earthshine_wave0, earthshine_flux0 = ill2flux(earth_e+star_e, self.information['dir_path']) - + + earthshine_wave0, earthshine_flux0 = ill2flux( + earth_e+star_e, self.information['dir_path']) + # sample as mci wavelength - wave_mci = np.linspace(2500, 11000, 8501) #np.arange(2500, 11000, 1) + wave_mci = np.linspace(2500, 11000, 8501) # np.arange(2500, 11000, 1) f1 = interp1d(wave0, zodi0) zodi_mci = f1(wave_mci) - + f2 = interp1d(earthshine_wave0, earthshine_flux0) earthshine_mci = f2(wave_mci) - self.zodiacal_wave = wave_mci # in A self.zodiacal_flux = zodi_mci - + self.earthshine_wave = wave_mci # A self.earthshine_flux = earthshine_mci - + ####################################################################################### ######################################################################################### - - self.cal_sky_noise() - ################################# + self.cal_sky_noise() - self.information['target'] =deg2HMS(self.information['ra_obj'], self.information['dec_obj']) - - self.information['CRVAL1']=self.information['ra_pnt0'] - self.information['CRVAL2']=self.information['dec_pnt0'] - - self.information['CRPIX1']=self.information['xsize']/2-0.5 #### - self.information['CRPIX2']=self.information['ysize']/2-0.5 #### - - self.information['CD1_1']=-np.cos(-theta)*self.information['pixel_size']/3600.0 #### - self.information['CD1_2']= np.sin(-theta)*self.information['pixel_size']/3600.0 #### - - self.information['CD2_1']= np.sin(-theta)*self.information['pixel_size']/3600.0 #### - self.information['CD2_2']= np.cos(-theta)*self.information['pixel_size']/3600.0 #### - - ####################################################################### - if self.TianceEffect: - ra_list = self.star['ra_gaia'].tolist() - dec_list = self.star['dec_gaia'].tolist() - pmra_list = self.star['pmra_gaia'].tolist() - pmdec_list = self.star['pmdec_gaia'].tolist() - parallax_list = self.star['parallax_gaia'].tolist() - rv_list = [0.0 for i in range(len(ra_list))] - - ################################################ - newRa, newDec = shao.onOrbitObsPosition(self.information['dir_path'], ra_list, dec_list, pmra_list, \ - pmdec_list, rv_list, parallax_list, len(ra_list), \ - self.information['pos_x'], self.information['pos_y'], self.information['pos_z'], self.information['velocity_x'],self.information['velocity_y'],self.information['velocity_z'], "J2000", self.TianCe_day, self.TianCe_exp_start) + ################################# + + self.information['target'] = deg2HMS( + self.information['ra_obj'], self.information['dec_obj']) + + self.information['CRVAL1'] = self.information['ra_pnt0'] + self.information['CRVAL2'] = self.information['dec_pnt0'] + + self.information['CRPIX1'] = self.information['xsize']/2-0.5 + self.information['CRPIX2'] = self.information['ysize']/2-0.5 + + self.information['CD1_1'] = - \ + np.cos(-theta)*self.information['pixel_size']/3600.0 + self.information['CD1_2'] = np.sin(-theta) * \ + self.information['pixel_size']/3600.0 + + self.information['CD2_1'] = np.sin(-theta) * \ + self.information['pixel_size']/3600.0 + self.information['CD2_2'] = np.cos(-theta) * \ + self.information['pixel_size']/3600.0 + + ####################################################################### + if self.TianceEffect: + if get_file_extension(starcat) == '.fits': + + ra_list = self.star['ra'].tolist() + dec_list = self.star['dec'].tolist() + + pmra_list = [0.0 for i in range(len(ra_list))] + pmdec_list = [0.0 for i in range(len(ra_list))] + parallax_list = [0.0 for i in range(len(ra_list))] + rv_list = [0.0 for i in range(len(ra_list))] + else: + + ra_list = self.star['ra_gaia'].tolist() + dec_list = self.star['dec_gaia'].tolist() + pmra_list = self.star['pmra_gaia'].tolist() + pmdec_list = self.star['pmdec_gaia'].tolist() + parallax_list = self.star['parallax_gaia'].tolist() + rv_list = [0.0 for i in range(len(ra_list))] + + ################################################ + newRa, newDec = shao.onOrbitObsPosition(self.information['dir_path'], ra_list, dec_list, pmra_list, + pmdec_list, rv_list, parallax_list, len( + ra_list), + self.information['pos_x'], self.information['pos_y'], self.information['pos_z'], self.information['velocity_x'], self.information['velocity_y'], self.information['velocity_z'], "J2000", self.TianCe_day, self.TianCe_exp_start) else: - newRa =self.star['ra_gaia'] - newDec =self.star['dec_gaia'] + + if get_file_extension(starcat) == '.fits': + newRa = self.star['ra'] + newDec = self.star['dec'] + + else: + + newRa = self.star['ra_gaia'] + newDec = self.star['dec_gaia'] ###################################################### - - st_ra=[] - st_dec =[] - st_phot_C1=[] - st_phot_C2=[] - st_phot_C3=[] - - st_posX_C1=[] - st_posX_C2=[] - st_posX_C3=[] - - st_posY_C1=[] - st_posY_C2=[] - st_posY_C3=[] - - st_magu=[] - st_magg=[] - st_magr=[] - st_magi=[] - st_magz=[] - + + st_ra = [] + st_dec = [] + st_phot_C1 = [] + st_phot_C2 = [] + st_phot_C3 = [] + + st_posX_C1 = [] + st_posX_C2 = [] + st_posX_C3 = [] + + st_posY_C1 = [] + st_posY_C2 = [] + st_posY_C3 = [] + + st_magu = [] + st_magg = [] + st_magr = [] + st_magi = [] + st_magz = [] + #################### generate star image ########## - - for j in tqdm(range(nsrcs)): ### nsrcs length - - if j==0: + + for j in tqdm(range(nsrcs)): # nsrcs length + + if j == 0: self.log.info('begin iteration........') - ###############33 - #if self.debug: + # 33 + # if self.debug: #self.log.info('j = %i' % (j)) - - starRa = 3600.0*( newRa[j] ) # ra of star, arcsecond - starDec = 3600.0*( newDec[j] ) # dec of star, arcsecond - + + starRa = 3600.0*(newRa[j]) # ra of star, arcsecond + starDec = 3600.0*(newDec[j]) # dec of star, arcsecond + ################################################################### ################################################################### - fsx,fsy=cal_pos(center_ra,center_dec, rotTelPos, rotSkyPos, starRa, starDec) - row= fsy/pixelscale+self.information['ysize']/2-0.5 ### row number on CCD image - col= fsx/pixelscale+self.information['xsize']/2-0.5 ### col number on CCD image - - #print(col,row) - - if row>=self.information['ysize']+100 or row<=-100 or col>=self.information['xsize']+100 or col <=-100: + fsx, fsy = cal_pos(center_ra, center_dec, + rotTelPos, rotSkyPos, starRa, starDec) + # row number on CCD image + row = fsy/pixelscale+self.information['ysize']/2-0.5 + # col number on CCD image + col = fsx/pixelscale+self.information['xsize']/2-0.5 + + # print(col,row) + + if row >= self.information['ysize']+100 or row <= -100 or col >= self.information['xsize']+100 or col <= -100: continue - - nlayccd=nlayccd+1 - - if self.debug: - if nlayccd>1: + + nlayccd = nlayccd+1 + + if self.debug: + if nlayccd > 1: break - - st_ra.append( np.float64(starRa/3600.0)) - st_dec.append(np.float64(starDec/3600.0)) ################################################################ for i in range(3): - ### - ch=channel[i] - star_input[ch][int(nlayccd)-1, 0] =fsx #ra - star_input[ch][int(nlayccd)-1, 1] =fsy #dec - + ### + ch = channel[i] + star_input[ch][int(nlayccd)-1, 0] = fsx # ra + star_input[ch][int(nlayccd)-1, 1] = fsy # dec + ############# do field distottion ########## - - if self.distortion: - + + if self.distortion: + for i in range(3): - - ch=channel[i] - fpx,fpy=distortField(fsx, fsy, ch) - obj[ch][0]=fpx - obj[ch][1]=fpy - - star_output[ch][int(nlayccd)-1, 0] =fpx #ra - star_output[ch][int(nlayccd)-1, 1] =fpy #dec - + + ch = channel[i] + fpx, fpy = distortField(fsx, fsy, ch) + obj[ch][0] = fpx + obj[ch][1] = fpy + + star_output[ch][int(nlayccd)-1, 0] = fpx # ra + star_output[ch][int(nlayccd)-1, 1] = fpy # dec + else: - - fpx=fsx - fpy=fsy - - for i in range(3): - - ch=channel[i] - - obj[ch][0]=fpx - obj[ch][1]=fpy - - star_output[ch][int(nlayccd)-1, 0] =fpx #ra - star_output[ch][int(nlayccd)-1, 1] =fpy #dec - + + fpx = fsx + fpy = fsy + + for i in range(3): + + ch = channel[i] + + obj[ch][0] = fpx + obj[ch][1] = fpy + + star_output[ch][int(nlayccd)-1, 0] = fpx # ra + star_output[ch][int(nlayccd)-1, 1] = fpy # dec + ####################################################################### - + ####### use SED_code to generate star SED ####### - # SED of j-th star - umag = self.star['umag'][j] - gmag = self.star['gmag'][j] - rmag = self.star['rmag'][j] - imag = self.star['imag'][j] - zmag = self.star['zmag'][j] + if get_file_extension(starcat) == '.fits': + umag = self.star['gmag'][j] + gmag = self.star['gmag'][j] + rmag = self.star['rmag'][j] + imag = self.star['imag'][j] + zmag = self.star['zmag'][j] + + # SED of j-th star + else: + umag = self.star['umag'][j] + gmag = self.star['gmag'][j] + rmag = self.star['rmag'][j] + imag = self.star['imag'][j] + zmag = self.star['zmag'][j] + + flag = (umag > 0 and gmag > 0 and rmag > + 0 and imag > 0 and zmag > 0) + + if flag == False: + continue + wave = np.linspace(2500, 11000, 8501) # Input redshift redshift = 0 - + # Loading galaxy SED template - t=sed.Gal_Temp(self.information['dir_path']) + t = sed.Gal_Temp(self.information['dir_path']) # Calculating the magnitude (u, g, r, i, z) of each template t.toMag(redshift=redshift) # Calculating flux ugriz = np.array([umag, gmag, rmag, imag, zmag]) - star_flux = sed.Model_Galaxy_SED(wave, ugriz, redshift, t, self.information['dir_path']) - - ##cal_SED_photons(self, flux_arr): - intscales,PSF_eff_weight=self.cal_SED_photons(star_flux) - - gx=dict() - gy=dict() - + star_flux = sed.Model_Galaxy_SED( + wave, ugriz, redshift, t, self.information['dir_path']) + + # cal_SED_photons(self, flux_arr): + intscales, PSF_eff_weight = self.cal_SED_photons(star_flux) + + gx = dict() + gy = dict() + #self.log.info('magu =%f, magg=%f, magr=%f, magi=%f,magz=%f' % (umag,gmag,rmag,imag,zmag)) - for i in range(3): - ch=channel[i] - gy[ch]= obj[ch][1]/pixelscale+self.information['ysize']/2-0.5 ### row number on CCD image - gx[ch]= obj[ch][0]/pixelscale+self.information['xsize']/2-0.5 ### col number on CCD image - + for i in range(3): + ch = channel[i] + gy[ch] = obj[ch][1]/pixelscale+self.information['ysize'] / \ + 2-0.5 # row number on CCD image + gx[ch] = obj[ch][0]/pixelscale+self.information['xsize'] / \ + 2-0.5 # col number on CCD image + #self.log.info('Channel in =%s, PosX(in pixel)=%f, PosY(in pixel)=%f' % (channel[i], gx[ch], gy[ch])) - + if self.debug: - + self.log.info('Star number on CCD is = %i' % (nlayccd)) - - - if nlayccd %10 == 0: + + if nlayccd % 10 == 0: self.log.info('Star number on CCD is = %i' % (nlayccd)) - + ###### + + st_ra.append(np.float64(starRa/3600.0)) + st_dec.append(np.float64(starDec/3600.0)) + st_phot_C1.append(intscales['g']) st_phot_C2.append(intscales['r']) st_phot_C3.append(intscales['i']) - + st_posX_C1.append(gx['g']) st_posX_C2.append(gx['r']) st_posX_C3.append(gx['i']) - + st_posY_C1.append(gy['g']) st_posY_C2.append(gy['r']) st_posY_C3.append(gy['i']) - + st_magu.append(umag) st_magg.append(gmag) st_magr.append(rmag) st_magi.append(imag) st_magz.append(zmag) - + ## self.log.info('begin cal PSF') ###################################################################### - psf=dict() - + psf = dict() + for i in range(3): - ch=channel[i] + ch = channel[i] ####### - psfmat=self.get_PSF(fsx, fsy, ch) - + psfmat = self.get_PSF(fsx, fsy, ch) + for iwave in range(7): - if iwave==0: - temp=PSF_eff_weight[ch][iwave]*psfmat[:,:,iwave] + if iwave == 0: + temp = PSF_eff_weight[ch][iwave]*psfmat[:, :, iwave] else: - temp=temp+PSF_eff_weight[ch][iwave]*psfmat[:,:,iwave] - - temp=temp/temp.sum() - - ####rotate the PSF data - if abs(theta.deg>0): - psf[ch]=ndimage.rotate(temp, theta.deg, order=1, reshape=True) # here we choose reshape=False, the rotated image will + temp = temp + \ + PSF_eff_weight[ch][iwave]*psfmat[:, :, iwave] + + temp = temp/temp.sum() + + # rotate the PSF data + if abs(theta.deg > 0): + # here we choose reshape=False, the rotated image will + psf[ch] = ndimage.rotate( + temp, theta.deg, order=1, reshape=True) else: - psf[ch]=temp - - conv = psf[ch] - conv=conv/conv.sum() - - conv=conv*intscales[ch] - ################################################# - - stamp_img = galsim.Image(conv, copy=True) - stamp_img.setOrigin(0,0) - stamp_img.scale=0.025 - + psf[ch] = temp + + conv = psf[ch] + conv = conv/conv.sum() + + conv = conv*intscales[ch] + ################################################# + + stamp_img = galsim.Image(conv, copy=True) + stamp_img.setOrigin(0, 0) + stamp_img.scale = 0.025 + # self.log.info('begining galsim.PhotonArray.makeFromImage') - + # self.log.info('stamp_img.array.max()= %i' % (stamp_img.array.max())) - + ###print('stamp_img.array.max(): ', stamp_img.array.max() ) - - ################################################# - - photons=galsim.PhotonArray.makeFromImage(stamp_img, max_flux=max(1.0, stamp_img.array.max()/100000.0)) - - cx0,cy0=centroid(stamp_img.array) - + + ################################################# + + photons = galsim.PhotonArray.makeFromImage( + stamp_img, max_flux=max(1.0, stamp_img.array.max()/100000.0)) + + cx0, cy0 = centroid(stamp_img.array) + ##self.log.info('appfat= %s'%(self.appFatt)) - - if self.appFatt : + + if self.appFatt: ###self.log.info('begin appfat ........') - - ### apply treering and bright fatter and diffusion; - SimpleTreeRing = galsim.SiliconSensor().simple_treerings(amplitude=self.information['treering']) - + + # apply treering and bright fatter and diffusion; + SimpleTreeRing = galsim.SiliconSensor().simple_treerings( + amplitude=self.information['treering']) + cx, cy = centroid(conv) - - pos = galsim.PositionD(x=int(cx), y=int(cy)) ### set subimge center as the pos - - siliconsensor = galsim.SiliconSensor(strength=self.information['fatter'], diffusion_factor=self.information['difusion'], treering_func=SimpleTreeRing, treering_center=pos) - - image = galsim.Image(conv.shape[0], conv.shape[1]) - image.scale = 0.025 - image.setOrigin(0,0) - - photons.x=photons.x/image.scale - photons.y=photons.y/image.scale - - siliconsensor.accumulate(photons, image) - - photons=galsim.PhotonArray.makeFromImage(image, max_flux=max(1.0, stamp_img.array.max()/100000.0)) - - cx0,cy0=centroid(image.array) - - + + # set subimge center as the pos + pos = galsim.PositionD(x=int(cx), y=int(cy)) + + siliconsensor = galsim.SiliconSensor( + strength=self.information['fatter'], diffusion_factor=self.information['difusion'], treering_func=SimpleTreeRing, treering_center=pos) + + image = galsim.Image(conv.shape[0], conv.shape[1]) + image.scale = 0.025 + image.setOrigin(0, 0) + + photons.x = photons.x/image.scale + photons.y = photons.y/image.scale + + siliconsensor.accumulate(photons, image) + + photons = galsim.PhotonArray.makeFromImage( + image, max_flux=max(1.0, stamp_img.array.max()/100000.0)) + + cx0, cy0 = centroid(image.array) + ############################################ ############################################ - photons.x=photons.x-cx0*0.025 - photons.y=photons.y-cy0*0.025 - + photons.x = photons.x-cx0*0.025 + photons.y = photons.y-cy0*0.025 + ########################################################## - ######################################################## - photons.x=photons.x/0.05+gx[ch] - photons.y=photons.y/0.05+gy[ch] - - photons.addTo(final_image[ch]) - + ######################################################## + photons.x = photons.x/0.05+gx[ch] + photons.y = photons.y/0.05+gy[ch] + + photons.addTo(final_image[ch]) + ############################### - ###### debug code + # debug code # fi= galsim.ImageF(int(self.information['xsize']), int(self.information['ysize'])) # fi.setOrigin(0,0) - # photons.addTo(fi) - # icx,i cy=centroid(fi.array) - # print(icx,icy) + # photons.addTo(fi) + # icx,i cy=centroid(fi.array) + # print(icx,icy) ############################################################### - + #### add ghost image #### if self.ghosts: - ghostphotons=galsim.PhotonArray(len(photons.x),x=photons.x, y=photons.y, flux=photons.flux) - ghostphotons.flux=ghostMx*ghostphotons.flux - ghostphotons.x=photons.x+ghostOffsetY - ghostphotons.y=photons.y+ghostOffsetX - - if ghostphotons.flux.max()>0.01: - ghostphotons.addTo(final_image[ch]) - + ghostphotons = galsim.PhotonArray( + len(photons.x), x=photons.x, y=photons.y, flux=photons.flux) + ghostphotons.flux = ghostMx*ghostphotons.flux + ghostphotons.x = photons.x+ghostOffsetY + ghostphotons.y = photons.y+ghostOffsetX + + if ghostphotons.flux.max() > 0.01: + ghostphotons.addTo(final_image[ch]) + ############################################################### - print('total star nummber on CCD is: ',nlayccd ) - + print('total star nummber on CCD is: ', nlayccd) + self.log.info('total star nummber on CCD = %i' % (nlayccd)) - - tab=Table() - tab['st_ra'] =np.asarray(st_ra) - tab['st_dec'] =np.asarray(st_dec) - - tab['phot_C1']=np.asarray(st_phot_C1) - tab['phot_C2']=np.asarray(st_phot_C2) - tab['phot_C3']=np.asarray(st_phot_C3) - - tab['posX_C1']=np.asarray(st_posX_C1) - tab['posX_C2']=np.asarray(st_posX_C2) - tab['posX_C3']=np.asarray(st_posX_C3) - - tab['posY_C1']=np.asarray(st_posY_C1) - tab['posY_C2']=np.asarray(st_posY_C2) - tab['posY_C3']=np.asarray(st_posY_C3) - - - tab['st_magu']=np.asarray(st_magu) - tab['st_magg']=np.asarray(st_magg) - tab['st_magr']=np.asarray(st_magr) - tab['st_magi']=np.asarray(st_magi) - tab['st_magz']=np.asarray(st_magz) - - ###################################33 - - - file=self.result_path+'/log_Data/star_info'+'_SN_'+str(self.information['simnumber'])+'.fits' - tab.write(file,overwrite=True) - - ################################################################# + + tab = Table() + tab['st_ra'] = np.asarray(st_ra) + tab['st_dec'] = np.asarray(st_dec) + + tab['phot_C1'] = np.asarray(st_phot_C1) + tab['phot_C2'] = np.asarray(st_phot_C2) + tab['phot_C3'] = np.asarray(st_phot_C3) + + tab['posX_C1'] = np.asarray(st_posX_C1) + tab['posX_C2'] = np.asarray(st_posX_C2) + tab['posX_C3'] = np.asarray(st_posX_C3) + + tab['posY_C1'] = np.asarray(st_posY_C1) + tab['posY_C2'] = np.asarray(st_posY_C2) + tab['posY_C3'] = np.asarray(st_posY_C3) + + tab['st_magu'] = np.asarray(st_magu) + tab['st_magg'] = np.asarray(st_magg) + tab['st_magr'] = np.asarray(st_magr) + tab['st_magi'] = np.asarray(st_magi) + tab['st_magz'] = np.asarray(st_magz) + + # 33 + + file = self.result_path+'/log_Data/star_info' + \ + '_SN_'+str(self.information['simnumber'])+'.fits' + tab.write(file, overwrite=True) + + ################################################################# ################################################################# - - fullimg['g']=final_image['g'].array - fullimg['r']=final_image['r'].array - fullimg['i']=final_image['i'].array - - + + fullimg['g'] = final_image['g'].array + fullimg['r'] = final_image['r'].array + fullimg['i'] = final_image['i'].array + return fullimg - + ################################################################################ ################################################################################ def zodiacal(self, ra, dec, time): """ For given RA, DEC and TIME, return the interpolated zodical spectrum in Leinert-1998. - + :param ra: RA in unit of degree, ICRS frame :param dec: DEC in unit of degree, ICRS frame :param time: the specified string that in ISO format i.e., yyyy-mm-dd. @@ -1889,580 +2037,634 @@ class MCIsimulator(): wave_A: wavelength of the zodical spectrum spec_mjy: flux of the zodical spectrum, in unit of MJy/sr spec_erg: flux of the zodical spectrum, in unit of erg/s/cm^2/A/sr - + """ - + # get solar position dt = datetime.fromisoformat(time) ###jd = julian.to_jd(dt, fmt='jd') - + jd = time2jd(dt) t = Time(jd, format='jd', scale='utc') - + astro_sun = get_sun(t) ra_sun, dec_sun = astro_sun.gcrs.ra.deg, astro_sun.gcrs.dec.deg - - radec_sun = SkyCoord(ra=ra_sun*u.degree, dec=dec_sun*u.degree, frame='gcrs') + + radec_sun = SkyCoord(ra=ra_sun*u.degree, + dec=dec_sun*u.degree, frame='gcrs') lb_sun = radec_sun.transform_to('geocentrictrueecliptic') - + # get offsets between the target and sun. radec_obj = SkyCoord(ra=ra*u.degree, dec=dec*u.degree, frame='icrs') lb_obj = radec_obj.transform_to('geocentrictrueecliptic') - + beta = abs(lb_obj.lat.degree) lamda = abs(lb_obj.lon.degree - lb_sun.lon.degree) - + # interpolated zodical surface brightness at 0.5 um - zodi = pd.read_csv(self.information['dir_path']+'MCI_inputData/refs/zodi_map.dat', sep='\s+', header=None, comment='#') + zodi = pd.read_csv( + self.information['dir_path']+'MCI_inputData/refs/zodi_map.dat', sep='\s+', header=None, comment='#') beta_angle = np.array([0, 5, 10, 15, 20, 25, 30, 45, 60, 75]) lamda_angle = np.array([0, 5, 10, 15, 20, 25, 30, 35, 40, 45, - 60, 75, 90, 105, 120, 135, 150, 165, 180]) + 60, 75, 90, 105, 120, 135, 150, 165, 180]) xx, yy = np.meshgrid(beta_angle, lamda_angle) f = interpolate.interp2d(xx, yy, zodi, kind='linear') zodi_obj = f(beta, lamda) # 10^�? W m�? sr�? um�? - + # read the zodical spectrum in the ecliptic - cat_spec = pd.read_csv(self.information['dir_path']+'MCI_inputData/refs/solar_spec.dat', sep='\s+', header=None, comment='#') + cat_spec = pd.read_csv( + self.information['dir_path']+'MCI_inputData/refs/solar_spec.dat', sep='\s+', header=None, comment='#') wave = cat_spec[0].values # A spec0 = cat_spec[1].values # 10^-8 W m^�? sr^�? μm^�? zodi_norm = 252 # 10^-8 W m^�? sr^�? μm^�? - + spec = spec0 * (zodi_obj / zodi_norm) * 1e-8 # W m^�? sr^�? μm^�? - + # convert to the commonly used unit of MJy/sr, erg/s/cm^2/A/sr wave_A = wave # A - #spec_mjy = spec * 0.1 * wave_A**2 / 3e18 * 1e23 * 1e-6 # MJy/sr + # spec_mjy = spec * 0.1 * wave_A**2 / 3e18 * 1e23 * 1e-6 # MJy/sr spec_erg = spec * 0.1 # erg/s/cm^2/A/sr - spec_erg2 = spec_erg / 4.25452e10 # erg/s/cm^2/A/arcsec^2 - - self.zodiacal_wave=wave_A # in A - - self.zodiacal_flux=spec_erg2 - + # erg/s/cm^2/A/arcsec^2 + spec_erg2 = spec_erg / 4.25452e10 + + self.zodiacal_wave = wave_A # in A + + self.zodiacal_flux = spec_erg2 + return wave_A, spec_erg2 ################################################################################## - + ########################################################################## - def cal_Lensing_galaxy_img(self): + def cal_Lensing_galaxy_img(self): ##################### - - - self.dsx_arc = self.information['pixel_size'] # arcsec, pixel scale size; - self.bsz_arc = max(self.information['ysize'] ,self.information['xsize'])*self.dsx_arc # arcsec, field size; + + # arcsec, pixel scale size; + self.dsx_arc = self.information['pixel_size'] + # arcsec, field size; + self.bsz_arc = max( + self.information['ysize'], self.information['xsize'])*self.dsx_arc self.bsz_deg = self.bsz_arc/3600. - + ############################################################# - ### galaxy catlog information - ra = 74.0563449685417 + # galaxy catlog information + ra = 74.0563449685417 dec = -34.155241212932374 - + # halo_id = 229600100382 - if self.sim_star ==False : - self.information['star_ra'] = ra + if self.sim_star == False: + self.information['star_ra'] = ra self.information['star_dec'] = dec - + self.information['gal_ra'] = ra - self.information['gal_dec']= dec - - self.information['ra_obj'] =self.information['star_ra'] - self.information['dec_obj'] =self.information['star_dec'] - - - losscale =self.information['pixel_size'] - rotTelPos=self.information['rotTelPos'] - rotSkyPos=self.information['rotSkyPos'] - - theta = rotTelPos - rotSkyPos - - center_ra =self.information['T_disRa'] +self.information['star_ra'] - center_dec =self.information['T_disDec'] +self.information['star_dec'] - - self.information['ra_pnt0'] =center_ra - self.information['dec_pnt0']=center_dec + self.information['gal_dec'] = dec + + self.information['ra_obj'] = self.information['star_ra'] + self.information['dec_obj'] = self.information['star_dec'] + + losscale = self.information['pixel_size'] + rotTelPos = self.information['rotTelPos'] + rotSkyPos = self.information['rotSkyPos'] + + theta = rotTelPos - rotSkyPos + + center_ra = self.information['T_disRa'] + self.information['star_ra'] + center_dec = self.information['T_disDec'] + \ + self.information['star_dec'] + + self.information['ra_pnt0'] = center_ra + self.information['dec_pnt0'] = center_dec #################################################################### ################################################################################## - time_jd=time2jd(self.dt) - - x_sat=float(self.orbit_pars[self.orbit_exp_num,1]) - y_sat=float(self.orbit_pars[self.orbit_exp_num,2]) - z_sat=float(self.orbit_pars[self.orbit_exp_num,3]) - - wave0, zodi0 = self.zodiacal(self.information['ra_pnt0'], self.information['dec_pnt0'], self.TianCe_day) # erg/s/cm^2/A/arcsec^2 - + time_jd = time2jd(self.dt) + + x_sat = float(self.orbit_pars[self.orbit_exp_num, 1]) + y_sat = float(self.orbit_pars[self.orbit_exp_num, 2]) + z_sat = float(self.orbit_pars[self.orbit_exp_num, 3]) + + wave0, zodi0 = self.zodiacal( + self.information['ra_pnt0'], self.information['dec_pnt0'], self.TianCe_day) # erg/s/cm^2/A/arcsec^2 + # EarthShine from straylight sl = StrayLight(self.information['dir_path'], jtime=time_jd, sat=np.array([x_sat, y_sat, z_sat]), radec=np.array([(ra*u.degree).value, (dec*u.degree).value])) earth_e = sl.caculateEarthShineFilter(filter='r') - star_e = sl.caculateStarLightFilter(filter='r') + star_e = sl.caculateStarLightFilter(filter='r') angle_earth = earth_angle(time_jd, x_sat, y_sat, z_sat, ra, dec) - + if angle_earth < 0: earth_e = 0 - - earthshine_wave0, earthshine_flux0 = ill2flux(earth_e+star_e,self.information['dir_path']) - + + earthshine_wave0, earthshine_flux0 = ill2flux( + earth_e+star_e, self.information['dir_path']) + # sample as ifs wavelength - wave_mci = np.linspace(2500, 11000, 8501) #np.arange(2500, 11000, 1) + wave_mci = np.linspace(2500, 11000, 8501) # np.arange(2500, 11000, 1) f1 = interp1d(wave0, zodi0) zodi_mci = f1(wave_mci) - + f2 = interp1d(earthshine_wave0, earthshine_flux0) earthshine_mci = f2(wave_mci) # df = pd.DataFrame({'wave': wave_ifs, # 'zodi': zodi_ifs, # 'earthshine': earthshine_ifs}) - + self.zodiacal_wave = wave_mci # in A self.zodiacal_flux = zodi_mci - + self.earthshine_wave = wave_mci # A self.earthshine_flux = earthshine_mci - + ######################################################################################## - + ################################################################################## - self.cal_sky_noise() - - ############ load galaxy data with SED ############################ - + self.cal_sky_noise() + + ############ load galaxy data with SED ############################ + + self.information['target'] = deg2HMS( + self.information['star_ra'], self.information['star_dec']) + + self.information['CRVAL1'] = self.information['ra_pnt0'] + self.information['CRVAL2'] = self.information['dec_pnt0'] + + self.information['CRPIX1'] = self.information['xsize']/2-0.5 + self.information['CRPIX2'] = self.information['ysize']/2-0.5 + + self.information['CD1_1'] = - \ + np.cos(-theta)*self.information['pixel_size']/3600.0 + self.information['CD1_2'] = np.sin(-theta) * \ + self.information['pixel_size']/3600.0 + + self.information['CD2_1'] = np.sin(-theta) * \ + self.information['pixel_size']/3600.0 + self.information['CD2_2'] = np.cos(-theta) * \ + self.information['pixel_size']/3600.0 + + obj = dict() + obj['g'] = np.zeros(3) + obj['r'] = np.zeros(3) + obj['i'] = np.zeros(3) + + fullimg = dict() + galaxy_input = dict() - - self.information['target'] =deg2HMS(self.information['star_ra'], self.information['star_dec']) - - self.information['CRVAL1']=self.information['ra_pnt0'] - self.information['CRVAL2']=self.information['dec_pnt0'] - - self.information['CRPIX1']=self.information['xsize']/2-0.5 #### - self.information['CRPIX2']=self.information['ysize']/2-0.5 #### - - self.information['CD1_1'] =-np.cos(-theta)*self.information['pixel_size']/3600.0 #### - self.information['CD1_2'] = np.sin(-theta)*self.information['pixel_size']/3600.0 #### - - self.information['CD2_1'] = np.sin(-theta)*self.information['pixel_size']/3600.0 #### - self.information['CD2_2'] = np.cos(-theta)*self.information['pixel_size']/3600.0 #### - - obj=dict() - obj['g']=np.zeros(3) - obj['r']=np.zeros(3) - obj['i']=np.zeros(3) - - fullimg=dict() - galaxy_input=dict() - nsrcs = 72000 - - galaxy_input['g']=np.zeros((nsrcs,3)) - galaxy_input['r']=np.zeros((nsrcs,3)) - galaxy_input['i']=np.zeros((nsrcs,3)) - - galaxy_output=dict() - galaxy_output['g']=np.zeros((nsrcs,3)) - galaxy_output['r']=np.zeros((nsrcs,3)) - galaxy_output['i']=np.zeros((nsrcs,3)) - - channel=['g','r','i'] - final_image=dict() - - final_image['g'] = galsim.ImageF(int(self.information['xsize']), int(self.information['ysize'])) - final_image['r'] = galsim.ImageF(int(self.information['xsize']), int(self.information['ysize'])) - final_image['i'] = galsim.ImageF(int(self.information['xsize']), int(self.information['ysize'])) - - final_image['g'].setOrigin(0,0) - final_image['r'].setOrigin(0,0) - final_image['i'].setOrigin(0,0) - - #################################################################### - - gal_ra=[]##.append(np.float64(galRa/3600.0)) - gal_dec=[]###.append(np.float64(galDec/3600.0)) + galaxy_input['g'] = np.zeros((nsrcs, 3)) + galaxy_input['r'] = np.zeros((nsrcs, 3)) + galaxy_input['i'] = np.zeros((nsrcs, 3)) - phot_C1=[]##.append(intscales['g']) - phot_C2=[]###.append(intscales['r']) - phot_C3=[]###.append(intscales['i']) - - posX_C1=[]##.append(gx['g']) - posX_C2=[]#.append(gx['r']) - posX_C3=[]#.append(gx['i']) - - posY_C1=[]#.append(gy['g']) - posY_C2=[]#.append(gy['r']) - posY_C3=[]#.append(gy['i']) - - - gal_magu=[] - gal_magg=[] - gal_magr=[] - gal_magi=[] - gal_magz=[] - - ######################################## - - nlayccd = 0 - - ####################generate loc image - - if self.debug: - nk2=1 + galaxy_output = dict() + galaxy_output['g'] = np.zeros((nsrcs, 3)) + galaxy_output['r'] = np.zeros((nsrcs, 3)) + galaxy_output['i'] = np.zeros((nsrcs, 3)) + + channel = ['g', 'r', 'i'] + final_image = dict() + + final_image['g'] = galsim.ImageF( + int(self.information['xsize']), int(self.information['ysize'])) + final_image['r'] = galsim.ImageF( + int(self.information['xsize']), int(self.information['ysize'])) + final_image['i'] = galsim.ImageF( + int(self.information['xsize']), int(self.information['ysize'])) + + final_image['g'].setOrigin(0, 0) + final_image['r'].setOrigin(0, 0) + final_image['i'].setOrigin(0, 0) + + #################################################################### + + gal_ra = [] # .append(np.float64(galRa/3600.0)) + gal_dec = [] # .append(np.float64(galDec/3600.0)) + + phot_C1 = [] # .append(intscales['g']) + phot_C2 = [] # .append(intscales['r']) + phot_C3 = [] # .append(intscales['i']) + + posX_C1 = [] # .append(gx['g']) + posX_C2 = [] # .append(gx['r']) + posX_C3 = [] # .append(gx['i']) + + posY_C1 = [] # .append(gy['g']) + posY_C2 = [] # .append(gy['r']) + posY_C3 = [] # .append(gy['i']) + + galID = [] + haloID = [] + + gal_new_ra = [] + gal_new_dec = [] + + gal_ori_ra = [] + gal_ori_dec = [] + + gal_rescale = [] + gal_szs = [] + + gal_magu = [] + gal_magg = [] + gal_magr = [] + gal_magi = [] + gal_magz = [] + + ######################################## + + nlayccd = 0 + + # generate loc image + + if self.debug: + nk2 = 1 else: - nk2=1 - - for k2 in (range(nk2)): ### - print('k2=',k2) - + nk2 = 1 + + for k2 in (range(nk2)): + print('k2=', k2) + # Lens_SED_IMG_0.025_230606 - + if self.lensing: - filename=self.information['dir_path']+'MCI_inputData/galaxy_Input/Lens_SED_IMG_0.025_230606/Lens_img_cut_IMG_'+str(k2+1)+'.fits' - - else: - filename=self.information['dir_path']+'MCI_inputData/galaxy_Input/noLens_SED_IMG_0.025_230626/Lens_img_cut_IMG_'+str(k2+1)+'.fits' - - - - - self.log.info('galaxy_Input image path is: %s' %(filename)) - + filename = self.information['dir_path'] + \ + 'MCI_inputData/galaxy_Input/Lens_SED_IMG_0.025_230606/Lens_img_cut_IMG_' + \ + str(k2+1)+'.fits' + + else: + filename = self.information['dir_path'] + \ + 'MCI_inputData/galaxy_Input/noLens_SED_IMG_0.025_230626/Lens_img_cut_IMG_' + \ + str(k2+1)+'.fits' + + self.log.info('galaxy_Input image path is: %s' % (filename)) + if not os.path.exists(filename): print('finish load all the input galaxy image fits files') break - - srcs_cat=fits.open(filename) - + + srcs_cat = fits.open(filename) + #### load galaxy SED fitsfile ### - + if self.lensing: - filename=self.information['dir_path']+'MCI_inputData/galaxy_Input/Lens_SED_IMG_0.025_230606/Lens_img_cut_SED_'+str(k2+1)+'.fits' - + filename = self.information['dir_path'] + \ + 'MCI_inputData/galaxy_Input/Lens_SED_IMG_0.025_230606/Lens_img_cut_SED_' + \ + str(k2+1)+'.fits' + else: - - filename=self.information['dir_path']+'MCI_inputData/galaxy_Input/noLens_SED_IMG_0.025_230626/Lens_img_cut_SED_'+str(k2+1)+'.fits' - srcs_sed=fits.open(filename) - - self.log.info('galaxy_Input SED path is: %s' %(filename)) - + + filename = self.information['dir_path'] + \ + 'MCI_inputData/galaxy_Input/noLens_SED_IMG_0.025_230626/Lens_img_cut_SED_' + \ + str(k2+1)+'.fits' + srcs_sed = fits.open(filename) + + self.log.info('galaxy_Input SED path is: %s' % (filename)) + ###### do Tiance Effect ### - ra_list =[] - dec_list=[] - - - for kkk in range(1,len(srcs_cat)): - t1=srcs_cat[kkk].header['new_ra'] -self.information['gal_ra'] +self.information['star_ra'] + ra_list = [] + dec_list = [] + + for kkk in range(1, len(srcs_cat)): + t1 = srcs_cat[kkk].header['new_ra'] - \ + self.information['gal_ra'] + self.information['star_ra'] ra_list.append(float(t1)) - - t2=srcs_cat[kkk].header['new_dec'] -self.information['gal_dec'] +self.information['star_dec'] + + t2 = srcs_cat[kkk].header['new_dec'] - \ + self.information['gal_dec'] + self.information['star_dec'] dec_list.append(float(t2)) - - - if self.TianceEffect: - - pmra_list = [0.0 for i in range(len(ra_list))] - pmdec_list = [0.0 for i in range(len(ra_list))] - parallax_list = [0.0 for i in range(len(ra_list))] - rv_list = [0.0 for i in range(len(ra_list))] - - ################################################ - newRa, newDec = shao.onOrbitObsPosition(self.information['dir_path'],ra_list, dec_list, pmra_list, \ - pmdec_list, rv_list, parallax_list, len(ra_list), \ - self.information['pos_x'], self.information['pos_y'], self.information['pos_z'], self.information['velocity_x'],self.information['velocity_y'],self.information['velocity_z'], "J2000", self.TianCe_day, self.TianCe_exp_start) + + if self.TianceEffect: + + pmra_list = [0.0 for i in range(len(ra_list))] + pmdec_list = [0.0 for i in range(len(ra_list))] + parallax_list = [0.0 for i in range(len(ra_list))] + rv_list = [0.0 for i in range(len(ra_list))] + + ################################################ + newRa, newDec = shao.onOrbitObsPosition(self.information['dir_path'], ra_list, dec_list, pmra_list, + pmdec_list, rv_list, parallax_list, len( + ra_list), + self.information['pos_x'], self.information['pos_y'], self.information['pos_z'], self.information['velocity_x'], self.information['velocity_y'], self.information['velocity_z'], "J2000", self.TianCe_day, self.TianCe_exp_start) else: - newRa =ra_list - newDec =dec_list - - + newRa = ra_list + newDec = dec_list + ############################################################################ ################################################################### for k1 in tqdm(range(len(newRa))): #print('k1=', k1) - - galRa = newRa[k1]*3600##*(srcs_cat[k1].header['new_ra'] -self.information['gal_ra'] +self.information['star_ra']) # ra of galaxies, arcsecond - galDec = newDec[k1]*3600####(srcs_cat[k1].header['new_dec']-self.information['gal_dec']+self.information['star_dec']) # dec of galaxies, arcsecond - ########################################################################### + # *(srcs_cat[k1].header['new_ra'] -self.information['gal_ra'] +self.information['star_ra']) # ra of galaxies, arcsecond + galRa = newRa[k1]*3600 + # (srcs_cat[k1].header['new_dec']-self.information['gal_dec']+self.information['star_dec']) # dec of galaxies, arcsecond + galDec = newDec[k1]*3600 + + ########################################################################### ############################################################################ ### test code #### - ################################################################# - fsx,fsy=cal_pos(center_ra,center_dec, rotTelPos, rotSkyPos, galRa, galDec) + fsx, fsy = cal_pos(center_ra, center_dec, + rotTelPos, rotSkyPos, galRa, galDec) - - if abs(fsx)>235 or abs(fsy)>235: + if abs(fsx) > 235 or abs(fsy) > 235: continue - - # # SED of j-th galaxy ,# unit of 10-17 erg/s/A/cm2 - gal_flux=srcs_sed[k1+1].data ## here is k1+1, not k1, k1 begins with 0 - + # # SED of j-th galaxy ,# unit of 10-17 erg/s/A/cm2 + # here is k1+1, not k1, k1 begins with 0 + gal_flux = srcs_sed[k1+1].data - ################################ ### rotate the lensed_images_g ### - if abs(theta.deg)>0: - lensed_images_g=ndimage.rotate(srcs_cat[k1+1].data, -theta.deg, order=1, reshape=True) # here we choose reshape=False, the rotated image will + if abs(theta.deg) > 0: + # here we choose reshape=False, the rotated image will + lensed_images_g = ndimage.rotate( + srcs_cat[k1+1].data, -theta.deg, order=1, reshape=True) else: - lensed_images_g=srcs_cat[k1+1].data + lensed_images_g = srcs_cat[k1+1].data - - if lensed_images_g.sum()<=0: + if lensed_images_g.sum() <= 0: continue - ################################################################ for i in range(3): - ### - ch=channel[i] - galaxy_input[ch][int(nlayccd)-1, 0] =fsx #ra - galaxy_input[ch][int(nlayccd)-1, 1] =fsy #dec - #galaxy_input[ch][int(nlayccd)-1, 2] =mag[ch] # mag g - + ### + ch = channel[i] + galaxy_input[ch][int(nlayccd)-1, 0] = fsx # ra + galaxy_input[ch][int(nlayccd)-1, 1] = fsy # dec + # galaxy_input[ch][int(nlayccd)-1, 2] =mag[ch] # mag g + ############# do field distottion ########## - - if self.distortion: - + + if self.distortion: + for i in range(3): - - ch=channel[i] - - fpx,fpy=distortField(fsx, fsy, ch) - obj[ch][0]=fpx - obj[ch][1]=fpy - #obj[ch][2]=mag[ch] - - galaxy_output[ch][int(nlayccd)-1, 0] =fpx #ra - galaxy_output[ch][int(nlayccd)-1, 1] =fpy #dec - #galaxy_output[ch][int(nlayccd)-1, 2] =mag[ch] # mag g - - + + ch = channel[i] + + fpx, fpy = distortField(fsx, fsy, ch) + obj[ch][0] = fpx + obj[ch][1] = fpy + # obj[ch][2]=mag[ch] + + galaxy_output[ch][int(nlayccd)-1, 0] = fpx # ra + galaxy_output[ch][int(nlayccd)-1, 1] = fpy # dec + # galaxy_output[ch][int(nlayccd)-1, 2] =mag[ch] # mag g + else: - - fpx=fsx - fpy=fsy - - - for i in range(3): - - ch=channel[i] - - obj[ch][0]=fpx - obj[ch][1]=fpy - #obj[ch][2]=mag[ch] - - galaxy_output[ch][int(nlayccd)-1, 0] =fpx #ra - galaxy_output[ch][int(nlayccd)-1, 1] =fpy #dec - #galaxy_output[ch][int(nlayccd)-1, 2] =mag[ch] # mag g - - ####################################################################### + + fpx = fsx + fpy = fsy + + for i in range(3): + + ch = channel[i] + + obj[ch][0] = fpx + obj[ch][1] = fpy + # obj[ch][2]=mag[ch] + + galaxy_output[ch][int(nlayccd)-1, 0] = fpx # ra + galaxy_output[ch][int(nlayccd)-1, 1] = fpy # dec + # galaxy_output[ch][int(nlayccd)-1, 2] =mag[ch] # mag g + + ####################################################################### #self.log.info('Galaxy number=%i, Ra(in arcsec)=%f, Dec(in arcsec)=%f' % (nlayccd, fpx, fpy)) - #self.log.info('Galaxy number=%i, Mag_g=%f, Mag_r=%f,Mag_i=%f' % (nlayccd, mag['g'],mag['r'],mag['i'])) - + #self.log.info('Galaxy number=%i, Mag_g=%f, Mag_r=%f,Mag_i=%f' % (nlayccd, mag['g'],mag['r'],mag['i'])) + #print('Flux sum =', gal_flux.sum()) - ##cal_SED_photons(self, flux_arr): - intscales,PSF_eff_weight=self.cal_SED_photons(gal_flux) - - - ls_imgsum=lensed_images_g.sum() - - if intscales['g'].max()/ls_imgsum<0.1 and intscales['r'].max()/ls_imgsum<0.1 and intscales['i'].max()/ls_imgsum<0.1: + # cal_SED_photons(self, flux_arr): + intscales, PSF_eff_weight = self.cal_SED_photons(gal_flux) + + ls_imgsum = lensed_images_g.sum() + + if intscales['g'].max()/ls_imgsum < 0.1 and intscales['r'].max()/ls_imgsum < 0.1 and intscales['i'].max()/ls_imgsum < 0.1: ######### continue ######## test code ########## - - if self.debug: - if nlayccd>1: + + if self.debug: + if nlayccd > 1: ######### break - - ############################33 - - img=dict() - - lensed_images_g=lensed_images_g/ls_imgsum - img['g']=lensed_images_g*intscales['g'] - img['r']=lensed_images_g*intscales['r'] - img['i']=lensed_images_g*intscales['i'] - - if img['g'].max()<0.01 and img['r'].max()<0.01 and img['i'].max()<0.01: + + # 33 + + img = dict() + + lensed_images_g = lensed_images_g/ls_imgsum + img['g'] = lensed_images_g*intscales['g'] + img['r'] = lensed_images_g*intscales['r'] + img['i'] = lensed_images_g*intscales['i'] + + if img['g'].max() < 0.01 and img['r'].max() < 0.01 and img['i'].max() < 0.01: ######### continue - - - nlayccd=nlayccd+1 - + + nlayccd = nlayccd+1 ################################################ - - gx=dict() - gy=dict() - + + gx = dict() + gy = dict() + for i in range(3): - - ch=channel[i] - - gy[ch]= obj[ch][1]/losscale+self.information['ysize']/2-0.5 ### row number on CCD image - gx[ch]= obj[ch][0]/losscale+self.information['xsize']/2-0.5 ### col number on CCD image - - ###################################################################### - - gal_ra.append(np.float64(galRa/3600.0)) + + ch = channel[i] + + gy[ch] = obj[ch][1]/losscale+self.information['ysize'] / \ + 2-0.5 # row number on CCD image + gx[ch] = obj[ch][0]/losscale+self.information['xsize'] / \ + 2-0.5 # col number on CCD image + + ###################################################################### + + gal_ra.append(np.float64(galRa/3600.0)) gal_dec.append(np.float64(galDec/3600.0)) phot_C1.append(intscales['g']) phot_C2.append(intscales['r']) phot_C3.append(intscales['i']) - + posX_C1.append(gx['g']) posX_C2.append(gx['r']) posX_C3.append(gx['i']) - + posY_C1.append(gy['g']) posY_C2.append(gy['r']) posY_C3.append(gy['i']) - - + gal_magu.append(srcs_cat[k1+1].header['magu']) gal_magg.append(srcs_cat[k1+1].header['magg']) gal_magr.append(srcs_cat[k1+1].header['magr']) gal_magi.append(srcs_cat[k1+1].header['magi']) gal_magz.append(srcs_cat[k1+1].header['magz']) - - #self.log.info('Galaxy number=%i, Mag_g=%f, Mag_r=%f,Mag_i=%f' % (nlayccd, mag['g'],mag['r'],mag['i'])) - - if nlayccd %1000 ==0: + + galID.append(srcs_cat[k1+1].header['GALAXID']) + haloID.append(srcs_cat[k1+1].header['HALOID']) + + gal_new_ra.append(srcs_cat[k1+1].header['NEW_RA']) + gal_new_dec.append(srcs_cat[k1+1].header['NEW_DEC']) + + gal_ori_ra.append(srcs_cat[k1+1].header['OLD_RA']) + gal_ori_dec.append(srcs_cat[k1+1].header['OLD_DEC']) + + gal_rescale.append(srcs_cat[k1+1].header['RESCALE']) + gal_szs.append(srcs_cat[k1+1].header['SZS']) + + #self.log.info('Galaxy number=%i, Mag_g=%f, Mag_r=%f,Mag_i=%f' % (nlayccd, mag['g'],mag['r'],mag['i'])) + + if nlayccd % 1000 == 0: self.log.info('Galaxy number on CCD is = %i' % (nlayccd)) - - - psf=dict() - - + + psf = dict() + for i in range(3): - ch=channel[i] - - psfmat=self.get_PSF(fsx, fsy, ch) - - temp=0 - + ch = channel[i] + + psfmat = self.get_PSF(fsx, fsy, ch) + + temp = 0 + for iwave in range(7): - temp=temp+PSF_eff_weight[ch][iwave]*psfmat[:,:,iwave] - - temp=temp/temp.sum() - - ##### rotate the PSF data - if abs(theta.deg)>0: - psf[ch]=ndimage.rotate(temp, theta.deg, order=1, reshape=False) # here we choose reshape=False, the rotated image will + temp = temp + \ + PSF_eff_weight[ch][iwave]*psfmat[:, :, iwave] + + temp = temp/temp.sum() + + # rotate the PSF data + if abs(theta.deg) > 0: + # here we choose reshape=False, the rotated image will + psf[ch] = ndimage.rotate( + temp, theta.deg, order=1, reshape=False) else: - psf[ch]=temp - - - conv = fftconvolve(img[ch], psf[ch], mode='full') - #continue - #suppress negative numbers - - conv[conv < 0.0] = 0.0 - - ################################################# - stamp_img = galsim.Image(conv, copy=True) - stamp_img.setOrigin(0,0) - stamp_img.scale=0.025 - - photons=galsim.PhotonArray.makeFromImage(stamp_img, max_flux=1.0) - - cx0,cy0=centroid(stamp_img.array) - ########### apply fat effect to galaxy image ##### - if self.appFatt : - - ### apply treering and bright fatter and diffusion; - - SimpleTreeRing = galsim.SiliconSensor().simple_treerings(amplitude=self.information['treering']) - + psf[ch] = temp + + conv = fftconvolve(img[ch], psf[ch], mode='full') + # continue + # suppress negative numbers + + conv[conv < 0.0] = 0.0 + + ################################################# + stamp_img = galsim.Image(conv, copy=True) + stamp_img.setOrigin(0, 0) + stamp_img.scale = 0.025 + + photons = galsim.PhotonArray.makeFromImage( + stamp_img, max_flux=1.0) + + cx0, cy0 = centroid(stamp_img.array) + ########### apply fat effect to galaxy image ##### + if self.appFatt: + + # apply treering and bright fatter and diffusion; + + SimpleTreeRing = galsim.SiliconSensor().simple_treerings( + amplitude=self.information['treering']) + cx, cy = centroid(conv) - - pos = galsim.PositionD(x=int(cx), y=int(cy)) ### set subimge center as the pos - - siliconsensor = galsim.SiliconSensor(strength=self.information['fatter'], diffusion_factor=self.information['difusion'], treering_func=SimpleTreeRing, treering_center=pos) - - image = galsim.Image(conv.shape[1],conv.shape[0]) - image.scale = 0.025 - image.setOrigin(0,0) - - photons.x=photons.x/image.scale - photons.y=photons.y/image.scale - - siliconsensor.accumulate(photons, image) - - photons=galsim.PhotonArray.makeFromImage(image, max_flux=1.0) - - cx0,cy0=centroid(image.array) + + # set subimge center as the pos + pos = galsim.PositionD(x=int(cx), y=int(cy)) + + siliconsensor = galsim.SiliconSensor( + strength=self.information['fatter'], diffusion_factor=self.information['difusion'], treering_func=SimpleTreeRing, treering_center=pos) + + image = galsim.Image(conv.shape[1], conv.shape[0]) + image.scale = 0.025 + image.setOrigin(0, 0) + + photons.x = photons.x/image.scale + photons.y = photons.y/image.scale + + siliconsensor.accumulate(photons, image) + + photons = galsim.PhotonArray.makeFromImage( + image, max_flux=1.0) + + cx0, cy0 = centroid(image.array) ############################################################## ############################################################## - ################################################################## - ################################################################## - - photons.x=photons.x-cx0*0.025 - photons.y=photons.y-cy0*0.025 - - photons.x=photons.x/0.05+gx[ch] - photons.y=photons.y/0.05+gy[ch] - - photons.addTo(final_image[ch]) - + ################################################################## + ################################################################## + + photons.x = photons.x-cx0*0.025 + photons.y = photons.y-cy0*0.025 + + photons.x = photons.x/0.05+gx[ch] + photons.y = photons.y/0.05+gy[ch] + + photons.addTo(final_image[ch]) + #################################################### ############################################ ############################################ ######################################################################## - print('total los nummber on CCD is: ',nlayccd ) - + print('total los nummber on CCD is: ', nlayccd) + self.log.info('total los nummber on CCD is = %i' % (nlayccd)) - - ################################################################# - tab=Table() - tab['gal_ra']=np.asarray(gal_ra) - tab['gal_dec']=np.asarray(gal_dec) - - tab['phot_C1']=np.asarray(phot_C1) - tab['phot_C2']=np.asarray(phot_C2) - tab['phot_C3']=np.asarray(phot_C3) - - tab['posX_C1']=np.asarray(posX_C1) - tab['posX_C2']=np.asarray(posX_C2) - tab['posX_C3']=np.asarray(posX_C3) - - tab['posY_C1']=np.asarray(posY_C1) - tab['posY_C2']=np.asarray(posY_C2) - tab['posY_C3']=np.asarray(posY_C3) - - tab['gal_magu']=np.asarray(gal_magu) - tab['gal_magg']=np.asarray(gal_magg) - tab['gal_magr']=np.asarray(gal_magr) - tab['gal_magi']=np.asarray(gal_magi) - tab['gal_magz']=np.asarray(gal_magz) - - + + ################################################################# + tab = Table() + tab['gal_ra'] = np.asarray(gal_ra) + tab['gal_dec'] = np.asarray(gal_dec) + + tab['phot_C1'] = np.asarray(phot_C1) + tab['phot_C2'] = np.asarray(phot_C2) + tab['phot_C3'] = np.asarray(phot_C3) + + tab['posX_C1'] = np.asarray(posX_C1) + tab['posX_C2'] = np.asarray(posX_C2) + tab['posX_C3'] = np.asarray(posX_C3) + + tab['posY_C1'] = np.asarray(posY_C1) + tab['posY_C2'] = np.asarray(posY_C2) + tab['posY_C3'] = np.asarray(posY_C3) + + tab['gal_magu'] = np.asarray(gal_magu) + tab['gal_magg'] = np.asarray(gal_magg) + tab['gal_magr'] = np.asarray(gal_magr) + tab['gal_magi'] = np.asarray(gal_magi) + tab['gal_magz'] = np.asarray(gal_magz) + + tab['gal_ID'] = np.asarray(galID) + tab['halo_ID'] = np.asarray(haloID) + + tab['gal_new_ra'] = np.asarray(gal_new_ra) + tab['gal_new_dec'] = np.asarray(gal_new_dec) + + tab['gal_ori_ra'] = np.asarray(gal_ori_ra) + tab['gal_ori_dec'] = np.asarray(gal_ori_dec) + + tab['gal_rescale'] = np.asarray(gal_rescale) + tab['gal_szs'] = np.asarray(gal_szs) + #################################################################### - - file=self.result_path+'/log_Data/gal_info'+'_SN_'+str(self.information['simnumber'])+'.fits' - tab.write(file,overwrite=True) - - ####################################################################### - - fullimg['g']=final_image['g'].array - fullimg['r']=final_image['r'].array - fullimg['i']=final_image['i'].array - + + file = self.result_path+'/log_Data/gal_info' + \ + '_SN_'+str(self.information['simnumber'])+'.fits' + tab.write(file, overwrite=True) + + ####################################################################### + + fullimg['g'] = final_image['g'].array + fullimg['r'] = final_image['r'].array + fullimg['i'] = final_image['i'].array + return fullimg -############################################################################### +############################################################################### + +############################################################################### -############################################################################### def generatePRNU(self, ave=1.0, sigma=0.01): """ @@ -2472,57 +2674,65 @@ class MCIsimulator(): :rtype: ndarray """ self.log.info('Generating a flat field...') - self.log.info('The flat field has mean value of 1 and a given fluctuations, usually either 1 or 2 percent defined by sigma= %d...' % sigma) - - self.PRNU=dict() - + self.log.info( + 'The flat field has mean value of 1 and a given fluctuations, usually either 1 or 2 percent defined by sigma= %d...' % sigma) + + self.PRNU = dict() + np.random.seed(self.filterP[self.filter_g]['seed']) - self.PRNU['g'] = np.random.normal(loc=ave, scale=sigma, size=(self.information['ysize'], self.information['xsize'])) + self.PRNU['g'] = np.random.normal(loc=ave, scale=sigma, size=( + self.information['ysize'], self.information['xsize'])) np.random.seed(self.filterP[self.filter_r]['seed']) - self.PRNU['r'] = np.random.normal(loc=ave, scale=sigma, size=(self.information['ysize'], self.information['xsize'])) + self.PRNU['r'] = np.random.normal(loc=ave, scale=sigma, size=( + self.information['ysize'], self.information['xsize'])) np.random.seed(self.filterP[self.filter_i]['seed']) - self.PRNU['i'] = np.random.normal(loc=ave, scale=sigma, size=(self.information['ysize'], self.information['xsize'])) + self.PRNU['i'] = np.random.normal(loc=ave, scale=sigma, size=( + self.information['ysize'], self.information['xsize'])) - return self.PRNU ############################################################################### ############################################################################### + def MakeFlatMatrix(self, img, seed): #### - ysize, xsize=img.shape + ysize, xsize = img.shape np.random.seed(seed) - r1,r2,r3,r4 = np.random.random(4) + r1, r2, r3, r4 = np.random.random(4) a1 = -0.5 + 0.2*r1 a2 = -0.5 + 0.2*r2 a3 = r3+5 a4 = r4+5 - xmin,xmax,ymin,ymax = 0, xsize,0, ysize - Flty, Fltx = np.mgrid[ymin:ymax, xmin:xmax] + xmin, xmax, ymin, ymax = 0, xsize, 0, ysize + Flty, Fltx = np.mgrid[ymin:ymax, xmin:xmax] np.random.seed(seed) - p1,p2,bg=np.random.poisson(1000, 3) - Fltz = 1e-6*(a1 * (Fltx-p1) ** 2 + a2 * (Flty-p2) ** 2 - a3*Fltx - a4*Flty) + bg*20 + p1, p2, bg = np.random.poisson(1000, 3) + Fltz = 1e-6*(a1 * (Fltx-p1) ** 2 + a2 * (Flty-p2) + ** 2 - a3*Fltx - a4*Flty) + bg*20 FlatMat = Fltz/np.mean(Fltz) - + return FlatMat -#################################################################################################### - +#################################################################################################### + def applyFlat(self): - - #### apply Flat field to image - self.FlatMat=dict() + + # apply Flat field to image + self.FlatMat = dict() ### - self.FlatMat['g']=self.MakeFlatMatrix(self.image_g, self.filterP[self.filter_g]['seed']) - self.image_g*=self.FlatMat['g'] + self.FlatMat['g'] = self.MakeFlatMatrix( + self.image_g, self.filterP[self.filter_g]['seed']) + self.image_g *= self.FlatMat['g'] ### - self.FlatMat['r']=self.MakeFlatMatrix(self.image_r, self.filterP[self.filter_r]['seed']) - self.image_r*=self.FlatMat['r'] + self.FlatMat['r'] = self.MakeFlatMatrix( + self.image_r, self.filterP[self.filter_r]['seed']) + self.image_r *= self.FlatMat['r'] ### - self.FlatMat['i']=self.MakeFlatMatrix(self.image_i, self.filterP[self.filter_i]['seed']) - self.image_g*=self.FlatMat['i'] + self.FlatMat['i'] = self.MakeFlatMatrix( + self.image_i, self.filterP[self.filter_i]['seed']) + self.image_g *= self.FlatMat['i'] return - + ###################################################################################################### def applyPRNUeffect(self): """ @@ -2532,15 +2742,15 @@ class MCIsimulator(): before CTI and other effects, the flat field file must be the same size as the pixels that see the sky. """ - ### generate flatfiledfile, with - flatsigma=self.information['flatsigma'] - - self.generatePRNU(ave=1.0, sigma=flatsigma) + # generate flatfiledfile, with + flatsigma = self.information['flatsigma'] + + self.generatePRNU(ave=1.0, sigma=flatsigma) self.image_g *= self.PRNU['g'] self.image_r *= self.PRNU['r'] self.image_i *= self.PRNU['i'] self.log.info('Applied flatfield to images.') - + ################################################################################################## ################################################################################################## @@ -2552,59 +2762,71 @@ class MCIsimulator(): For details, see the documentation for the cosmicrays class in the support package. """ self.readCosmicRayInformation() - - self.cr['exptime'] = self.information['exptime'] #to scale the number of cosmics with exposure time - - #cosmic ray image - crImage = np.zeros((self.information['ysize'], self.information['xsize']), dtype=float) - - #cosmic ray instance - cosmics_g = cosmicrays.cosmicrays(self.log, crImage, self.information['exptime'], crInfo=self.cr) - cosmics_r = cosmicrays.cosmicrays(self.log, crImage, self.information['exptime'], crInfo=self.cr) - cosmics_i = cosmicrays.cosmicrays(self.log, crImage, self.information['exptime'], crInfo=self.cr) - CCD_cr_g = cosmics_g.addUpToFraction(self.information['coveringfraction']*self.information['exptime']/300.0, limit=None) - CCD_cr_r = cosmics_r.addUpToFraction(self.information['coveringfraction']*self.information['exptime']/300.0, limit=None) - CCD_cr_i = cosmics_i.addUpToFraction(self.information['coveringfraction']*self.information['exptime']/300.0, limit=None) - - #paste the information + # to scale the number of cosmics with exposure time + self.cr['exptime'] = self.information['exptime'] + + # cosmic ray image + crImage = np.zeros( + (self.information['ysize'], self.information['xsize']), dtype=float) + + # cosmic ray instance + cosmics_g = cosmicrays.cosmicrays( + self.log, crImage, self.information['exptime'], crInfo=self.cr) + cosmics_r = cosmicrays.cosmicrays( + self.log, crImage, self.information['exptime'], crInfo=self.cr) + cosmics_i = cosmicrays.cosmicrays( + self.log, crImage, self.information['exptime'], crInfo=self.cr) + + CCD_cr_g = cosmics_g.addUpToFraction( + self.information['coveringfraction']*self.information['exptime']/300.0, limit=None) + CCD_cr_r = cosmics_r.addUpToFraction( + self.information['coveringfraction']*self.information['exptime']/300.0, limit=None) + CCD_cr_i = cosmics_i.addUpToFraction( + self.information['coveringfraction']*self.information['exptime']/300.0, limit=None) + + # paste the information #self.image += CCD_cr self.image_g += CCD_cr_g self.image_r += CCD_cr_r self.image_i += CCD_cr_i - - if self.save_cosmicrays and self.cosmicRays: - + if self.save_cosmicrays and self.cosmicRays: + self.log.info('Saved the cosmicRays fits...') - fits.writeto(self.result_path+'/ori_Sky/cosmicMap_C1_N_'+str(self.information['simnumber'])+'.fits',np.int32(CCD_cr_g), overwrite=True) - fits.writeto(self.result_path+'/ori_Sky/cosmicMap_C2_N_'+str(self.information['simnumber'])+'.fits',np.int32(CCD_cr_r), overwrite=True) - fits.writeto(self.result_path+'/ori_Sky/cosmicMap_C3_N_'+str(self.information['simnumber'])+'.fits',np.int32(CCD_cr_i), overwrite=True) - - - #count the covering factor + fits.writeto(self.result_path+'/ori_Sky/cosmicMap_C1_N_'+str( + self.information['simnumber'])+'.fits', np.int32(CCD_cr_g), overwrite=True) + fits.writeto(self.result_path+'/ori_Sky/cosmicMap_C2_N_'+str( + self.information['simnumber'])+'.fits', np.int32(CCD_cr_r), overwrite=True) + fits.writeto(self.result_path+'/ori_Sky/cosmicMap_C3_N_'+str( + self.information['simnumber'])+'.fits', np.int32(CCD_cr_i), overwrite=True) + + # count the covering factor #area_cr = np.count_nonzero(self.cosmicMap) area_cr_g = np.count_nonzero(CCD_cr_g) area_cr_r = np.count_nonzero(CCD_cr_r) area_cr_i = np.count_nonzero(CCD_cr_i) - + #self.log.info('The cosmic ray covering factor is %i pixels ' % area_cr) - self.log.info('The cosmic ray in C1 channel covering factor is %i pixels ' % area_cr_g) - self.log.info('The cosmic ray in C2 channel covering factor is %i pixels ' % area_cr_r) - self.log.info('The cosmic ray in C3 channel covering factor is %i pixels ' % area_cr_i) - + self.log.info( + 'The cosmic ray in C1 channel covering factor is %i pixels ' % area_cr_g) + self.log.info( + 'The cosmic ray in C2 channel covering factor is %i pixels ' % area_cr_r) + self.log.info( + 'The cosmic ray in C3 channel covering factor is %i pixels ' % area_cr_i) + ######################################################################################## def ShutterEffectMat(self, img, t_exp=300, t_shutter=1.3, dist_bearing=4000, dt=0.001): # Generate Shutter-Effect normalized image # t_shutter: time of shutter movement # dist_bearing: distance between two bearings of shutter leaves - # dt: delta_t of sampling - + # dt: delta_t of sampling + SampleNumb = int(t_shutter/dt+1) - + DistHalf = dist_bearing/2 - + t = np.arange(SampleNumb)*dt a_arr = 5.84*np.sin(2*math.pi/t_shutter*t) v = np.zeros(SampleNumb) @@ -2613,15 +2835,15 @@ class MCIsimulator(): s = np.zeros(SampleNumb) s1 = np.zeros(SampleNumb) s2 = np.zeros(SampleNumb) - brt = np.zeros(SampleNumb) + brt = np.zeros(SampleNumb) idx = np.arange(SampleNumb) sidx = np.zeros(SampleNumb) s1idx = np.zeros(SampleNumb) s2idx = np.zeros(SampleNumb) - + v[0] = 0 theta[0] = 0 - + for i in range(SampleNumb-1): v[i+1] = v[i]+a_arr[i]*dt theta[i+1] = theta[i]+v[i]*dt @@ -2629,58 +2851,59 @@ class MCIsimulator(): s2[i] = dist_bearing-DistHalf*np.cos(theta[i]) s1idx[i] = int(s1[i]/dist_bearing*(SampleNumb)) s2idx[i] = int(s2[i]/dist_bearing*(SampleNumb)) - brt[(idx>s1idx[i]) & (idxt_shutter*2: + brt[(idx > s1idx[i]) & (idx < s2idx[i])] += dt + + if t_exp > t_shutter*2: brt = brt*2+(t_exp-t_shutter*2) else: brt = brt*2 - + x = (x-dist_bearing/2)*100 - + intp = interpolate.splrep(x, brt, s=0) - - xmin = 0 # + + xmin = 0 # xmax = img.shape[1] # row - ymin = 0 # + ymin = 0 # ymax = img.shape[0] # column - if xminnp.max(x): + if xmin < np.min(x) or xmax > np.max(x): raise LookupError("Out of focal-plane bounds in X-direction.") - if ymin<0 or ymax>25331: + if ymin < 0 or ymax > 25331: raise LookupError("Out of focal-plane bounds in Y-direction.") - + sizex = xmax-xmin sizey = ymax-ymin xnewgrid = np.mgrid[xmin:(xmin+sizex)] expeffect = interpolate.splev(xnewgrid, intp, der=0) expeffect /= np.max(expeffect) - exparrnormal = np.tile(expeffect, (sizey,1)) - + exparrnormal = np.tile(expeffect, (sizey, 1)) + # Image *= exparrnormal - - shutter=(1-exparrnormal)*t_exp - shutter=shutter/shutter.max()*(t_shutter*2) - + + shutter = (1-exparrnormal)*t_exp + shutter = shutter/shutter.max()*(t_shutter*2) + return shutter - -######################################################################################## + +######################################################################################## def addshuttereffect(self): ''' apply shutter effect to image''' - # - if self.information['exptime']>0: - self.shutter=self.ShutterEffectMat(self.image_g) - - self.shutterMat=1-self.shutter/self.information['exptime'] - + # + if self.information['exptime'] > 0: + self.shutter = self.ShutterEffectMat(self.image_g) + + self.shutterMat = 1-self.shutter/self.information['exptime'] + self.image_g *= self.shutterMat self.image_r *= self.shutterMat self.image_i *= self.shutterMat - if self.information['simnumber']==1: - fits.writeto(self.result_path+'/cali_Data/'+'shutter.fits', self.shutter, overwrite=True) - + if self.information['simnumber'] == 1: + fits.writeto(self.result_path+'/cali_Data/' + + 'shutter.fits', self.shutter, overwrite=True) + return - -######################################################################################## + +######################################################################################## def applyDarkCurrent(self): """ Apply dark current. Scales the dark with the exposure time. @@ -2688,7 +2911,7 @@ class MCIsimulator(): Additionally saves the image without noise to a FITS file. """ - #add dark + # add dark dark = self.information['exptime'] * self.information['dark'] self.image_g += dark @@ -2702,22 +2925,22 @@ class MCIsimulator(): """ Add Poisson sky noise to the image. """ - skynoise_g=self.Sky_Noise['g']*np.ones_like(self.image_g) - + skynoise_g = self.Sky_Noise['g']*np.ones_like(self.image_g) + np.random.seed(11*self.information['simnumber']) - self.image_g =self.image_g+ np.random.poisson(lam=skynoise_g) + self.image_g = self.image_g + np.random.poisson(lam=skynoise_g) self.log.info('Added Poisson sky noise on channel g') - skynoise_r=self.Sky_Noise['r']*np.ones_like(self.image_r) + skynoise_r = self.Sky_Noise['r']*np.ones_like(self.image_r) np.random.seed(111*self.information['simnumber']) - self.image_r =self.image_r+ np.random.poisson(lam=skynoise_r) + self.image_r = self.image_r + np.random.poisson(lam=skynoise_r) self.log.info('Added Poisson sky noise on channel r') - - skynoise_i=self.Sky_Noise['i']*np.ones_like(self.image_i) + + skynoise_i = self.Sky_Noise['i']*np.ones_like(self.image_i) np.random.seed(1111*self.information['simnumber']) - self.image_i =self.image_i+ np.random.poisson(lam=skynoise_i) + self.image_i = self.image_i + np.random.poisson(lam=skynoise_i) self.log.info('Added Poisson sky noise on channel i') - + return ############################################################################### @@ -2725,121 +2948,125 @@ class MCIsimulator(): def applyCosmetics(self): """ Apply cosmetic defects described in the input file. - + #Number of hot and dead pixels from MSSL/Euclid/TR/12003 Issue 2 Draft b .. Warning:: This method does not work if the input file has exactly one line. """ ####################################################################### - cosmetics = np.loadtxt(self.information['dir_path']+'MCI_inputData/data/Cosmetics_g.txt') + cosmetics = np.loadtxt( + self.information['dir_path']+'MCI_inputData/data/Cosmetics_g.txt') - x = np.round(cosmetics[:, 0]).astype(int) ## row number - y = np.round(cosmetics[:, 1]).astype(int) ## col number + x = np.round(cosmetics[:, 0]).astype(int) # row number + y = np.round(cosmetics[:, 1]).astype(int) # col number value = np.round(cosmetics[:, 2]).astype(int) - #cosmetics_g=np.zeros((4636,235526)) - - self.log.info('Adding cosmetic defects to C1 channel:' ) + # cosmetics_g=np.zeros((4636,235526)) + + self.log.info('Adding cosmetic defects to C1 channel:') for xc, yc, val in zip(x, y, value): - if 0 < xc < 4616 and 27 < (yc % 1499) <1179: - - self.image_g[xc, yc] = val - #cosmetics_g[yc,xc]=val + if 0 < xc < 4616 and 27 < (yc % 1499) < 1179: + + self.image_g[xc, yc] = val + # cosmetics_g[yc,xc]=val self.log.info('x=%i, y=%i, value=%f' % (xc, yc, val)) ###################################################################### ####################################################################### - cosmetics = np.loadtxt(self.information['dir_path']+'MCI_inputData/data/Cosmetics_r.txt') + cosmetics = np.loadtxt( + self.information['dir_path']+'MCI_inputData/data/Cosmetics_r.txt') - x = np.round(cosmetics[:, 0]).astype(int) ## row number - y = np.round(cosmetics[:, 1]).astype(int) ## col number + x = np.round(cosmetics[:, 0]).astype(int) # row number + y = np.round(cosmetics[:, 1]).astype(int) # col number value = np.round(cosmetics[:, 2]).astype(int) - self.log.info('Adding cosmetic defects to C2 channel:' ) + self.log.info('Adding cosmetic defects to C2 channel:') for xc, yc, val in zip(x, y, value): - if 0 < xc < 4616 and 27 < (yc % 1499) <1179: - - self.image_r[xc, yc] = val - #cosmetics_r[yc,xc]=val + if 0 < xc < 4616 and 27 < (yc % 1499) < 1179: + + self.image_r[xc, yc] = val + # cosmetics_r[yc,xc]=val self.log.info('x=%i, y=%i, value=%f' % (xc, yc, val)) ############################################################################## ####################################################################### - cosmetics = np.loadtxt(self.information['dir_path']+'MCI_inputData/data/Cosmetics_i.txt') + cosmetics = np.loadtxt( + self.information['dir_path']+'MCI_inputData/data/Cosmetics_i.txt') - x = np.round(cosmetics[:, 0]).astype(int) ## row number - y = np.round(cosmetics[:, 1]).astype(int) ## col number + x = np.round(cosmetics[:, 0]).astype(int) # row number + y = np.round(cosmetics[:, 1]).astype(int) # col number value = np.round(cosmetics[:, 2]).astype(int) - #cosmetics_i=np.zeros((4636,235526)) - - self.log.info('Adding cosmetic defects to C3 channel:' ) + # cosmetics_i=np.zeros((4636,235526)) + + self.log.info('Adding cosmetic defects to C3 channel:') for xc, yc, val in zip(x, y, value): - if 0 < xc < 4616 and 27 < (yc % 1499) <1179: - - self.image_i[xc, yc] = val - #cosmetics_i[yc,xc]=val + if 0 < xc < 4616 and 27 < (yc % 1499) < 1179: + + self.image_i[xc, yc] = val + # cosmetics_i[yc,xc]=val self.log.info('x=%i, y=%i, value=%f' % (xc, yc, val)) - ####### save cosmetics image code #### + ####### save cosmetics image code #### # if self.simnumber<2: - # #save cosmic ray image map - + # #save cosmic ray image map + # obsid=self.simnumber - # bluefile=self.result_path+'/calibration_Data/IFS_cosmetics'+'_'+str(obsid)+'_B.fits' - # redfile =self.result_path+'/calibration_Data/IFS_cosmetics'+'_'+str(obsid)+'_R.fits' - - # fits.writeto(bluefile, cosmetics_b, overwrite=True) + # bluefile=self.result_path+'/calibration_Data/IFS_cosmetics'+'_'+str(obsid)+'_B.fits' + # redfile =self.result_path+'/calibration_Data/IFS_cosmetics'+'_'+str(obsid)+'_R.fits' + + # fits.writeto(bluefile, cosmetics_b, overwrite=True) # fits.writeto(redfile, cosmetics_r, overwrite=True) - + # #output information to a FITS file # self.log.info('Save cosmetics images fits file to calibration_Data file ') -############################################################################################################################# +############################################################################################################################# def applyRadiationDamage(self): """ Applies CDM03 radiation model to the image being constructed. .. seealso:: Class :`CDM03` """ - #save image without CTI + # save image without CTI self.noCTI_g = self.image_g.copy() - + self.log.debug('Starting to apply radiation damage model...') - #at this point we can give fake data... + # at this point we can give fake data... cti = CDM03bidir(self.information, [], log=self.log) - #here we need the right input data - self.image_g = cti.applyRadiationDamage(self.image_g.copy().transpose(), iquadrant=self.information['quadrant']).transpose() + # here we need the right input data + self.image_g = cti.applyRadiationDamage(self.image_g.copy( + ).transpose(), iquadrant=self.information['quadrant']).transpose() self.log.info('Radiation damage added.') ################################################# - + self.noCTI_r = self.image_r.copy() - - + self.log.debug('Starting to apply radiation damage model...') - #at this point we can give fake data... + # at this point we can give fake data... cti = CDM03bidir(self.information, [], log=self.log) - #here we need the right input data - self.image_r = cti.applyRadiationDamage(self.image_r.copy().transpose(), iquadrant=self.information['quadrant']).transpose() + # here we need the right input data + self.image_r = cti.applyRadiationDamage(self.image_r.copy( + ).transpose(), iquadrant=self.information['quadrant']).transpose() self.log.info('Radiation damage added.') ################################################## - + self.noCTI_i = self.image_i.copy() - + self.log.debug('Starting to apply radiation damage model...') - #at this point we can give fake data... + # at this point we can give fake data... cti = CDM03bidir(self.information, [], log=self.log) - #here we need the right input data - self.image_i = cti.applyRadiationDamage(self.image_i.copy().transpose(), iquadrant=self.information['quadrant']).transpose() + # here we need the right input data + self.image_i = cti.applyRadiationDamage(self.image_i.copy( + ).transpose(), iquadrant=self.information['quadrant']).transpose() self.log.info('Radiation damage added.') - ########################################################################### def applyNonlinearity(self): """ Applies a CCD273 non-linearity model to the image being constructed. - + """ self.log.debug('Starting to apply non-linearity model...') @@ -2851,7 +3078,7 @@ class MCIsimulator(): self.image_r = CCDnonLinearityModel(self.image_r.copy()) self.log.info('Non-linearity effects included.') - ######################################################################## + ######################################################################## self.log.debug('Starting to apply non-linearity model...') self.image_i = CCDnonLinearityModel(self.image_i.copy()) @@ -2860,266 +3087,290 @@ class MCIsimulator(): ############################################################################### def applyReadoutNoise(self): - """ Applies readout noise to the image being constructed. The noise is drawn from a Normal (Gaussian) distribution with average=0.0 and std=readout noise. - """ - if self.overscans and self.information['xsize']==9216 and self.information['ysize']==9232 : - xmin=dict() - xmax=dict() - ymin=dict() - ymax=dict() - - ############## calculate the non-over subimg of the final matrix of the image - for k in range(1,17): - xmin[k]=0 - xmax[k]=4616+self.overscan - - ymin[k]=(1152+self.prescan+self.overscan)*(k-1) - ymax[k]=(1152+self.prescan+self.overscan)*(k) - ############### - np.random.seed(2*self.information['simnumber']) - noise_g = np.random.normal(loc=0.0, scale=self.information['g_rdnois'+str(k)], size=(4616+self.overscan,1152+self.overscan+self.prescan)) - self.image_g[xmin[k]:xmax[k], ymin[k]:ymax[k]]+=noise_g - self.log.info('Bias of %i counts were added to the g band image' % self.information['g_rdnois'+str(k)]) - - np.random.seed(22*self.information['simnumber']) - noise_r = np.random.normal(loc=0.0, scale=self.information['r_rdnois'+str(k)], size=(4616+self.overscan,1152+self.overscan+self.prescan)) - self.image_r[xmin[k]:xmax[k], ymin[k]:ymax[k]]+=noise_r - self.log.info('Bias of %i counts were added to the r band image' % self.information['r_rdnois'+str(k)]) - - np.random.seed(222*self.information['simnumber']) - noise_i = np.random.normal(loc=0.0, scale=self.information['i_rdnois'+str(k)], size=(4616+self.overscan,1152+self.overscan+self.prescan)) - self.image_i[xmin[k]:xmax[k], ymin[k]:ymax[k]]+=noise_i - self.log.info('Bias of %i counts were added to the i band image' % self.information['i_rdnois'+str(k)]) - - ### end for - + """ + if self.overscans and self.information['xsize'] == 9216 and self.information['ysize'] == 9232: + xmin = dict() + xmax = dict() + ymin = dict() + ymax = dict() + + # calculate the non-over subimg of the final matrix of the image + for k in range(1, 17): + xmin[k] = 0 + xmax[k] = 4616+self.overscan + + ymin[k] = (1152+self.prescan+self.overscan)*(k-1) + ymax[k] = (1152+self.prescan+self.overscan)*(k) + ############### + np.random.seed(2*self.information['simnumber']) + noise_g = np.random.normal(loc=0.0, scale=self.information['g_rdnois'+str( + k)], size=(4616+self.overscan, 1152+self.overscan+self.prescan)) + self.image_g[xmin[k]:xmax[k], ymin[k]:ymax[k]] += noise_g + self.log.info('Bias of %i counts were added to the g band image' % + self.information['g_rdnois'+str(k)]) + + np.random.seed(22*self.information['simnumber']) + noise_r = np.random.normal(loc=0.0, scale=self.information['r_rdnois'+str( + k)], size=(4616+self.overscan, 1152+self.overscan+self.prescan)) + self.image_r[xmin[k]:xmax[k], ymin[k]:ymax[k]] += noise_r + self.log.info('Bias of %i counts were added to the r band image' % + self.information['r_rdnois'+str(k)]) + + np.random.seed(222*self.information['simnumber']) + noise_i = np.random.normal(loc=0.0, scale=self.information['i_rdnois'+str( + k)], size=(4616+self.overscan, 1152+self.overscan+self.prescan)) + self.image_i[xmin[k]:xmax[k], ymin[k]:ymax[k]] += noise_i + self.log.info('Bias of %i counts were added to the i band image' % + self.information['i_rdnois'+str(k)]) + + # end for + else: - + np.random.seed(3*self.information['simnumber']) noise = np.random.normal(loc=0.0, scale=4, size=self.image_g.shape) - self.log.info('Sum of readnoise in g channel = %f' % np.sum(noise)) - #add to the image - self.image_g += noise - - ####################################################### - np.random.seed(33*self.information['simnumber']) + self.log.info('Sum of readnoise in g channel = %f' % np.sum(noise)) + # add to the image + self.image_g += noise + + ####################################################### + np.random.seed(33*self.information['simnumber']) noise = np.random.normal(loc=0.0, scale=4, size=self.image_r.shape) - self.log.info('Sum of readnoise in r channel= %f' % np.sum(noise)) - #add to the image - self.image_r += noise - - ######################################## - np.random.seed(333*self.information['simnumber']) + self.log.info('Sum of readnoise in r channel= %f' % np.sum(noise)) + # add to the image + self.image_r += noise + + ######################################## + np.random.seed(333*self.information['simnumber']) noise = np.random.normal(loc=0.0, scale=4, size=self.image_i.shape) - self.log.info('Sum of readnoise in i channel= %f' % np.sum(noise)) - #add to the image + self.log.info('Sum of readnoise in i channel= %f' % np.sum(noise)) + # add to the image self.image_i += noise - + return - -########################################################################################################## - + +########################################################################################################## + def electrons2ADU(self): """ Convert from electrons to ADUs using the value read from the configuration file. """ ##### if self.overscans: - ###################### - xmin=dict() - xmax=dict() - ymin=dict() - ymax=dict() - - ############## calculate the non-over subimg of the final matrix of the image - for k in range(1,17): - xmin[k]=0 - xmax[k]=4616+self.overscan - - ymin[k]=(1152+self.overscan+self.prescan)*(k-1) - ymax[k]=(1152+self.overscan+self.prescan)*(k) + ###################### + xmin = dict() + xmax = dict() + ymin = dict() + ymax = dict() + + # calculate the non-over subimg of the final matrix of the image + for k in range(1, 17): + xmin[k] = 0 + xmax[k] = 4616+self.overscan + + ymin[k] = (1152+self.overscan+self.prescan)*(k-1) + ymax[k] = (1152+self.overscan+self.prescan)*(k) ############### - - self.image_g[xmin[k]:xmax[k], ymin[k]:ymax[k]]/=self.information['g_gain'+str(k)] - - self.image_r[xmin[k]:xmax[k], ymin[k]:ymax[k]]/=self.information['r_gain'+str(k)] - - self.image_i[xmin[k]:xmax[k], ymin[k]:ymax[k]]/=self.information['i_gain'+str(k)] - - ### end for + + self.image_g[xmin[k]:xmax[k], ymin[k]:ymax[k] + ] /= self.information['g_gain'+str(k)] + + self.image_r[xmin[k]:xmax[k], ymin[k]:ymax[k] + ] /= self.information['r_gain'+str(k)] + + self.image_i[xmin[k]:xmax[k], ymin[k]:ymax[k] + ] /= self.information['i_gain'+str(k)] + + # end for return - - #################################################################################### - + + #################################################################################### + def applyBias(self): """ Adds a bias level to the image being constructed. The value of bias is read from the configure file and stored in the information dictionary (key bias). - + """ - - xmin=dict() - xmax=dict() - ymin=dict() - ymax=dict() - - ############## calculate the non-over subimg of the final matrix of the image - for k in range(1,17): - xmin[k]=0 - xmax[k]=4616+self.overscan - - ymin[k]=(1152+self.prescan+self.overscan)*(k-1) - ymax[k]=(1152+self.prescan+self.overscan)*(k) - ############### - self.image_g[xmin[k]:xmax[k], ymin[k]:ymax[k]]+=self.information['g_detbia'+str(k)] - self.log.info('Bias of %i counts were added to the g band image' % self.information['g_detbia'+str(k)]) - - self.image_r[xmin[k]:xmax[k], ymin[k]:ymax[k]]+=self.information['r_detbia'+str(k)] - self.log.info('Bias of %i counts were added to the g band image' % self.information['r_detbia'+str(k)]) - - self.image_i[xmin[k]:xmax[k], ymin[k]:ymax[k]]+=self.information['i_detbia'+str(k)] - self.log.info('Bias of %i counts were added to the g band image' % self.information['i_detbia'+str(k)]) - - ### end for + + xmin = dict() + xmax = dict() + ymin = dict() + ymax = dict() + + # calculate the non-over subimg of the final matrix of the image + for k in range(1, 17): + xmin[k] = 0 + xmax[k] = 4616+self.overscan + + ymin[k] = (1152+self.prescan+self.overscan)*(k-1) + ymax[k] = (1152+self.prescan+self.overscan)*(k) + ############### + self.image_g[xmin[k]:xmax[k], ymin[k]:ymax[k] + ] += self.information['g_detbia'+str(k)] + self.log.info('Bias of %i counts were added to the g band image' % + self.information['g_detbia'+str(k)]) + + self.image_r[xmin[k]:xmax[k], ymin[k]:ymax[k] + ] += self.information['r_detbia'+str(k)] + self.log.info('Bias of %i counts were added to the g band image' % + self.information['r_detbia'+str(k)]) + + self.image_i[xmin[k]:xmax[k], ymin[k]:ymax[k] + ] += self.information['i_detbia'+str(k)] + self.log.info('Bias of %i counts were added to the g band image' % + self.information['i_detbia'+str(k)]) + + # end for return - + ############################################################################## def img_fits_save(self, data, filename): - #### - + #### + ofd_g = fits.PrimaryHDU() #### World coordinate system and related parameters ##### - hdu_g = fits.ImageHDU(data) - - hdu_g.header['WCSAXES']=(np.int16(2) , 'number of WCS axes') - hdu_g.header['CRPIX1'] =( round(float(self.information['CRPIX1']) ,1) , 'x-coordinate of reference pixel') - hdu_g.header['CRPIX2'] =( round(float(self.information['CRPIX2']) ,1) , 'y-coordinate of reference pixel') - - hdu_g.header['CRVAL1'] =( float(self.information['CRVAL1']) , 'first axis value at reference pixel') - hdu_g.header['CRVAL2'] =( float(self.information['CRVAL2']) , 'second axis value at reference pixel') - hdu_g.header['CTYPE1'] =( 'RA---TAN' , 'the coordinate type for the first axis') - hdu_g.header['CTYPE2'] =( 'DEC--TAN' , 'the coordinate type for the second axis') - hdu_g.header['CD1_1'] =( float(self.information['CD1_1']) , 'partial of first axis coordinate w.r.t. x') - hdu_g.header['CD1_2'] =( float(self.information['CD1_2']) , 'partial of first axis coordinate w.r.t. y') - hdu_g.header['CD2_1'] =( float(self.information['CD2_1']) , 'partial of second axis coordinate w.r.t. x') - hdu_g.header['CD2_2'] =( float(self.information['CD2_2']) , 'partial of second axis coordinate w.r.t. y') - - hdulist_g=fits.HDUList([ofd_g, hdu_g]) - - file_g=self.result_path+'/ori_Sky/'+filename +'.fits' - + hdu_g = fits.ImageHDU(data) + + hdu_g.header['WCSAXES'] = (np.int16(2), 'number of WCS axes') + hdu_g.header['CRPIX1'] = ( + round(float(self.information['CRPIX1']), 1), 'x-coordinate of reference pixel') + hdu_g.header['CRPIX2'] = ( + round(float(self.information['CRPIX2']), 1), 'y-coordinate of reference pixel') + + hdu_g.header['CRVAL1'] = ( + float(self.information['CRVAL1']), 'first axis value at reference pixel') + hdu_g.header['CRVAL2'] = ( + float(self.information['CRVAL2']), 'second axis value at reference pixel') + hdu_g.header['CTYPE1'] = ( + 'RA---TAN', 'the coordinate type for the first axis') + hdu_g.header['CTYPE2'] = ( + 'DEC--TAN', 'the coordinate type for the second axis') + hdu_g.header['CD1_1'] = ( + float(self.information['CD1_1']), 'partial of first axis coordinate w.r.t. x') + hdu_g.header['CD1_2'] = ( + float(self.information['CD1_2']), 'partial of first axis coordinate w.r.t. y') + hdu_g.header['CD2_1'] = ( + float(self.information['CD2_1']), 'partial of second axis coordinate w.r.t. x') + hdu_g.header['CD2_2'] = ( + float(self.information['CD2_2']), 'partial of second axis coordinate w.r.t. y') + + hdulist_g = fits.HDUList([ofd_g, hdu_g]) + + file_g = self.result_path+'/ori_Sky/'+filename + '.fits' + hdulist_g.writeto(file_g, overwrite=True) return - - + #################################################################################### + def applyBleeding(self, img, direction='not_horizon'): """ Apply bleeding along the CCD readout direction if the number of electrons in a pixel exceeds the full-well capacity. - + direction: this is the CCD readout direction, and default value is horizon direction - + :return: the bleeding image """ - - data=img.copy() - - if data.max() 0.: overload /= 2. #self.image[j, i] -= overload - data[i, j] -= overload + data[i, j] -= overload sum += overload - + elif sum > 0.: if -overload > sum: overload = -sum #self.image[j, i] -= overload - data[i,j] -= overload + data[i, j] -= overload sum += overload ###################################################### for i, column in enumerate(data): - if column.max() <=self.information['fullwellcapacity']: + if column.max() <= self.information['fullwellcapacity']: continue sum = 0. for j, value in enumerate(column[::-1]): - #second round - from top to bottom (bleeding was half'd already, so now full) + # second round - from top to bottom (bleeding was half'd already, so now full) overload = value - self.information['fullwellcapacity'] if overload > 0.: #self.image[-j-1, i] -= overload - data[ i,-j-1] -= overload + data[i, -j-1] -= overload sum += overload - + elif sum > 0.: if -overload > sum: overload = -sum #self.image[-j-1, i] -= overload - data[i,-j-1,] -= overload + data[i, -j-1,] -= overload sum += overload - - else: - - #loop over each column, as bleeding is modelled column-wise + + else: + + # loop over each column, as bleeding is modelled column-wise for i, column in enumerate(data.T): sum = 0. for j, value in enumerate(column): - #first round - from bottom to top (need to half the bleeding) + # first round - from bottom to top (need to half the bleeding) overload = value - self.information['fullwellcapacity'] if overload > 0.: overload /= 2. #self.image[j, i] -= overload data[j, i] -= overload - + sum += overload elif sum > 0.: if -overload > sum: overload = -sum #self.image[j, i] -= overload - data[j, i] -= overload + data[j, i] -= overload sum += overload ################################ for i, column in enumerate(data.T): sum = 0. for j, value in enumerate(column[::-1]): - #second round - from top to bottom (bleeding was half'd already, so now full) + # second round - from top to bottom (bleeding was half'd already, so now full) overload = value - self.information['fullwellcapacity'] if overload > 0.: #self.image[-j-1, i] -= overload data[-j-1, i] -= overload - + sum += overload elif sum > 0.: if -overload > sum: overload = -sum #self.image[-j-1, i] -= overload - data[-j-1, i] -= overload + data[-j-1, i] -= overload sum += overload - + #####print('Applying column bleeding finished.......') return data - + ############################################################################ def discretise(self, max=2**16-1): @@ -3133,132 +3384,130 @@ class MCIsimulator(): :return: None """ - - #avoid negative numbers in case bias level was not added + # avoid negative numbers in case bias level was not added self.image_g[self.image_g < 0.0] = 0. - #cut of the values larger than max + # cut of the values larger than max self.image_g[self.image_g > max] = max self.image_g = np.rint(self.image_g).astype(int) self.log.info('Maximum and total values of the image are %i and %i, respectively' % (np.max(self.image_g), np.sum(self.image_g))) - #avoid negative numbers in case bias level was not added + # avoid negative numbers in case bias level was not added self.image_r[self.image_r < 0.0] = 0. - #cut of the values larger than max + # cut of the values larger than max self.image_r[self.image_r > max] = max self.image_r = np.rint(self.image_r).astype(int) self.log.info('Maximum and total values of the image are %i and %i, respectively' % (np.max(self.image_r), np.sum(self.image_r))) - + ############################################################################### - #avoid negative numbers in case bias level was not added + # avoid negative numbers in case bias level was not added self.image_i[self.image_i < 0.0] = 0. - #cut of the values larger than max + # cut of the values larger than max self.image_i[self.image_i > max] = max self.image_i = np.rint(self.image_i).astype(int) self.log.info('Maximum and total values of the image are %i and %i, respectively' % (np.max(self.image_i), np.sum(self.image_i))) - - ################################################################################################## + + ################################################################################################## def addScanEffect(self, img): - #### read CCD image to matrix as defined data format + # read CCD image to matrix as defined data format ''' function: add prescan and overscan empty zone to the CCD physical image - + return: img - + ''' - + ### xsize is column, ysize is row - - self.prescan =self.information['prescan'] ## horizon direction , columnn - self.overscan=self.information['overscan'] ## vertical direction, row - + + # horizon direction , columnn + self.prescan = self.information['prescan'] + self.overscan = self.information['overscan'] # vertical direction, row + row = self.information['ysize'] col = self.information['xsize'] - if row !=9232 or col !=9216: ##### + if row != 9232 or col != 9216: print('image size is not correct.......') sys.exit(1) #### ########################################### - xmin=dict() - xmax=dict() - ymin=dict() - ymax=dict() - #### physical CCD zone 1-16 - for n in range(1,17): - - #### physical zone index - if n<9: - xmin[n]=4616 # row number - xmax[n]=4616*2 - - ymin[n]=(n-1)*1152 # col number - ymax[n]=ymin[n]+1152 + xmin = dict() + xmax = dict() + ymin = dict() + ymax = dict() + # physical CCD zone 1-16 + for n in range(1, 17): + + # physical zone index + if n < 9: + xmin[n] = 4616 # row number + xmax[n] = 4616*2 + + ymin[n] = (n-1)*1152 # col number + ymax[n] = ymin[n]+1152 else: - xmin[n]=0 - xmax[n]=4616 - - ymin[n]=(16-n)*1152 - ymax[n]=ymin[n]+1152 + xmin[n] = 0 + xmax[n] = 4616 + + ymin[n] = (16-n)*1152 + ymax[n] = ymin[n]+1152 ########################################### - temp=np.zeros((int(4616+self.overscan), int((1152+self.overscan+self.prescan)*16))) - - matxmin=dict() - matxmax=dict() - matymin=dict() - matymax=dict() - -############## get the non-over subimg of the final matrix of the image - for k in range(1,17): - - ### big new image include prescan and overscan; - matxmin[k]=0 ### row number - matxmax[k]=4616 ### row number - - matymin[k]=(1152+self.overscan+self.prescan)*(k-1)+self.prescan ## col number start - matymax[k]= matymin[k]+1152 ## col number end - + temp = np.zeros( + (int(4616+self.overscan), int((1152+self.overscan+self.prescan)*16))) + + matxmin = dict() + matxmax = dict() + matymin = dict() + matymax = dict() + +# get the non-over subimg of the final matrix of the image + for k in range(1, 17): + + # big new image include prescan and overscan; + matxmin[k] = 0 # row number + matxmax[k] = 4616 # row number + + matymin[k] = (1152+self.overscan+self.prescan) * \ + (k-1)+self.prescan # col number start + matymax[k] = matymin[k]+1152 # col number end + ################################ - - for k in range(1,17): - if k<=4: ### zos1 zos2 zos3 zos4 - subimg=img[xmin[k]:xmax[k],ymin[k]:ymax[k]] # get k-th subimg from input img - subimg=np.flipud(subimg) ## down to up, up to down - - - - if k>=5 and k<=8: ### zos5 zos6 zos7 zos8 - subimg=img[xmin[k]:xmax[k],ymin[k]:ymax[k]] # get k-th subimg from input img - subimg=np.flipud(subimg) ## down to up, up to down - subimg=np.fliplr(subimg) ## left to right ,right to left - - - - if k>=9 and k<=12: ### zos5 zos6 zos7 zos8 - subimg=img[xmin[k]:xmax[k],ymin[k]:ymax[k]] # get k-th subimg from input img - subimg=np.fliplr(subimg) ## left to right ,right to left - - - - if k>=13 and k<=16: ### zos5 zos6 zos7 zos8 - subimg=img[xmin[k]:xmax[k],ymin[k]:ymax[k]] # get k-th subimg from input img - - + + for k in range(1, 17): + if k <= 4: # zos1 zos2 zos3 zos4 + # get k-th subimg from input img + subimg = img[xmin[k]:xmax[k], ymin[k]:ymax[k]] + subimg = np.flipud(subimg) # down to up, up to down + + if k >= 5 and k <= 8: # zos5 zos6 zos7 zos8 + # get k-th subimg from input img + subimg = img[xmin[k]:xmax[k], ymin[k]:ymax[k]] + subimg = np.flipud(subimg) # down to up, up to down + subimg = np.fliplr(subimg) # left to right ,right to left + + if k >= 9 and k <= 12: # zos5 zos6 zos7 zos8 + # get k-th subimg from input img + subimg = img[xmin[k]:xmax[k], ymin[k]:ymax[k]] + subimg = np.fliplr(subimg) # left to right ,right to left + + if k >= 13 and k <= 16: # zos5 zos6 zos7 zos8 + # get k-th subimg from input img + subimg = img[xmin[k]:xmax[k], ymin[k]:ymax[k]] + ###################### - - temp[matxmin[k]:matxmax[k],matymin[k]:matymax[k]]=subimg[:,:] - #### end for + + temp[matxmin[k]:matxmax[k], matymin[k]:matymax[k]] = subimg[:, :] + # end for return temp ########################################################################### - - ######################################################################################### + ######################################################################################### def writeOutputs(self, obnum=1): """ @@ -3268,1222 +3517,1764 @@ class MCIsimulator(): Updates header with the input values and flags used during simulation. """ - ## Readout information - - HeaderTest='no' + # Readout information + + HeaderTest = 'no' ########################################################################## - if self.source=='EXDF': - obsid=20100000000+obnum - - if self.source=='STAR': - obsid=20200000000+obnum - - if self.source=='PIPR': - obsid=20300000000+obnum - - if self.source=='TRNS': - obsid=20400000000+obnum - - if self.source=='COMB': - obsid=20500000000+obnum - - if self.source=='CALI': - obsid=20600000000+obnum - - if self.source=='BIAS': - obsid=20700000000+obnum - - if self.source=='DARK': - obsid=20800000000+obnum - - if self.source=='FLAT': - obsid=20900000000+obnum - ############################# - - if self.source=='OSBS': - obsid=21000000000+obnum - - if self.source=='OSDK': - obsid=21100000000+obnum - - if self.source=='OSFT': - obsid=21200000000+obnum - - if self.source=='FRNG': - obsid=21300000000+obnum - + if self.source == 'EXDF': + obsid = 20100000000+obnum + + if self.source == 'STAR': + obsid = 20200000000+obnum + + if self.source == 'PIPR': + obsid = 20300000000+obnum + + if self.source == 'TRNS': + obsid = 20400000000+obnum + + if self.source == 'COMB': + obsid = 20500000000+obnum + + if self.source == 'CALI': + obsid = 20600000000+obnum + + if self.source == 'BIAS': + obsid = 20700000000+obnum + + if self.source == 'DARK': + obsid = 20800000000+obnum + + if self.source == 'FLAT': + obsid = 20900000000+obnum + ############################# + + if self.source == 'OSBS': + obsid = 21000000000+obnum + + if self.source == 'OSDK': + obsid = 21100000000+obnum + + if self.source == 'OSFT': + obsid = 21200000000+obnum + + if self.source == 'FRNG': + obsid = 21300000000+obnum + ####################################################################### - exp_starttime=self.dt.strftime("%Y%m%d%H%M%S") - - ### exposure end time is t2 ; - t2=self.dt+timedelta(seconds=self.information['exptime']) - exp_endtime=t2.strftime("%Y%m%d%H%M%S") + exp_starttime = self.dt.strftime("%Y%m%d%H%M%S") + + # exposure end time is t2 ; + t2 = self.dt+timedelta(seconds=self.information['exptime']) + exp_endtime = t2.strftime("%Y%m%d%H%M%S") ### data read time is the exposure end time ### - ### data read end time is t3, and this is the write file time; - t3=self.dt+timedelta(seconds=self.information['exptime'])+timedelta(seconds=self.information['readouttime']) - - - if self.filterP[self.filter_g]['number']>9: - filternum=str(self.filterP[self.filter_g]['number']) + # data read end time is t3, and this is the write file time; + t3 = self.dt+timedelta(seconds=self.information['exptime'])+timedelta( + seconds=self.information['readouttime']) + + if self.filterP[self.filter_g]['number'] > 9: + filternum = str(self.filterP[self.filter_g]['number']) else: - filternum='0'+str(self.filterP[self.filter_g]['number']) - - - filename_g='CSST_MCI_C1_'+self.source+'_'+exp_starttime+'_'+exp_endtime+'_'+str(obsid)+'_'+ \ - filternum+'_L0_V01' - + filternum = '0'+str(self.filterP[self.filter_g]['number']) + + filename_g = 'CSST_MCI_C1_'+self.source+'_'+exp_starttime+'_'+exp_endtime+'_'+str(obsid)+'_' + \ + filternum+'_L0_V01' + ####################################################################### ####################################################################### - #create a new FITS file, using HDUList instance + # create a new FITS file, using HDUList instance + ofd_g = fits.PrimaryHDU() + # add primary header ofd_g = fits.PrimaryHDU() - #### add primary header - ofd_g = fits.PrimaryHDU() - ofd_g.header['SIMPLE']=( True, 'conforms to FITS standard') - ofd_g.header['BITPIX']=( 0, 'array data type') - ofd_g.header['NAXIS'] =( 0, 'number of array dimensions') - ofd_g.header['NEXTEND']=( np.int16(1), 'number of array dimensions') + ofd_g.header['SIMPLE'] = (True, 'conforms to FITS standard') + ofd_g.header['BITPIX'] = (0, 'array data type') + ofd_g.header['NAXIS'] = (0, 'number of array dimensions') + ofd_g.header['NEXTEND'] = (np.int16(1), 'number of array dimensions') ####################################################################### ########################### - temp=t3.utcnow() - data_time=temp.strftime("%Y-%m-%dT%H:%M:%S.%f") - ofd_g.header['DATE'] =(data_time[:21], 'written date (yyyy-mm-ddThh:mm:ss.s)') - ofd_g.header['FILENAME']=(filename_g[:68],'') - ofd_g.header['FILETYPE'] =( self.source[:12], 'observation type') - ofd_g.header['TELESCOP']=('CSST', 'telescope name') - ofd_g.header['INSTRUME']=('MCI', 'instrument name') - ofd_g.header['RADECSYS']=('ICRS', 'coordinate system of the object') - ofd_g.header['EQUINOX'] =(float(2000.0), '') - ofd_g.header['FITSSWV']=('mci_sim_0.8.03', 'FITS creating software version') + temp = t3.utcnow() + data_time = temp.strftime("%Y-%m-%dT%H:%M:%S.%f") + ofd_g.header['DATE'] = ( + data_time[:21], 'written date (yyyy-mm-ddThh:mm:ss.s)') + ofd_g.header['FILENAME'] = (filename_g[:68], '') + ofd_g.header['FILETYPE'] = (self.source[:12], 'observation type') + ofd_g.header['TELESCOP'] = ('CSST', 'telescope name') + ofd_g.header['INSTRUME'] = ('MCI', 'instrument name') + ofd_g.header['RADECSYS'] = ( + 'ICRS', 'coordinate system of the object') + ofd_g.header['EQUINOX'] = (float(2000.0), '') + ofd_g.header['FITSSWV'] = ( + 'mci_sim_0.8.03', 'FITS creating software version') ############################################################################## - ######### Object information ######################################### - ofd_g.header['OBJECT'] =(self.information['name_obj'][:30], 'object name') - ofd_g.header['TARGET'] =(self.information['target'][:15], 'target name (hhmmss.s+ddmmss)') + ######### Object information ######################################### + ofd_g.header['OBJECT'] = ( + self.information['name_obj'][:30], 'object name') + ofd_g.header['TARGET'] = ( + self.information['target'][:15], 'target name (hhmmss.s+ddmmss)') ####################################################################### - ofd_g.header['OBSID'] =(str(obsid) , 'observation ID') - ofd_g.header['RA_OBJ'] =(float(self.information['ra_obj']) , 'object RA (deg)') - ofd_g.header['DEC_OBJ']=(float(self.information['dec_obj']) , 'object Dec (deg)') - + ofd_g.header['OBSID'] = (str(obsid), 'observation ID') + ofd_g.header['RA_OBJ'] = ( + float(self.information['ra_obj']), 'object RA (deg)') + ofd_g.header['DEC_OBJ'] = ( + float(self.information['dec_obj']), 'object Dec (deg)') + ######## Telescope information ############### - - ofd_g.header['REFFRAME']=('CSSTGSC-1.0' , 'guiding catalog version') - ofd_g.header['DATE-OBS']=(data_time[:21] , 'observation date (yyyy-mm-ddThh:mm:ss.s)') - ofd_g.header['SATESWV']=('softwave-1.0', 'satellite software version') - ofd_g.header['EXPSTART']=(np.float64(time2mjd(self.dt)), 'exposure start time (MJD)') - ofd_g.header['CABSTART']=(np.float64(time2jd(self.dt)), 'first cabin time after exposure start (MJD)') - ofd_g.header['SUNANGL0']=(np.float32(0.0) , 'angle between the Sun and opt axis at CABSTART') - ofd_g.header['MOONANG0']=(np.float32(0.0) , 'angle between the Moon and opt axis at CABSTART') - ofd_g.header['TEL_ALT0']=(np.float64(0.0), 'angle between opt axis and Elimb at CABSTART') - ofd_g.header['POS_ANG0']=(np.float64(0.0), 'angle between y axis and North Pole at CABSTART') - ofd_g.header['POSI0_X'] =(np.float64(self.information['pos_x']) , 'orbital position in X at CABSTART (km)') - ofd_g.header['POSI0_Y'] =(np.float64(self.information['pos_y']) , 'orbital position in Y at CABSTART (km)') - ofd_g.header['POSI0_Z'] =(np.float64(self.information['pos_z']) , 'orbital position in Z at CABSTART (km)') - ofd_g.header['VELO0_X']=( np.float64(self.information['velocity_x']) , 'orbital velocity in X at CABSTART (km/s)') - ofd_g.header['VELO0_Y']=( np.float64(self.information['velocity_y']) , 'orbital velocity in Y at CABSTART (km/s)') - ofd_g.header['VELO0_Z']=( np.float64(self.information['velocity_z']) , 'orbital velocity in Z at CABSTART (km/s)') - ofd_g.header['Euler0_1']=( np.float64(0.0), 'Euler angle 1 at CABSTART (deg)') - ofd_g.header['Euler0_2']=( np.float64(0.0), 'Euler angle 2 at CABSTART (deg)') - ofd_g.header['Euler0_3']=( np.float64(0.0), 'Euler angle 3 at CABSTART (deg)') - - + + ofd_g.header['REFFRAME'] = ('CSSTGSC-1.0', 'guiding catalog version') + ofd_g.header['DATE-OBS'] = (data_time[:21], + 'observation date (yyyy-mm-ddThh:mm:ss.s)') + ofd_g.header['SATESWV'] = ( + 'softwave-1.0', 'satellite software version') + ofd_g.header['EXPSTART'] = (np.float64( + time2mjd(self.dt)), 'exposure start time (MJD)') + ofd_g.header['CABSTART'] = (np.float64( + time2jd(self.dt)), 'first cabin time after exposure start (MJD)') + ofd_g.header['SUNANGL0'] = (np.float32( + 0.0), 'angle between the Sun and opt axis at CABSTART') + ofd_g.header['MOONANG0'] = (np.float32( + 0.0), 'angle between the Moon and opt axis at CABSTART') + ofd_g.header['TEL_ALT0'] = (np.float64( + 0.0), 'angle between opt axis and Elimb at CABSTART') + ofd_g.header['POS_ANG0'] = (np.float64( + 0.0), 'angle between y axis and North Pole at CABSTART') + ofd_g.header['POSI0_X'] = (np.float64( + self.information['pos_x']), 'orbital position in X at CABSTART (km)') + ofd_g.header['POSI0_Y'] = (np.float64( + self.information['pos_y']), 'orbital position in Y at CABSTART (km)') + ofd_g.header['POSI0_Z'] = (np.float64( + self.information['pos_z']), 'orbital position in Z at CABSTART (km)') + ofd_g.header['VELO0_X'] = (np.float64( + self.information['velocity_x']), 'orbital velocity in X at CABSTART (km/s)') + ofd_g.header['VELO0_Y'] = (np.float64( + self.information['velocity_y']), 'orbital velocity in Y at CABSTART (km/s)') + ofd_g.header['VELO0_Z'] = (np.float64( + self.information['velocity_z']), 'orbital velocity in Z at CABSTART (km/s)') + ofd_g.header['Euler0_1'] = (np.float64( + 0.0), 'Euler angle 1 at CABSTART (deg)') + ofd_g.header['Euler0_2'] = (np.float64( + 0.0), 'Euler angle 2 at CABSTART (deg)') + ofd_g.header['Euler0_3'] = (np.float64( + 0.0), 'Euler angle 3 at CABSTART (deg)') + ############################################################## ##### - ofd_g.header['RA_PNT0']=( float(self.information['ra_pnt0']) , 'pointing RA at CABSTART (deg)') - ofd_g.header['DEC_PNT0']=(float(self.information['dec_pnt0']) , 'pointing Dec at CABSTART (deg)') - ofd_g.header['EXPEND'] =(float(time2mjd(t2)), 'exposure end time (MJD)') - ofd_g.header['CABEND'] =(float(time2jd(t2)) , 'first cabin time after exposure end (MJD)') - ofd_g.header['SUNANGL1']=(np.float32(0.0), 'angle between the Sun and opt axis at CABEND') - ofd_g.header['MOONANG1']=(np.float32(0.0) , 'angle between the Moon and opt axis at CABEND') - ofd_g.header['TEL_ALT1']=(np.float64(0.0) , 'angle between opt axis and Elimb at CABEND') - ofd_g.header['POS_ANG1']=(float(0.0) , 'angle between y axis and North Pole at CABEND') - + ofd_g.header['RA_PNT0'] = ( + float(self.information['ra_pnt0']), 'pointing RA at CABSTART (deg)') + ofd_g.header['DEC_PNT0'] = ( + float(self.information['dec_pnt0']), 'pointing Dec at CABSTART (deg)') + ofd_g.header['EXPEND'] = (float(time2mjd(t2)), + 'exposure end time (MJD)') + ofd_g.header['CABEND'] = (float(time2jd(t2)), + 'first cabin time after exposure end (MJD)') + ofd_g.header['SUNANGL1'] = (np.float32( + 0.0), 'angle between the Sun and opt axis at CABEND') + ofd_g.header['MOONANG1'] = (np.float32( + 0.0), 'angle between the Moon and opt axis at CABEND') + ofd_g.header['TEL_ALT1'] = (np.float64( + 0.0), 'angle between opt axis and Elimb at CABEND') + ofd_g.header['POS_ANG1'] = ( + float(0.0), 'angle between y axis and North Pole at CABEND') + ############################################################## - - t2jd=time2jd(t2) - - if self.orbit_pars[-1,0]9: - filternum=str(self.filterP[self.filter_r]['number']) + + if self.filterP[self.filter_r]['number'] > 9: + filternum = str(self.filterP[self.filter_r]['number']) else: - filternum='0'+str(self.filterP[self.filter_r]['number']) - - - filename_r='CSST_MCI_C2_'+self.source+'_'+exp_starttime+'_'+exp_endtime+'_'+str(obsid)+'_'+ \ - filternum+'_L0_V01' - + filternum = '0'+str(self.filterP[self.filter_r]['number']) + + filename_r = 'CSST_MCI_C2_'+self.source+'_'+exp_starttime+'_'+exp_endtime+'_'+str(obsid)+'_' + \ + filternum+'_L0_V01' + ####################################################################### ####################################################################### - #create a new FITS file, using HDUList instance + # create a new FITS file, using HDUList instance ofd_r = fits.PrimaryHDU() - #### add primary header - + # add primary header + ########## - ofd_r.header['SIMPLE']=( True, 'conforms to FITS standard') - ofd_r.header['BITPIX']=( 0, 'array data type') - ofd_r.header['NAXIS'] =( 0, 'number of array dimensions') - ofd_r.header['NEXTEND']=( np.int16(1), 'number of array dimensions') - - - temp=t3.utcnow() - data_time=temp.strftime("%Y-%m-%dT%H:%M:%S.%f") - ofd_r.header['DATE'] =(data_time[:21], 'written date (yyyy-mm-ddThh:mm:ss.s)') - ofd_r.header['FILENAME']=(filename_r[:68],'') - ofd_r.header['FILETYPE'] =( self.source[:12], 'observation type') - ofd_r.header['TELESCOP']=('CSST', 'telescope name') - ofd_r.header['INSTRUME']=('MCI', 'instrument name') - ofd_r.header['RADECSYS']=('ICRS', 'coordinate system of the object') - ofd_r.header['EQUINOX'] =(float(2000.0), '') - ofd_r.header['FITSSWV']=('mci_sim_0.8.03', 'FITS creating software version') - ######### Object information ######################################### - ofd_r.header['OBJECT'] =(self.information['name_obj'][:30], 'object name') - ofd_r.header['TARGET'] =(self.information['target'][:15], 'target name (hhmmss.s+ddmmss)') + ofd_r.header['SIMPLE'] = (True, 'conforms to FITS standard') + ofd_r.header['BITPIX'] = (0, 'array data type') + ofd_r.header['NAXIS'] = (0, 'number of array dimensions') + ofd_r.header['NEXTEND'] = (np.int16(1), 'number of array dimensions') + + temp = t3.utcnow() + data_time = temp.strftime("%Y-%m-%dT%H:%M:%S.%f") + ofd_r.header['DATE'] = ( + data_time[:21], 'written date (yyyy-mm-ddThh:mm:ss.s)') + ofd_r.header['FILENAME'] = (filename_r[:68], '') + ofd_r.header['FILETYPE'] = (self.source[:12], 'observation type') + ofd_r.header['TELESCOP'] = ('CSST', 'telescope name') + ofd_r.header['INSTRUME'] = ('MCI', 'instrument name') + ofd_r.header['RADECSYS'] = ( + 'ICRS', 'coordinate system of the object') + ofd_r.header['EQUINOX'] = (float(2000.0), '') + ofd_r.header['FITSSWV'] = ( + 'mci_sim_0.8.03', 'FITS creating software version') + ######### Object information ######################################### + ofd_r.header['OBJECT'] = ( + self.information['name_obj'][:30], 'object name') + ofd_r.header['TARGET'] = ( + self.information['target'][:15], 'target name (hhmmss.s+ddmmss)') ####################################################################### - ofd_r.header['OBSID'] =(str(obsid) , 'observation ID') - ofd_r.header['RA_OBJ'] =(float(self.information['ra_obj']) , 'object RA (deg)') - ofd_r.header['DEC_OBJ']=(float(self.information['dec_obj']) , 'object Dec (deg)') - + ofd_r.header['OBSID'] = (str(obsid), 'observation ID') + ofd_r.header['RA_OBJ'] = ( + float(self.information['ra_obj']), 'object RA (deg)') + ofd_r.header['DEC_OBJ'] = ( + float(self.information['dec_obj']), 'object Dec (deg)') + ######## Telescope information ############### - - ofd_r.header['REFFRAME']=('CSSTGSC-1.0' , 'guiding catalog version') - ofd_r.header['DATE-OBS']=(data_time[:21] , 'observation date (yyyy-mm-ddThh:mm:ss.s)') - ofd_r.header['SATESWV']=('softwave-1.0', 'satellite software version') - ofd_r.header['EXPSTART']=(np.float64(time2mjd(self.dt)), 'exposure start time (MJD)') - ofd_r.header['CABSTART']=(np.float64(time2jd(self.dt)), 'first cabin time after exposure start (MJD)') - ofd_r.header['SUNANGL0']=(np.float32(0.0) , 'angle between the Sun and opt axis at CABSTART') - ofd_r.header['MOONANG0']=(np.float32(0.0) , 'angle between the Moon and opt axis at CABSTART') - ofd_r.header['TEL_ALT0']=(np.float64(0.0), 'angle between opt axis and Elimb at CABSTART') - ofd_r.header['POS_ANG0']=(np.float64(0.0), 'angle between y axis and North Pole at CABSTART') - ofd_r.header['POSI0_X'] =(np.float64(self.information['pos_x']) , 'orbital position in X at CABSTART (km)') - ofd_r.header['POSI0_Y'] =(np.float64(self.information['pos_y']) , 'orbital position in Y at CABSTART (km)') - ofd_r.header['POSI0_Z'] =(np.float64(self.information['pos_z']) , 'orbital position in Z at CABSTART (km)') - ofd_r.header['VELO0_X']=( np.float64(self.information['velocity_x']) , 'orbital velocity in X at CABSTART (km/s)') - ofd_r.header['VELO0_Y']=( np.float64(self.information['velocity_y']) , 'orbital velocity in Y at CABSTART (km/s)') - ofd_r.header['VELO0_Z']=( np.float64(self.information['velocity_z']) , 'orbital velocity in Z at CABSTART (km/s)') - ofd_r.header['Euler0_1']=( np.float64(0.0), 'Euler angle 1 at CABSTART (deg)') - ofd_r.header['Euler0_2']=( np.float64(0.0), 'Euler angle 2 at CABSTART (deg)') - ofd_r.header['Euler0_3']=( np.float64(0.0), 'Euler angle 3 at CABSTART (deg)') - + + ofd_r.header['REFFRAME'] = ('CSSTGSC-1.0', 'guiding catalog version') + ofd_r.header['DATE-OBS'] = (data_time[:21], + 'observation date (yyyy-mm-ddThh:mm:ss.s)') + ofd_r.header['SATESWV'] = ( + 'softwave-1.0', 'satellite software version') + ofd_r.header['EXPSTART'] = (np.float64( + time2mjd(self.dt)), 'exposure start time (MJD)') + ofd_r.header['CABSTART'] = (np.float64( + time2jd(self.dt)), 'first cabin time after exposure start (MJD)') + ofd_r.header['SUNANGL0'] = (np.float32( + 0.0), 'angle between the Sun and opt axis at CABSTART') + ofd_r.header['MOONANG0'] = (np.float32( + 0.0), 'angle between the Moon and opt axis at CABSTART') + ofd_r.header['TEL_ALT0'] = (np.float64( + 0.0), 'angle between opt axis and Elimb at CABSTART') + ofd_r.header['POS_ANG0'] = (np.float64( + 0.0), 'angle between y axis and North Pole at CABSTART') + ofd_r.header['POSI0_X'] = (np.float64( + self.information['pos_x']), 'orbital position in X at CABSTART (km)') + ofd_r.header['POSI0_Y'] = (np.float64( + self.information['pos_y']), 'orbital position in Y at CABSTART (km)') + ofd_r.header['POSI0_Z'] = (np.float64( + self.information['pos_z']), 'orbital position in Z at CABSTART (km)') + ofd_r.header['VELO0_X'] = (np.float64( + self.information['velocity_x']), 'orbital velocity in X at CABSTART (km/s)') + ofd_r.header['VELO0_Y'] = (np.float64( + self.information['velocity_y']), 'orbital velocity in Y at CABSTART (km/s)') + ofd_r.header['VELO0_Z'] = (np.float64( + self.information['velocity_z']), 'orbital velocity in Z at CABSTART (km/s)') + ofd_r.header['Euler0_1'] = (np.float64( + 0.0), 'Euler angle 1 at CABSTART (deg)') + ofd_r.header['Euler0_2'] = (np.float64( + 0.0), 'Euler angle 2 at CABSTART (deg)') + ofd_r.header['Euler0_3'] = (np.float64( + 0.0), 'Euler angle 3 at CABSTART (deg)') + ############################################################## ##### - ofd_r.header['RA_PNT0']=( float(self.information['ra_pnt0']) , 'pointing RA at CABSTART (deg)') - ofd_r.header['DEC_PNT0']=(float(self.information['dec_pnt0']) , 'pointing Dec at CABSTART (deg)') - ofd_r.header['EXPEND'] =(float(time2mjd(t2)), 'exposure end time (MJD)') - ofd_r.header['CABEND'] =(float(time2jd(t2)) , 'first cabin time after exposure end (MJD)') - ofd_r.header['SUNANGL1']=(np.float32(0.0), 'angle between the Sun and opt axis at CABEND') - ofd_r.header['MOONANG1']=(np.float32(0.0) , 'angle between the Moon and opt axis at CABEND') - ofd_r.header['TEL_ALT1']=(np.float64(0.0) , 'angle between opt axis and Elimb at CABEND') - ofd_r.header['POS_ANG1']=(float(0.0) , 'angle between y axis and North Pole at CABEND') - + ofd_r.header['RA_PNT0'] = ( + float(self.information['ra_pnt0']), 'pointing RA at CABSTART (deg)') + ofd_r.header['DEC_PNT0'] = ( + float(self.information['dec_pnt0']), 'pointing Dec at CABSTART (deg)') + ofd_r.header['EXPEND'] = (float(time2mjd(t2)), + 'exposure end time (MJD)') + ofd_r.header['CABEND'] = (float(time2jd(t2)), + 'first cabin time after exposure end (MJD)') + ofd_r.header['SUNANGL1'] = (np.float32( + 0.0), 'angle between the Sun and opt axis at CABEND') + ofd_r.header['MOONANG1'] = (np.float32( + 0.0), 'angle between the Moon and opt axis at CABEND') + ofd_r.header['TEL_ALT1'] = (np.float64( + 0.0), 'angle between opt axis and Elimb at CABEND') + ofd_r.header['POS_ANG1'] = ( + float(0.0), 'angle between y axis and North Pole at CABEND') ############################################################## - - ofd_r.header['POSI1_X'] =(float(p1x) , 'orbital position in X at CABEND (km)') - ofd_r.header['POSI1_Y'] =(float(p1y) , 'orbital position in Y at CABEND (km)') - ofd_r.header['POSI1_Z'] =(float(p1z) , 'orbital position in Z at CABEND (km)') - - ofd_r.header['VELO1_X']=(float(p1vx) , 'orbital velocity in X at CABEND (km/s)') - ofd_r.header['VELO1_Y']=(float(p1vy) , 'orbital velocity in Y at CABEND (km/s)') - ofd_r.header['VELO1_Z']=(float(p1vz), 'orbital velocity in Z at CABEND (km/s)') - - ofd_r.header['Euler1_1']=( np.float64(0.0), 'Euler angle 1 at CABEND (deg)') - ofd_r.header['Euler1_2']=( np.float64(0.0), 'Euler angle 2 at CABEND (deg)') - ofd_r.header['Euler1_3']=( np.float64(0.0), 'Euler angle 3 at CABEND (deg)') - ofd_r.header['RA_PNT1'] =(float(ofd_r.header['RA_PNT0']), 'pointing RA at CABEND (deg)') - ofd_r.header['DEC_PNT1']=(float(ofd_r.header['DEC_PNT0']), 'pointing Dec at CABEND (deg)') - ofd_r.header['EPOCH'] =(np.float32(time2jd(t3.utcnow())), 'equinox of pointing RA and Dec') - ofd_r.header['EXPTIME']=(np.float32(self.information['exptime']), 'exposure time (s)') - - ofd_r.header['CHECKSUM'] =(0, '0') + + ofd_r.header['POSI1_X'] = ( + float(p1x), 'orbital position in X at CABEND (km)') + ofd_r.header['POSI1_Y'] = ( + float(p1y), 'orbital position in Y at CABEND (km)') + ofd_r.header['POSI1_Z'] = ( + float(p1z), 'orbital position in Z at CABEND (km)') + + ofd_r.header['VELO1_X'] = ( + float(p1vx), 'orbital velocity in X at CABEND (km/s)') + ofd_r.header['VELO1_Y'] = ( + float(p1vy), 'orbital velocity in Y at CABEND (km/s)') + ofd_r.header['VELO1_Z'] = ( + float(p1vz), 'orbital velocity in Z at CABEND (km/s)') + + ofd_r.header['Euler1_1'] = (np.float64( + 0.0), 'Euler angle 1 at CABEND (deg)') + ofd_r.header['Euler1_2'] = (np.float64( + 0.0), 'Euler angle 2 at CABEND (deg)') + ofd_r.header['Euler1_3'] = (np.float64( + 0.0), 'Euler angle 3 at CABEND (deg)') + ofd_r.header['RA_PNT1'] = ( + float(ofd_r.header['RA_PNT0']), 'pointing RA at CABEND (deg)') + ofd_r.header['DEC_PNT1'] = ( + float(ofd_r.header['DEC_PNT0']), 'pointing Dec at CABEND (deg)') + ofd_r.header['EPOCH'] = (np.float32( + time2jd(t3.utcnow())), 'equinox of pointing RA and Dec') + ofd_r.header['EXPTIME'] = (np.float32( + self.information['exptime']), 'exposure time (s)') + + ofd_r.header['CHECKSUM'] = (0, '0') ################################################ - ########## finish header for 0 layer #################### - ########## finish header for 0 layer #################### - ########## finish header for 0 layer - - if HeaderTest=='yes': + ########## finish header for 0 layer #################### + ########## finish header for 0 layer #################### + # finish header for 0 layer + + if HeaderTest == 'yes': hdu_r = fits.ImageHDU() - else: - hdu_r = fits.ImageHDU(data=np.uint16(self.image_r)) + else: + hdu_r = fits.ImageHDU(data=np.uint16(self.image_r)) ### MCI header for image layer ### - #### need review thie header - hdu_r.header['XTENSION']=( 'IMAGE' , 'extension type') - hdu_r.header['BITPIX'] =( np.int16(16) , 'array data type') - hdu_r.header['NAXIS'] =( np.int16(2) , 'number of array dimensions') - - hdu_r.header['NAXIS1'] =( np.int32(4936) , '') - hdu_r.header['NAXIS2'] =( np.int32(23984) , '') - - - hdu_r.header['PCOUNT']=( np.int16(0) , 'number of parameters') - hdu_r.header['GCOUNT']=( np.int16(1) , 'number of groups') - - hdu_r.header['BSCALE']=(int(1),'') - hdu_r.header['BZERO'] =(int(32768),'') - - hdu_r.header['EXTNAME']=( 'SCI' , '') - hdu_r.header['EXTVER']=(np.int16(1),'') - - hdu_r.header['BUNIT'] =('ADU','physical unit of array values') - + # need review thie header + hdu_r.header['XTENSION'] = ('IMAGE', 'extension type') + hdu_r.header['BITPIX'] = (np.int16(16), 'array data type') + hdu_r.header['NAXIS'] = (np.int16(2), 'number of array dimensions') + + hdu_r.header['NAXIS1'] = (np.int32(4936), '') + hdu_r.header['NAXIS2'] = (np.int32(23984), '') + + hdu_r.header['PCOUNT'] = (np.int16(0), 'number of parameters') + hdu_r.header['GCOUNT'] = (np.int16(1), 'number of groups') + + hdu_r.header['BSCALE'] = (int(1), '') + hdu_r.header['BZERO'] = (int(32768), '') + + hdu_r.header['EXTNAME'] = ('SCI', '') + hdu_r.header['EXTVER'] = (np.int16(1), '') + + hdu_r.header['BUNIT'] = ('ADU', 'physical unit of array values') + ###### file information ############### - - temp=t3.utcnow() - data_time=temp.strftime("%Y-%m-%dT%H:%M:%S.%f") - hdu_r.header['DATE'] =(data_time[:21], 'written date (yyyy-mm-ddThh:mm:ss.s)') - hdu_r.header['FILENAME']=(filename_r[:68],'') - hdu_r.header['FILETYPE'] =( self.source[:12], 'observation type') - hdu_r.header['RADECSYS']=('ICRS', 'coordinate system of the object') - hdu_r.header['EQUINOX'] =(float(2000.1), '') - hdu_r.header['FITSSWV']=('4.2.1', 'FITS creating software version') - + + temp = t3.utcnow() + data_time = temp.strftime("%Y-%m-%dT%H:%M:%S.%f") + hdu_r.header['DATE'] = ( + data_time[:21], 'written date (yyyy-mm-ddThh:mm:ss.s)') + hdu_r.header['FILENAME'] = (filename_r[:68], '') + hdu_r.header['FILETYPE'] = (self.source[:12], 'observation type') + hdu_r.header['RADECSYS'] = ( + 'ICRS', 'coordinate system of the object') + hdu_r.header['EQUINOX'] = (float(2000.1), '') + hdu_r.header['FITSSWV'] = ('4.2.1', 'FITS creating software version') + ######################################## - + #### instrument status and object information ###### - hdu_r.header['TELESCOP']=('CSST', 'telescope name') - hdu_r.header['INSTRUME']=('MCI', 'instrument name') - hdu_r.header['CHANNEL'] =('C2', 'channel number') - hdu_r.header['FILTERNO'] =(filternum, 'filter number') - hdu_r.header['DIFFUSER']=( bool(True) , 'insert diffuser status for flat calibration') - hdu_r.header['FLAMP'] =( np.int16(0) , 'status of flat lamp') - hdu_r.header['MCISTAT'] =( np.int16(0) , 'MCI components status parameter') - - hdu_r.header['DATE-OBS'] =(data_time[:21] , 'observation date (yyyy-mm-ddThh:mm:ss.s)') - hdu_r.header['OBJECT'] =( 'MCI_obj' , 'object name') - - hdu_r.header['TARGET'] =(self.information['target'][:15], 'target name (hhmmss.s+ddmmss)') + hdu_r.header['TELESCOP'] = ('CSST', 'telescope name') + hdu_r.header['INSTRUME'] = ('MCI', 'instrument name') + hdu_r.header['CHANNEL'] = ('C2', 'channel number') + hdu_r.header['FILTERNO'] = (filternum, 'filter number') + hdu_r.header['DIFFUSER'] = ( + bool(True), 'insert diffuser status for flat calibration') + hdu_r.header['FLAMP'] = (np.int16(0), 'status of flat lamp') + hdu_r.header['MCISTAT'] = ( + np.int16(0), 'MCI components status parameter') + + hdu_r.header['DATE-OBS'] = (data_time[:21], + 'observation date (yyyy-mm-ddThh:mm:ss.s)') + hdu_r.header['OBJECT'] = ('MCI_obj', 'object name') + + hdu_r.header['TARGET'] = ( + self.information['target'][:15], 'target name (hhmmss.s+ddmmss)') ####################################################################### - hdu_r.header['OBSID'] =(str(obsid) , 'observation ID') - hdu_r.header['RA_OBJ'] =(float(self.information['ra_obj']) , 'object RA (deg)') - hdu_r.header['DEC_OBJ']=(float(self.information['dec_obj']) , 'object Dec (deg)') - + hdu_r.header['OBSID'] = (str(obsid), 'observation ID') + hdu_r.header['RA_OBJ'] = ( + float(self.information['ra_obj']), 'object RA (deg)') + hdu_r.header['DEC_OBJ'] = ( + float(self.information['dec_obj']), 'object Dec (deg)') + ##### detector and Filter information ##### - hdu_r.header['FILTER'] =(self.filter_r[:6] , 'filter band') + hdu_r.header['FILTER'] = (self.filter_r[:6], 'filter band') ##### Detector information #### - hdu_r.header['DETSN'] =('E2V-CCD-290-0000000' , 'detector serial number') - hdu_r.header['DETNAME'] =('blue-opt' , 'detector name') - ####need review here - - - hdu_r.header['DETTEMP0'] =(np.float32(0) , 'detector temperature at EXPSTART (K)') - hdu_r.header['DETTEMP1'] =(np.float32(0) , 'detector temperature at EXPEND (K)') - hdu_r.header['DETTEMP2'] =(np.float32(0) , 'detector temperature at READT1 (K)') - - - - hdu_r.header['DETSIZE'] =(str(self.information['ysize'])+'*'+str( self.information['xsize']), 'detector size') - hdu_r.header['DATASECT'] =(str(self.image_g.shape[0])+'*'+str(self.image_g.shape[1]), 'data section') - - hdu_r.header['PIXSCAL1']=(float(0.05) , 'pixel scale for axis 1 (arcsec/pixel)') - hdu_r.header['PIXSCAL2']=(float(0.05) , 'pixel scale for axis 2 (arcsec/pixel)') - - hdu_r.header['PIXSIZE1']=(int(10) , 'pixel size for axis 1 (micron)') - hdu_r.header['PIXSIZE2']=(int(10) , 'pixel size for axis 2 (micron)') - - hdu_r.header['NCHANNEL'] =(np.int16(16) , 'number of readout channels') - + hdu_r.header['DETSN'] = ( + 'E2V-CCD-290-0000000', 'detector serial number') + hdu_r.header['DETNAME'] = ('blue-opt', 'detector name') + # need review here + + hdu_r.header['DETTEMP0'] = (np.float32( + 0), 'detector temperature at EXPSTART (K)') + hdu_r.header['DETTEMP1'] = (np.float32( + 0), 'detector temperature at EXPEND (K)') + hdu_r.header['DETTEMP2'] = (np.float32( + 0), 'detector temperature at READT1 (K)') + + hdu_r.header['DETSIZE'] = (str( + self.information['ysize'])+'*'+str(self.information['xsize']), 'detector size') + hdu_r.header['DATASECT'] = ( + str(self.image_g.shape[0])+'*'+str(self.image_g.shape[1]), 'data section') + + hdu_r.header['PIXSCAL1'] = ( + float(0.05), 'pixel scale for axis 1 (arcsec/pixel)') + hdu_r.header['PIXSCAL2'] = ( + float(0.05), 'pixel scale for axis 2 (arcsec/pixel)') + + hdu_r.header['PIXSIZE1'] = (int(10), 'pixel size for axis 1 (micron)') + hdu_r.header['PIXSIZE2'] = (int(10), 'pixel size for axis 2 (micron)') + + hdu_r.header['NCHANNEL'] = (np.int16(16), 'number of readout channels') + + hdu_r.header['PSCAN1'] = ( + np.int32(27), 'horizontal prescan width, per readout channel') + hdu_r.header['PSCAN2'] = ( + np.int32(0), 'vertical prescan width, per readout channel') + + hdu_r.header['OSCAN1'] = ( + np.int32(320), 'horizontal overscan width, per readout channel') + hdu_r.header['OSCAN2'] = ( + np.int32(320), 'vertical overscan width, per readout channel') + + hdu_r.header['BIN_X'] = (np.int16(1), 'bin number in X') + hdu_r.header['BIN_Y'] = (np.int16(1), 'bin number in Y') - hdu_r.header['PSCAN1'] =(np.int32(27) , 'horizontal prescan width, per readout channel') - hdu_r.header['PSCAN2'] =(np.int32(0) , 'vertical prescan width, per readout channel') - - hdu_r.header['OSCAN1'] =(np.int32(320) , 'horizontal overscan width, per readout channel') - hdu_r.header['OSCAN2'] =(np.int32(320) , 'vertical overscan width, per readout channel') - - hdu_r.header['BIN_X'] =(np.int16(1) , 'bin number in X') - hdu_r.header['BIN_Y'] =(np.int16(1) , 'bin number in Y') - #### World coordinate system information ##### - - hdu_r.header['WCSAXES']=(np.int16(2) , 'number of WCS axes') - hdu_r.header['CRPIX1'] =( round(float(self.information['CRPIX1']) ,1) , 'x-coordinate of reference pixel') - hdu_r.header['CRPIX2'] =( round(float(self.information['CRPIX2']) ,1) , 'y-coordinate of reference pixel') - - hdu_r.header['CRVAL1'] =( float(self.information['CRVAL1']) , 'value of reference pixel on axis 1') - hdu_r.header['CRVAL2'] =( float(self.information['CRVAL2']) , 'value of reference pixel on axis 2') - - hdu_r.header['CTYPE1'] =( 'RA---TAN' , 'type of RA WCS projection') - hdu_r.header['CTYPE2'] =( 'DEC--TAN' , 'type of Dec WCS projection') - - hdu_r.header['CD1_1'] =( float(self.information['CD1_1']) , 'transformation matrix element (deg/pix)') - hdu_r.header['CD1_2'] =( float(self.information['CD1_2']) , 'transformation matrix element (deg/pix)') - hdu_r.header['CD2_1'] =( float(self.information['CD2_1']) , 'transformation matrix element (deg/pix)') - hdu_r.header['CD2_2'] =( float(self.information['CD2_2']) , 'transformation matrix element (deg/pix)') - - + + hdu_r.header['WCSAXES'] = (np.int16(2), 'number of WCS axes') + hdu_r.header['CRPIX1'] = ( + round(float(self.information['CRPIX1']), 1), 'x-coordinate of reference pixel') + hdu_r.header['CRPIX2'] = ( + round(float(self.information['CRPIX2']), 1), 'y-coordinate of reference pixel') + + hdu_r.header['CRVAL1'] = ( + float(self.information['CRVAL1']), 'value of reference pixel on axis 1') + hdu_r.header['CRVAL2'] = ( + float(self.information['CRVAL2']), 'value of reference pixel on axis 2') + + hdu_r.header['CTYPE1'] = ('RA---TAN', 'type of RA WCS projection') + hdu_r.header['CTYPE2'] = ('DEC--TAN', 'type of Dec WCS projection') + + hdu_r.header['CD1_1'] = ( + float(self.information['CD1_1']), 'transformation matrix element (deg/pix)') + hdu_r.header['CD1_2'] = ( + float(self.information['CD1_2']), 'transformation matrix element (deg/pix)') + hdu_r.header['CD2_1'] = ( + float(self.information['CD2_1']), 'transformation matrix element (deg/pix)') + hdu_r.header['CD2_2'] = ( + float(self.information['CD2_2']), 'transformation matrix element (deg/pix)') + ###### Readout information ####### - hdu_r.header['GAINLVL'] =( np.float32(1.5) , 'gain level (e-/ADU)') - hdu_r.header['GAIN01'] =( np.float32(self.information['r_gain1']) , 'CCD gain [channel 1] (e-/ADU)') - hdu_r.header['GAIN02'] =( np.float32(self.information['r_gain2']) , 'CCD gain [channel 2] (e-/ADU)') - hdu_r.header['GAIN03'] =( np.float32(self.information['r_gain3']) , 'CCD gain [channel 3] (e-/ADU)') - hdu_r.header['GAIN04'] =( np.float32(self.information['r_gain4']) , 'CCD gain [channel 4] (e-/ADU)') - hdu_r.header['GAIN05'] =( np.float32(self.information['r_gain5']) , 'CCD gain [channel 5] (e-/ADU)') - hdu_r.header['GAIN06'] =( np.float32(self.information['r_gain6']) , 'CCD gain [channel 6] (e-/ADU)') - hdu_r.header['GAIN07'] =( np.float32(self.information['r_gain7']) , 'CCD gain [channel 7] (e-/ADU)') - hdu_r.header['GAIN08'] =( np.float32(self.information['r_gain8']) , 'CCD gain [channel 8] (e-/ADU)') - hdu_r.header['GAIN09'] =( np.float32(self.information['r_gain9']) , 'CCD gain [channel 9] (e-/ADU)') - hdu_r.header['GAIN10']=( np.float32(self.information['r_gain10']) , 'CCD gain [channel 10] (e-/ADU)') - hdu_r.header['GAIN11']=( np.float32(self.information['r_gain11']) , 'CCD gain [channel 11] (e-/ADU)') - hdu_r.header['GAIN12']=( np.float32(self.information['r_gain12']) , 'CCD gain [channel 12] (e-/ADU)') - hdu_r.header['GAIN13']=( np.float32(self.information['r_gain13']) , 'CCD gain [channel 13] (e-/ADU)') - hdu_r.header['GAIN14']=( np.float32(self.information['r_gain14']) , 'CCD gain [channel 14] (e-/ADU)') - hdu_r.header['GAIN15']=( np.float32(self.information['r_gain15']) , 'CCD gain [channel 15] (e-/ADU)') - hdu_r.header['GAIN16']=( np.float32(self.information['r_gain16']) , 'CCD gain [channel 16] (e-/ADU)') + hdu_r.header['GAINLVL'] = (np.float32( + 1.5), 'gain level (e-/ADU)') + hdu_r.header['GAIN01'] = (np.float32( + self.information['r_gain1']), 'CCD gain [channel 1] (e-/ADU)') + hdu_r.header['GAIN02'] = (np.float32( + self.information['r_gain2']), 'CCD gain [channel 2] (e-/ADU)') + hdu_r.header['GAIN03'] = (np.float32( + self.information['r_gain3']), 'CCD gain [channel 3] (e-/ADU)') + hdu_r.header['GAIN04'] = (np.float32( + self.information['r_gain4']), 'CCD gain [channel 4] (e-/ADU)') + hdu_r.header['GAIN05'] = (np.float32( + self.information['r_gain5']), 'CCD gain [channel 5] (e-/ADU)') + hdu_r.header['GAIN06'] = (np.float32( + self.information['r_gain6']), 'CCD gain [channel 6] (e-/ADU)') + hdu_r.header['GAIN07'] = (np.float32( + self.information['r_gain7']), 'CCD gain [channel 7] (e-/ADU)') + hdu_r.header['GAIN08'] = (np.float32( + self.information['r_gain8']), 'CCD gain [channel 8] (e-/ADU)') + hdu_r.header['GAIN09'] = (np.float32( + self.information['r_gain9']), 'CCD gain [channel 9] (e-/ADU)') + hdu_r.header['GAIN10'] = (np.float32( + self.information['r_gain10']), 'CCD gain [channel 10] (e-/ADU)') + hdu_r.header['GAIN11'] = (np.float32( + self.information['r_gain11']), 'CCD gain [channel 11] (e-/ADU)') + hdu_r.header['GAIN12'] = (np.float32( + self.information['r_gain12']), 'CCD gain [channel 12] (e-/ADU)') + hdu_r.header['GAIN13'] = (np.float32( + self.information['r_gain13']), 'CCD gain [channel 13] (e-/ADU)') + hdu_r.header['GAIN14'] = (np.float32( + self.information['r_gain14']), 'CCD gain [channel 14] (e-/ADU)') + hdu_r.header['GAIN15'] = (np.float32( + self.information['r_gain15']), 'CCD gain [channel 15] (e-/ADU)') + hdu_r.header['GAIN16'] = (np.float32( + self.information['r_gain16']), 'CCD gain [channel 16] (e-/ADU)') ####### - hdu_r.header['RON01'] =( np.float32(self.information['r_rdnois1']) , 'readout noise [channel 01] (e-)') - hdu_r.header['RON02'] =( np.float32(self.information['r_rdnois2']) , 'readout noise [channel 02] (e-)') - hdu_r.header['RON03'] =( np.float32(self.information['r_rdnois3']) , 'readout noise [channel 03] (e-)') - hdu_r.header['RON04'] =( np.float32(self.information['r_rdnois4']) , 'readout noise [channel 04] (e-)') - hdu_r.header['RON05'] =( np.float32(self.information['r_rdnois5']) , 'readout noise [channel 05] (e-)') - hdu_r.header['RON06'] =( np.float32(self.information['r_rdnois6']) , 'readout noise [channel 06] (e-)') - hdu_r.header['RON07'] =( np.float32(self.information['r_rdnois7']) , 'readout noise [channel 07] (e-)') - hdu_r.header['RON08'] =( np.float32(self.information['r_rdnois8']) , 'readout noise [channel 08] (e-)') - hdu_r.header['RON09'] =( np.float32(self.information['r_rdnois9']) , 'readout noise [channel 09] (e-)') - hdu_r.header['RON10']=( np.float32(self.information['r_rdnois10']) , 'readout noise [channel 10] (e-)') - hdu_r.header['RON11']=( np.float32(self.information['r_rdnois11']) , 'readout noise [channel 11] (e-)') - hdu_r.header['RON12']=( np.float32(self.information['r_rdnois12']) , 'readout noise [channel 12] (e-)') - hdu_r.header['RON13']=( np.float32(self.information['r_rdnois13']) , 'readout noise [channel 13] (e-)') - hdu_r.header['RON14']=( np.float32(self.information['r_rdnois14']) , 'readout noise [channel 14] (e-)') - hdu_r.header['RON15']=( np.float32(self.information['r_rdnois15']) , 'readout noise [channel 15] (e-)') - hdu_r.header['RON16']=( np.float32(self.information['r_rdnois16']) , 'readout noise [channel 16] (e-)') - + hdu_r.header['RON01'] = (np.float32( + self.information['r_rdnois1']), 'readout noise [channel 01] (e-)') + hdu_r.header['RON02'] = (np.float32( + self.information['r_rdnois2']), 'readout noise [channel 02] (e-)') + hdu_r.header['RON03'] = (np.float32( + self.information['r_rdnois3']), 'readout noise [channel 03] (e-)') + hdu_r.header['RON04'] = (np.float32( + self.information['r_rdnois4']), 'readout noise [channel 04] (e-)') + hdu_r.header['RON05'] = (np.float32( + self.information['r_rdnois5']), 'readout noise [channel 05] (e-)') + hdu_r.header['RON06'] = (np.float32( + self.information['r_rdnois6']), 'readout noise [channel 06] (e-)') + hdu_r.header['RON07'] = (np.float32( + self.information['r_rdnois7']), 'readout noise [channel 07] (e-)') + hdu_r.header['RON08'] = (np.float32( + self.information['r_rdnois8']), 'readout noise [channel 08] (e-)') + hdu_r.header['RON09'] = (np.float32( + self.information['r_rdnois9']), 'readout noise [channel 09] (e-)') + hdu_r.header['RON10'] = (np.float32( + self.information['r_rdnois10']), 'readout noise [channel 10] (e-)') + hdu_r.header['RON11'] = (np.float32( + self.information['r_rdnois11']), 'readout noise [channel 11] (e-)') + hdu_r.header['RON12'] = (np.float32( + self.information['r_rdnois12']), 'readout noise [channel 12] (e-)') + hdu_r.header['RON13'] = (np.float32( + self.information['r_rdnois13']), 'readout noise [channel 13] (e-)') + hdu_r.header['RON14'] = (np.float32( + self.information['r_rdnois14']), 'readout noise [channel 14] (e-)') + hdu_r.header['RON15'] = (np.float32( + self.information['r_rdnois15']), 'readout noise [channel 15] (e-)') + hdu_r.header['RON16'] = (np.float32( + self.information['r_rdnois16']), 'readout noise [channel 16] (e-)') + ####### - hdu_r.header['DETBIA01']=( np.float32(self.information['r_detbia1']) , 'amplifier bias grey value [channel 1] (ADU)') - hdu_r.header['DETBIA02']=( np.float32(self.information['r_detbia2']) , 'amplifier bias grey value [channel 2] (ADU)') - hdu_r.header['DETBIA03']=( np.float32(self.information['r_detbia3']) , 'amplifier bias grey value [channel 3] (ADU)') - hdu_r.header['DETBIA04']=( np.float32(self.information['r_detbia4']) , 'amplifier bias grey value [channel 4] (ADU)') - hdu_r.header['DETBIA05']=( np.float32(self.information['r_detbia5']) , 'amplifier bias grey value [channel 5] (ADU)') - hdu_r.header['DETBIA06']=( np.float32(self.information['r_detbia6']) , 'amplifier bias grey value [channel 6] (ADU)') - hdu_r.header['DETBIA07']=( np.float32(self.information['r_detbia7']) , 'amplifier bias grey value [channel 7] (ADU)') - hdu_r.header['DETBIA08']=( np.float32(self.information['r_detbia8']) , 'amplifier bias grey value [channel 8] (ADU)') - hdu_r.header['DETBIA09']=( np.float32(self.information['r_detbia9']) , 'amplifier bias grey value [channel 9] (ADU)') - hdu_r.header['DETBIA10']=( np.float32(self.information['r_detbia10']) , 'amplifier bias grey value [channel 10] (ADU)') - hdu_r.header['DETBIA11']=( np.float32(self.information['r_detbia11']) , 'amplifier bias grey value [channel 11] (ADU)') - hdu_r.header['DETBIA12']=( np.float32(self.information['r_detbia12']) , 'amplifier bias grey value [channel 12] (ADU)') - hdu_r.header['DETBIA13']=( np.float32(self.information['r_detbia13']) , 'amplifier bias grey value [channel 13] (ADU)') - hdu_r.header['DETBIA14']=( np.float32(self.information['r_detbia14']) , 'amplifier bias grey value [channel 14] (ADU)') - hdu_r.header['DETBIA15']=( np.float32(self.information['r_detbia15']) , 'amplifier bias grey value [channel 15] (ADU)') - hdu_r.header['DETBIA16']=( np.float32(self.information['r_detbia16']) , 'amplifier bias grey value [channel 16] (ADU)') - hdu_r.header['ROSPEED'] =( np.float32(100) , 'readout speed (MHz)') - + hdu_r.header['DETBIA01'] = (np.float32( + self.information['r_detbia1']), 'amplifier bias grey value [channel 1] (ADU)') + hdu_r.header['DETBIA02'] = (np.float32( + self.information['r_detbia2']), 'amplifier bias grey value [channel 2] (ADU)') + hdu_r.header['DETBIA03'] = (np.float32( + self.information['r_detbia3']), 'amplifier bias grey value [channel 3] (ADU)') + hdu_r.header['DETBIA04'] = (np.float32( + self.information['r_detbia4']), 'amplifier bias grey value [channel 4] (ADU)') + hdu_r.header['DETBIA05'] = (np.float32( + self.information['r_detbia5']), 'amplifier bias grey value [channel 5] (ADU)') + hdu_r.header['DETBIA06'] = (np.float32( + self.information['r_detbia6']), 'amplifier bias grey value [channel 6] (ADU)') + hdu_r.header['DETBIA07'] = (np.float32( + self.information['r_detbia7']), 'amplifier bias grey value [channel 7] (ADU)') + hdu_r.header['DETBIA08'] = (np.float32( + self.information['r_detbia8']), 'amplifier bias grey value [channel 8] (ADU)') + hdu_r.header['DETBIA09'] = (np.float32( + self.information['r_detbia9']), 'amplifier bias grey value [channel 9] (ADU)') + hdu_r.header['DETBIA10'] = (np.float32( + self.information['r_detbia10']), 'amplifier bias grey value [channel 10] (ADU)') + hdu_r.header['DETBIA11'] = (np.float32( + self.information['r_detbia11']), 'amplifier bias grey value [channel 11] (ADU)') + hdu_r.header['DETBIA12'] = (np.float32( + self.information['r_detbia12']), 'amplifier bias grey value [channel 12] (ADU)') + hdu_r.header['DETBIA13'] = (np.float32( + self.information['r_detbia13']), 'amplifier bias grey value [channel 13] (ADU)') + hdu_r.header['DETBIA14'] = (np.float32( + self.information['r_detbia14']), 'amplifier bias grey value [channel 14] (ADU)') + hdu_r.header['DETBIA15'] = (np.float32( + self.information['r_detbia15']), 'amplifier bias grey value [channel 15] (ADU)') + hdu_r.header['DETBIA16'] = (np.float32( + self.information['r_detbia16']), 'amplifier bias grey value [channel 16] (ADU)') + hdu_r.header['ROSPEED'] = (np.float32(100), 'readout speed (MHz)') + ###################################### #### exposure and shutter information ##### - hdu_r.header['EXPSTART']=(np.float64(time2mjd(self.dt)), 'exposure start time (MJD)') - hdu_r.header['EXPEND'] =(float(time2mjd(t2)), 'exposure end time (MJD)') - hdu_r.header['EXPTIME'] =(np.float32(self.information['exptime']), 'exposure time (s)') - hdu_r.header['DARKTIME'] =(np.float32(self.information['exptime']), 'dark current time (s)') - hdu_r.header['SHTSTAT']=( bool(True) , 'shutter status') - - ###### satellite and its allitide information ############## - hdu_r.header['REFFRAME']=('CSSTGSC-1.0' , 'guiding catalog version') - hdu_r.header['SATESWV']=('softwave-1.0', 'satellite software version') - hdu_r.header['CABSTART']=(np.float64(time2jd(self.dt)), 'first cabin time after exposure start (MJD)') - hdu_r.header['SUNANGL0']=(np.float32(0.0) , 'angle between the Sun and opt axis at CABSTART') - hdu_r.header['MOONANG0']=(np.float32(0.0) , 'angle between the Moon and opt axis at CABSTART') - hdu_r.header['TEL_ALT0']=(np.float64(0.0), 'angle between opt axis and Elimb at CABSTART') - hdu_r.header['POS_ANG0']=(np.float64(0.0), 'angle between y axis and North Pole at CABSTART') - hdu_r.header['POSI0_X'] =(np.float64(self.information['pos_x']) , 'orbital position in X at CABSTART (km)') - hdu_r.header['POSI0_Y'] =(np.float64(self.information['pos_y']) , 'orbital position in Y at CABSTART (km)') - hdu_r.header['POSI0_Z'] =(np.float64(self.information['pos_z']) , 'orbital position in Z at CABSTART (km)') - hdu_r.header['VELO0_X']=( np.float64(self.information['velocity_x']) , 'orbital velocity in X at CABSTART (km/s)') - hdu_r.header['VELO0_Y']=( np.float64(self.information['velocity_y']) , 'orbital velocity in Y at CABSTART (km/s)') - hdu_r.header['VELO0_Z']=( np.float64(self.information['velocity_z']) , 'orbital velocity in Z at CABSTART (km/s)') - hdu_r.header['Euler0_1']=( np.float64(0.0), 'Euler angle 1 at CABSTART (deg)') - hdu_r.header['Euler0_2']=( np.float64(0.0), 'Euler angle 2 at CABSTART (deg)') - hdu_r.header['Euler0_3']=( np.float64(0.0), 'Euler angle 3 at CABSTART (deg)') - hdu_r.header['RA_PNT0']=( float(self.information['ra_pnt0']) , 'pointing RA at CABSTART (deg)') - hdu_r.header['DEC_PNT0']=(float(self.information['dec_pnt0']) , 'pointing Dec at CABSTART (deg)') - hdu_r.header['CABEND'] =(float(time2jd(t2)) , 'first cabin time after exposure end (MJD)') - hdu_r.header['SUNANGL1']=(np.float32(0.0), 'angle between the Sun and opt axis at CABEND') - hdu_r.header['MOONANG1']=(np.float32(0.0) , 'angle between the Moon and opt axis at CABEND') - hdu_r.header['TEL_ALT1']=(np.float64(0.0) , 'angle between opt axis and Elimb at CABEND') - hdu_r.header['POS_ANG1']=(float(0.0) , 'angle between y axis and North Pole at CABEND') - hdu_r.header['POSI1_X'] =(float(p1x) , 'orbital position in X at CABEND (km)') - hdu_r.header['POSI1_Y'] =(float(p1y) , 'orbital position in Y at CABEND (km)') - hdu_r.header['POSI1_Z'] =(float(p1z) , 'orbital position in Z at CABEND (km)') - hdu_r.header['VELO1_X']=(float(p1vx) , 'orbital velocity in X at CABEND (km/s)') - hdu_r.header['VELO1_Y']=(float(p1vy) , 'orbital velocity in Y at CABEND (km/s)') - hdu_r.header['VELO1_Z']=(float(p1vz), 'orbital velocity in Z at CABEND (km/s)') - hdu_r.header['Euler1_1']=( np.float64(0.0), 'Euler angle 1 at CABEND (deg)') - hdu_r.header['Euler1_2']=( np.float64(0.0), 'Euler angle 2 at CABEND (deg)') - hdu_r.header['Euler1_3']=( np.float64(0.0), 'Euler angle 3 at CABEND (deg)') - hdu_r.header['RA_PNT1'] =(float(hdu_r.header['RA_PNT0']), 'pointing RA at CABEND (deg)') - hdu_r.header['DEC_PNT1']=(float(hdu_r.header['DEC_PNT0']), 'pointing Dec at CABEND (deg)') - hdu_r.header['EPOCH'] =(np.float32(time2jd(t3.utcnow())), 'equinox of pointing RA and Dec') - hdu_r.header['CHECKSUM'] =(0, '0') + hdu_r.header['EXPSTART'] = (np.float64( + time2mjd(self.dt)), 'exposure start time (MJD)') + hdu_r.header['EXPEND'] = (float(time2mjd(t2)), + 'exposure end time (MJD)') + hdu_r.header['EXPTIME'] = (np.float32( + self.information['exptime']), 'exposure time (s)') + hdu_r.header['DARKTIME'] = (np.float32( + self.information['exptime']), 'dark current time (s)') + hdu_r.header['SHTSTAT'] = (bool(True), 'shutter status') + + ###### satellite and its allitide information ############## + hdu_r.header['REFFRAME'] = ('CSSTGSC-1.0', 'guiding catalog version') + hdu_r.header['SATESWV'] = ( + 'softwave-1.0', 'satellite software version') + hdu_r.header['CABSTART'] = (np.float64( + time2jd(self.dt)), 'first cabin time after exposure start (MJD)') + hdu_r.header['SUNANGL0'] = (np.float32( + 0.0), 'angle between the Sun and opt axis at CABSTART') + hdu_r.header['MOONANG0'] = (np.float32( + 0.0), 'angle between the Moon and opt axis at CABSTART') + hdu_r.header['TEL_ALT0'] = (np.float64( + 0.0), 'angle between opt axis and Elimb at CABSTART') + hdu_r.header['POS_ANG0'] = (np.float64( + 0.0), 'angle between y axis and North Pole at CABSTART') + hdu_r.header['POSI0_X'] = (np.float64( + self.information['pos_x']), 'orbital position in X at CABSTART (km)') + hdu_r.header['POSI0_Y'] = (np.float64( + self.information['pos_y']), 'orbital position in Y at CABSTART (km)') + hdu_r.header['POSI0_Z'] = (np.float64( + self.information['pos_z']), 'orbital position in Z at CABSTART (km)') + hdu_r.header['VELO0_X'] = (np.float64( + self.information['velocity_x']), 'orbital velocity in X at CABSTART (km/s)') + hdu_r.header['VELO0_Y'] = (np.float64( + self.information['velocity_y']), 'orbital velocity in Y at CABSTART (km/s)') + hdu_r.header['VELO0_Z'] = (np.float64( + self.information['velocity_z']), 'orbital velocity in Z at CABSTART (km/s)') + hdu_r.header['Euler0_1'] = (np.float64( + 0.0), 'Euler angle 1 at CABSTART (deg)') + hdu_r.header['Euler0_2'] = (np.float64( + 0.0), 'Euler angle 2 at CABSTART (deg)') + hdu_r.header['Euler0_3'] = (np.float64( + 0.0), 'Euler angle 3 at CABSTART (deg)') + hdu_r.header['RA_PNT0'] = ( + float(self.information['ra_pnt0']), 'pointing RA at CABSTART (deg)') + hdu_r.header['DEC_PNT0'] = ( + float(self.information['dec_pnt0']), 'pointing Dec at CABSTART (deg)') + hdu_r.header['CABEND'] = (float(time2jd(t2)), + 'first cabin time after exposure end (MJD)') + hdu_r.header['SUNANGL1'] = (np.float32( + 0.0), 'angle between the Sun and opt axis at CABEND') + hdu_r.header['MOONANG1'] = (np.float32( + 0.0), 'angle between the Moon and opt axis at CABEND') + hdu_r.header['TEL_ALT1'] = (np.float64( + 0.0), 'angle between opt axis and Elimb at CABEND') + hdu_r.header['POS_ANG1'] = ( + float(0.0), 'angle between y axis and North Pole at CABEND') + hdu_r.header['POSI1_X'] = ( + float(p1x), 'orbital position in X at CABEND (km)') + hdu_r.header['POSI1_Y'] = ( + float(p1y), 'orbital position in Y at CABEND (km)') + hdu_r.header['POSI1_Z'] = ( + float(p1z), 'orbital position in Z at CABEND (km)') + hdu_r.header['VELO1_X'] = ( + float(p1vx), 'orbital velocity in X at CABEND (km/s)') + hdu_r.header['VELO1_Y'] = ( + float(p1vy), 'orbital velocity in Y at CABEND (km/s)') + hdu_r.header['VELO1_Z'] = ( + float(p1vz), 'orbital velocity in Z at CABEND (km/s)') + hdu_r.header['Euler1_1'] = (np.float64( + 0.0), 'Euler angle 1 at CABEND (deg)') + hdu_r.header['Euler1_2'] = (np.float64( + 0.0), 'Euler angle 2 at CABEND (deg)') + hdu_r.header['Euler1_3'] = (np.float64( + 0.0), 'Euler angle 3 at CABEND (deg)') + hdu_r.header['RA_PNT1'] = ( + float(hdu_r.header['RA_PNT0']), 'pointing RA at CABEND (deg)') + hdu_r.header['DEC_PNT1'] = ( + float(hdu_r.header['DEC_PNT0']), 'pointing Dec at CABEND (deg)') + hdu_r.header['EPOCH'] = (np.float32( + time2jd(t3.utcnow())), 'equinox of pointing RA and Dec') + hdu_r.header['CHECKSUM'] = (0, '0') ############################################################## - ################ finish MCI header for image layer in G channel - ##############################################################################################333 - - hdulist_r=fits.HDUList([ofd_r, hdu_r]) + # finish MCI header for image layer in G channel + # 333 + + hdulist_r = fits.HDUList([ofd_r, hdu_r]) #### - ofd_r.header.add_comment('========================================================================',after='FITSSWV') - ofd_r.header.add_comment('OBJECT INFORMATION',after='FITSSWV') - ofd_r.header.add_comment('========================================================================',after='FITSSWV') - - ofd_r.header.add_comment('========================================================================',after='DEC_OBJ') - ofd_r.header.add_comment('TELESCOPE INFORMATION',after='DEC_OBJ') - ofd_r.header.add_comment('========================================================================',after='DEC_OBJ') - - ofd_r.header.add_comment('========================================================================',after='EXPTIME') - ofd_r.header.add_comment('VERIFICATION INFORMATION',after='EXPTIME') - ofd_r.header.add_comment('========================================================================',after='EXPTIME') - + ofd_r.header.add_comment( + '========================================================================', after='FITSSWV') + ofd_r.header.add_comment('OBJECT INFORMATION', after='FITSSWV') + ofd_r.header.add_comment( + '========================================================================', after='FITSSWV') + + ofd_r.header.add_comment( + '========================================================================', after='DEC_OBJ') + ofd_r.header.add_comment('TELESCOPE INFORMATION', after='DEC_OBJ') + ofd_r.header.add_comment( + '========================================================================', after='DEC_OBJ') + + ofd_r.header.add_comment( + '========================================================================', after='EXPTIME') + ofd_r.header.add_comment('VERIFICATION INFORMATION', after='EXPTIME') + ofd_r.header.add_comment( + '========================================================================', after='EXPTIME') + ####################################################################### - hdu_r.header.add_comment('========================================================================',after='BUNIT') - hdu_r.header.add_comment('FILE INFORMATION',after='BUNIT') - hdu_r.header.add_comment('========================================================================',after='BUNIT') - - hdu_r.header.add_comment('========================================================================',after='FITSSWV') - hdu_r.header.add_comment('INSTRUMENT STATUS AND OBJECT INFORMATION',after='FITSSWV') - hdu_r.header.add_comment('========================================================================',after='FITSSWV') - - hdu_r.header.add_comment('========================================================================',after='DEC_OBJ') - hdu_r.header.add_comment('DETECTOR AND FILTER INFORMATION',after='DEC_OBJ') - hdu_r.header.add_comment('========================================================================',after='DEC_OBJ') - - hdu_r.header.add_comment('========================================================================',after='BIN_Y') - hdu_r.header.add_comment('WORLD COORDINATE SYSTEM INFORMATION',after='BIN_Y') - hdu_r.header.add_comment('========================================================================',after='BIN_Y') - - hdu_r.header.add_comment('========================================================================',after='CD2_2') - hdu_r.header.add_comment('READOUT INFORMATION',after='CD2_2') - hdu_r.header.add_comment('========================================================================',after='CD2_2') - - hdu_r.header.add_comment('========================================================================',after='ROSPEED') - hdu_r.header.add_comment('EXPOSURE AND SHUTTER INFORMATION',after='ROSPEED') - hdu_r.header.add_comment('========================================================================',after='ROSPEED') - - hdu_r.header.add_comment('========================================================================',after='SHTSTAT') - hdu_r.header.add_comment('SATELLITE AND ITS ATTITUDE INFORMATION',after='SHTSTAT') - hdu_r.header.add_comment('========================================================================',after='SHTSTAT') - - hdu_r.header.add_comment('========================================================================',after='EPOCH') - hdu_r.header.add_comment('VERIFICATION INFORMATION',after='EPOCH') - hdu_r.header.add_comment('========================================================================',after='EPOCH') - + hdu_r.header.add_comment( + '========================================================================', after='BUNIT') + hdu_r.header.add_comment('FILE INFORMATION', after='BUNIT') + hdu_r.header.add_comment( + '========================================================================', after='BUNIT') + + hdu_r.header.add_comment( + '========================================================================', after='FITSSWV') + hdu_r.header.add_comment( + 'INSTRUMENT STATUS AND OBJECT INFORMATION', after='FITSSWV') + hdu_r.header.add_comment( + '========================================================================', after='FITSSWV') + + hdu_r.header.add_comment( + '========================================================================', after='DEC_OBJ') + hdu_r.header.add_comment( + 'DETECTOR AND FILTER INFORMATION', after='DEC_OBJ') + hdu_r.header.add_comment( + '========================================================================', after='DEC_OBJ') + + hdu_r.header.add_comment( + '========================================================================', after='BIN_Y') + hdu_r.header.add_comment( + 'WORLD COORDINATE SYSTEM INFORMATION', after='BIN_Y') + hdu_r.header.add_comment( + '========================================================================', after='BIN_Y') + + hdu_r.header.add_comment( + '========================================================================', after='CD2_2') + hdu_r.header.add_comment('READOUT INFORMATION', after='CD2_2') + hdu_r.header.add_comment( + '========================================================================', after='CD2_2') + + hdu_r.header.add_comment( + '========================================================================', after='ROSPEED') + hdu_r.header.add_comment( + 'EXPOSURE AND SHUTTER INFORMATION', after='ROSPEED') + hdu_r.header.add_comment( + '========================================================================', after='ROSPEED') + + hdu_r.header.add_comment( + '========================================================================', after='SHTSTAT') + hdu_r.header.add_comment( + 'SATELLITE AND ITS ATTITUDE INFORMATION', after='SHTSTAT') + hdu_r.header.add_comment( + '========================================================================', after='SHTSTAT') + + hdu_r.header.add_comment( + '========================================================================', after='EPOCH') + hdu_r.header.add_comment('VERIFICATION INFORMATION', after='EPOCH') + hdu_r.header.add_comment( + '========================================================================', after='EPOCH') + ##################################### - ################ finish MCI header for image layer in R channel + # finish MCI header for image layer in R channel - if self.source=='DARK' or self.source=='FLAT' or self.source=='BIAS': - file_r=self.result_path+'/cali_Data/'+filename_r+'.fits' + if self.source == 'DARK' or self.source == 'FLAT' or self.source == 'BIAS': + file_r = self.result_path+'/cali_Data/'+filename_r+'.fits' else: - file_r=self.result_path+'/sky_Data/'+filename_r +'.fits' - + file_r = self.result_path+'/sky_Data/'+filename_r + '.fits' + hdulist_r.writeto(file_r, checksum=True) - + print('MCI_r.fits is created ') - + ################################################################################# - ### i band - - #create a new FITS file, using HDUList instance + # i band + + # create a new FITS file, using HDUList instance ofd_i = fits.PrimaryHDU() - - - if self.filterP[self.filter_i]['number']>9: - filternum=str(self.filterP[self.filter_i]['number']) + + if self.filterP[self.filter_i]['number'] > 9: + filternum = str(self.filterP[self.filter_i]['number']) else: - filternum='0'+str(self.filterP[self.filter_i]['number']) - - - filename_i='CSST_MCI_C3_'+self.source+'_'+exp_starttime+'_'+exp_endtime+'_'+str(obsid)+'_'+ \ - filternum+'_L0_V01' - - #### add primary header - - ofd_i.header['SIMPLE']=( True, 'conforms to FITS standard') - ofd_i.header['BITPIX']=( 0, 'array data type') - ofd_i.header['NAXIS'] =( 0, 'number of array dimensions') - ofd_i.header['NEXTEND']=( np.int16(1), 'number of array dimensions') + filternum = '0'+str(self.filterP[self.filter_i]['number']) + + filename_i = 'CSST_MCI_C3_'+self.source+'_'+exp_starttime+'_'+exp_endtime+'_'+str(obsid)+'_' + \ + filternum+'_L0_V01' + + # add primary header + + ofd_i.header['SIMPLE'] = (True, 'conforms to FITS standard') + ofd_i.header['BITPIX'] = (0, 'array data type') + ofd_i.header['NAXIS'] = (0, 'number of array dimensions') + ofd_i.header['NEXTEND'] = (np.int16(1), 'number of array dimensions') ############################### - temp=t3.utcnow() - data_time=temp.strftime("%Y-%m-%dT%H:%M:%S.%f") - ofd_i.header['DATE'] =(data_time[:21], 'written date (yyyy-mm-ddThh:mm:ss.s)') - ofd_i.header['FILENAME']=(filename_i[:68],'') - ofd_i.header['FILETYPE'] =( self.source[:12], 'observation type') - ofd_i.header['TELESCOP']=('CSST', 'telescope name') - ofd_i.header['INSTRUME']=('MCI', 'instrument name') - ofd_i.header['RADECSYS']=('ICRS', 'coordinate system of the object') - ofd_i.header['EQUINOX'] =(float(2000.0), '') - ofd_i.header['FITSSWV']=('mci_sim_0.8.03', 'FITS creating software version') + temp = t3.utcnow() + data_time = temp.strftime("%Y-%m-%dT%H:%M:%S.%f") + ofd_i.header['DATE'] = ( + data_time[:21], 'written date (yyyy-mm-ddThh:mm:ss.s)') + ofd_i.header['FILENAME'] = (filename_i[:68], '') + ofd_i.header['FILETYPE'] = (self.source[:12], 'observation type') + ofd_i.header['TELESCOP'] = ('CSST', 'telescope name') + ofd_i.header['INSTRUME'] = ('MCI', 'instrument name') + ofd_i.header['RADECSYS'] = ( + 'ICRS', 'coordinate system of the object') + ofd_i.header['EQUINOX'] = (float(2000.0), '') + ofd_i.header['FITSSWV'] = ( + 'mci_sim_0.8.03', 'FITS creating software version') ############################################################################## - ######### Object information ######################################### - ofd_i.header['OBJECT'] =(self.information['name_obj'][:30], 'object name') - ofd_i.header['TARGET'] =(self.information['target'][:15], 'target name (hhmmss.s+ddmmss)') + ######### Object information ######################################### + ofd_i.header['OBJECT'] = ( + self.information['name_obj'][:30], 'object name') + ofd_i.header['TARGET'] = ( + self.information['target'][:15], 'target name (hhmmss.s+ddmmss)') ####################################################################### - ofd_i.header['OBSID'] =(str(obsid) , 'observation ID') - ofd_i.header['RA_OBJ'] =(float(self.information['ra_obj']) , 'object RA (deg)') - ofd_i.header['DEC_OBJ']=(float(self.information['dec_obj']) , 'object Dec (deg)') - - - ######## Telescope information ############### - ofd_i.header['REFFRAME']=('CSSTGSC-1.0' , 'guiding catalog version') - ofd_i.header['DATE-OBS']=(data_time[:21] , 'observation date (yyyy-mm-ddThh:mm:ss.s)') - ofd_i.header['SATESWV']=('softwave-1.0', 'satellite software version') - ofd_i.header['EXPSTART']=(np.float64(time2mjd(self.dt)), 'exposure start time (MJD)') - ofd_i.header['CABSTART']=(np.float64(time2jd(self.dt)), 'first cabin time after exposure start (MJD)') - ofd_i.header['SUNANGL0']=(np.float32(0.0) , 'angle between the Sun and opt axis at CABSTART') - ofd_i.header['MOONANG0']=(np.float32(0.0) , 'angle between the Moon and opt axis at CABSTART') - ofd_i.header['TEL_ALT0']=(np.float64(0.0), 'angle between opt axis and Elimb at CABSTART') - ofd_i.header['POS_ANG0']=(np.float64(0.0), 'angle between y axis and North Pole at CABSTART') - ofd_i.header['POSI0_X'] =(np.float64(self.information['pos_x']) , 'orbital position in X at CABSTART (km)') - ofd_i.header['POSI0_Y'] =(np.float64(self.information['pos_y']) , 'orbital position in Y at CABSTART (km)') - ofd_i.header['POSI0_Z'] =(np.float64(self.information['pos_z']) , 'orbital position in Z at CABSTART (km)') - ofd_i.header['VELO0_X']=( np.float64(self.information['velocity_x']) , 'orbital velocity in X at CABSTART (km/s)') - ofd_i.header['VELO0_Y']=( np.float64(self.information['velocity_y']) , 'orbital velocity in Y at CABSTART (km/s)') - ofd_i.header['VELO0_Z']=( np.float64(self.information['velocity_z']) , 'orbital velocity in Z at CABSTART (km/s)') - ofd_i.header['Euler0_1']=( np.float64(0.0), 'Euler angle 1 at CABSTART (deg)') - ofd_i.header['Euler0_2']=( np.float64(0.0), 'Euler angle 2 at CABSTART (deg)') - ofd_i.header['Euler0_3']=( np.float64(0.0), 'Euler angle 3 at CABSTART (deg)') - - - ofd_i.header['RA_PNT0']=( float(self.information['ra_pnt0']) , 'pointing RA at CABSTART (deg)') - ofd_i.header['DEC_PNT0']=(float(self.information['dec_pnt0']) , 'pointing Dec at CABSTART (deg)') - ofd_i.header['EXPEND'] =(float(time2mjd(t2)), 'exposure end time (MJD)') - ofd_i.header['CABEND'] =(float(time2jd(t2)) , 'first cabin time after exposure end (MJD)') - ofd_i.header['SUNANGL1']=(np.float32(0.0), 'angle between the Sun and opt axis at CABEND') - ofd_i.header['MOONANG1']=(np.float32(0.0) , 'angle between the Moon and opt axis at CABEND') - ofd_i.header['TEL_ALT1']=(np.float64(0.0) , 'angle between opt axis and Elimb at CABEND') - ofd_i.header['POS_ANG1']=(float(0.0) , 'angle between y axis and North Pole at CABEND') + ofd_i.header['OBSID'] = (str(obsid), 'observation ID') + ofd_i.header['RA_OBJ'] = ( + float(self.information['ra_obj']), 'object RA (deg)') + ofd_i.header['DEC_OBJ'] = ( + float(self.information['dec_obj']), 'object Dec (deg)') + ######## Telescope information ############### + ofd_i.header['REFFRAME'] = ('CSSTGSC-1.0', 'guiding catalog version') + ofd_i.header['DATE-OBS'] = (data_time[:21], + 'observation date (yyyy-mm-ddThh:mm:ss.s)') + ofd_i.header['SATESWV'] = ( + 'softwave-1.0', 'satellite software version') + ofd_i.header['EXPSTART'] = (np.float64( + time2mjd(self.dt)), 'exposure start time (MJD)') + ofd_i.header['CABSTART'] = (np.float64( + time2jd(self.dt)), 'first cabin time after exposure start (MJD)') + ofd_i.header['SUNANGL0'] = (np.float32( + 0.0), 'angle between the Sun and opt axis at CABSTART') + ofd_i.header['MOONANG0'] = (np.float32( + 0.0), 'angle between the Moon and opt axis at CABSTART') + ofd_i.header['TEL_ALT0'] = (np.float64( + 0.0), 'angle between opt axis and Elimb at CABSTART') + ofd_i.header['POS_ANG0'] = (np.float64( + 0.0), 'angle between y axis and North Pole at CABSTART') + ofd_i.header['POSI0_X'] = (np.float64( + self.information['pos_x']), 'orbital position in X at CABSTART (km)') + ofd_i.header['POSI0_Y'] = (np.float64( + self.information['pos_y']), 'orbital position in Y at CABSTART (km)') + ofd_i.header['POSI0_Z'] = (np.float64( + self.information['pos_z']), 'orbital position in Z at CABSTART (km)') + ofd_i.header['VELO0_X'] = (np.float64( + self.information['velocity_x']), 'orbital velocity in X at CABSTART (km/s)') + ofd_i.header['VELO0_Y'] = (np.float64( + self.information['velocity_y']), 'orbital velocity in Y at CABSTART (km/s)') + ofd_i.header['VELO0_Z'] = (np.float64( + self.information['velocity_z']), 'orbital velocity in Z at CABSTART (km/s)') + ofd_i.header['Euler0_1'] = (np.float64( + 0.0), 'Euler angle 1 at CABSTART (deg)') + ofd_i.header['Euler0_2'] = (np.float64( + 0.0), 'Euler angle 2 at CABSTART (deg)') + ofd_i.header['Euler0_3'] = (np.float64( + 0.0), 'Euler angle 3 at CABSTART (deg)') + + ofd_i.header['RA_PNT0'] = ( + float(self.information['ra_pnt0']), 'pointing RA at CABSTART (deg)') + ofd_i.header['DEC_PNT0'] = ( + float(self.information['dec_pnt0']), 'pointing Dec at CABSTART (deg)') + ofd_i.header['EXPEND'] = (float(time2mjd(t2)), + 'exposure end time (MJD)') + ofd_i.header['CABEND'] = (float(time2jd(t2)), + 'first cabin time after exposure end (MJD)') + ofd_i.header['SUNANGL1'] = (np.float32( + 0.0), 'angle between the Sun and opt axis at CABEND') + ofd_i.header['MOONANG1'] = (np.float32( + 0.0), 'angle between the Moon and opt axis at CABEND') + ofd_i.header['TEL_ALT1'] = (np.float64( + 0.0), 'angle between opt axis and Elimb at CABEND') + ofd_i.header['POS_ANG1'] = ( + float(0.0), 'angle between y axis and North Pole at CABEND') ############################################################## - - ofd_i.header['POSI1_X'] =(float(p1x) , 'orbital position in X at CABEND (km)') - ofd_i.header['POSI1_Y'] =(float(p1y) , 'orbital position in Y at CABEND (km)') - ofd_i.header['POSI1_Z'] =(float(p1z) , 'orbital position in Z at CABEND (km)') - - ofd_i.header['VELO1_X']=(float(p1vx) , 'orbital velocity in X at CABEND (km/s)') - ofd_i.header['VELO1_Y']=(float(p1vy) , 'orbital velocity in Y at CABEND (km/s)') - ofd_i.header['VELO1_Z']=(float(p1vz), 'orbital velocity in Z at CABEND (km/s)') - + ofd_i.header['POSI1_X'] = ( + float(p1x), 'orbital position in X at CABEND (km)') + ofd_i.header['POSI1_Y'] = ( + float(p1y), 'orbital position in Y at CABEND (km)') + ofd_i.header['POSI1_Z'] = ( + float(p1z), 'orbital position in Z at CABEND (km)') + + ofd_i.header['VELO1_X'] = ( + float(p1vx), 'orbital velocity in X at CABEND (km/s)') + ofd_i.header['VELO1_Y'] = ( + float(p1vy), 'orbital velocity in Y at CABEND (km/s)') + ofd_i.header['VELO1_Z'] = ( + float(p1vz), 'orbital velocity in Z at CABEND (km/s)') + ################### - - ofd_i.header['Euler1_1']=( np.float64(0.0), 'Euler angle 1 at CABEND (deg)') - ofd_i.header['Euler1_2']=( np.float64(0.0), 'Euler angle 2 at CABEND (deg)') - ofd_i.header['Euler1_3']=( np.float64(0.0), 'Euler angle 3 at CABEND (deg)') - ofd_i.header['RA_PNT1'] =(float(ofd_i.header['RA_PNT0']), 'pointing RA at CABEND (deg)') - ofd_i.header['DEC_PNT1']=(float(ofd_i.header['DEC_PNT0']), 'pointing Dec at CABEND (deg)') - ofd_i.header['EPOCH'] =(np.float32(time2jd(t3.utcnow())), 'equinox of pointing RA and Dec') - ofd_i.header['EXPTIME']=(np.float32(self.information['exptime']), 'exposure time (s)') - - ofd_i.header['CHECKSUM'] =(0, '0') + + ofd_i.header['Euler1_1'] = (np.float64( + 0.0), 'Euler angle 1 at CABEND (deg)') + ofd_i.header['Euler1_2'] = (np.float64( + 0.0), 'Euler angle 2 at CABEND (deg)') + ofd_i.header['Euler1_3'] = (np.float64( + 0.0), 'Euler angle 3 at CABEND (deg)') + ofd_i.header['RA_PNT1'] = ( + float(ofd_i.header['RA_PNT0']), 'pointing RA at CABEND (deg)') + ofd_i.header['DEC_PNT1'] = ( + float(ofd_i.header['DEC_PNT0']), 'pointing Dec at CABEND (deg)') + ofd_i.header['EPOCH'] = (np.float32( + time2jd(t3.utcnow())), 'equinox of pointing RA and Dec') + ofd_i.header['EXPTIME'] = (np.float32( + self.information['exptime']), 'exposure time (s)') + + ofd_i.header['CHECKSUM'] = (0, '0') ################################################ - ########## finish header for 0 layer #################### - - ########## finish header for 0 layer + ########## finish header for 0 layer #################### - #new image HDU - if HeaderTest=='yes': + # finish header for 0 layer + + # new image HDU + if HeaderTest == 'yes': hdu_i = fits.ImageHDU() else: hdu_i = fits.ImageHDU(data=np.uint16(self.image_i)) - - - #### need review thie header + + # need review thie header ### MCI header for image layer ### - #### need review thie header - hdu_i.header['XTENSION']=( 'IMAGE' , 'extension type') - hdu_i.header['BITPIX'] =( np.int16(16) , 'array data type') - hdu_i.header['NAXIS'] =( np.int16(2) , 'number of array dimensions') - - hdu_i.header['NAXIS1'] =( np.int32(4936) , '') - hdu_i.header['NAXIS2'] =( np.int32(23984) , '') - - - hdu_i.header['PCOUNT']=( np.int16(0) , 'number of parameters') - hdu_i.header['GCOUNT']=( np.int16(1) , 'number of groups') - - hdu_i.header['BSCALE']=(int(1),'') - hdu_i.header['BZERO'] =(int(32768),'') - - hdu_i.header['EXTNAME']=( 'SCI' , '') - hdu_i.header['EXTVER']=(np.int16(1),'') - - hdu_i.header['BUNIT'] =('ADU','physical unit of array values') - + # need review thie header + hdu_i.header['XTENSION'] = ('IMAGE', 'extension type') + hdu_i.header['BITPIX'] = (np.int16(16), 'array data type') + hdu_i.header['NAXIS'] = (np.int16(2), 'number of array dimensions') + + hdu_i.header['NAXIS1'] = (np.int32(4936), '') + hdu_i.header['NAXIS2'] = (np.int32(23984), '') + + hdu_i.header['PCOUNT'] = (np.int16(0), 'number of parameters') + hdu_i.header['GCOUNT'] = (np.int16(1), 'number of groups') + + hdu_i.header['BSCALE'] = (int(1), '') + hdu_i.header['BZERO'] = (int(32768), '') + + hdu_i.header['EXTNAME'] = ('SCI', '') + hdu_i.header['EXTVER'] = (np.int16(1), '') + + hdu_i.header['BUNIT'] = ('ADU', 'physical unit of array values') + ###### file information ############### - - temp=t3.utcnow() - data_time=temp.strftime("%Y-%m-%dT%H:%M:%S.%f") - hdu_i.header['DATE'] =(data_time[:21], 'written date (yyyy-mm-ddThh:mm:ss.s)') - hdu_i.header['FILENAME']=(filename_i[:68],'') - hdu_i.header['FILETYPE'] =( self.source[:12], 'observation type') - hdu_i.header['RADECSYS']=('ICRS', 'coordinate system of the object') - hdu_i.header['EQUINOX'] =(float(2000.1), '') - hdu_i.header['FITSSWV']=('4.2.1', 'FITS creating software version') - + + temp = t3.utcnow() + data_time = temp.strftime("%Y-%m-%dT%H:%M:%S.%f") + hdu_i.header['DATE'] = ( + data_time[:21], 'written date (yyyy-mm-ddThh:mm:ss.s)') + hdu_i.header['FILENAME'] = (filename_i[:68], '') + hdu_i.header['FILETYPE'] = (self.source[:12], 'observation type') + hdu_i.header['RADECSYS'] = ( + 'ICRS', 'coordinate system of the object') + hdu_i.header['EQUINOX'] = (float(2000.1), '') + hdu_i.header['FITSSWV'] = ('4.2.1', 'FITS creating software version') + ######################################## - + #### instrument status and object information ###### - hdu_i.header['TELESCOP']=('CSST', 'telescope name') - hdu_i.header['INSTRUME']=('MCI', 'instrument name') - hdu_i.header['CHANNEL'] =('C3', 'channel number') - hdu_i.header['FILTERNO'] =(filternum, 'filter number') - hdu_i.header['DIFFUSER']=( bool(True) , 'insert diffuser status for flat calibration') - hdu_i.header['FLAMP'] =( np.int16(0) , 'status of flat lamp') - hdu_i.header['MCISTAT'] =( np.int16(0) , 'MCI components status parameter') - - hdu_i.header['DATE-OBS'] =(data_time[:21] , 'observation date (yyyy-mm-ddThh:mm:ss.s)') - hdu_i.header['OBJECT'] =( 'MCI_obj' , 'object name') - - hdu_i.header['TARGET'] =(self.information['target'][:15], 'target name (hhmmss.s+ddmmss)') + hdu_i.header['TELESCOP'] = ('CSST', 'telescope name') + hdu_i.header['INSTRUME'] = ('MCI', 'instrument name') + hdu_i.header['CHANNEL'] = ('C3', 'channel number') + hdu_i.header['FILTERNO'] = (filternum, 'filter number') + hdu_i.header['DIFFUSER'] = ( + bool(True), 'insert diffuser status for flat calibration') + hdu_i.header['FLAMP'] = (np.int16(0), 'status of flat lamp') + hdu_i.header['MCISTAT'] = ( + np.int16(0), 'MCI components status parameter') + + hdu_i.header['DATE-OBS'] = (data_time[:21], + 'observation date (yyyy-mm-ddThh:mm:ss.s)') + hdu_i.header['OBJECT'] = ('MCI_obj', 'object name') + + hdu_i.header['TARGET'] = ( + self.information['target'][:15], 'target name (hhmmss.s+ddmmss)') ####################################################################### - hdu_i.header['OBSID'] =(str(obsid) , 'observation ID') - hdu_i.header['RA_OBJ'] =(float(self.information['ra_obj']) , 'object RA (deg)') - hdu_i.header['DEC_OBJ']=(float(self.information['dec_obj']) , 'object Dec (deg)') - + hdu_i.header['OBSID'] = (str(obsid), 'observation ID') + hdu_i.header['RA_OBJ'] = ( + float(self.information['ra_obj']), 'object RA (deg)') + hdu_i.header['DEC_OBJ'] = ( + float(self.information['dec_obj']), 'object Dec (deg)') + ##### detector and Filter information ##### - hdu_i.header['FILTER'] =(self.filter_i[:6] , 'filter band') + hdu_i.header['FILTER'] = (self.filter_i[:6], 'filter band') ##### Detector information #### - hdu_i.header['DETSN'] =('E2V-CCD-290-0000000' , 'detector serial number') - hdu_i.header['DETNAME'] =('opt-red' , 'detector name') - ####need review here - - - hdu_i.header['DETTEMP0'] =(np.float32(0) , 'detector temperature at EXPSTART (K)') - hdu_i.header['DETTEMP1'] =(np.float32(0) , 'detector temperature at EXPEND (K)') - hdu_i.header['DETTEMP2'] =(np.float32(0) , 'detector temperature at READT1 (K)') - - - - hdu_i.header['DETSIZE'] =(str(self.information['ysize'])+'*'+str( self.information['xsize']), 'detector size') - hdu_i.header['DATASECT'] =(str(self.image_g.shape[0])+'*'+str(self.image_g.shape[1]), 'data section') - - hdu_i.header['PIXSCAL1']=(float(0.05) , 'pixel scale for axis 1 (arcsec/pixel)') - hdu_i.header['PIXSCAL2']=(float(0.05) , 'pixel scale for axis 2 (arcsec/pixel)') - - hdu_i.header['PIXSIZE1']=(int(10) , 'pixel size for axis 1 (micron)') - hdu_i.header['PIXSIZE2']=(int(10) , 'pixel size for axis 2 (micron)') - - hdu_i.header['NCHANNEL'] =(np.int16(16) , 'number of readout channels') - + hdu_i.header['DETSN'] = ( + 'E2V-CCD-290-0000000', 'detector serial number') + hdu_i.header['DETNAME'] = ('opt-red', 'detector name') + # need review here + + hdu_i.header['DETTEMP0'] = (np.float32( + 0), 'detector temperature at EXPSTART (K)') + hdu_i.header['DETTEMP1'] = (np.float32( + 0), 'detector temperature at EXPEND (K)') + hdu_i.header['DETTEMP2'] = (np.float32( + 0), 'detector temperature at READT1 (K)') + + hdu_i.header['DETSIZE'] = (str( + self.information['ysize'])+'*'+str(self.information['xsize']), 'detector size') + hdu_i.header['DATASECT'] = ( + str(self.image_g.shape[0])+'*'+str(self.image_g.shape[1]), 'data section') + + hdu_i.header['PIXSCAL1'] = ( + float(0.05), 'pixel scale for axis 1 (arcsec/pixel)') + hdu_i.header['PIXSCAL2'] = ( + float(0.05), 'pixel scale for axis 2 (arcsec/pixel)') + + hdu_i.header['PIXSIZE1'] = (int(10), 'pixel size for axis 1 (micron)') + hdu_i.header['PIXSIZE2'] = (int(10), 'pixel size for axis 2 (micron)') + + hdu_i.header['NCHANNEL'] = (np.int16(16), 'number of readout channels') + + hdu_i.header['PSCAN1'] = ( + np.int32(27), 'horizontal prescan width, per readout channel') + hdu_i.header['PSCAN2'] = ( + np.int32(0), 'vertical prescan width, per readout channel') + + hdu_i.header['OSCAN1'] = ( + np.int32(320), 'horizontal overscan width, per readout channel') + hdu_i.header['OSCAN2'] = ( + np.int32(320), 'vertical overscan width, per readout channel') + + hdu_i.header['BIN_X'] = (np.int16(1), 'bin number in X') + hdu_i.header['BIN_Y'] = (np.int16(1), 'bin number in Y') - hdu_i.header['PSCAN1'] =(np.int32(27) , 'horizontal prescan width, per readout channel') - hdu_i.header['PSCAN2'] =(np.int32(0) , 'vertical prescan width, per readout channel') - - hdu_i.header['OSCAN1'] =(np.int32(320) , 'horizontal overscan width, per readout channel') - hdu_i.header['OSCAN2'] =(np.int32(320) , 'vertical overscan width, per readout channel') - - hdu_i.header['BIN_X'] =(np.int16(1) , 'bin number in X') - hdu_i.header['BIN_Y'] =(np.int16(1) , 'bin number in Y') - #### World coordinate system information ##### - - hdu_i.header['WCSAXES']=(np.int16(2) , 'number of WCS axes') - hdu_i.header['CRPIX1'] =( round(float(self.information['CRPIX1']) ,1) , 'x-coordinate of reference pixel') - hdu_i.header['CRPIX2'] =( round(float(self.information['CRPIX2']) ,1) , 'y-coordinate of reference pixel') - - hdu_i.header['CRVAL1'] =( float(self.information['CRVAL1']) , 'value of reference pixel on axis 1') - hdu_i.header['CRVAL2'] =( float(self.information['CRVAL2']) , 'value of reference pixel on axis 2') - - hdu_i.header['CTYPE1'] =( 'RA---TAN' , 'type of RA WCS projection') - hdu_i.header['CTYPE2'] =( 'DEC--TAN' , 'type of Dec WCS projection') - - hdu_i.header['CD1_1'] =( float(self.information['CD1_1']) , 'transformation matrix element (deg/pix)') - hdu_i.header['CD1_2'] =( float(self.information['CD1_2']) , 'transformation matrix element (deg/pix)') - hdu_i.header['CD2_1'] =( float(self.information['CD2_1']) , 'transformation matrix element (deg/pix)') - hdu_i.header['CD2_2'] =( float(self.information['CD2_2']) , 'transformation matrix element (deg/pix)') - - + + hdu_i.header['WCSAXES'] = (np.int16(2), 'number of WCS axes') + hdu_i.header['CRPIX1'] = ( + round(float(self.information['CRPIX1']), 1), 'x-coordinate of reference pixel') + hdu_i.header['CRPIX2'] = ( + round(float(self.information['CRPIX2']), 1), 'y-coordinate of reference pixel') + + hdu_i.header['CRVAL1'] = ( + float(self.information['CRVAL1']), 'value of reference pixel on axis 1') + hdu_i.header['CRVAL2'] = ( + float(self.information['CRVAL2']), 'value of reference pixel on axis 2') + + hdu_i.header['CTYPE1'] = ('RA---TAN', 'type of RA WCS projection') + hdu_i.header['CTYPE2'] = ('DEC--TAN', 'type of Dec WCS projection') + + hdu_i.header['CD1_1'] = ( + float(self.information['CD1_1']), 'transformation matrix element (deg/pix)') + hdu_i.header['CD1_2'] = ( + float(self.information['CD1_2']), 'transformation matrix element (deg/pix)') + hdu_i.header['CD2_1'] = ( + float(self.information['CD2_1']), 'transformation matrix element (deg/pix)') + hdu_i.header['CD2_2'] = ( + float(self.information['CD2_2']), 'transformation matrix element (deg/pix)') + ###### Readout information ####### - hdu_i.header['GAINLVL'] =( np.float32(1.5) , 'gain level (e-/ADU)') - hdu_i.header['GAIN01'] =( np.float32(self.information['i_gain1']) , 'CCD gain [channel 1] (e-/ADU)') - hdu_i.header['GAIN02'] =( np.float32(self.information['i_gain2']) , 'CCD gain [channel 2] (e-/ADU)') - hdu_i.header['GAIN03'] =( np.float32(self.information['i_gain3']) , 'CCD gain [channel 3] (e-/ADU)') - hdu_i.header['GAIN04'] =( np.float32(self.information['i_gain4']) , 'CCD gain [channel 4] (e-/ADU)') - hdu_i.header['GAIN05'] =( np.float32(self.information['i_gain5']) , 'CCD gain [channel 5] (e-/ADU)') - hdu_i.header['GAIN06'] =( np.float32(self.information['i_gain6']) , 'CCD gain [channel 6] (e-/ADU)') - hdu_i.header['GAIN07'] =( np.float32(self.information['i_gain7']) , 'CCD gain [channel 7] (e-/ADU)') - hdu_i.header['GAIN08'] =( np.float32(self.information['i_gain8']) , 'CCD gain [channel 8] (e-/ADU)') - hdu_i.header['GAIN09'] =( np.float32(self.information['i_gain9']) , 'CCD gain [channel 9] (e-/ADU)') - hdu_i.header['GAIN10']=( np.float32(self.information['i_gain10']) , 'CCD gain [channel 10] (e-/ADU)') - hdu_i.header['GAIN11']=( np.float32(self.information['i_gain11']) , 'CCD gain [channel 11] (e-/ADU)') - hdu_i.header['GAIN12']=( np.float32(self.information['i_gain12']) , 'CCD gain [channel 12] (e-/ADU)') - hdu_i.header['GAIN13']=( np.float32(self.information['i_gain13']) , 'CCD gain [channel 13] (e-/ADU)') - hdu_i.header['GAIN14']=( np.float32(self.information['i_gain14']) , 'CCD gain [channel 14] (e-/ADU)') - hdu_i.header['GAIN15']=( np.float32(self.information['i_gain15']) , 'CCD gain [channel 15] (e-/ADU)') - hdu_i.header['GAIN16']=( np.float32(self.information['i_gain16']) , 'CCD gain [channel 16] (e-/ADU)') + hdu_i.header['GAINLVL'] = (np.float32( + 1.5), 'gain level (e-/ADU)') + hdu_i.header['GAIN01'] = (np.float32( + self.information['i_gain1']), 'CCD gain [channel 1] (e-/ADU)') + hdu_i.header['GAIN02'] = (np.float32( + self.information['i_gain2']), 'CCD gain [channel 2] (e-/ADU)') + hdu_i.header['GAIN03'] = (np.float32( + self.information['i_gain3']), 'CCD gain [channel 3] (e-/ADU)') + hdu_i.header['GAIN04'] = (np.float32( + self.information['i_gain4']), 'CCD gain [channel 4] (e-/ADU)') + hdu_i.header['GAIN05'] = (np.float32( + self.information['i_gain5']), 'CCD gain [channel 5] (e-/ADU)') + hdu_i.header['GAIN06'] = (np.float32( + self.information['i_gain6']), 'CCD gain [channel 6] (e-/ADU)') + hdu_i.header['GAIN07'] = (np.float32( + self.information['i_gain7']), 'CCD gain [channel 7] (e-/ADU)') + hdu_i.header['GAIN08'] = (np.float32( + self.information['i_gain8']), 'CCD gain [channel 8] (e-/ADU)') + hdu_i.header['GAIN09'] = (np.float32( + self.information['i_gain9']), 'CCD gain [channel 9] (e-/ADU)') + hdu_i.header['GAIN10'] = (np.float32( + self.information['i_gain10']), 'CCD gain [channel 10] (e-/ADU)') + hdu_i.header['GAIN11'] = (np.float32( + self.information['i_gain11']), 'CCD gain [channel 11] (e-/ADU)') + hdu_i.header['GAIN12'] = (np.float32( + self.information['i_gain12']), 'CCD gain [channel 12] (e-/ADU)') + hdu_i.header['GAIN13'] = (np.float32( + self.information['i_gain13']), 'CCD gain [channel 13] (e-/ADU)') + hdu_i.header['GAIN14'] = (np.float32( + self.information['i_gain14']), 'CCD gain [channel 14] (e-/ADU)') + hdu_i.header['GAIN15'] = (np.float32( + self.information['i_gain15']), 'CCD gain [channel 15] (e-/ADU)') + hdu_i.header['GAIN16'] = (np.float32( + self.information['i_gain16']), 'CCD gain [channel 16] (e-/ADU)') ####### - hdu_i.header['RON01'] =( np.float32(self.information['i_rdnois1']) , 'readout noise [channel 01] (e-)') - hdu_i.header['RON02'] =( np.float32(self.information['i_rdnois2']) , 'readout noise [channel 02] (e-)') - hdu_i.header['RON03'] =( np.float32(self.information['i_rdnois3']) , 'readout noise [channel 03] (e-)') - hdu_i.header['RON04'] =( np.float32(self.information['i_rdnois4']) , 'readout noise [channel 04] (e-)') - hdu_i.header['RON05'] =( np.float32(self.information['i_rdnois5']) , 'readout noise [channel 05] (e-)') - hdu_i.header['RON06'] =( np.float32(self.information['i_rdnois6']) , 'readout noise [channel 06] (e-)') - hdu_i.header['RON07'] =( np.float32(self.information['i_rdnois7']) , 'readout noise [channel 07] (e-)') - hdu_i.header['RON08'] =( np.float32(self.information['i_rdnois8']) , 'readout noise [channel 08] (e-)') - hdu_i.header['RON09'] =( np.float32(self.information['i_rdnois9']) , 'readout noise [channel 09] (e-)') - hdu_i.header['RON10']=( np.float32(self.information['i_rdnois10']) , 'readout noise [channel 10] (e-)') - hdu_i.header['RON11']=( np.float32(self.information['i_rdnois11']) , 'readout noise [channel 11] (e-)') - hdu_i.header['RON12']=( np.float32(self.information['i_rdnois12']) , 'readout noise [channel 12] (e-)') - hdu_i.header['RON13']=( np.float32(self.information['i_rdnois13']) , 'readout noise [channel 13] (e-)') - hdu_i.header['RON14']=( np.float32(self.information['i_rdnois14']) , 'readout noise [channel 14] (e-)') - hdu_i.header['RON15']=( np.float32(self.information['i_rdnois15']) , 'readout noise [channel 15] (e-)') - hdu_i.header['RON16']=( np.float32(self.information['i_rdnois16']) , 'readout noise [channel 16] (e-)') - + hdu_i.header['RON01'] = (np.float32( + self.information['i_rdnois1']), 'readout noise [channel 01] (e-)') + hdu_i.header['RON02'] = (np.float32( + self.information['i_rdnois2']), 'readout noise [channel 02] (e-)') + hdu_i.header['RON03'] = (np.float32( + self.information['i_rdnois3']), 'readout noise [channel 03] (e-)') + hdu_i.header['RON04'] = (np.float32( + self.information['i_rdnois4']), 'readout noise [channel 04] (e-)') + hdu_i.header['RON05'] = (np.float32( + self.information['i_rdnois5']), 'readout noise [channel 05] (e-)') + hdu_i.header['RON06'] = (np.float32( + self.information['i_rdnois6']), 'readout noise [channel 06] (e-)') + hdu_i.header['RON07'] = (np.float32( + self.information['i_rdnois7']), 'readout noise [channel 07] (e-)') + hdu_i.header['RON08'] = (np.float32( + self.information['i_rdnois8']), 'readout noise [channel 08] (e-)') + hdu_i.header['RON09'] = (np.float32( + self.information['i_rdnois9']), 'readout noise [channel 09] (e-)') + hdu_i.header['RON10'] = (np.float32( + self.information['i_rdnois10']), 'readout noise [channel 10] (e-)') + hdu_i.header['RON11'] = (np.float32( + self.information['i_rdnois11']), 'readout noise [channel 11] (e-)') + hdu_i.header['RON12'] = (np.float32( + self.information['i_rdnois12']), 'readout noise [channel 12] (e-)') + hdu_i.header['RON13'] = (np.float32( + self.information['i_rdnois13']), 'readout noise [channel 13] (e-)') + hdu_i.header['RON14'] = (np.float32( + self.information['i_rdnois14']), 'readout noise [channel 14] (e-)') + hdu_i.header['RON15'] = (np.float32( + self.information['i_rdnois15']), 'readout noise [channel 15] (e-)') + hdu_i.header['RON16'] = (np.float32( + self.information['i_rdnois16']), 'readout noise [channel 16] (e-)') + ####### - hdu_i.header['DETBIA01']=( np.float32(self.information['i_detbia1']) , 'amplifier bias grey value [channel 1] (ADU)') - hdu_i.header['DETBIA02']=( np.float32(self.information['i_detbia2']) , 'amplifier bias grey value [channel 2] (ADU)') - hdu_i.header['DETBIA03']=( np.float32(self.information['i_detbia3']) , 'amplifier bias grey value [channel 3] (ADU)') - hdu_i.header['DETBIA04']=( np.float32(self.information['i_detbia4']) , 'amplifier bias grey value [channel 4] (ADU)') - hdu_i.header['DETBIA05']=( np.float32(self.information['i_detbia5']) , 'amplifier bias grey value [channel 5] (ADU)') - hdu_i.header['DETBIA06']=( np.float32(self.information['i_detbia6']) , 'amplifier bias grey value [channel 6] (ADU)') - hdu_i.header['DETBIA07']=( np.float32(self.information['i_detbia7']) , 'amplifier bias grey value [channel 7] (ADU)') - hdu_i.header['DETBIA08']=( np.float32(self.information['i_detbia8']) , 'amplifier bias grey value [channel 8] (ADU)') - hdu_i.header['DETBIA09']=( np.float32(self.information['i_detbia9']) , 'amplifier bias grey value [channel 9] (ADU)') - hdu_i.header['DETBIA10']=( np.float32(self.information['i_detbia10']) , 'amplifier bias grey value [channel 10] (ADU)') - hdu_i.header['DETBIA11']=( np.float32(self.information['i_detbia11']) , 'amplifier bias grey value [channel 11] (ADU)') - hdu_i.header['DETBIA12']=( np.float32(self.information['i_detbia12']) , 'amplifier bias grey value [channel 12] (ADU)') - hdu_i.header['DETBIA13']=( np.float32(self.information['i_detbia13']) , 'amplifier bias grey value [channel 13] (ADU)') - hdu_i.header['DETBIA14']=( np.float32(self.information['i_detbia14']) , 'amplifier bias grey value [channel 14] (ADU)') - hdu_i.header['DETBIA15']=( np.float32(self.information['i_detbia15']) , 'amplifier bias grey value [channel 15] (ADU)') - hdu_i.header['DETBIA16']=( np.float32(self.information['i_detbia16']) , 'amplifier bias grey value [channel 16] (ADU)') - hdu_i.header['ROSPEED'] =( np.float32(100) , 'readout speed (MHz)') - + hdu_i.header['DETBIA01'] = (np.float32( + self.information['i_detbia1']), 'amplifier bias grey value [channel 1] (ADU)') + hdu_i.header['DETBIA02'] = (np.float32( + self.information['i_detbia2']), 'amplifier bias grey value [channel 2] (ADU)') + hdu_i.header['DETBIA03'] = (np.float32( + self.information['i_detbia3']), 'amplifier bias grey value [channel 3] (ADU)') + hdu_i.header['DETBIA04'] = (np.float32( + self.information['i_detbia4']), 'amplifier bias grey value [channel 4] (ADU)') + hdu_i.header['DETBIA05'] = (np.float32( + self.information['i_detbia5']), 'amplifier bias grey value [channel 5] (ADU)') + hdu_i.header['DETBIA06'] = (np.float32( + self.information['i_detbia6']), 'amplifier bias grey value [channel 6] (ADU)') + hdu_i.header['DETBIA07'] = (np.float32( + self.information['i_detbia7']), 'amplifier bias grey value [channel 7] (ADU)') + hdu_i.header['DETBIA08'] = (np.float32( + self.information['i_detbia8']), 'amplifier bias grey value [channel 8] (ADU)') + hdu_i.header['DETBIA09'] = (np.float32( + self.information['i_detbia9']), 'amplifier bias grey value [channel 9] (ADU)') + hdu_i.header['DETBIA10'] = (np.float32( + self.information['i_detbia10']), 'amplifier bias grey value [channel 10] (ADU)') + hdu_i.header['DETBIA11'] = (np.float32( + self.information['i_detbia11']), 'amplifier bias grey value [channel 11] (ADU)') + hdu_i.header['DETBIA12'] = (np.float32( + self.information['i_detbia12']), 'amplifier bias grey value [channel 12] (ADU)') + hdu_i.header['DETBIA13'] = (np.float32( + self.information['i_detbia13']), 'amplifier bias grey value [channel 13] (ADU)') + hdu_i.header['DETBIA14'] = (np.float32( + self.information['i_detbia14']), 'amplifier bias grey value [channel 14] (ADU)') + hdu_i.header['DETBIA15'] = (np.float32( + self.information['i_detbia15']), 'amplifier bias grey value [channel 15] (ADU)') + hdu_i.header['DETBIA16'] = (np.float32( + self.information['i_detbia16']), 'amplifier bias grey value [channel 16] (ADU)') + hdu_i.header['ROSPEED'] = (np.float32(100), 'readout speed (MHz)') + ###################################### #### exposure and shutter information ##### - hdu_i.header['EXPSTART']=(np.float64(time2mjd(self.dt)), 'exposure start time (MJD)') - hdu_i.header['EXPEND'] =(float(time2mjd(t2)), 'exposure end time (MJD)') - hdu_i.header['EXPTIME'] =(np.float32(self.information['exptime']), 'exposure time (s)') - hdu_i.header['DARKTIME'] =(np.float32(self.information['exptime']), 'dark current time (s)') - hdu_i.header['SHTSTAT']=( bool(True) , 'shutter status') - - ###### satellite and its allitide information ############## - hdu_i.header['REFFRAME']=('CSSTGSC-1.0' , 'guiding catalog version') - hdu_i.header['SATESWV']=('softwave-1.0', 'satellite software version') - hdu_i.header['CABSTART']=(np.float64(time2jd(self.dt)), 'first cabin time after exposure start (MJD)') - hdu_i.header['SUNANGL0']=(np.float32(0.0) , 'angle between the Sun and opt axis at CABSTART') - hdu_i.header['MOONANG0']=(np.float32(0.0) , 'angle between the Moon and opt axis at CABSTART') - hdu_i.header['TEL_ALT0']=(np.float64(0.0), 'angle between opt axis and Elimb at CABSTART') - hdu_i.header['POS_ANG0']=(np.float64(0.0), 'angle between y axis and North Pole at CABSTART') - hdu_i.header['POSI0_X'] =(np.float64(self.information['pos_x']) , 'orbital position in X at CABSTART (km)') - hdu_i.header['POSI0_Y'] =(np.float64(self.information['pos_y']) , 'orbital position in Y at CABSTART (km)') - hdu_i.header['POSI0_Z'] =(np.float64(self.information['pos_z']) , 'orbital position in Z at CABSTART (km)') - hdu_i.header['VELO0_X']=( np.float64(self.information['velocity_x']) , 'orbital velocity in X at CABSTART (km/s)') - hdu_i.header['VELO0_Y']=( np.float64(self.information['velocity_y']) , 'orbital velocity in Y at CABSTART (km/s)') - hdu_i.header['VELO0_Z']=( np.float64(self.information['velocity_z']) , 'orbital velocity in Z at CABSTART (km/s)') - hdu_i.header['Euler0_1']=( np.float64(0.0), 'Euler angle 1 at CABSTART (deg)') - hdu_i.header['Euler0_2']=( np.float64(0.0), 'Euler angle 2 at CABSTART (deg)') - hdu_i.header['Euler0_3']=( np.float64(0.0), 'Euler angle 3 at CABSTART (deg)') - hdu_i.header['RA_PNT0']=( float(self.information['ra_pnt0']) , 'pointing RA at CABSTART (deg)') - hdu_i.header['DEC_PNT0']=(float(self.information['dec_pnt0']) , 'pointing Dec at CABSTART (deg)') - hdu_i.header['CABEND'] =(float(time2jd(t2)) , 'first cabin time after exposure end (MJD)') - hdu_i.header['SUNANGL1']=(np.float32(0.0), 'angle between the Sun and opt axis at CABEND') - hdu_i.header['MOONANG1']=(np.float32(0.0) , 'angle between the Moon and opt axis at CABEND') - hdu_i.header['TEL_ALT1']=(np.float64(0.0) , 'angle between opt axis and Elimb at CABEND') - hdu_i.header['POS_ANG1']=(float(0.0) , 'angle between y axis and North Pole at CABEND') - hdu_i.header['POSI1_X'] =(float(p1x) , 'orbital position in X at CABEND (km)') - hdu_i.header['POSI1_Y'] =(float(p1y) , 'orbital position in Y at CABEND (km)') - hdu_i.header['POSI1_Z'] =(float(p1z) , 'orbital position in Z at CABEND (km)') - hdu_i.header['VELO1_X']=(float(p1vx) , 'orbital velocity in X at CABEND (km/s)') - hdu_i.header['VELO1_Y']=(float(p1vy) , 'orbital velocity in Y at CABEND (km/s)') - hdu_i.header['VELO1_Z']=(float(p1vz), 'orbital velocity in Z at CABEND (km/s)') - hdu_i.header['Euler1_1']=( np.float64(0.0), 'Euler angle 1 at CABEND (deg)') - hdu_i.header['Euler1_2']=( np.float64(0.0), 'Euler angle 2 at CABEND (deg)') - hdu_i.header['Euler1_3']=( np.float64(0.0), 'Euler angle 3 at CABEND (deg)') - hdu_i.header['RA_PNT1'] =(float(hdu_i.header['RA_PNT0']), 'pointing RA at CABEND (deg)') - hdu_i.header['DEC_PNT1']=(float(hdu_i.header['DEC_PNT0']), 'pointing Dec at CABEND (deg)') - hdu_i.header['EPOCH'] =(np.float32(time2jd(t3.utcnow())), 'equinox of pointing RA and Dec') - hdu_i.header['CHECKSUM'] =(0, '0') - + hdu_i.header['EXPSTART'] = (np.float64( + time2mjd(self.dt)), 'exposure start time (MJD)') + hdu_i.header['EXPEND'] = (float(time2mjd(t2)), + 'exposure end time (MJD)') + hdu_i.header['EXPTIME'] = (np.float32( + self.information['exptime']), 'exposure time (s)') + hdu_i.header['DARKTIME'] = (np.float32( + self.information['exptime']), 'dark current time (s)') + hdu_i.header['SHTSTAT'] = (bool(True), 'shutter status') + + ###### satellite and its allitide information ############## + hdu_i.header['REFFRAME'] = ('CSSTGSC-1.0', 'guiding catalog version') + hdu_i.header['SATESWV'] = ( + 'softwave-1.0', 'satellite software version') + hdu_i.header['CABSTART'] = (np.float64( + time2jd(self.dt)), 'first cabin time after exposure start (MJD)') + hdu_i.header['SUNANGL0'] = (np.float32( + 0.0), 'angle between the Sun and opt axis at CABSTART') + hdu_i.header['MOONANG0'] = (np.float32( + 0.0), 'angle between the Moon and opt axis at CABSTART') + hdu_i.header['TEL_ALT0'] = (np.float64( + 0.0), 'angle between opt axis and Elimb at CABSTART') + hdu_i.header['POS_ANG0'] = (np.float64( + 0.0), 'angle between y axis and North Pole at CABSTART') + hdu_i.header['POSI0_X'] = (np.float64( + self.information['pos_x']), 'orbital position in X at CABSTART (km)') + hdu_i.header['POSI0_Y'] = (np.float64( + self.information['pos_y']), 'orbital position in Y at CABSTART (km)') + hdu_i.header['POSI0_Z'] = (np.float64( + self.information['pos_z']), 'orbital position in Z at CABSTART (km)') + hdu_i.header['VELO0_X'] = (np.float64( + self.information['velocity_x']), 'orbital velocity in X at CABSTART (km/s)') + hdu_i.header['VELO0_Y'] = (np.float64( + self.information['velocity_y']), 'orbital velocity in Y at CABSTART (km/s)') + hdu_i.header['VELO0_Z'] = (np.float64( + self.information['velocity_z']), 'orbital velocity in Z at CABSTART (km/s)') + hdu_i.header['Euler0_1'] = (np.float64( + 0.0), 'Euler angle 1 at CABSTART (deg)') + hdu_i.header['Euler0_2'] = (np.float64( + 0.0), 'Euler angle 2 at CABSTART (deg)') + hdu_i.header['Euler0_3'] = (np.float64( + 0.0), 'Euler angle 3 at CABSTART (deg)') + hdu_i.header['RA_PNT0'] = ( + float(self.information['ra_pnt0']), 'pointing RA at CABSTART (deg)') + hdu_i.header['DEC_PNT0'] = ( + float(self.information['dec_pnt0']), 'pointing Dec at CABSTART (deg)') + hdu_i.header['CABEND'] = (float(time2jd(t2)), + 'first cabin time after exposure end (MJD)') + hdu_i.header['SUNANGL1'] = (np.float32( + 0.0), 'angle between the Sun and opt axis at CABEND') + hdu_i.header['MOONANG1'] = (np.float32( + 0.0), 'angle between the Moon and opt axis at CABEND') + hdu_i.header['TEL_ALT1'] = (np.float64( + 0.0), 'angle between opt axis and Elimb at CABEND') + hdu_i.header['POS_ANG1'] = ( + float(0.0), 'angle between y axis and North Pole at CABEND') + hdu_i.header['POSI1_X'] = ( + float(p1x), 'orbital position in X at CABEND (km)') + hdu_i.header['POSI1_Y'] = ( + float(p1y), 'orbital position in Y at CABEND (km)') + hdu_i.header['POSI1_Z'] = ( + float(p1z), 'orbital position in Z at CABEND (km)') + hdu_i.header['VELO1_X'] = ( + float(p1vx), 'orbital velocity in X at CABEND (km/s)') + hdu_i.header['VELO1_Y'] = ( + float(p1vy), 'orbital velocity in Y at CABEND (km/s)') + hdu_i.header['VELO1_Z'] = ( + float(p1vz), 'orbital velocity in Z at CABEND (km/s)') + hdu_i.header['Euler1_1'] = (np.float64( + 0.0), 'Euler angle 1 at CABEND (deg)') + hdu_i.header['Euler1_2'] = (np.float64( + 0.0), 'Euler angle 2 at CABEND (deg)') + hdu_i.header['Euler1_3'] = (np.float64( + 0.0), 'Euler angle 3 at CABEND (deg)') + hdu_i.header['RA_PNT1'] = ( + float(hdu_i.header['RA_PNT0']), 'pointing RA at CABEND (deg)') + hdu_i.header['DEC_PNT1'] = ( + float(hdu_i.header['DEC_PNT0']), 'pointing Dec at CABEND (deg)') + hdu_i.header['EPOCH'] = (np.float32( + time2jd(t3.utcnow())), 'equinox of pointing RA and Dec') + hdu_i.header['CHECKSUM'] = (0, '0') + ############################################################## - ################ finish MCI header for image layer in G channel - ##############################################################################################333 - - hdulist_i=fits.HDUList([ofd_i, hdu_i]) + # finish MCI header for image layer in G channel + # 333 + + hdulist_i = fits.HDUList([ofd_i, hdu_i]) #### - ofd_i.header.add_comment('========================================================================',after='FITSSWV') - ofd_i.header.add_comment('OBJECT INFORMATION',after='FITSSWV') - ofd_i.header.add_comment('========================================================================',after='FITSSWV') - - ofd_i.header.add_comment('========================================================================',after='DEC_OBJ') - ofd_i.header.add_comment('TELESCOPE INFORMATION',after='DEC_OBJ') - ofd_i.header.add_comment('========================================================================',after='DEC_OBJ') - - ofd_i.header.add_comment('========================================================================',after='EXPTIME') - ofd_i.header.add_comment('VERIFICATION INFORMATION',after='EXPTIME') - ofd_i.header.add_comment('========================================================================',after='EXPTIME') - + ofd_i.header.add_comment( + '========================================================================', after='FITSSWV') + ofd_i.header.add_comment('OBJECT INFORMATION', after='FITSSWV') + ofd_i.header.add_comment( + '========================================================================', after='FITSSWV') + + ofd_i.header.add_comment( + '========================================================================', after='DEC_OBJ') + ofd_i.header.add_comment('TELESCOPE INFORMATION', after='DEC_OBJ') + ofd_i.header.add_comment( + '========================================================================', after='DEC_OBJ') + + ofd_i.header.add_comment( + '========================================================================', after='EXPTIME') + ofd_i.header.add_comment('VERIFICATION INFORMATION', after='EXPTIME') + ofd_i.header.add_comment( + '========================================================================', after='EXPTIME') + ####################################################################### - hdu_i.header.add_comment('========================================================================',after='BUNIT') - hdu_i.header.add_comment('FILE INFORMATION',after='BUNIT') - hdu_i.header.add_comment('========================================================================',after='BUNIT') - - hdu_i.header.add_comment('========================================================================',after='FITSSWV') - hdu_i.header.add_comment('INSTRUMENT STATUS AND OBJECT INFORMATION',after='FITSSWV') - hdu_i.header.add_comment('========================================================================',after='FITSSWV') - - hdu_i.header.add_comment('========================================================================',after='DEC_OBJ') - hdu_i.header.add_comment('DETECTOR AND FILTER INFORMATION',after='DEC_OBJ') - hdu_i.header.add_comment('========================================================================',after='DEC_OBJ') - - hdu_i.header.add_comment('========================================================================',after='BIN_Y') - hdu_i.header.add_comment('WORLD COORDINATE SYSTEM INFORMATION',after='BIN_Y') - hdu_i.header.add_comment('========================================================================',after='BIN_Y') - - hdu_i.header.add_comment('========================================================================',after='CD2_2') - hdu_i.header.add_comment('READOUT INFORMATION',after='CD2_2') - hdu_i.header.add_comment('========================================================================',after='CD2_2') - - hdu_i.header.add_comment('========================================================================',after='ROSPEED') - hdu_i.header.add_comment('EXPOSURE AND SHUTTER INFORMATION',after='ROSPEED') - hdu_i.header.add_comment('========================================================================',after='ROSPEED') - - hdu_i.header.add_comment('========================================================================',after='SHTSTAT') - hdu_i.header.add_comment('SATELLITE AND ITS ATTITUDE INFORMATION',after='SHTSTAT') - hdu_i.header.add_comment('========================================================================',after='SHTSTAT') - - hdu_i.header.add_comment('========================================================================',after='EPOCH') - hdu_i.header.add_comment('VERIFICATION INFORMATION',after='EPOCH') - hdu_i.header.add_comment('========================================================================',after='EPOCH') + hdu_i.header.add_comment( + '========================================================================', after='BUNIT') + hdu_i.header.add_comment('FILE INFORMATION', after='BUNIT') + hdu_i.header.add_comment( + '========================================================================', after='BUNIT') + + hdu_i.header.add_comment( + '========================================================================', after='FITSSWV') + hdu_i.header.add_comment( + 'INSTRUMENT STATUS AND OBJECT INFORMATION', after='FITSSWV') + hdu_i.header.add_comment( + '========================================================================', after='FITSSWV') + + hdu_i.header.add_comment( + '========================================================================', after='DEC_OBJ') + hdu_i.header.add_comment( + 'DETECTOR AND FILTER INFORMATION', after='DEC_OBJ') + hdu_i.header.add_comment( + '========================================================================', after='DEC_OBJ') + + hdu_i.header.add_comment( + '========================================================================', after='BIN_Y') + hdu_i.header.add_comment( + 'WORLD COORDINATE SYSTEM INFORMATION', after='BIN_Y') + hdu_i.header.add_comment( + '========================================================================', after='BIN_Y') + + hdu_i.header.add_comment( + '========================================================================', after='CD2_2') + hdu_i.header.add_comment('READOUT INFORMATION', after='CD2_2') + hdu_i.header.add_comment( + '========================================================================', after='CD2_2') + + hdu_i.header.add_comment( + '========================================================================', after='ROSPEED') + hdu_i.header.add_comment( + 'EXPOSURE AND SHUTTER INFORMATION', after='ROSPEED') + hdu_i.header.add_comment( + '========================================================================', after='ROSPEED') + + hdu_i.header.add_comment( + '========================================================================', after='SHTSTAT') + hdu_i.header.add_comment( + 'SATELLITE AND ITS ATTITUDE INFORMATION', after='SHTSTAT') + hdu_i.header.add_comment( + '========================================================================', after='SHTSTAT') + + hdu_i.header.add_comment( + '========================================================================', after='EPOCH') + hdu_i.header.add_comment('VERIFICATION INFORMATION', after='EPOCH') + hdu_i.header.add_comment( + '========================================================================', after='EPOCH') # hdu_i.header.add_comment('========================================================================',before='CHECKSUM') # hdu_i.header.add_comment('VERIFICATION INFORMATION',before='CHECKSUM') # hdu_i.header.add_comment('========================================================================',before='CHECKSUM') ##################################### - ################ finish MCI header for image layer in i channel - ################ finish MCI header for image layer - if self.source=='DARK' or self.source=='FLAT' or self.source=='BIAS': - file_i=self.result_path+'/cali_Data/'+filename_i+'.fits' + # finish MCI header for image layer in i channel + # finish MCI header for image layer + if self.source == 'DARK' or self.source == 'FLAT' or self.source == 'BIAS': + file_i = self.result_path+'/cali_Data/'+filename_i+'.fits' else: - file_i=self.result_path+'/sky_Data/'+filename_i +'.fits' - + file_i = self.result_path+'/sky_Data/'+filename_i + '.fits' + hdulist_i.writeto(file_i, checksum=True) - -################################################################################################# +################################################################################################# def simulate(self, simnumber): """ @@ -4492,475 +5283,519 @@ class MCIsimulator(): :return: None """ - + ############################################################################################## ############################################################################################## - sourcelist=['EXDF','STAR','PIPR','TRNS','COMB','CALI'] - - sim_list=['FLAT','BIAS','DARK','EXDF','STAR','PIPR','TRNS','COMB','CALI'] - + sourcelist = ['EXDF', 'STAR', 'PIPR', 'TRNS', 'COMB', 'CALI'] + + sim_list = ['FLAT', 'BIAS', 'DARK', 'EXDF', + 'STAR', 'PIPR', 'TRNS', 'COMB', 'CALI'] + if self.source not in sim_list: print('Sourcein is wrong') sys.exit(1) - - - self._loadGhostModel() - self.load_filter_PSF() - self.information['simnumber']=simnumber - + + self._loadGhostModel() + self.load_filter_PSF() + self.information['simnumber'] = simnumber + self.debug = self.information['debug'] ########################### - flag=0 - - self.dt_num=int((self.information['simnumber']-1)*(self.information['exptime']+self.information['readouttime']+50)/120) - now_dt=datetime.utcnow() - now_jd=time2jd(now_dt) - - for k in range(1,50,1): - - fn=self.information['dir_path']+'MCI_inputData/TianCe/orbit20160925/'+str(k)+'.txt'; - d=np.loadtxt(fn); - - for kk in range(len(d[:,0])): - if now_jd-d[kk,0]<=0: - flag=1 + flag = 0 + + self.dt_num = int((self.information['simnumber']-1)*( + self.information['exptime']+self.information['readouttime']+50)/120) + now_dt = datetime.utcnow() + now_jd = time2jd(now_dt) + + for k in range(1, 50, 1): + + fn = self.information['dir_path'] + \ + 'MCI_inputData/TianCe/orbit20160925/'+str(k)+'.txt' + d = np.loadtxt(fn) + + for kk in range(len(d[:, 0])): + if now_jd-d[kk, 0] <= 0: + flag = 1 break - if flag==1: + if flag == 1: print('find time index...... ') break - - ################################################################ - - if kk +self.dt_num < len(d[:,0]): - - exptime_start_jd=d[kk+self.dt_num,0] - - self.orbit_pars=d - self.orbit_file_num=k - self.orbit_exp_num =kk - - self.information['pos_x']=float(self.orbit_pars[self.orbit_exp_num,1]) - self.information['pos_y']=float(self.orbit_pars[self.orbit_exp_num,2]) - self.information['pos_z']=float(self.orbit_pars[self.orbit_exp_num,3]) - self.information['velocity_x']=float(self.orbit_pars[self.orbit_exp_num,4]) - self.information['velocity_y']=float(self.orbit_pars[self.orbit_exp_num,5]) - self.information['velocity_z']=float(self.orbit_pars[self.orbit_exp_num,6]) - + + ################################################################ + + if kk + self.dt_num < len(d[:, 0]): + + exptime_start_jd = d[kk+self.dt_num, 0] + + self.orbit_pars = d + self.orbit_file_num = k + self.orbit_exp_num = kk + + self.information['pos_x'] = float( + self.orbit_pars[self.orbit_exp_num, 1]) + self.information['pos_y'] = float( + self.orbit_pars[self.orbit_exp_num, 2]) + self.information['pos_z'] = float( + self.orbit_pars[self.orbit_exp_num, 3]) + self.information['velocity_x'] = float( + self.orbit_pars[self.orbit_exp_num, 4]) + self.information['velocity_y'] = float( + self.orbit_pars[self.orbit_exp_num, 5]) + self.information['velocity_z'] = float( + self.orbit_pars[self.orbit_exp_num, 6]) + else: - - fn=self.information['dir_path']+'MCI_inputData/TianCe/orbit20160925/'+str(k+1)+'.txt'; - d=np.loadtxt(fn); - - self.orbit_pars=d - self.orbit_file_num=k+1 - self.orbit_exp_num =self.dt_num - - self.information['pos_x']=float(self.orbit_pars[self.orbit_exp_num,1]) - self.information['pos_y']=float(self.orbit_pars[self.orbit_exp_num,2]) - self.information['pos_z']=float(self.orbit_pars[self.orbit_exp_num,3]) - self.information['velocity_x']=float(self.orbit_pars[self.orbit_exp_num,4]) - self.information['velocity_y']=float(self.orbit_pars[self.orbit_exp_num,5]) - self.information['velocity_z']=float(self.orbit_pars[self.orbit_exp_num,6]) + + fn = self.information['dir_path'] + \ + 'MCI_inputData/TianCe/orbit20160925/'+str(k+1)+'.txt' + d = np.loadtxt(fn) + + self.orbit_pars = d + self.orbit_file_num = k+1 + self.orbit_exp_num = self.dt_num + + self.information['pos_x'] = float( + self.orbit_pars[self.orbit_exp_num, 1]) + self.information['pos_y'] = float( + self.orbit_pars[self.orbit_exp_num, 2]) + self.information['pos_z'] = float( + self.orbit_pars[self.orbit_exp_num, 3]) + self.information['velocity_x'] = float( + self.orbit_pars[self.orbit_exp_num, 4]) + self.information['velocity_y'] = float( + self.orbit_pars[self.orbit_exp_num, 5]) + self.information['velocity_z'] = float( + self.orbit_pars[self.orbit_exp_num, 6]) ########################################## - - + ###self.dt=julian.from_jd(exptime_start_jd, fmt='jd') self.dt = jd2time(exptime_start_jd) - self.TianCe_day=str(self.dt.year)+self.dt.strftime("-%m-%d") ####str(self.dt.year)+'-'+str(self.dt.month)+'-'+str(self.dt.day) - - self.TianCe_exp_start=dt2hmd(self.dt) - + # str(self.dt.year)+'-'+str(self.dt.month)+'-'+str(self.dt.day) + self.TianCe_day = str(self.dt.year)+self.dt.strftime("-%m-%d") + + self.TianCe_exp_start = dt2hmd(self.dt) + ############################################################# - + if self.source in sourcelist: - - #self.earthshine_theta=30.0 # in degree - + + # self.earthshine_theta=30.0 # in degree + ################################### if self.sky_shift_rot: - - if self.information['simnumber']>1: - + + if self.information['simnumber'] > 1: + np.random.seed(self.information['simnumber']) ud = np.random.random() # Choose a random pointing ra in degree - dis_ra = 2*(ud-1)*10/3600.0 - + dis_ra = 2*(ud-1)*10/3600.0 + np.random.seed(10*self.information['simnumber']) ud = np.random.random() # Choose a random pointing dec in degree - dis_dec = 2*(ud-1)*10/3600.0 # - + dis_dec = 2*(ud-1)*10/3600.0 + np.random.seed(100*self.information['simnumber']) - ud = np.random.random() # Choose a random telescope rotation in degree - rotTelPos = 2*(ud-1)*5.0*galsim.degrees # the image will rotate in clockwise rotaion between -10-10 degree + ud = np.random.random() # Choose a random telescope rotation in degree + # the image will rotate in clockwise rotaion between -10-10 degree + rotTelPos = 2*(ud-1)*5.0*galsim.degrees rotSkyPos = 0.0*galsim.degrees - + ################################ - # ### test code - # rotTelPos = 90.0*galsim.degrees + # ### test code + # rotTelPos = 90.0*galsim.degrees # dis_dec= -200*0.05/3600 # dis_ra = 100*0.05/3600 - - + else: - - dis_ra = 0 # - dis_dec = 0 # T - - rotTelPos = 0.0*galsim.degrees # the image will rotate in clockwise rotaion between -10-10 degree + + dis_ra = 0 # + dis_dec = 0 # T + + # the image will rotate in clockwise rotaion between -10-10 degree + rotTelPos = 0.0*galsim.degrees rotSkyPos = 0.0*galsim.degrees - - + else: - - dis_ra = 0 # - dis_dec = 0 # T - - rotTelPos = 0.0*galsim.degrees # the image will rotate in clockwise rotaion between -10-10 degree + + dis_ra = 0 # + dis_dec = 0 # T + + # the image will rotate in clockwise rotaion between -10-10 degree + rotTelPos = 0.0*galsim.degrees rotSkyPos = 0.0*galsim.degrees - + ##################################################### - - self.information['T_disRa'] =dis_ra # telescope pointing Ra displacement - self.information['T_disDec'] =dis_dec # telescope pointing Dec displacement - - self.information['rotTelPos']=rotTelPos # telescope rotation in degree - self.information['rotSkyPos']=rotSkyPos # sky rotation in degree - - self.information['name_obj'] ='MCI_obj' - - theta = self.information['rotTelPos'] - self.information['rotSkyPos'] - - self.information['rotangle']=theta.deg - #print('rotangle',theta.deg ) - - self.log.info('dis_ra(in pixel)=%f, dis_dec(in pixel)=%f, sky_rot(in deg)=%f' % (dis_ra*3600/0.05, dis_dec*3600/0.05, theta.deg)) - ####################################################################################################### - + + # telescope pointing Ra displacement + self.information['T_disRa'] = dis_ra + # telescope pointing Dec displacement + self.information['T_disDec'] = dis_dec + + # telescope rotation in degree + self.information['rotTelPos'] = rotTelPos + # sky rotation in degree + self.information['rotSkyPos'] = rotSkyPos + + self.information['name_obj'] = 'MCI_obj' + + theta = self.information['rotTelPos'] - \ + self.information['rotSkyPos'] + + self.information['rotangle'] = theta.deg + #print('rotangle',theta.deg ) + + self.log.info('dis_ra(in pixel)=%f, dis_dec(in pixel)=%f, sky_rot(in deg)=%f' % ( + dis_ra*3600/0.05, dis_dec*3600/0.05, theta.deg)) + ####################################################################################################### + ############################################################################# ######### simulate star images from star SED data ################## - - if self.sim_star : + + if self.sim_star: ########################### - - starimg=self.cal_StarSED_img() - - if 'starimg' in dir(): + + starimg = self.cal_StarSED_img() + + if 'starimg' in dir(): self.log.info('Generate artifical stars finished...') # fits.writeto(self.result_path+'/ori_Sky/starimg_C1_'+str(simnumber)+'.fits',starimg['g'], overwrite=True) # fits.writeto(self.result_path+'/ori_Sky/starimg_C2_'+str(simnumber)+'.fits',starimg['r'], overwrite=True) - # fits.writeto(self.result_path+'/ori_Sky/starimg_C3_'+str(simnumber)+'.fits',starimg['i'], overwrite=True) - - self.img_fits_save(starimg['g'], 'star_ori_C1_'+str(simnumber)) - self.img_fits_save(starimg['r'], 'star_ori_C2_'+str(simnumber)) - self.img_fits_save(starimg['i'], 'star_ori_C3_'+str(simnumber)) - - - print('star image finished') - + # fits.writeto(self.result_path+'/ori_Sky/starimg_C3_'+str(simnumber)+'.fits',starimg['i'], overwrite=True) + + self.img_fits_save( + starimg['g'], 'star_ori_C1_'+str(simnumber)) + self.img_fits_save( + starimg['r'], 'star_ori_C2_'+str(simnumber)) + self.img_fits_save( + starimg['i'], 'star_ori_C3_'+str(simnumber)) + + print('star image finished') ########################################################################## # # ######################################################################## - # ###### generate galaxy SED image without Lensing effect ########## - - if self.sim_galaxy and self.source=='EXDF' : - - losimg=self.cal_Lensing_galaxy_img() - - if 'losimg' in dir(): + # ###### generate galaxy SED image without Lensing effect ########## + + if self.sim_galaxy and self.source == 'EXDF': + + losimg = self.cal_Lensing_galaxy_img() + + if 'losimg' in dir(): self.log.info('Generate los finished...') - print('losimage finished') + print('losimage finished') # fits.writeto(self.result_path+'/ori_Sky/galimg_C1_'+str(simnumber)+'.fits',losimg['g'], overwrite=True) # fits.writeto(self.result_path+'/ori_Sky/galimg_C2_'+str(simnumber)+'.fits',losimg['r'], overwrite=True) - # fits.writeto(self.result_path+'/ori_Sky/galimg_C3_'+str(simnumber)+'.fits',losimg['i'], overwrite=True) - - self.img_fits_save(losimg['g'], 'gal_ori_C1_'+str(simnumber)) - self.img_fits_save(losimg['r'], 'gal_ori_C2_'+str(simnumber)) - self.img_fits_save(losimg['i'], 'gal_ori_C3_'+str(simnumber)) - - + # fits.writeto(self.result_path+'/ori_Sky/galimg_C3_'+str(simnumber)+'.fits',losimg['i'], overwrite=True) + + self.img_fits_save( + losimg['g'], 'gal_ori_C1_'+str(simnumber)) + self.img_fits_save( + losimg['r'], 'gal_ori_C2_'+str(simnumber)) + self.img_fits_save( + losimg['i'], 'gal_ori_C3_'+str(simnumber)) + ################################################################## - ### stack the image - - if 'losimg' in dir(): - self.image_g+=losimg['g'] - self.image_r+=losimg['r'] - self.image_i+=losimg['i'] - - if 'starimg' in dir(): - self.image_g+=starimg['g'] - self.image_r+=starimg['r'] - self.image_i+=starimg['i'] - - + # stack the image + + if 'losimg' in dir(): + self.image_g += losimg['g'] + self.image_r += losimg['r'] + self.image_i += losimg['i'] + + if 'starimg' in dir(): + self.image_g += starimg['g'] + self.image_r += starimg['r'] + self.image_i += starimg['i'] + ########################################################################################################### - - fits.writeto(self.result_path+'/ori_Sky/original_C1_'+str(simnumber)+'.fits',self.image_g, overwrite=True) - fits.writeto(self.result_path+'/ori_Sky/original_C2_'+str(simnumber)+'.fits',self.image_r, overwrite=True) - fits.writeto(self.result_path+'/ori_Sky/original_C3_'+str(simnumber)+'.fits',self.image_i, overwrite=True) - + + fits.writeto(self.result_path+'/ori_Sky/original_C1_' + + str(simnumber)+'.fits', self.image_g, overwrite=True) + fits.writeto(self.result_path+'/ori_Sky/original_C2_' + + str(simnumber)+'.fits', self.image_r, overwrite=True) + fits.writeto(self.result_path+'/ori_Sky/original_C3_' + + str(simnumber)+'.fits', self.image_i, overwrite=True) + # self.img_fits_save(self.image_g, 'full_ori_C1_'+str(simnumber)) # self.img_fits_save(self.image_g, 'full_ori_C2_'+str(simnumber)) # self.img_fits_save(self.image_g, 'full_ori_C3_'+str(simnumber)) - - ######################################################################################################### - - ####### end if source =='SKY' - - elif self.source=='FLAT': - - theta=0 - self.information['exptime']=100*self.information['simnumber']#np.ceil(self.information['simnumber']/2.0) - self.information['name_obj']='FLAT' - - self.information['rotangle']=0 - - self.information['CRVAL1']=0 - self.information['CRVAL2']=0 - - self.information['tel_Pra']=0 - self.information['tel_Pdec']=0 - - self.information['CRPIX1']=self.information['tel_Pra']*self.information['pixel_size'] #### - self.information['CRPIX2']=self.information['tel_Pdec']*self.information['pixel_size'] #### - - self.information['CD1_1']=-np.cos(theta)*self.information['pixel_size'] #### - self.information['CD1_2']= np.sin(theta)*self.information['pixel_size'] #### - - self.information['CD2_1']= np.sin(theta)*self.information['pixel_size'] #### - self.information['CD2_2']= np.cos(theta)*self.information['pixel_size'] #### - - self.information['ra_obj'] =0 - self.information['dec_obj'] =0 - self.information['ra_pnt0'] =0 - self.information['dec_pnt0']=0 - self.information['target'] ='FLAT' - - self.image_g +=5000*self.information['simnumber'] - self.image_r +=5000*self.information['simnumber'] - self.image_i +=5000*self.information['simnumber'] - - elif self.source=='DARK': - - theta=0 - - self.information['exptime']=2*3600*self.information['simnumber'] - self.information['name_obj']='DARK' - - self.information['rotangle']=0 - - self.information['CRVAL1']=0 - self.information['CRVAL2']=0 - - self.information['tel_Pra']=0 - self.information['tel_Pdec']=0 - self.information['CRPIX1']=self.information['tel_Pra']*self.information['pixel_size'] #### - self.information['CRPIX2']=self.information['tel_Pdec']*self.information['pixel_size'] #### - - self.information['CD1_1']=-np.cos(theta)*self.information['pixel_size'] #### - self.information['CD1_2']= np.sin(theta)*self.information['pixel_size'] #### - - self.information['CD2_1']= np.sin(theta)*self.information['pixel_size'] #### - self.information['CD2_2']= np.cos(theta)*self.information['pixel_size'] #### - - self.information['ra_obj'] =0 - self.information['dec_obj'] =0 - self.information['ra_pnt0'] =0 - self.information['dec_pnt0']=0 - self.information['target'] ='DARK' - - self.image_g=np.zeros((self.information['ysize'], self.information['xsize']), dtype=float) - self.image_r=np.zeros((self.information['ysize'], self.information['xsize']), dtype=float) - self.image_i=np.zeros((self.information['ysize'], self.information['xsize']), dtype=float) - - elif self.source=='BIAS': - - theta=0 - - self.information['exptime']=0.0 - - self.information['name_obj']='BIAS' - - self.information['rotangle']=0 - - self.information['CRVAL1']=0 - self.information['CRVAL2']=0 - - self.information['tel_Pra']=0 - self.information['tel_Pdec']=0 - - self.information['CRPIX1']=self.information['tel_Pra']*self.information['pixel_size'] #### - self.information['CRPIX2']=self.information['tel_Pdec']*self.information['pixel_size'] #### - - self.information['CD1_1']=-np.cos(theta)*self.information['pixel_size'] #### - self.information['CD1_2']= np.sin(theta)*self.information['pixel_size'] #### - - self.information['CD2_1']= np.sin(theta)*self.information['pixel_size'] #### - self.information['CD2_2']= np.cos(theta)*self.information['pixel_size'] #### - - self.image_g=np.zeros((self.information['ysize'], self.information['xsize']), dtype=float) - self.image_r=np.zeros((self.information['ysize'], self.information['xsize']), dtype=float) - self.image_i=np.zeros((self.information['ysize'], self.information['xsize']), dtype=float) - self.information['target'] ='BIAS' - self.information['ra_obj'] =0 - self.information['dec_obj'] =0 - self.information['ra_pnt0'] =0 - self.information['dec_pnt0']=0 - - + + ######################################################################################################### + + # end if source =='SKY' + + elif self.source == 'FLAT': + + theta = 0 + # np.ceil(self.information['simnumber']/2.0) + self.information['exptime'] = 100*self.information['simnumber'] + self.information['name_obj'] = 'FLAT' + + self.information['rotangle'] = 0 + + self.information['CRVAL1'] = 0 + self.information['CRVAL2'] = 0 + + self.information['tel_Pra'] = 0 + self.information['tel_Pdec'] = 0 + + self.information['CRPIX1'] = self.information['tel_Pra'] * \ + self.information['pixel_size'] + self.information['CRPIX2'] = self.information['tel_Pdec'] * \ + self.information['pixel_size'] + + self.information['CD1_1'] = - \ + np.cos(theta)*self.information['pixel_size'] + self.information['CD1_2'] = np.sin( + theta)*self.information['pixel_size'] + + self.information['CD2_1'] = np.sin( + theta)*self.information['pixel_size'] + self.information['CD2_2'] = np.cos( + theta)*self.information['pixel_size'] + + self.information['ra_obj'] = 0 + self.information['dec_obj'] = 0 + self.information['ra_pnt0'] = 0 + self.information['dec_pnt0'] = 0 + self.information['target'] = 'FLAT' + + self.image_g += 5000*self.information['simnumber'] + self.image_r += 5000*self.information['simnumber'] + self.image_i += 5000*self.information['simnumber'] + + elif self.source == 'DARK': + + theta = 0 + + self.information['exptime'] = 2*3600*self.information['simnumber'] + self.information['name_obj'] = 'DARK' + + self.information['rotangle'] = 0 + + self.information['CRVAL1'] = 0 + self.information['CRVAL2'] = 0 + + self.information['tel_Pra'] = 0 + self.information['tel_Pdec'] = 0 + self.information['CRPIX1'] = self.information['tel_Pra'] * \ + self.information['pixel_size'] + self.information['CRPIX2'] = self.information['tel_Pdec'] * \ + self.information['pixel_size'] + + self.information['CD1_1'] = - \ + np.cos(theta)*self.information['pixel_size'] + self.information['CD1_2'] = np.sin( + theta)*self.information['pixel_size'] + + self.information['CD2_1'] = np.sin( + theta)*self.information['pixel_size'] + self.information['CD2_2'] = np.cos( + theta)*self.information['pixel_size'] + + self.information['ra_obj'] = 0 + self.information['dec_obj'] = 0 + self.information['ra_pnt0'] = 0 + self.information['dec_pnt0'] = 0 + self.information['target'] = 'DARK' + + self.image_g = np.zeros( + (self.information['ysize'], self.information['xsize']), dtype=float) + self.image_r = np.zeros( + (self.information['ysize'], self.information['xsize']), dtype=float) + self.image_i = np.zeros( + (self.information['ysize'], self.information['xsize']), dtype=float) + + elif self.source == 'BIAS': + + theta = 0 + + self.information['exptime'] = 0.0 + + self.information['name_obj'] = 'BIAS' + + self.information['rotangle'] = 0 + + self.information['CRVAL1'] = 0 + self.information['CRVAL2'] = 0 + + self.information['tel_Pra'] = 0 + self.information['tel_Pdec'] = 0 + + self.information['CRPIX1'] = self.information['tel_Pra'] * \ + self.information['pixel_size'] + self.information['CRPIX2'] = self.information['tel_Pdec'] * \ + self.information['pixel_size'] + + self.information['CD1_1'] = - \ + np.cos(theta)*self.information['pixel_size'] + self.information['CD1_2'] = np.sin( + theta)*self.information['pixel_size'] + + self.information['CD2_1'] = np.sin( + theta)*self.information['pixel_size'] + self.information['CD2_2'] = np.cos( + theta)*self.information['pixel_size'] + + self.image_g = np.zeros( + (self.information['ysize'], self.information['xsize']), dtype=float) + self.image_r = np.zeros( + (self.information['ysize'], self.information['xsize']), dtype=float) + self.image_i = np.zeros( + (self.information['ysize'], self.information['xsize']), dtype=float) + self.information['target'] = 'BIAS' + self.information['ra_obj'] = 0 + self.information['dec_obj'] = 0 + self.information['ra_pnt0'] = 0 + self.information['dec_pnt0'] = 0 + else: - print('Souce is not correct and programe will return') + print('Souce is not correct and programe will return') sys.exit(1) - - + ######################################################################################################################## - ######################################################################################################################## - - #Apply flat-field large scale structure for one chip + ######################################################################################################################## + + # Apply flat-field large scale structure for one chip if self.flatfieldM: self.applyFlat() print('applyFlat') ######################################################## if self.PRNUeffect: - self.applyPRNUeffect() + self.applyPRNUeffect() print('applyPRNUeffect') #################################################################### if self.source in sourcelist: if self.cosmicRays: - + self.addCosmicRays() print('addCosmicRays finisth') - + ################################################## if self.skyback: if self.source in sourcelist: self.applyPoissonSkyNoise() print('apply Poisson Sky Noise') - ################################################# - - if self.darknoise: + ################################################# + + if self.darknoise: self.applyDarkCurrent() print('applyDarkCurrent finisth') - + ################################################# - if self.shutterEffect and self.information['exptime']>2.6: + if self.shutterEffect and self.information['exptime'] > 2.6: self.addshuttereffect() print('add shutter effect ') - + ################################################# if self.bleeding: - - self.image_g=self.applyBleeding(self.image_g.copy()) - self.image_r=self.applyBleeding(self.image_r.copy()) - self.image_i=self.applyBleeding(self.image_i.copy()) + + self.image_g = self.applyBleeding(self.image_g.copy()) + self.image_r = self.applyBleeding(self.image_r.copy()) + self.image_i = self.applyBleeding(self.image_i.copy()) print('apply bleeding effect finisth') - + ################################################ - + if self.nonlinearity: self.applyNonlinearity() print('applyNonlinearity') - + # ################################################ - #### read CCD image to output matrix as defined - - - if self.overscans and self.information['xsize']==9216 and self.information['ysize']==9232 : - - self.image_g=self.addScanEffect(self.image_g.copy()) - self.image_r=self.addScanEffect(self.image_r.copy()) - self.image_i=self.addScanEffect(self.image_i.copy()) + # read CCD image to output matrix as defined + + if self.overscans and self.information['xsize'] == 9216 and self.information['ysize'] == 9232: + + self.image_g = self.addScanEffect(self.image_g.copy()) + self.image_r = self.addScanEffect(self.image_r.copy()) + self.image_i = self.addScanEffect(self.image_i.copy()) print('apply overscan zone 1-16') - + ################################################################# if self.source in sourcelist: if self.radiationDamage: - + self.applyRadiationDamage() print('applyRadiationDamage()') ###################################################################### ###### apply readoutNoise ###### - - + if self.readoutNoise: self.applyReadoutNoise() print('apply readout noise') - + ###################################################################### - if self.information['xsize']==9216 and self.information['ysize']==9232 and self.overscans : - self.electrons2ADU() ### apply gain + if self.information['xsize'] == 9216 and self.information['ysize'] == 9232 and self.overscans: + self.electrons2ADU() # apply gain print('apply 1-16 zone by different gain ') - + else: - self.image_g=self.image_g/1.5 - self.image_r=self.image_r/1.5 - self.image_i=self.image_i/1.5 + self.image_g = self.image_g/1.5 + self.image_r = self.image_r/1.5 + self.image_i = self.image_i/1.5 print('apply gain finish') ###################################################################### - #size of the output image array, xsize is column, ysize is row, xsize = 9216,ysize = 9232 - + # size of the output image array, xsize is column, ysize is row, xsize = 9216,ysize = 9232 - if self.information['xsize']==9216 and self.information['ysize']==9232 and self.overscans : - self.applyBias() ### + if self.information['xsize'] == 9216 and self.information['ysize'] == 9232 and self.overscans: + self.applyBias() print('apply bias finish') else: - self.image_g=self.image_g+500.0 - self.image_r=self.image_r+500.0 - self.image_i=self.image_i+500.0 - - ################################################################### - if self.cosmetics and self.information['xsize']==9216 and self.information['ysize']==9232 : - + self.image_g = self.image_g+500.0 + self.image_r = self.image_r+500.0 + self.image_i = self.image_i+500.0 + + ################################################################### + if self.cosmetics and self.information['xsize'] == 9216 and self.information['ysize'] == 9232: + self.applyCosmetics() print('apply Cosmetics...') - + ################################################## if self.intscale: - self.discretise() + self.discretise() ################################################## - self.writeOutputs(simnumber) - - + self.writeOutputs(simnumber) + ####################################################### self.log.info('Using the following input values:') - + for key, value in self.information.items(): self.log.info('%s = %s' % (key, value)) self.log.info('Using the following booleans:') - + for key, value in self.booleans.items(): - self.log.info('%s = %s' % (key, value)) + self.log.info('%s = %s' % (key, value)) ####################################################### - - - self.log.info('Finished the ith_Exposure = %i' % (simnumber)) - - print('The iLoop= % d simlaiton finished. ' %simnumber) - + self.log.info('Finished the ith_Exposure = %i' % (simnumber)) + + print('The iLoop= % d simlaiton finished. ' % simnumber) + + ################################################################################################ -def runMCIsim(sourcein,configfile,dir_path, result_path, debug, iLoop): - - +def runMCIsim(sourcein, configfile, dir_path, result_path, debug, iLoop): + print('Path Test:dir_path', dir_path) - sim= dict() + sim = dict() sim[iLoop] = MCIsimulator(configfile) - - sim[iLoop].configure(iLoop,sourcein,dir_path,result_path) # load the configfile; - - sim[iLoop].information['sourcein'] =sourcein - sim[iLoop].information['debug'] =debug - sim[iLoop].information['result_path'] = result_path - - - sim[iLoop].simulate(iLoop) - + + sim[iLoop].configure(iLoop, sourcein, dir_path, + result_path) # load the configfile; + + sim[iLoop].information['sourcein'] = sourcein + sim[iLoop].information['debug'] = debug + sim[iLoop].information['result_path'] = result_path + + sim[iLoop].simulate(iLoop) + return -################################################################################################ +################################################################################################ diff --git a/csst_mci_sim/earthshine.py b/csst_mci_sim/earthshine.py index 29dcfbc..bee2b12 100644 --- a/csst_mci_sim/earthshine.py +++ b/csst_mci_sim/earthshine.py @@ -177,8 +177,8 @@ class StrayLight(object): # band_star_e2 = star_e2[:][filterIndex[filter]] # return max(band_star_e1, band_star_e2) - -############################################################################### + +############################################################################### def caculateEarthShineFilter(self, filter='i'): @@ -207,7 +207,7 @@ class StrayLight(object): ############################################################################### -### test +# test # path='/home/yan/MCI/' # time_jd = 2460417.59979167 # x_sat = -4722.543136 diff --git a/csst_mci_sim/mci_so/__pycache__/__init__.cpython-311.pyc b/csst_mci_sim/mci_so/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0cfa51aed7d5e0c7e2f8fe2ac372f8698db5cfe GIT binary patch literal 187 zcmZ3^%ge<81fI!@(?IlN5CH>>P{wCAAY(d13PUi1CZpd?AD^CCqMuw`ToRv~oEZ<4MCE`5^Y!E7GxIV_;^XxS mDt~d<y?;IiQ#yNPJ*sWMurn03(W+fnosCFfOhD literal 0 HcmV?d00001 diff --git a/csst_mci_sim/straylight.py b/csst_mci_sim/straylight.py index c2e3453..cb37588 100644 --- a/csst_mci_sim/straylight.py +++ b/csst_mci_sim/straylight.py @@ -205,7 +205,7 @@ class StrayLight(object): ############################################################################### -## test +# test # path='/home/yan/MCI/' # time_jd = 2460417.59979167 # x_sat = -4722.543136 diff --git a/csst_mci_sim/support/MCIinstrumentModel.py b/csst_mci_sim/support/MCIinstrumentModel.py index 95771db..175ff50 100644 --- a/csst_mci_sim/support/MCIinstrumentModel.py +++ b/csst_mci_sim/support/MCIinstrumentModel.py @@ -21,12 +21,12 @@ def MCIinformation(): """ Returns a dictionary describing MCI CCD. The following information is provided (id: value - reference):: - + dob: 0 - CDM03 (Short et al. 2010) - fwc: 90000 - CCD spec EUCL-EST-RS-6-002 (for CDM03) + fwc: 90000 - CCD spec EUCL-EST-RS-6-002 (for CDM03) rdose: 30000000000.0 - derived (above the PLM requirement) - sfwc: 730000.0 - CDM03 (Short et al. 2010), see also the CCD spec EUCL-EST-RS-6-002 - st: 5e-06 - CDM03 (Short et al. 2010) + sfwc: 730000.0 - CDM03 (Short et al. 2010), see also the CCD spec EUCL-EST-RS-6-002 + st: 5e-06 - CDM03 (Short et al. 2010) svg: 1e-10 - CDM03 (Short et al. 2010) t: 0.01024 - CDM03 (Short et al. 2010) trapfile: cdm_euclid.dat - CDM03 (derived, refitted to CCD204 data) @@ -40,19 +40,19 @@ def MCIinformation(): """ ######################################################################################################### - out=dict() - out.update({'dob' : 0, 'rdose' : 8.0e9, - 'parallelTrapfile' : 'cdm_euclid_parallel.dat', 'serialTrapfile' : 'cdm_euclid_serial.dat', - 'beta_s' : 0.6, 'beta_p': 0.6, 'fwc' : 90000, 'vth' : 1.168e7, 't' : 20.48e-3, 'vg' : 6.e-11, - 'st' : 5.0e-6, 'sfwc' : 730000., 'svg' : 1.0e-10}) + out = dict() + out.update({'dob': 0, 'rdose': 8.0e9, + 'parallelTrapfile': 'cdm_euclid_parallel.dat', 'serialTrapfile': 'cdm_euclid_serial.dat', + 'beta_s': 0.6, 'beta_p': 0.6, 'fwc': 90000, 'vth': 1.168e7, 't': 20.48e-3, 'vg': 6.e-11, + 'st': 5.0e-6, 'sfwc': 730000., 'svg': 1.0e-10}) return out # def CCDnonLinearityModel(data, beta=6e-7): -# """ +# """ -# The non-linearity is modelled based on the results presented. +# The non-linearity is modelled based on the results presented. # :param data: data to which the non-linearity model is being applied to # :type data: ndarray @@ -60,7 +60,7 @@ def MCIinformation(): # :rtype: float or ndarray # """ # out = data-beta*data**2 - + # return out ################################################################### diff --git a/csst_mci_sim/support/__pycache__/MCIinstrumentModel.cpython-311.pyc b/csst_mci_sim/support/__pycache__/MCIinstrumentModel.cpython-311.pyc deleted file mode 100644 index 032f1df938acf5327069ccacacdeb3d0449a8d30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1792 zcma)6-D@0G6u+~x`RJsZ=D`}JR1b(H3)!!vraG9ExG5!}DW#hTEyysLdv|us?96!Y zoozQ(2_mTAgAYP|@Sz~oN?&{t1QGlPgggkw@xg~Y}Iom1xJJ z8ivW)8?nckFyU(4yw)BR1Q^Keh~uRe;{shXp!5+`E|G^Y;pslE zhq$`*7P&+24SYS66NHgws7|wV2!F$LgpSe^)SzSZB+Y%AyN_=k_TOo!1>qjIpF*Ps zAYJbPWdrq6{A}I^MAYHlh8MW7T3v=}b*Ts`=ArM0x0HAgOAle}=7GYLM@?wie$1eN zz}Fdq>9D+M8mTp9vA+QtZXhIhvAVQco`tDeBjgg81lupdOu16dAKk6ra!h!sjHK>Y zmq0|!flKSvD}_t7wZipUVXjav&%hMsxT`O(j18LOG!)E)S*4^)MWu`~?zONyrtFQd z#jt!BT)VQ0&Zmi0wK(90Nd35w>PTPzr|Z)o7{f?Jn5sO+<-hwWqzNyuLV4~uWV(+A z!xJsngbFKE{wJbnrCdaiXU-pI=O_b`+mUKI6CB#KSnT*7EmG{Ye*St$POHRwQnj26 zRjy{r=drn@J%FR~bq;;49KAj+`z_hP*eY``s=OVKyMd&@!Om18z{FDR&y=Q`DG=G* zZZe5I*}Ev)5k{rzKNak&-f|UV-~X|=HF*@SrJnje^Htnirw2X=EF!F06uYx2?OpUf zvb3%mxLjX!A2s&g|LXUTFS^m#nf+(q-kI-7eppCN!R2#{?l<55_|q?UexA?g5*?c( z8A?kwnK(4N)=NP$-nG|14{tDOTO#THM~RMQn&^mHqRAxFa+8dZNmdnaqGO%pGf7s3 zn+(Shy3F!gqKB~*YEHo88>L3rWTmzpl(73t!fVDjKto&ecDKJkjyA&NgD`cPH-HRUM5ea9dt zPi?OppmK5*gC4Og8akGh+Wms?CsEFo{l}v(V{ODfTi{RQQQ;t_kacuT(>j?kE!!cA Ooja?Y>X3i3RMVedruGs5 diff --git a/csst_mci_sim/support/__pycache__/__init__.cpython-311.pyc b/csst_mci_sim/support/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 15e38979bd24b4bb93b9ac94441d99eae69c11fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmZ3^%ge<81fI!@(?IlN5CH>>P{wCAAY(d13PUi1CZpd?AD^CCqMuw`ToRv~oEZ<4MCBBh78K+cmFUOEXXa&= q#K-FuRQ}?y$<0qG%}KQ@Vg;HHazQaakodsN$jJDC0Y(%t1H}Ltxi3-x diff --git a/csst_mci_sim/support/__pycache__/cosmicrays.cpython-311.pyc b/csst_mci_sim/support/__pycache__/cosmicrays.cpython-311.pyc deleted file mode 100644 index dc5c6fe77de6f9462dd81a29a6c07d7d8efd9e58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12483 zcmeG?ZEV|Ck|gzES(ap5@@H%(bm}Blkl6WZK7_`xW7kOvG}$I;Hubet8IiW>NTNzo ziDgjNF3W(f)wK; z^hG8mxldLexBK!mFVPYoOGG(35@jTbjxcfh8b>E3j-_RR=HroQl7&Vcg2<$3?gkf^ zCDaIA`4}_B4Y*IIXqKB~l2MtKr#I`(h#bv|%*{AGDGD)~NiSrvW-kb8$|bO3}h32CL6JKwnBmrmH}d(4ImA7@1?;lY&TdvkYEYQUcKQ zC7BV~q$I;yU_t%UvYZGF4)Pqw%_gFP$PJ+EfFMo{N-~Vo(}5W&af%V+$=EecJbB>A z(Zfei96S~r0LpPy*li>cLW+q>0wSoy0cix7I}Xs}G7b2-WloY2W{ISj5F}0-pb^wf z`G9CgGr+3&6k?UZ4L7C<4U0`CFiW8A1}7q@lOhvA^c`@!Ln8NPk{3BCM4wN_ev~p- zT#E2e;SRwl33`X<0|STL?yr#;oez>)_qn*t0eVqH)tBS^4MyZ4dnpm+<6NX9ZTMA| zy>Aad@eaWe6C_A2Nb7`+b+fj2$O$`=RFKRD)&(Ue>tXBRU56#rtGV@6frv@We~=)x zG(4lmO6d}B0Y{xg1N11+m*YWXL@Zln$=pQ3fY=BcX2J%>nFQM44-gFv2qhSiiP2GE zDuj|Ln2E;>jBw_5ybD75WE4SO%ffGoxZT{fnf z_!NgFT@d*xKF&mG5IpF}h(MK~dB%u%E&zr*YtX+GV@LY8Oo>0OG$W{6mS{BS z4@tGD&-W zX^xb{&%tXJzo>|)b%sTbVRgZQje4%K(SuISE^*OG5s9OSZW1CARL!YVPirtyLPA1~ z(4gtxzce^4#JIr}6CZqW^xPnv{z*{of;c#U%Hb(q9*jtm9F9f!Ff>{VQZkVcMCgH4 z2h!C8un1Q;3_3y%hvx#OhH~Xjm|H>{`E6pogJ|o?*ylZKfi`%#)}2IK*PV&?CKg^@ zd=)C(tG&CHw-tL2s;=#*m>pYuVXdLL(9pBm)}0xfKa+vKHBZx5p1qGedsWZAqGw;B z{QoUXL0A+DA_`V0|Lj3Wl5D6Cf|xP#pco8QVpbB9l#BqDo{Gx2Pg<{9X{TbhK&~hg z$Hy?sJ!7UhXkn?j27*Y}RgI}Ao!VnumRSs?q|{kwVQtqj&guFZ{arQsyIH$Zr_?_O zqao)~+$d*(VJJROzx5@;SYB2osMO5?2duND84?|$cRE(IXXsU?XNNDm`^vQn^{NN zKSiVi@N0ozD@b2cWiW8nRMKTs{JGp^g8qd5R;@5by!KAIO=(joGfc!i*kh(yur_G7 z$V6plw_Df3)?LTCM7*N-S?8P=*5p?Ld0z#;N=~U7OA<;;jh=1RS)gZYjh;3$=1M#0 z2=hunyP^G44Q>8!;vZRPXrZ!|13%EP77Z1jnbxqMOqAbLQlHR&6DoHo9dO+?!Nihk zFU|CzG zUrSZLmKyz9tNOKC`Zd>_w@V2qT@~EZ0j0%KZc$n-EP{6m{5dcfxo}G!+6|)t6?%3* z3%*C}i>wBg+A^?IZD3JY5q2HdMyGoI#55lQ=P3{C(Vb`Dfr~zg7!?2_CnrU4mztIw zV-j>fw&!)98>Y7?rxIL0f8KF-Q3>k4s0;4~;Lqw_#ycfxs zM$I13sMGM4)xCKR34Y!ixRAyU=y`pALN% zD)`4$|9H_qo~Z+;hOhBw{>8SOZJ}$i>sB}?s@~oVwd(b4Qv0~czv#@03+_dC?((Ci z-i%{o&1y?qhRQs9tKP_b=Oh}N=clvcoty97Tu3dZ@`o1wTJ`NN`gUh*tG?#!>D$wg z3AAKvnbBJ=sCjqh_RI%?Tf)4Mv8@4qJ7EcjK0NmRvAZXhPUOYAL#lso(Z5&q?bQK* z=jD-aJA%=^7}^xdUkDD{_vEF!uP?p6PK=WE$G^eptrs&RnYq=b=FG@ilRq=EY9zp% zra<=K{EeI~H?ris{Z{6!$J?LDkFJo*<13>N$ou2!_QS>Pht~;b^Rqa~j<0T`^M~@x z^0RjbR!*bBlBNOOM+73+?@@9i6$C?mBZMWIlAg@5=k{ zdX_vnPr2BpcJvoJ`U@SXr`{nyvfR4jU%B?6`9Al_HnsP#+Hs`Vaiq|3Kzc$^}`2y!1)y^6Z1&2O|&rK6>lZo$BuA)Si>Y zo|9_lNwsyT*gAxlxwQdnftDOq2<(CXM>x%0UYgKzdM%_YBM`<3$T?BAVJWKCuHyCCZkCJ@?$$_aj!i<<0xWGfn=E0bYEvl^!;ALC`PztIZ?ibwx==#zTf&W3=U*DByK5+&$(3_#oz1E9b)2%-wn35b4z^(AFXI15DONHPnx zRiKSw*90NzHqp9l-=j&5F?X*RdpSiLmxgns`BprtFYm9ZV)vt#LO zo?V`K(D!g}Vb@8ud#Knwl(83Go!_~UnRq1Ex3o_U>|SY61N#dHhSk8Z+Bi~d9Ld;G z0E27I*H-8ZKJo=sU+}jc-~73E&)+_;db*3A?t-WLFeu+o14%zWr7uFhEGU>-{ zhaMbxc}} z_pWd&SJjuA6 zB0Z`GMl)j@m-xqwecal<_%hfAuYCCW`>+3U^w-ow*QYJN@;&sa`%V@2ol<*-i#@|? z>u_cqY<6#R!P8Up^yFK<>J2^W4Sjm#vtyqh{p{42V}*-X3Rhn(UJV!Cm@HnMD)55Z zn<(}sR8K-50&8yXEVk{=%f&s%)wUDGwiB5%tLs%J;hv!meIvHmbZqGX-Ueh%<$>;K;Lev#WT7 zWj82csT4D+E9lY*Qr^-(96Jz*tRHIM!?9D=b`YqmdzG;lnZ60ZttPga&St}_T;)`z z#8*Ia#0f}(Hjzbn_)J5HFQE!MR^Q@PRAF?Jka>yb*OhD|M5(@D}qU&nGbrp7Sy*J~AfG)P!wnugC zLHV`D!2Ddn)rmJvkUD=JFg}ZLI|s=)RE!5*D6}lj#JF%+bBDt*flWqH-V+YLnPj4+ zmb!456(ZrV*n&o*GfZFkB;-CJFnGK;5p71CpwE(09Fn(MlQ}Zr*tSm8NOV*X7D1 S3FvN~euL}(yGAQU=6?aRIbr1h diff --git a/csst_mci_sim/support/__pycache__/logger.cpython-311.pyc b/csst_mci_sim/support/__pycache__/logger.cpython-311.pyc deleted file mode 100644 index 31911dd0b915a22738102d66e693c21821522f7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1483 zcmZ`(&1)M+6rWv<tXcN1JI)SF4;EUMqj-(Z7h4)$t9=0S?wxPOh?k2_ujnk`Hg-r7EJ_e z&-tzSLl&XGm5?qyVb06I{DNF`fLzVheeFPtcOCYui@((lGOqpzRdPpPn_sjkr=-~r z9N~olCypJEuPEtr>XK&2h#$6EUeF?508-ahMpe_SR>_w(3*ew$k4-2e9w$L4NVo3` zug5}%a;_Y?-K5}AKctLt1MNBR zFXr-7eV`vNMoC?em~#kqRP1;yduz*9IJG*40bg7LwCw#fvs7a)^>E*;5f3uQE9vRt zKETTnH3Z!lixw&W9GDlWfY{Z6-g#YZetxjPEPKR}V*o9f#Oxq*u?B#Me)OwJU_GLO zlYWob$!)`pDs{bQGrJo@pwaYv8rWT0CyJ7=Nkkiv1zI9PfWaZ`pnxl{zUd1Xxac{< zMv{k7(PsdjnG(>*g&jCF4s>+?#!Z_8e!H~7$@}ES&2H%S{ZvrcegG9EXFffozRH%` z0#5A~NR@(IQQ-l!GT)-&vlyGw;J_*$nZ0-aS$o?RW| z?Fes=@b)x^@|RAG&55x&Hm*g+wJFlFI3MT%HRyEL@a=M=p=O25ZYnnlpe@oO?T@a1X7`uIAP{u`qd|)x2#Nwqoh=rN z7U(&5$RUT8V+TcxqL<{E`+m(m=R4O>z}Ip>;mlX#_mNN~PEPkMwV!2?gP z&@A}i>4Rq-JnL-KX-cSngA)Aj+9>Kh_!(ico|H5|NuZ|0F9hG9CL4rCpaFp%r^0(a z$3|meT6e{hiYTRf1&A}#aYcqF%gfPt93z<|A^}FRUn9LhjJZZyTbG+-1Xgee zPSvI|E#+nunHi)6mo;B-XI(I7oHx8?d(x9?HlHH+)lxC!(l`pAfQnUv zMsd(CZb+QwGYLiJloZ$3)pNYd811sCWTa%(fMh632iN&TM&yQ%ymItAVKQtCwi3e5 zso2rM_J8@O7g|rnH-WX{YkMgw7X0zOU%xZVz8sThZvCrzioO^7`#)>#esJ)&r(*wh z|H4$mtG_z+IUdZ|-;Mfg9Y6WwQ=j8uiSJy2EYkFE{_~fyJL%u|eEjpBQ(;E8CDS^a z6{VD{+hOUtH<60PqkJO5CxtMpGq^#z?ecZqi?K*DGdCqlx?d6nK}^Pzu?SheZjTE$ zWju(usod|*cF&~d#O`@M*?nPfv|EnPWfHuSlDfMv9f`%2?x-v)k-2C*0)^IuoJprs zlF}`ULRWfT_m$sf@RR=$NS@khrW%`;h1H2$*RlV}c5SB=N zh6ID|g4aThbrd(c98l;I$@6W9yal`{(AS7$lJ-^eqe`jFhOI_6uqrLs1x6*3N@WSh zA^)Sya;OgAGM4`<5Gv$YUM|0Kj!$y&WICg8a$1Zk63;0!QYsUh;dm|v^`) z&F<18B8YNSiW6}Xu}>0mE)JM0%4NS0~nOTMZprLr1ZpV}accHm^QYcxK)HPIz6^4m_{5_G!W6 z3(jqCFh3?WLl?U9^uXvqWGWrS(_IdD>d8s}4>*!)#hsP7efFXFwJOLm)$Hzcj z%LwAv5k4mWlWtADV5Brise7~56oBNTVqzqoK#nAZNq(+IIe4~ov_VRcejcYG7-|8m ztg;YfzwAB)P$GVZc!lpCA0CPfrUVhuQoxKX(*;kRiKY_0gdUTKK45Gpb1&?ckdbso z5_v&FevZy(AyLC5=kMok(y~lR`wi2|ei^jK-64To8430=HMjVM`JPABI%%Vo^j%MPS)d zAJq6g_{m=Y$y2}KC|_Xd#Imr}c2a9T`JtjU58j*Bn$K(A3q|jR{Lr@7zwB5#nIASI z0K>k}^6=_$&AY$o-Jc(N;14X_SXLHuOS$}+?LgDp_SNCro;A;2#}>&*M|=JC7PjqLp+FKK}j`Lo+? z`&Ro3OkuLf^=NIq#kO8(IBDnsb^fI@%M+_-Zbb@$=Ibc>I^Lh!nAyB}F9aG#5tI(! zNPhSeum8;hD@Rt3-|AlJhRJR*`-v#DV7&vjfk;5#BN7lem_|K(gMJry`#r+nP@BrJ zf=#ejupMySrc_xjvt}H5tAM>f5-j!2o-Mg}q)0%1wv^zUNe~!fInuDM80KzDTR^d4Pn8G(F%y$IpeY#w&2BUXpgoD<-l7!Y6C~zA8i6+& zPwDj}ZZ1Z~$(6UUEJEC7v2+@WUxT0ghd@Apv{DUiz^9>tve~!g@7MhOMSnlY0e=8& zh*xi=H2+~pH8j4-uf%TEeeBzAPt&YR?liphu1?|)6x9cC*GDVro~`qn1>n4toM+EthXqU z_(~>0ftj=mHtB|&6+g~h04mBIU6Wiwu;IyYxYvDTERG`xPbaqN>-&l z)G>tz)M0n+(^1KV`ld*EY<;JtzA0h^R32PoSz?5K1%}4RW=0g)-!Ak5eGdCZ8OImT zzl5hwcK|XD#6;abBAyAmjMI#()tOWp3~2_@xa!Ee_?Q@pNpV4UO^Y)mcGs>mvY41A zZFT32kV(X4MaHd!Gi~6ZD*~t)S0a&Yp#1i`%2_{vigFwXsN5c^anAy?a9co)0SUJ0Lu`p5$bzns^ha~pyE6{76HUGM+xVIN_>bA`s zwz#(oa~9x3&M?s@EC!*_!c8~kAAF##>s2KCA;fNjh&!M0(yqFD7o zddfbSUHUK&+Eezy?$U>O_@1&4$1Z)C2l6TVaPHEFiH(8_4z)Ww54aaaFAHLv2{ML` zi4xL^Z-VrR(5l6nPnhaN?NbgP_43+rE_@d9pgjei4MyNz+oX{-Luw5F*z5y7Fd6O=z+`=lU3w$hFZ?XzW{{))J zcYpw&_^5`^(){W`!FBt*<_|A04?_DuZximsH$xw^+;eS(MzzprF*J&7@xNWR;9hVO z76V^2;j+699RvUx5s`@QiA3g7AR{pDi$uPk;S;42XCxw|qLGLMUOq~i0&I7>am^GvKYV&zqyPV)nGztoObCcirksMfDd@n# z=h|>TB1{p*NO;OVJiGLPAV>m1Rqt4~=LwdnY`n_~tP;Ud3#-h8I6W<0fS#rONQgW! z{6SJ0>`P(dCBlBc%)jZ5<&_Hi={%ANVmgCB%<+vvxXnHxPOq0EzJkf6_! zsB02x&4jE#L>>aNyQr;W&x35OqMV)N>`sjVuy2b))O@}F4khqjBNSE54`>ly*# z=8+(!7WZaF=~B!WLRHHWR%Ni2Rr|N5z@=cXk~memdd_L-)l{9pSz(_wl_1smE~tL* znd)E8WtB=QTv7^;9K({~Z|5ag-UaZ0B@(Fll!Ocd26*7WDaOIY;8ePklhU*RFe7ogH)i6| z8EyvmfOt(nu><-L6)DfSiFyNnwb<@}wU^ z^IyPEmVuCKiTZ}+1B+MlBinU>rODNUYtLzQ2lFF%KNx=Vm6egz7YZY{PidhJu#q%R zXVKFMw{^aTrP1Z+(pY}@fv+B-0$NvvjOII9^c}@aynh@n99xfX`T8|qf6>=ZJdycx zhCr_3D++NJ&-ueUK;a(}v|t1C2x_2fEXS(wskWbq!;7_C<5h8UEf-pN&EzK4QB%*U znCK5iSWW2=^}Sobe^qm?;%xhDg@avH7Irl+Tk}oHqgwM#1KC=}#HS_d>lrt}PRBvU+az4Cx zt)wAUWjwghK&DrU3J z-=xDWp?0!=HtIjJ8BN(bV5ix0!~HnAS!zk(xQeZln! zUT(Kz#qT0P>ml4IAs0%oBSDUrkY&LV;FI9KW69o1=p~lEhXh@t(jNfP?Q&*L%3xAK zf(8b;Hz)Vq29{mNJOXIVBm@2=hA&a4v(h{kbpU~WM7Sw~f0hBnF#=j4^sMe672(bd z3VR6BNh+x<#d`n}QO5ExoowvFuSo7U&0o#+ALReQPfjF0Gwh4{fw;_HMLqDj&?> z3w)r$HJPj193E3w5Ng32BYtsH(k zxYk^-7ld~_T1!W6YyE|Z^-G(9yI04^BpVtj^&3xt!NnQf%Qvwo3!@s%_hzFV$t_v zMb$XI9=OxLKJnp^E#IK#8!Y+;s}&A7|EOAnyKE0U$R9zB44Rl&;UFBv%v^fj(A5I) z=f?DWm!Y4fP{|~B!n%hCwGnQFyW%Mc<+gEY>@4L2RK%lh4>+P19UZK{3C z`rW3!xn=!=i=2M8rl%byM7QlwR?-=u8+RxxIlPZPutQnND|8dxxUpxF?Y=_#N oenIlTtS&vdmqtr)clrg%|FXLDL=)YBW0pwQa~OM+5Y_X)06YfKwg7M?K!9x#4jjEymmF(H6?`9WzynkFQnZ5}-GplL%&S;u3D8)LiUAqno# zkX3#-QKXV8t2HYkd9!VoD$RPa-#rhbHQdcoXmMO8^Jf31sNqKBX zd8M7@+wHu4hKA9}HFY!?H1Drg<{$`Jv0V>|fcR_2TxFXul$$UTn=nKP+p$P&o+jvp zSda+CiAa?`ndl!0 zMrP@YM05s>p>8N7Q-dGQ`@;ksCE~Q7igyr^`MC>0%IU%c44NQRPJrth6cwd}vT!gW zRG*%Y(4jf$ma9yt5>-w^l>!@_*dYv zgk-h4ylI=;oE%SMIf?K3wTo?Z_CNtkIdZwy?yB zCzG7@UEcaGYkK!zS#4Ev-}P%ZuBDtAt%KD%vW5oMagsg#9%q>14O1*WwN-}TjR5%` z*oy?9`EqLn9q7vUzcXxm*tE(dElzIor#)y|^@FBJUzAbdD5AhMFTl%QfMYMf%U^(3 z?11OD9t2_V67ku2gHS%;7|@{Fh>By(RKBGCa-gA<{;HSMU%^zB)USI<{aQv>Qh)VJ z>c^StlKS;8slSrZtMxNDS(N}==pxQk=6aP(RjyaX=yE+BQ=RKoGx}UlugDE!3ENb0 z&%YGlbDnEtHDlann=xI)keLYb1?WD=4;PJ$k<{DsW72R*e34Q>BWc`zKd#Jq(~k3E zd38k{(xCKlv4++aV5UZik~KT}Y2H2`tuNL>))s75YFsp{nCNqvwJN6Nxl9XVChIPV zFL9~@^sSe~9Yqx-8)M$KI<+L4m#Zb~ca*a;wcF$@MRFFhVMjR!V^PZ~vdyH7Ofg0_ zDzP0`p@}i6^)sfQlx-%)L>5JpY|dw!iEJrES-!7|BeCPWJ7-(7(vSZt+nn3yQ)R~U zv#n0We15iBX`>>8i{hj5!N$~)wfU^6BU^V|{asAmw$-r~$yv#^9p!d2)@^dOA~_q` zen~V`wJIHqO)W>(l1La|tY_-el?C4lJ=Gp$r|SwBV^?|&P7&4unyxPN3q1xQI}>22 zlw53};r}eT#x#5Y&O}n1&PSXkrFS1Kv!>)q8j6>-! zT?+eO*-|t|v0cx%wn_^AOvS)OM+}rlHYAk^@(XN6VIO~C(_(A@BH;gQ!Q-5A; zrkzC`lxZ&PIZFOwi-M^s!6X#SvJyn)S*CYRcNOIwWv^+01KMEUb?%$V|FWN zQ()~%tXPYJ*QewuFt-x>!Uk3ue5AJMVLV_r7gwD!(!KJ1uxGL)$Dd3*!Cp8j6XK%&@? z0a*f6AwrQ^=O#SM{D}5$!h%ntxya-JVkSz>fkI3WmQRRIuggijkmLg-c$%jwz$Fw0 z{Lm{Ph>0GB;)S4}A}D`kHkea>-aF{=5FZmhug5dx+=Or3M5jVzE*b$fAf*ft@cIC~ z1=8CUbke`Do!sx8awc>>&pz(}`0ev5BlD^%GC!jGHpN<1aZp~}9u!5;)HsO8Cd}(Z zN0E825*MTMssM=I_XB5MgKU?AJr|11(?O*_kUuau<&;(&85>f`#DjrogxoIks>kI_ zw7?3MSos?E(|-3v$R9ZpbcaJ1#ClacDk)t$Je1Q8EHWMOhXb$zmRmBX%TB?A76r?= zVm(VJhba{Ue`4VfO~L=Pgfj3H3FTrvPtZi;Ld9&54qPFH@)$@yTEGHiI4tN!qJDBD zbb<0y3qpAS7)A?K(a1P;Aw-W~hznXO7#E9qcwkz3?gZ`0@nd5XZ=4ozKQ#-nxPXZ@ zymB!^gz^guRB(oZc_dW$W3gZa%z4=#o)5ab0v7Yr7X`gk`J?<&@y{R)$zVVl8>Mk< zP9~V-8+nSX;j$!AnTB@qP= zFajQ!r>L1wI4EE+O9TzsFBqcpG^of<%P}(M#&U=#c<7bgp#1r{g8_MN7+=}G*c_0{ zvoFhj#c}}^G_ig`bGctO4!SlSkk?Uk4h(aV0`7r9&MD|180F$7xmXxWPJ(gS@SzEz zGVc<|LCHI4m4=GPy}%hz8UD{2Wr86v7t;A;G#;Wu(FpZ30Kh^*{EuL-Tta@p5xhD% z!fEZi)_!jy?Ob_h^_`5ijn%g0D!}_W!w_#6V)3D8n0fj2bPtEQdCbjX?kpG|Nblz` z5080R%mc><(<2<_i-Iaci!+bpEV=*5js1&fZ?Q7K>Ho#*8EH>~ARHWa! zzIbEt9+o<@Qn^~0(K=bJQ?%rj_1Sza8dk1fmN&3|g)0&Naasqjb=;#t#9O?4i#Mb7vRZG>=8rkUo4nyo7Ju_wd&g6IZ^qus+1v9>?-O&@1H#amCYrc+saW9m%0X7%ifW7Uy7 zo^5DK1=7ydnU(IDcmE`lI#3_pha|iIn3{PUOE)*swIEKKyiKc_e*qU2}gb zJtZ=ZK5=o@3En!vnkJNS8|7Mje2Xum^|4yt|7F}9&8c|WyLx%$wbj>>BUuNLu1%l% z%)0XW>g&l77&r9O(dE(f2kWi(Bk73f?y)EPIO|#7dX_bv-LMd8=cnV#<7?IH7c!lD z+0MNp=fsouIO`;Don%du#hi&u=OEiD#lDyW(zM*LbPWD%=#8J8yLIm7`P=80j%KmS zWastq8{s`mkwu% z&WD|kj(&adulV0iPiBeTpU*!GK6?A>H~zF2LLKX^Uv_`h{piYL>h~Z0;Ug8^@et<- zFHd+M?fH5y*FVhn4{uds#9OE|OXCk!h_&I)*}G?##5a+L%i5GJ-NEU* zczst=Bi+JNo#~^TzL(ecCN)`GV``GKb@H~(WOcT_DRqgf@8avblKQOGkvhg%+j(m{ zm{CEqH>ViR-ox8_l7?(UE7+17JbZ%(3=Gy~`ex*IBv}SsJ9B6B?x^Hb;Lg#GVgqG`ZGZf86~I!@eD0gYk_f;`7~WnqRvVPOi<`qeJnms}59oZWv!@QS zx-J&$qF^Bfd>JfM1jNIbcpemAa9<)KCcXuK#P`od$@y^b02KgySSX1f0++2a6h$`> c3oHL_VL19e_;$1CYPpJ{-CM}cS8= 1200, wave <= 6300) - reddening_curve[idx] = 2.659 * ( -2.156 + 1.509 * wave_number[idx] - 0.198 * \ - (wave_number[idx] ** 2)) + 0.011 * (wave_number[idx] **3 ) + Rv - + reddening_curve[idx] = 2.659 * (-2.156 + 1.509 * wave_number[idx] - 0.198 * + (wave_number[idx] ** 2)) + 0.011 * (wave_number[idx] ** 3) + Rv + idx = np.logical_and(wave >= 6300, wave <= 22000) - reddening_curve[idx] = 2.659 * ( -1.857 + 1.040 * wave_number[idx]) + Rv + reddening_curve[idx] = 2.659 * (-1.857 + 1.040 * wave_number[idx]) + Rv return reddening_curve -def reddening(wave, flux, ebv = 0.0, law = 'calzetti', Rv = 4.05): + +def reddening(wave, flux, ebv=0.0, law='calzetti', Rv=4.05): """ Reddening an input spectra through a given reddening curve. @@ -52,10 +54,11 @@ def reddening(wave, flux, ebv = 0.0, law = 'calzetti', Rv = 4.05): float: Flux of spectra after reddening. """ if law == 'calzetti': - curve = Calzetti_Law(wave, Rv = Rv) + curve = Calzetti_Law(wave, Rv=Rv) fluxNew = flux / (10. ** (0.4 * ebv * curve)) return fluxNew + def flux_to_mag(wave, flux, path, band='GAIA_bp'): """Convert flux of given spectra to magnitude @@ -68,14 +71,14 @@ def flux_to_mag(wave, flux, path, band='GAIA_bp'): float: value of magnitude """ # /home/yan/MCI_sim/MCI_input/SED_Code/data - ##import os - - ###parent = os.path.dirname(os.path.realpath(__file__)) - + # + + # parent = os.path.dirname(os.path.realpath(__file__)) + band = ascii.read(path+'MCI_inputData/SED_Code/seddata/' + band + '.dat') - wave0= band['col1'] - curv0= band['col2'] - + wave0 = band['col1'] + curv0 = band['col2'] + # Setting the response func = interp1d(wave0, curv0) response = np.copy(wave) @@ -86,10 +89,11 @@ def flux_to_mag(wave, flux, path, band='GAIA_bp'): # Total Flux Tflux = np.trapz(flux * response, wave) / np.trapz(response, wave) - + return -2.5 * np.log10(Tflux) -def calibrate(wave, flux, mag, path,band='GAIA_bp'): + +def calibrate(wave, flux, mag, path, band='GAIA_bp'): """ Calibrate the spectra according to the magnitude. @@ -102,78 +106,83 @@ def calibrate(wave, flux, mag, path,band='GAIA_bp'): Returns: float: Flux of calibrated spectra. Units: 1e-17 erg/s/A/cm^2 """ - inst_mag = flux_to_mag(wave, flux, path,band = band) + inst_mag = flux_to_mag(wave, flux, path, band=band) instflux = 10 ** (-0.4 * inst_mag) realflux = (mag * u.STmag).to(u.erg/u.s/u.cm**2/u.AA).value # Normalization flux_ratio = realflux / instflux - flux_calibrate = flux * flux_ratio * 1e17 # Units: 10^-17 erg/s/A/cm^2 - + # Units: 10^-17 erg/s/A/cm^2 + flux_calibrate = flux * flux_ratio * 1e17 + return flux_calibrate # ------------ # SED Template + class Gal_Temp(): """ Template of Galaxy SED """ - - def __init__(self,path): - - ###import os - - ###parent = os.path.dirname(os.path.realpath(__file__)) - self.path=path - hdulist = fits.open(self.path+'MCI_inputData/SED_Code/seddata/galaxy_temp.fits') + + def __init__(self, path): + + # + + # parent = os.path.dirname(os.path.realpath(__file__)) + self.path = path + hdulist = fits.open( + self.path+'MCI_inputData/SED_Code/seddata/galaxy_temp.fits') self.wave = hdulist[1].data['wave'] self.flux = hdulist[2].data self.age_grid = hdulist[3].data['logAge'] self.feh_grid = hdulist[3].data['FeH'] - - def toMag(self, redshift = 0): + + def toMag(self, redshift=0): """Calculating magnitude Args: redshift (float, optional): redshift of spectra. Defaults to 0. """ wave = self.wave * (1 + redshift) - self.umag = flux_to_mag(wave, self.flux, self.path,band='SDSS_u') - self.gmag = flux_to_mag(wave, self.flux, self.path,band='SDSS_g') - self.rmag = flux_to_mag(wave, self.flux, self.path,band='SDSS_r') - self.imag = flux_to_mag(wave, self.flux, self.path,band='SDSS_i') - self.zmag = flux_to_mag(wave, self.flux, self.path,band='SDSS_z') - + self.umag = flux_to_mag(wave, self.flux, self.path, band='SDSS_u') + self.gmag = flux_to_mag(wave, self.flux, self.path, band='SDSS_g') + self.rmag = flux_to_mag(wave, self.flux, self.path, band='SDSS_r') + self.imag = flux_to_mag(wave, self.flux, self.path, band='SDSS_i') + self.zmag = flux_to_mag(wave, self.flux, self.path, band='SDSS_z') + + class Star_Temp(): """ Template of Stellar SED """ - - def __init__(self,path): - - ##import os - self.path=path - ####parent = os.path.dirname(os.path.realpath(__file__)) - ###print("获取其父目录——" + parent) # 从当前文件路径中获取目录 - hdulist = fits.open(path+'MCI_inputData/SED_Code/seddata/stellar_temp.fits') + + def __init__(self, path): + + # + self.path = path + # parent = os.path.dirname(os.path.realpath(__file__)) + # print("获取其父目录——" + parent) # 从当前文件路径中获取目录 + hdulist = fits.open( + path+'MCI_inputData/SED_Code/seddata/stellar_temp.fits') self.wave = hdulist[1].data['wave'] self.flux = hdulist[2].data self.Teff_grid = hdulist[3].data['Teff'] self.FeH_grid = hdulist[3].data['FeH'] - - self.bpmag = flux_to_mag(self.wave, self.flux, path,band='GAIA_bp') - self.rpmag = flux_to_mag(self.wave, self.flux, path,band='GAIA_rp') - - + + self.bpmag = flux_to_mag(self.wave, self.flux, path, band='GAIA_bp') + self.rpmag = flux_to_mag(self.wave, self.flux, path, band='GAIA_rp') + def toMag(self): wave = self.wave - self.bpmag = flux_to_mag(wave, self.flux, self.path,band='GAIA_bp') - self.rpmag = flux_to_mag(wave, self.flux, self.path,band='GAIA_rp') - + self.bpmag = flux_to_mag(wave, self.flux, self.path, band='GAIA_bp') + self.rpmag = flux_to_mag(wave, self.flux, self.path, band='GAIA_rp') + # ------------- # SED Modelling + def Model_Stellar_SED(wave, bp, rp, temp): """Modelling stellar SED based on bp, rp magnitude @@ -184,19 +193,20 @@ def Model_Stellar_SED(wave, bp, rp, temp): temp (class): Class of stellar template Returns: - float array: Spectral energy distribution of stellar SED, + float array: Spectral energy distribution of stellar SED, which have the same length to the input wave - """ + """ color0 = bp - rp colors = temp.bpmag - temp.rpmag - + idx = np.argmin(np.abs(colors - color0)) flux0 = temp.flux[idx] flux1 = np.interp(wave, temp.wave, flux0) - flux = calibrate(wave, flux1, rp, band = 'GAIA_rp') + flux = calibrate(wave, flux1, rp, band='GAIA_rp') return flux + def Model_Galaxy_SED(wave, ugriz, z, temp, path): """Modelling galaxy SED based on u,g,r,i,z magnitude @@ -213,30 +223,30 @@ def Model_Galaxy_SED(wave, ugriz, z, temp, path): sed = 10. ** (-0.4 * ugriz) sed = sed / sed[2] ntemp = len(temp.rmag) - dmag = np.zeros(ntemp) + dmag = np.zeros(ntemp) for j in range(ntemp): - ugriz0 = np.array([temp.umag[j], temp.gmag[j], temp.rmag[j], + ugriz0 = np.array([temp.umag[j], temp.gmag[j], temp.rmag[j], temp.imag[j], temp.zmag[j]]) sed0 = 10. ** (-0.4 * ugriz0) sed0 = sed0 / sed0[2] dmag[j] = np.sum(np.abs(sed - sed0)) - + idx = np.argmin(dmag) flux0 = temp.flux[idx] - + # Effect of E(B-V) ri0 = ugriz[2] - ugriz[3] - ri = temp.rmag - temp.imag + ri = temp.rmag - temp.imag dri = ri0 - ri[idx] Alambda = Calzetti_Law(np.array([6213 / (1 + z), 7625 / (1 + z)])) eri0 = (Alambda[0] - Alambda[1]) ebv = dri/eri0 - if ebv<0: - ebv=0 - if ebv>0.5: - ebv=0.5 - flux1 = reddening(temp.wave, flux0, ebv = ebv) - + if ebv < 0: + ebv = 0 + if ebv > 0.5: + ebv = 0.5 + flux1 = reddening(temp.wave, flux0, ebv=ebv) + flux2 = np.interp(wave, temp.wave * (1 + z), flux1) - flux = calibrate(wave, flux2, ugriz[2], path, band = 'SDSS_r') - return flux \ No newline at end of file + flux = calibrate(wave, flux2, ugriz[2], path, band='SDSS_r') + return flux diff --git a/csst_mci_sim/support/shao.py b/csst_mci_sim/support/shao.py index d2f2299..320def7 100644 --- a/csst_mci_sim/support/shao.py +++ b/csst_mci_sim/support/shao.py @@ -1,105 +1,117 @@ from ctypes import * def checkInputList(input_list, n): - if type(input_list) != type([1, 2, 3]): + if not isinstance(type(input_list), list): + # if type(input_list) != type([1, 2, 3]): raise TypeError("Input type is not list!", input_list) for i in input_list: - if type(i) != type(1.1): - if type(i) != type(1): - raise TypeError("Input list's element is not float or int!", input_list) + if not isinstance(type(i), float): # type(i) != type(1.1): + if not isinstance(type(i), int): # type(i) != type(1): + raise TypeError( + "Input list's element is not float or int!", input_list) if len(input_list) != n: - raise RuntimeError("Length of input list is not equal to stars' number!", input_list) - -def onOrbitObsPosition(path, input_ra_list, input_dec_list, input_pmra_list, input_pmdec_list, input_rv_list, \ - input_parallax_list, input_nstars, input_x, input_y, input_z, input_vx, input_vy, \ + raise RuntimeError( + "Length of input list is not equal to stars' number!", input_list) + + +def onOrbitObsPosition(path, input_ra_list, input_dec_list, input_pmra_list, input_pmdec_list, input_rv_list, + input_parallax_list, input_nstars, input_x, input_y, input_z, input_vx, input_vy, input_vz, input_epoch, input_date_str, input_time_str): - #Check input parameters - if type(input_nstars) != type(1): + # Check input parameters + if not isinstance(type(input_nstars), int): # type(input_nstars) != type(1): raise TypeError("Parameter 7 is not int!", input_nstars) - + checkInputList(input_ra_list, input_nstars) checkInputList(input_dec_list, input_nstars) checkInputList(input_pmra_list, input_nstars) checkInputList(input_pmdec_list, input_nstars) checkInputList(input_rv_list, input_nstars) checkInputList(input_parallax_list, input_nstars) - - if type(input_x) != type(1.1): + + if not isinstance(type(input_x), float): # type(input_x) != type(1.1): raise TypeError("Parameter 8 is not double!", input_x) - if type(input_y) != type(1.1): + if not isinstance(type(input_y), float): # type(input_y) != type(1.1): raise TypeError("Parameter 9 is not double!", input_y) - if type(input_z) != type(1.1): + if not isinstance(type(input_z), float): # type(input_z) != type(1.1): raise TypeError("Parameter 10 is not double!", input_z) - if type(input_vx) != type(1.1): + if not isinstance(type(input_vx), float): # type(input_vx) != type(1.1): raise TypeError("Parameter 11 is not double!", input_vx) - if type(input_vy) != type(1.1): + if not isinstance(type(input_vy), float): # type(input_vy) != type(1.1): raise TypeError("Parameter 12 is not double!", input_vy) - if type(input_vz) != type(1.1): + if not isinstance(type(input_vz), float): # type(input_vz) != type(1.1): raise TypeError("Parameter 13 is not double!", input_vz) - - #Convert km -> m - input_x = input_x*1000.0 - input_y = input_y*1000.0 + + # Convert km -> m + input_x = input_x*1000.0 + input_y = input_y*1000.0 input_z = input_z*1000.0 input_vx = input_vx*1000.0 input_vy = input_vy*1000.0 - input_vz = input_vz*1000.0 - - if type(input_date_str) != type("2025-03-05"): + input_vz = input_vz*1000.0 + + if not isinstance(type(input_date_str), str): # type(input_date_str) != type("2025-03-05"): raise TypeError("Parameter 15 is not string!", input_date_str) else: input_date_str = input_date_str.strip() - if not (input_date_str[4]=="-" and input_date_str[7]=="-"): + if not (input_date_str[4] == "-" and input_date_str[7] == "-"): raise TypeError("Parameter 15 format error (1)!", input_date_str) else: tmp = input_date_str.split("-") if len(tmp) != 3: - raise TypeError("Parameter 15 format error (2)!", input_date_str) + raise TypeError( + "Parameter 15 format error (2)!", input_date_str) input_year = int(tmp[0]) input_month = int(tmp[1]) input_day = int(tmp[2]) - if not (input_year>=1900 and input_year<=2100): - raise TypeError("Parameter 15 year range error [1900 ~ 2100]!", input_year) - if not (input_month>=1 and input_month<=12): - raise TypeError("Parameter 15 month range error [1 ~ 12]!", input_month) - if not (input_day>=1 and input_day<=31): - raise TypeError("Parameter 15 day range error [1 ~ 31]!", input_day) - - if type(input_time_str) != type("20:15:15.15"): + if not (input_year >= 1900 and input_year <= 2100): + raise TypeError( + "Parameter 15 year range error [1900 ~ 2100]!", input_year) + if not (input_month >= 1 and input_month <= 12): + raise TypeError( + "Parameter 15 month range error [1 ~ 12]!", input_month) + if not (input_day >= 1 and input_day <= 31): + raise TypeError( + "Parameter 15 day range error [1 ~ 31]!", input_day) + + if not isinstance(type(input_time_str), str): # type(input_time_str) != type("20:15:15.15"): raise TypeError("Parameter 16 is not string!", input_time_str) else: input_time_str = input_time_str.strip() - if not (input_time_str[2]==":" and input_time_str[5]==":"): + if not (input_time_str[2] == ":" and input_time_str[5] == ":"): raise TypeError("Parameter 16 format error (1)!", input_time_str) else: tmp = input_time_str.split(":") if len(tmp) != 3: - raise TypeError("Parameter 16 format error (2)!", input_time_str) + raise TypeError( + "Parameter 16 format error (2)!", input_time_str) input_hour = int(tmp[0]) input_minute = int(tmp[1]) input_second = float(tmp[2]) - if not (input_hour>=0 and input_hour<=23): - raise TypeError("Parameter 16 hour range error [0 ~ 23]!", input_hour) - if not (input_minute>=0 and input_minute<=59): - raise TypeError("Parameter 16 minute range error [0 ~ 59]!", input_minute) - if not (input_second>=0 and input_second<60.0): - raise TypeError("Parameter 16 second range error [0 ~ 60)!", input_second) - #Inital dynamic lib - + if not (input_hour >= 0 and input_hour <= 23): + raise TypeError( + "Parameter 16 hour range error [0 ~ 23]!", input_hour) + if not (input_minute >= 0 and input_minute <= 59): + raise TypeError( + "Parameter 16 minute range error [0 ~ 59]!", input_minute) + if not (input_second >= 0 and input_second < 60.0): + raise TypeError( + "Parameter 16 second range error [0 ~ 60)!", input_second) + # Inital dynamic lib + import os - currfile=os.getcwd() + currfile = os.getcwd() print(currfile) - + shao = cdll.LoadLibrary(path+'MCI_inputData/TianCe/libshao.so') - + shao.onOrbitObs.restype = c_int - + d3 = c_double * 3 - shao.onOrbitObs.argtypes = [c_double, c_double, c_double, c_double, c_double, c_double, \ - c_int, c_int, c_int, c_int, c_int, c_double, \ - c_double, POINTER(d3), POINTER(d3), \ - c_int, c_int, c_int, c_int, c_int, c_double, \ - POINTER(c_double), POINTER(c_double) ] + shao.onOrbitObs.argtypes = [c_double, c_double, c_double, c_double, c_double, c_double, + c_int, c_int, c_int, c_int, c_int, c_double, + c_double, POINTER(d3), POINTER(d3), + c_int, c_int, c_int, c_int, c_int, c_double, + POINTER(c_double), POINTER(c_double)] output_ra_list = list() output_dec_list = list() for i in range(input_nstars): @@ -113,22 +125,21 @@ def onOrbitObsPosition(path, input_ra_list, input_dec_list, input_pmra_list, inp v3 = d3(input_vx, input_vy, input_vz) input_year_c = c_int(input_year) input_month_c = c_int(input_month) - input_day_c = c_int(input_day) + input_day_c = c_int(input_day) input_hour_c = c_int(input_hour) input_minute_c = c_int(input_minute) - input_second_c = c_double(input_second) + input_second_c = c_double(input_second) DAT = c_double(37.0) output_ra = c_double(0.0) output_dec = c_double(0.0) - rs = shao.onOrbitObs(input_ra, input_dec, input_parallax, input_pmra, input_pmdec, input_rv, \ - input_year_c, input_month_c, input_day_c, input_hour_c, input_minute_c, input_second_c, \ - DAT, byref(p3), byref(v3), \ - input_year_c, input_month_c, input_day_c, input_hour_c, input_minute_c, input_second_c, \ + rs = shao.onOrbitObs(input_ra, input_dec, input_parallax, input_pmra, input_pmdec, input_rv, + input_year_c, input_month_c, input_day_c, input_hour_c, input_minute_c, input_second_c, + DAT, byref(p3), byref(v3), + input_year_c, input_month_c, input_day_c, input_hour_c, input_minute_c, input_second_c, byref(output_ra), byref(output_dec)) if rs != 0: raise RuntimeError("Calculate error!") output_ra_list.append(output_ra.value) output_dec_list.append(output_dec.value) - + return output_ra_list, output_dec_list - \ No newline at end of file diff --git a/csst_mci_sim/zodiacal.py b/csst_mci_sim/zodiacal.py index 350340c..b508cc2 100644 --- a/csst_mci_sim/zodiacal.py +++ b/csst_mci_sim/zodiacal.py @@ -9,6 +9,7 @@ from astropy import units as u from scipy import interpolate + def zodiacal(ra, dec, time, path): """ For given RA, DEC and TIME, return the interpolated zodical spectrum in Leinert-1998. @@ -19,7 +20,7 @@ def zodiacal(ra, dec, time, path): :param path: the relative file path :return: wave_A: wavelength of the zodical spectrum - + spec_erg: flux of the zodical spectrum, in unit of erg/s/cm^2/A/sr """ @@ -27,14 +28,15 @@ def zodiacal(ra, dec, time, path): # get solar position dt = datetime.fromisoformat(time) jd = julian.to_jd(dt, fmt='jd') - + ###jd = time2jd(dt) t = Time(jd, format='jd', scale='utc') astro_sun = get_sun(t) ra_sun, dec_sun = astro_sun.gcrs.ra.deg, astro_sun.gcrs.dec.deg - radec_sun = SkyCoord(ra=ra_sun*u.degree, dec=dec_sun*u.degree, frame='gcrs') + radec_sun = SkyCoord(ra=ra_sun*u.degree, + dec=dec_sun*u.degree, frame='gcrs') lb_sun = radec_sun.transform_to('geocentrictrueecliptic') # get offsets between the target and sun. @@ -45,16 +47,18 @@ def zodiacal(ra, dec, time, path): lamda = abs(lb_obj.lon.degree - lb_sun.lon.degree) # interpolated zodical surface brightness at 0.5 um - zodi = pd.read_csv(path+'MCI_inputData/refs/zodi_map.dat', sep='\s+', header=None, comment='#') + zodi = pd.read_csv(path+'MCI_inputData/refs/zodi_map.dat', + sep='\s+', header=None, comment='#') beta_angle = np.array([0, 5, 10, 15, 20, 25, 30, 45, 60, 75]) lamda_angle = np.array([0, 5, 10, 15, 20, 25, 30, 35, 40, 45, - 60, 75, 90, 105, 120, 135, 150, 165, 180]) + 60, 75, 90, 105, 120, 135, 150, 165, 180]) xx, yy = np.meshgrid(beta_angle, lamda_angle) f = interpolate.interp2d(xx, yy, zodi, kind='linear') zodi_obj = f(beta, lamda) # 10^�? W m�? sr�? um�? # read the zodical spectrum in the ecliptic - cat_spec = pd.read_csv(path+'MCI_inputData/refs/solar_spec.dat', sep='\s+', header=None, comment='#') + cat_spec = pd.read_csv( + path+'MCI_inputData/refs/solar_spec.dat', sep='\s+', header=None, comment='#') wave = cat_spec[0].values # A spec0 = cat_spec[1].values # 10^-8 W m^�? sr^�? μm^�? zodi_norm = 252 # 10^-8 W m^�? sr^�? μm^�? @@ -63,10 +67,11 @@ def zodiacal(ra, dec, time, path): # convert to the commonly used unit of MJy/sr, erg/s/cm^2/A/sr wave_A = wave # A - #spec_mjy = spec * 0.1 * wave_A**2 / 3e18 * 1e23 * 1e-6 # MJy/sr + # spec_mjy = spec * 0.1 * wave_A**2 / 3e18 * 1e23 * 1e-6 # MJy/sr spec_erg = spec * 0.1 # erg/s/cm^2/A/sr - spec_erg2 = spec_erg / 4.25452e10 # erg/s/cm^2/A/arcsec^2 - + # erg/s/cm^2/A/arcsec^2 + spec_erg2 = spec_erg / 4.25452e10 + return wave_A, spec_erg2 diff --git a/tests/test_mci_sim.py b/tests/test_mci_sim.py index b840ba1..a39b9d2 100644 --- a/tests/test_mci_sim.py +++ b/tests/test_mci_sim.py @@ -15,9 +15,9 @@ import sys import faulthandler from csst_mci_sim import csst_mci_sim + class TestDemoFunction(unittest.TestCase): def test_mci_sim_1(self): - """ Aim --- @@ -33,76 +33,77 @@ class TestDemoFunction(unittest.TestCase): This case aims to test whether the demo function returns `1` if input is `None`. """ faulthandler.enable() - + # demo function test - dir_path = os.path.join(os.environ['UNIT_TEST_DATA_ROOT'],'mci_sim/') + dir_path = os.path.join(os.environ['UNIT_TEST_DATA_ROOT'], 'mci_sim/') print(dir_path) - + # 获取当前工作目录 - # current_path = os.getcwd() + # current_path = os.getcwd() # print("当前路径:", current_path) - + configfile = './csst_mci_sim/mci_data/mci_all_9K.config' - + sourcein = 'EXDF' print(configfile) - - debug=True - - result_path = dir_path +'mci_sim_result/' - - csst_mci_sim.runMCIsim(sourcein, configfile, dir_path, result_path, debug, 1) - + + debug = True + + result_path = dir_path + 'mci_sim_result/' + + csst_mci_sim.runMCIsim(sourcein, configfile, + dir_path, result_path, debug, 1) + self.assertEqual( - 1 , 1, + 1, 1, "case 1: EXDF sim passes.", ) ############################################ + def test_mci_sim_2(self): - """ Aim --- Test mci sim function: STAR case. - + Criteria -------- Pass if the demo function returns `1`. - + Details ------- The demo function returns the length of the input argument list. This case aims to test whether the demo function returns `1` if input is `None`. """ faulthandler.enable() - + # demo function test - dir_path = os.path.join(os.environ['UNIT_TEST_DATA_ROOT'],'mci_sim/') + dir_path = os.path.join(os.environ['UNIT_TEST_DATA_ROOT'], 'mci_sim/') print(dir_path) - + # 获取当前工作目录 - # current_path = os.getcwd() + # current_path = os.getcwd() # print("当前路径:", current_path) - + configfile = './csst_mci_sim/mci_data/mci_all_9K.config' - + sourcein = 'STAR' print(configfile) - - debug=True - - result_path = dir_path +'mci_sim_result/' - - csst_mci_sim.runMCIsim(sourcein, configfile, dir_path, result_path, debug, 1) - + + debug = True + + result_path = dir_path + 'mci_sim_result/' + + csst_mci_sim.runMCIsim(sourcein, configfile, + dir_path, result_path, debug, 1) + self.assertEqual( - 1 , 1, + 1, 1, "case 2: STAR sim passes.", - ) - + ) + ######################################################### def test_mci_sim_3(self): - """ Aim --- @@ -118,33 +119,34 @@ class TestDemoFunction(unittest.TestCase): This case aims to test whether the demo function returns `1` if input is `None`. """ faulthandler.enable() - + # demo function test - dir_path = os.path.join(os.environ['UNIT_TEST_DATA_ROOT'],'mci_sim/') + dir_path = os.path.join(os.environ['UNIT_TEST_DATA_ROOT'], 'mci_sim/') print(dir_path) - + # 获取当前工作目录 - # current_path = os.getcwd() + # current_path = os.getcwd() # print("当前路径:", current_path) - + configfile = './csst_mci_sim/mci_data/mci_all_9K.config' - + sourcein = 'BIAS' print(configfile) - - debug=True - - result_path = dir_path +'mci_sim_result/' - - csst_mci_sim.runMCIsim(sourcein, configfile, dir_path, result_path, debug, 1) - + + debug = True + + result_path = dir_path + 'mci_sim_result/' + + csst_mci_sim.runMCIsim(sourcein, configfile, + dir_path, result_path, debug, 1) + self.assertEqual( - 1 , 1, + 1, 1, "case 3: BIAS sim passes.", ) ######################################################### + def test_mci_sim_4(self): - """ Aim --- @@ -160,34 +162,34 @@ class TestDemoFunction(unittest.TestCase): This case aims to test whether the demo function returns `1` if input is `None`. """ faulthandler.enable() - + # demo function test - dir_path = os.path.join(os.environ['UNIT_TEST_DATA_ROOT'],'mci_sim/') + dir_path = os.path.join(os.environ['UNIT_TEST_DATA_ROOT'], 'mci_sim/') print(dir_path) - + # 获取当前工作目录 - # current_path = os.getcwd() + # current_path = os.getcwd() # print("当前路径:", current_path) - + configfile = './csst_mci_sim/mci_data/mci_all_9K.config' - + sourcein = 'DARK' print(configfile) - - debug=True - - result_path = dir_path +'mci_sim_result/' - - csst_mci_sim.runMCIsim(sourcein, configfile, dir_path, result_path, debug, 1) - + + debug = True + + result_path = dir_path + 'mci_sim_result/' + + csst_mci_sim.runMCIsim(sourcein, configfile, + dir_path, result_path, debug, 1) + self.assertEqual( - 1 , 1, + 1, 1, "case 4: DARK sim passes.", - ) - + ) + ######################################################### def test_mci_sim_5(self): - """ Aim --- @@ -203,32 +205,30 @@ class TestDemoFunction(unittest.TestCase): This case aims to test whether the demo function returns `1` if input is `None`. """ faulthandler.enable() - + # demo function test - dir_path = os.path.join(os.environ['UNIT_TEST_DATA_ROOT'],'mci_sim/') + dir_path = os.path.join(os.environ['UNIT_TEST_DATA_ROOT'], 'mci_sim/') print(dir_path) - + # 获取当前工作目录 - # current_path = os.getcwd() + # current_path = os.getcwd() # print("当前路径:", current_path) - - configfile = './csst_mci_sim/mci_data/mci_all_9K.config' + + configfile = './csst_mci_sim/mci_data/mci_all_9K.config' sourcein = 'FLAT' print(configfile) - - debug=True - - result_path = dir_path +'mci_sim_result/' - - csst_mci_sim.runMCIsim(sourcein, configfile, dir_path, result_path, debug, 1) - + + debug = True + + result_path = dir_path + 'mci_sim_result/' + + csst_mci_sim.runMCIsim(sourcein, configfile, + dir_path, result_path, debug, 1) + self.assertEqual( - 1 , 1, + 1, 1, "case 5: FLAT sim passes.", ) - - -# ############################################################################ - \ No newline at end of file +# ############################################################################ diff --git a/tests/test_zodiacal.py b/tests/test_zodiacal.py index 0af5b66..2f69f73 100644 --- a/tests/test_zodiacal.py +++ b/tests/test_zodiacal.py @@ -42,7 +42,7 @@ class TestDemoFunction(unittest.TestCase): # current_path = os.getcwd() # print("当前路径:", current_path) - wave0, zodi0=zodiacal.zodiacal(10.0, 20.0, '2024-04-04', dir_path) + wave0, zodi0 = zodiacal.zodiacal(10.0, 20.0, '2024-04-04', dir_path) self.assertEqual( 1, 1, -- GitLab