Loading csst_ifs_sim/CTI/CTI.py +31 −34 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,7 @@ class CDM03bidir(): :param log: instance to Python logging :param log: instance to Python logging :type log: logging instance :type log: logging instance """ """ def __init__(self, settings, data, log=None): def __init__(self, settings, data, log=None): """ """ Class constructor. Class constructor. Loading @@ -39,7 +40,8 @@ class CDM03bidir(): :type log: logging instance :type log: logging instance """ """ self.data = data 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.values.update(settings) self.log = log self.log = log self._setupLogger() self._setupLogger() Loading @@ -55,7 +57,8 @@ class CDM03bidir(): self.params.update(self.values) self.params.update(self.values) # read in trap information # read in trap information trapdata = np.loadtxt(self.values['dir_path']+self.values['paralleltrapfile']) trapdata = np.loadtxt( self.values['dir_path']+self.values['paralleltrapfile']) if trapdata.ndim > 1: if trapdata.ndim > 1: self.nt_p = trapdata[:, 0] self.nt_p = trapdata[:, 0] self.sigma_p = trapdata[:, 1] self.sigma_p = trapdata[:, 1] Loading @@ -66,7 +69,8 @@ class CDM03bidir(): self.sigma_p = [trapdata[1],] self.sigma_p = [trapdata[1],] self.taur_p = [trapdata[2],] 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: if trapdata.ndim > 1: self.nt_s = trapdata[:, 0] self.nt_s = trapdata[:, 0] self.sigma_s = trapdata[:, 1] self.sigma_s = trapdata[:, 1] Loading @@ -85,7 +89,6 @@ class CDM03bidir(): self.nt_s *= 0.576 # thibaut's values traps / pixel #should be division? 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.sigma_s *= 1.e4 # thibaut's values in m**2 def _setupLogger(self): def _setupLogger(self): """ """ Set up the logger. Set up the logger. Loading @@ -94,7 +97,6 @@ class CDM03bidir(): # if self.log is None: # if self.log is None: # self.logger = False # self.logger = False def applyRadiationDamage(self, data, iquadrant=0): def applyRadiationDamage(self, data, iquadrant=0): """ """ Apply radian damage based on FORTRAN CDM03 model. The method assumes that Apply radian damage based on FORTRAN CDM03 model. The method assumes that Loading Loading @@ -158,7 +160,7 @@ class CDM03bidir(): self.log.info('jflip=%i' % jflip) self.log.info('jflip=%i' % jflip) ################################################################################# ################################################################################# ###modify # modify # sys.path.append('../so') # sys.path.append('../so') from ifs_so import cdm03bidir from ifs_so import cdm03bidir # from ifs_so.cdm03.cpython-38-x86_64-linux-gnu import cdm03bidir # from ifs_so.cdm03.cpython-38-x86_64-linux-gnu import cdm03bidir Loading @@ -171,14 +173,9 @@ class CDM03bidir(): params, params, [data.shape[0], data.shape[1], len(self.nt_p), len(self.nt_s), len(self.params)]) [data.shape[0], data.shape[1], len(self.nt_p), len(self.nt_s), len(self.params)]) return np.asanyarray(CTIed) return np.asanyarray(CTIed) ################################################################################################################# ################################################################################################################# ################################################################################################################# ################################################################################################################# csst_ifs_sim/csst_ifs_sim.py +292 −284 Original line number Original line Diff line number Diff line Loading @@ -5,6 +5,9 @@ Created on Thu Apr 11 15:18:57 2024 @author: yan @author: yan """ """ from scipy.interpolate import InterpolatedUnivariateSpline import logging.handlers import logging from astropy.utils.iers import conf from astropy.utils.iers import conf import galsim import galsim from scipy.integrate import simps from scipy.integrate import simps Loading @@ -28,7 +31,7 @@ import astropy.coordinates as coord import ctypes import ctypes import sys import sys ##sys.path.append('./csst_ifs_sim') # sys.path.append('./csst_ifs_sim') conf.auto_max_age = None conf.auto_max_age = None """ """ Loading Loading @@ -104,6 +107,7 @@ class CDM03bidir(): :param log: instance to Python logging :param log: instance to Python logging :type log: logging instance :type log: logging instance """ """ def __init__(self, settings, data, log=None): def __init__(self, settings, data, log=None): """ """ Class constructor. Class constructor. Loading @@ -116,7 +120,8 @@ class CDM03bidir(): :type log: logging instance :type log: logging instance """ """ self.data = data 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.values.update(settings) self.log = log self.log = log self._setupLogger() self._setupLogger() Loading @@ -132,7 +137,8 @@ class CDM03bidir(): self.params.update(self.values) self.params.update(self.values) # read in trap information # read in trap information trapdata = np.loadtxt(self.values['dir_path']+self.values['paralleltrapfile']) trapdata = np.loadtxt( self.values['dir_path']+self.values['paralleltrapfile']) if trapdata.ndim > 1: if trapdata.ndim > 1: self.nt_p = trapdata[:, 0] self.nt_p = trapdata[:, 0] self.sigma_p = trapdata[:, 1] self.sigma_p = trapdata[:, 1] Loading @@ -143,7 +149,8 @@ class CDM03bidir(): self.sigma_p = [trapdata[1],] self.sigma_p = [trapdata[1],] self.taur_p = [trapdata[2],] 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: if trapdata.ndim > 1: self.nt_s = trapdata[:, 0] self.nt_s = trapdata[:, 0] self.sigma_s = trapdata[:, 1] self.sigma_s = trapdata[:, 1] Loading @@ -162,14 +169,12 @@ class CDM03bidir(): self.nt_s *= 0.576 # thibaut's values traps / pixel #should be division? 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.sigma_s *= 1.e4 # thibaut's values in m**2 def _setupLogger(self): def _setupLogger(self): """ """ Set up the logger. Set up the logger. """ """ self.logger = True self.logger = True def applyRadiationDamage(self, data, iquadrant=0): def applyRadiationDamage(self, data, iquadrant=0): """ """ Apply radian damage based on FORTRAN CDM03 model. The method assumes that Apply radian damage based on FORTRAN CDM03 model. The method assumes that Loading Loading @@ -235,7 +240,7 @@ class CDM03bidir(): ############################################ ############################################ ################################################################################# ################################################################################# ###modify # modify # sys.path.append('../so') # sys.path.append('../so') #from .ifs_so import cdm03bidir #from .ifs_so import cdm03bidir try: try: Loading @@ -253,13 +258,13 @@ class CDM03bidir(): params, params, [data.shape[0], data.shape[1], len(self.nt_p), len(self.nt_s), len(self.params)]) [data.shape[0], data.shape[1], len(self.nt_p), len(self.nt_s), len(self.params)]) return np.asanyarray(CTIed) return np.asanyarray(CTIed) ################################################################################################################# ################################################################################################################# ################################################################################################################# ################################################################################################################# """ """ These functions can be used for logging information. These functions can be used for logging information. Loading @@ -267,8 +272,6 @@ These functions can be used for logging information. :version: 0.3 :version: 0.3 """ """ import logging import logging.handlers def lg(log_filename, loggername='logger'): def lg(log_filename, loggername='logger'): Loading @@ -287,7 +290,8 @@ def lg(log_filename, loggername='logger'): handler = logging.handlers.RotatingFileHandler(log_filename) handler = logging.handlers.RotatingFileHandler(log_filename) # maxBytes=20, backupCount=5) # maxBytes=20, backupCount=5) # create formatter # create formatter formatter = logging.Formatter('%(asctime)s - %(module)s - %(funcName)s - %(levelname)s - %(message)s') formatter = logging.Formatter( '%(asctime)s - %(module)s - %(funcName)s - %(levelname)s - %(message)s') # add formatter to ch # add formatter to ch handler.setFormatter(formatter) handler.setFormatter(formatter) # add handler to logger # add handler to logger Loading Loading @@ -343,7 +347,6 @@ def CCDnonLinearityModel(data, beta=6e-7): ############################################################################# ############################################################################# from scipy.interpolate import InterpolatedUnivariateSpline class cosmicrays(): class cosmicrays(): """ """ Loading @@ -369,6 +372,7 @@ class cosmicrays(): :param information: cosmic ray track information (file containing track length and energy information) and :param information: cosmic ray track information (file containing track length and energy information) and exposure time. exposure time. """ """ def __init__(self, log, image, crInfo=None, information=None): def __init__(self, log, image, crInfo=None, information=None): """ """ Cosmic ray generation class. Can either draw events from distributions or Cosmic ray generation class. Can either draw events from distributions or Loading Loading @@ -518,8 +522,6 @@ class cosmicrays(): return crImage return crImage def _drawEventsToCoveringFactor(self, coveringFraction=3.0, limit=1000, verbose=False): def _drawEventsToCoveringFactor(self, coveringFraction=3.0, limit=1000, verbose=False): """ """ Generate cosmic ray events up to a covering fraction and include it to a cosmic ray map (self.cosmicrayMap). Generate cosmic ray events up to a covering fraction and include it to a cosmic ray map (self.cosmicrayMap). Loading @@ -541,11 +543,11 @@ class cosmicrays(): raise ValueError( raise ValueError( 'coveringFraction error, it shoub be in [0.1, 1]!') 'coveringFraction error, it shoub be in [0.1, 1]!') self.cosmicrayMap = np.zeros((self.ysize, self.xsize)) self.cosmicrayMap = np.zeros((self.ysize, self.xsize)) # how many events to draw at once, too large number leads to exceeding the covering fraction # how many events to draw at once, too large number leads to exceeding the covering fraction cr_n = int(295 * self.information['exptime'] / 565. * coveringFraction / 1.4) cr_n = int( 295 * self.information['exptime'] / 565. * coveringFraction / 1.4) covering = 0.0 covering = 0.0 Loading @@ -555,11 +557,13 @@ class cosmicrays(): luck = np.random.rand(cr_n) luck = np.random.rand(cr_n) # draw the length of the tracks # draw the length of the tracks ius = InterpolatedUnivariateSpline(self.cr['cr_cdf'], self.cr['cr_u']) ius = InterpolatedUnivariateSpline( self.cr['cr_cdf'], self.cr['cr_u']) self.cr['cr_l'] = ius(luck) self.cr['cr_l'] = ius(luck) if limit is None: if limit is None: ius = InterpolatedUnivariateSpline(self.cr['cr_cde'], self.cr['cr_v']) ius = InterpolatedUnivariateSpline( self.cr['cr_cde'], self.cr['cr_v']) self.cr['cr_e'] = ius(luck) self.cr['cr_e'] = ius(luck) else: else: # set the energy directly to the limit # set the energy directly to the limit Loading @@ -576,13 +580,13 @@ class cosmicrays(): cr_phi = np.pi * np.random.rand(int(np.floor(cr_n))) cr_phi = np.pi * np.random.rand(int(np.floor(cr_n))) # find the intercepts # find the intercepts self.cosmicrayMap += self._cosmicRayIntercepts(self.cr['cr_e'], cr_x, cr_y, self.cr['cr_l'], cr_phi) self.cosmicrayMap += self._cosmicRayIntercepts( self.cr['cr_e'], cr_x, cr_y, self.cr['cr_l'], cr_phi) # count the covering factor # count the covering factor area_cr = np.count_nonzero(self.cosmicrayMap) area_cr = np.count_nonzero(self.cosmicrayMap) covering = 100.*area_cr / (self.xsize*self.ysize) covering = 100.*area_cr / (self.xsize*self.ysize) def addUpToFraction(self, coveringFraction, limit=None, verbose=False): def addUpToFraction(self, coveringFraction, limit=None, verbose=False): """ """ Add cosmic ray events up to the covering Fraction. Add cosmic ray events up to the covering Fraction. Loading @@ -597,7 +601,8 @@ class cosmicrays(): :return: image with cosmic rays :return: image with cosmic rays :rtype: ndarray :rtype: ndarray """ """ self._drawEventsToCoveringFactor(coveringFraction, limit=limit, verbose=verbose) self._drawEventsToCoveringFactor( coveringFraction, limit=limit, verbose=verbose) # paste cosmic rays # paste cosmic rays self.image += self.cosmicrayMap self.image += self.cosmicrayMap Loading Loading @@ -1148,6 +1153,8 @@ def beta_angle(x_sat, y_sat, z_sat, vx_sat, vy_sat, vz_sat, ra_obj, dec_obj): return angle return angle ############################################################################### ############################################################################### def find_min(arr): def find_min(arr): min_val = arr[0] min_val = arr[0] min_index = 0 min_index = 0 Loading @@ -1158,6 +1165,8 @@ def find_min(arr): return min_val, min_index return min_val, min_index ################################# ################################# def find_max(arr): def find_max(arr): max_val = arr[0] max_val = arr[0] max_index = 0 max_index = 0 Loading Loading @@ -1558,8 +1567,9 @@ def get_dx_dy_blue(wave): # dxdl = 0.2*np.array([-9.1519, -1.00000000e-06, 3.50000000e-08, -5.00000000e-09, # dxdl = 0.2*np.array([-9.1519, -1.00000000e-06, 3.50000000e-08, -5.00000000e-09, # -1.70000000e-11, 4.00949787e-12, -6.16873452e-15]) # -1.70000000e-11, 4.00949787e-12, -6.16873452e-15]) ##### update @2024.10.16 # update @2024.10.16 dydl=np.array([ 2447.9, -1/0.141, 0.0000075, 0.00000078, -0.000000000007] ) ; #色散方向 dydl = np.array([2447.9, -1/0.141, 0.0000075, 0.00000078, -0.000000000007]) # 色散方向 dxdl = np.array([5.46, -1.5e-02, 3.5e-08, -5.0e-09]) # 垂直方向 dxdl = np.array([5.46, -1.5e-02, 3.5e-08, -5.0e-09]) # 垂直方向 dx = 0.0 dx = 0.0 Loading Loading @@ -1593,8 +1603,9 @@ def get_dx_dy_red(wave): # 0.0000028, -0.0000000000007, 0.0, 0.0]) # 色散方向 # 0.0000028, -0.0000000000007, 0.0, 0.0]) # 色散方向 # dxdl = 0.00325*np.array([-1638.8, 4.0e-2, 5.500e-3, - # dxdl = 0.00325*np.array([-1638.8, 4.0e-2, 5.500e-3, - # 5.2e-10, 1.7000e-10, 7.1e-13, -5.16e-15]) # 垂直方向 # 5.2e-10, 1.7000e-10, 7.1e-13, -5.16e-15]) # 垂直方向 ## update @2014.10.17 # update @2014.10.17 dydl=np.array([3519.78622, -1/0.1555, 0.0000048, 0.00000028, -0.0000000000007] ) #色散方向 dydl = np.array([3519.78622, -1/0.1555, 0.0000048, 0.00000028, -0.0000000000007]) # 色散方向 dxdl = np.array([-5.6305, 1.0e-2, 5.500e-7, -5.2e-10]) # 垂直方向 dxdl = np.array([-5.6305, 1.0e-2, 5.500e-7, -5.2e-10]) # 垂直方向 dx = 0.0 dx = 0.0 Loading Loading @@ -2019,7 +2030,6 @@ class IFSsimulator(): result_day = now.strftime("%Y-%m-%d") result_day = now.strftime("%Y-%m-%d") if self.source == 'LAMP': if self.source == 'LAMP': if applyhole == 'yes': if applyhole == 'yes': ss = '_with_hole_' ss = '_with_hole_' Loading @@ -2042,9 +2052,8 @@ class IFSsimulator(): # else: # else: # self.result_path = '/data/ifspip/CCD_ima/'+self.source+ss+result_day # self.result_path = '/data/ifspip/CCD_ima/'+self.source+ss+result_day self.result_path = self.information['result_path'] + \ '/'+self.source+ss+result_day self.result_path= self.information['result_path']+'/'+self.source+ss+result_day print(self.information['result_path']) print(self.information['result_path']) if os.path.isdir(self.result_path) == False: if os.path.isdir(self.result_path) == False: Loading Loading @@ -2163,7 +2172,7 @@ class IFSsimulator(): slice_red['py'][i] = 50+250+randRedpos[i]*4 slice_red['py'][i] = 50+250+randRedpos[i]*4 slice_red['px'][i] = 3.55/0.015*(i-16)+1190.0+118 slice_red['px'][i] = 3.55/0.015*(i-16)+1190.0+118 ####### ####### ###### flip the fringe up to down,down to up@2024.10.16 # flip the fringe up to down,down to up@2024.10.16 self.slice_blue = dict() self.slice_blue = dict() self.slice_red = dict() self.slice_red = dict() self.slice_blue['py'] = 2000-slice_blue['py'] self.slice_blue['py'] = 2000-slice_blue['py'] Loading Loading @@ -2420,7 +2429,6 @@ class IFSsimulator(): self.log.info('Added dark current to bule and red channel') self.log.info('Added dark current to bule and red channel') if self.information['dark1_b'] > 0.001 or self.information['dark1_b'] > 0.001: if self.information['dark1_b'] > 0.001 or self.information['dark1_b'] > 0.001: self.log.error( self.log.error( 'dark1_b value error, it shoub be in [0.0001, 0.001]!') 'dark1_b value error, it shoub be in [0.0001, 0.001]!') Loading Loading @@ -2739,9 +2747,7 @@ class IFSsimulator(): 'rn4_r value error, it shoub be in [3, 10]!') 'rn4_r value error, it shoub be in [3, 10]!') raise ValueError( raise ValueError( 'rn4_r value error, it shoub be in [3, 10]!') 'rn4_r value error, it shoub be in [3, 10]!') ########################################################33 # 33 # blue zone 1 # blue zone 1 np.random.seed() np.random.seed() Loading Loading @@ -2910,7 +2916,6 @@ class IFSsimulator(): raise ValueError('gain4_r value error, it shoub be in [1, 2]!') raise ValueError('gain4_r value error, it shoub be in [1, 2]!') #################################################################### #################################################################### self.log.info( self.log.info( 'Converting from electrons to ADUs using a factor of gain') 'Converting from electrons to ADUs using a factor of gain') Loading @@ -2936,7 +2941,7 @@ class IFSsimulator(): ##########third part, means old zone 1 ################### ##########third part, means old zone 1 ################### self.image_b[0:1344, 2418*2:2418*3] /= self.information['gain3_b'] self.image_b[0:1344, 2418*2:2418*3] /= self.information['gain3_b'] #### fourth part, means old zone 2 # fourth part, means old zone 2 self.image_b[0:1344, 2418*3:2418*4] /= self.information['gain4_b'] self.image_b[0:1344, 2418*3:2418*4] /= self.information['gain4_b'] ############################################################################ ############################################################################ Loading Loading @@ -3264,7 +3269,6 @@ class IFSsimulator(): # def applyImageShift(self): # def applyImageShift(self): # """ # """ # Returns # Returns # ------- # ------- # None. # None. Loading Loading @@ -3368,7 +3372,7 @@ class IFSsimulator(): # y2 = y1+2048 # y2 = y1+2048 # temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgb[1024:2048, 2048:4096])) # temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgb[1024:2048, 2048:4096])) ### update 2024.10.18 # update 2024.10.18 # first part, old OSG part ,## shift: left to right # first part, old OSG part ,## shift: left to right x1 = 0 x1 = 0 x2 = x1+1024 x2 = x1+1024 Loading Loading @@ -3400,7 +3404,6 @@ class IFSsimulator(): y2 = y1+2048 y2 = y1+2048 temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgb[1024:2048, 2048:4096])) temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgb[1024:2048, 2048:4096])) self.image_b = temp self.image_b = temp ####################################################################### ####################################################################### Loading Loading @@ -3438,7 +3441,7 @@ class IFSsimulator(): # y2 = y1+3072 # y2 = y1+3072 # temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgr[1536:3072, 3072:6144])) # temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgr[1536:3072, 3072:6144])) ###### update @2024.10.18 # update @2024.10.18 # readout image ,first part, old OSG, shift: left to right # readout image ,first part, old OSG, shift: left to right x1 = 0 x1 = 0 x2 = x1+1536 x2 = x1+1536 Loading Loading @@ -3470,7 +3473,6 @@ class IFSsimulator(): y2 = y1+3072 y2 = y1+3072 temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgr[1536:3072, 3072:6144])) temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgr[1536:3072, 3072:6144])) self.image_r = temp self.image_r = temp return return Loading Loading @@ -3498,16 +3500,14 @@ class IFSsimulator(): """ """ ###### ###### ###### add random pointing error to telescope, the telescope poingt parameter in # add random pointing error to telescope, the telescope poingt parameter in ###### fits header have random pointing error # fits header have random pointing error ud_ra = np.random.random() # Choose a random shift in arcsec ud_ra = np.random.random() # Choose a random shift in arcsec self.information['ra_pnt0'] = self.information['dec_pnt0']+0.01*ud_ra self.information['ra_pnt0'] = self.information['dec_pnt0']+0.01*ud_ra ud_dec = np.random.random() ud_dec = np.random.random() self.information['dec_pnt0'] = self.information['dec_pnt0']+0.01*ud_dec self.information['dec_pnt0'] = self.information['dec_pnt0']+0.01*ud_dec HeaderTest = 'no' HeaderTest = 'no' sim_ver = str(self.information['sim_ver']) sim_ver = str(self.information['sim_ver']) Loading Loading @@ -4677,7 +4677,6 @@ class IFSsimulator(): ####################################################### ####################################################### # CCD quantum efficiency # CCD quantum efficiency CCD_Qe_lam = np.interp(lam, self.CCD_Qe[:, 0], self.CCD_Qe[:, 1]) CCD_Qe_lam = np.interp(lam, self.CCD_Qe[:, 0], self.CCD_Qe[:, 1]) Loading Loading @@ -4769,7 +4768,6 @@ class IFSsimulator(): photons_blue.addTo(blue_img) photons_blue.addTo(blue_img) # fits.writeto('blueImg.fits',blue_img.array,overwrite=True) # fits.writeto('blueImg.fits',blue_img.array,overwrite=True) if (lam >= 560.0) & (lam <= 1000.0): if (lam >= 560.0) & (lam <= 1000.0): Loading Loading @@ -4896,7 +4894,8 @@ class IFSsimulator(): ############### calculate the earthshine and zodiacal noise ,new code 2023.11.1 ############ ############### calculate the earthshine and zodiacal noise ,new code 2023.11.1 ############ ############### ############### self.log.info('Real telescope pointing in Ra = %f, Dec = %f' % (self.information['ra_pnt0'], self.information['dec_pnt0'])) self.log.info('Real telescope pointing in Ra = %f, Dec = %f' % ( self.information['ra_pnt0'], self.information['dec_pnt0'])) ra = self.information['ra_pnt0'] ra = self.information['ra_pnt0'] dec = self.information['dec_pnt0'] dec = self.information['dec_pnt0'] Loading @@ -4905,11 +4904,13 @@ class IFSsimulator(): if self.appbianpai: if self.appbianpai: sn = self.simnumber-1 sn=self.simnumber-1; x_sat = float(self.bianpai_data['x_sat'] x_sat = float(self.bianpai_data['x_sat'][sn*5+self.exptime_start_index]) [sn*5+self.exptime_start_index]) y_sat = float(self.bianpai_data['y_sat'][sn*5+self.exptime_start_index]) y_sat = float(self.bianpai_data['y_sat'] z_sat = float(self.bianpai_data['z_sat'][sn*5+self.exptime_start_index]) [sn*5+self.exptime_start_index]) z_sat = float(self.bianpai_data['z_sat'] [sn*5+self.exptime_start_index]) ### ### else: else: Loading Loading @@ -4997,14 +4998,20 @@ class IFSsimulator(): ############## doppler effect to photons.wavelength ############# ############## doppler effect to photons.wavelength ############# if self.appbianpai: if self.appbianpai: sn=self.simnumber-1; sn = self.simnumber-1 x_sat = float(self.bianpai_data['x_sat'][sn*5+self.exptime_start_index]) x_sat = float(self.bianpai_data['x_sat'] y_sat = float(self.bianpai_data['y_sat'][sn*5+self.exptime_start_index]) [sn*5+self.exptime_start_index]) z_sat = float(self.bianpai_data['z_sat'][sn*5+self.exptime_start_index]) y_sat = float(self.bianpai_data['y_sat'] [sn*5+self.exptime_start_index]) vx_sat = float(self.bianpai_data['vx_sat'][sn*5+self.exptime_start_index]) z_sat = float(self.bianpai_data['z_sat'] vy_sat = float(self.bianpai_data['vy_sat'][sn*5+self.exptime_start_index]) [sn*5+self.exptime_start_index]) vz_sat = float(self.bianpai_data['vz_sat'][sn*5+self.exptime_start_index]) vx_sat = float( self.bianpai_data['vx_sat'][sn*5+self.exptime_start_index]) vy_sat = float( self.bianpai_data['vy_sat'][sn*5+self.exptime_start_index]) vz_sat = float( self.bianpai_data['vz_sat'][sn*5+self.exptime_start_index]) else: else: Loading Loading @@ -5033,15 +5040,21 @@ class IFSsimulator(): ################################################# ################################################# if self.appbianpai: if self.appbianpai: sn=self.simnumber-1; sn = self.simnumber-1 p1x = float(self.bianpai_data['x_sat'][sn*5+self.exptime_end_index]) p1x = float(self.bianpai_data['x_sat'] p1y = float(self.bianpai_data['y_sat'][sn*5+self.exptime_end_index]) [sn*5+self.exptime_end_index]) p1z = float(self.bianpai_data['z_sat'][sn*5+self.exptime_end_index]) p1y = float(self.bianpai_data['y_sat'] [sn*5+self.exptime_end_index]) p1vx = float(self.bianpai_data['vx_sat'][sn*5+self.exptime_end_index]) p1z = float(self.bianpai_data['z_sat'] p1vy = float(self.bianpai_data['vy_sat'][sn*5+self.exptime_end_index]) [sn*5+self.exptime_end_index]) p1vz = float(self.bianpai_data['vz_sat'][sn*5+self.exptime_end_index]) p1vx = float(self.bianpai_data['vx_sat'] [sn*5+self.exptime_end_index]) p1vy = float(self.bianpai_data['vy_sat'] [sn*5+self.exptime_end_index]) p1vz = float(self.bianpai_data['vz_sat'] [sn*5+self.exptime_end_index]) else: else: Loading @@ -5052,7 +5065,8 @@ class IFSsimulator(): t2jd = time2jd(t2) t2jd = time2jd(t2) if self.orbit_pars[-1, 0] < t2jd: # orbit parameters are not in currenct txt file # orbit parameters are not in currenct txt file if self.orbit_pars[-1, 0] < t2jd: self.orbit_file_num = self.orbit_file_num+1 self.orbit_file_num = self.orbit_file_num+1 fn = self.information['dir_path'] + \ fn = self.information['dir_path'] + \ 'IFS_inputdata/TianCe/orbit20160925/' + \ 'IFS_inputdata/TianCe/orbit20160925/' + \ Loading Loading @@ -5394,7 +5408,6 @@ class IFSsimulator(): energy_blue = energy_blue+sum(photons_blue.flux) energy_blue = energy_blue+sum(photons_blue.flux) ################# ################# # fits.writeto('blueImg.fits',blue_img.array,overwrite=True) # fits.writeto('blueImg.fits',blue_img.array,overwrite=True) Loading Loading @@ -5856,9 +5869,6 @@ class IFSsimulator(): self.debug = self.information['debug'] self.debug = self.information['debug'] if self.information['exptime'] > 2000 or self.information['exptime'] < 0: if self.information['exptime'] > 2000 or self.information['exptime'] < 0: self.log.error( self.log.error( 'exptime value error, it shoub be in [0, 2000]!') 'exptime value error, it shoub be in [0, 2000]!') Loading @@ -5885,27 +5895,28 @@ class IFSsimulator(): ################################################################### ################################################################### if self.appbianpai: if self.appbianpai: ### load yunxingbianpai csv file # load yunxingbianpai csv file ############ load star data catlog ##################### ############ load star data catlog ##################### starcat = self.information['bianpai_file'] starcat = self.information['bianpai_file'] ##starcat='selection_20230517_concat.fits' # starcat='selection_20230517_concat.fits' ################################################### ################################################### self.log.info('Stat catlog file name is %s' % (starcat)) self.log.info('Stat catlog file name is %s' % (starcat)) ########################################## ########################################## df=pd.read_csv(self.information['dir_path']+'IFS_inputdata/TianCe/'+starcat) df = pd.read_csv( self.information['dir_path']+'IFS_inputdata/TianCe/'+starcat) ################################################################### ################################################################### sn=self.simnumber-1; sn = self.simnumber-1 arr=np.array(df['time'][sn*5:sn*5+5]); arr = np.array(df['time'][sn*5:sn*5+5]) self.exptime_start_jd,self.exptime_start_index=find_min(arr); self.exptime_start_jd, self.exptime_start_index = find_min(arr) self.exptime_end_jd, self.exptime_end_index =find_max(arr); self.exptime_end_jd, self.exptime_end_index = find_max(arr) ###self.earthshine_theta=df['earth_angle'][sn*5+index] # in degree # self.earthshine_theta=df['earth_angle'][sn*5+index] # in degree self.dt = jd2time(self.exptime_start_jd); self.dt = jd2time(self.exptime_start_jd) self.bianpai_data=df; self.bianpai_data = df ################################################################## ################################################################## else: else: Loading @@ -5917,8 +5928,6 @@ class IFSsimulator(): now_dt = datetime.utcnow() now_dt = datetime.utcnow() now_jd = time2jd(now_dt) now_jd = time2jd(now_dt) for k in range(1, 50, 1): for k in range(1, 50, 1): # fn=father_path+'/IFS_inputdata/TianCe/orbit20160925/'+str(k)+'.txt'; # fn=father_path+'/IFS_inputdata/TianCe/orbit20160925/'+str(k)+'.txt'; Loading Loading @@ -5958,7 +5967,6 @@ class IFSsimulator(): ################################################################## ################################################################## ################################################################## ################################################################## self.TianCe_day = self.dt.strftime("%Y-%m-%d") self.TianCe_day = self.dt.strftime("%Y-%m-%d") self.TianCe_exp_start = dt2hmd(self.dt) self.TianCe_exp_start = dt2hmd(self.dt) Loading Loading @@ -6182,8 +6190,8 @@ def runIFSsim(sourcein, configfile, dir_path, result_path, iLoop, debug, applyho simulate = dict() simulate = dict() simulate[iLoop] = IFSsimulator(configfile) simulate[iLoop] = IFSsimulator(configfile) simulate[iLoop].configure(sourcein, dir_path, result_path, iLoop, debug, applyhole) # load the configfile; simulate[iLoop].configure(sourcein, dir_path, result_path, iLoop, debug, applyhole) # load the configfile; if applyhole == 'yes' and sourcein == 'LAMP': if applyhole == 'yes' and sourcein == 'LAMP': simulate[iLoop].information['holemask'] = 'yes' simulate[iLoop].information['holemask'] = 'yes' Loading tests/test_ifs_sim.py +80 −76 Original line number Original line Diff line number Diff line Loading @@ -15,7 +15,7 @@ from csst_ifs_sim import csst_ifs_sim import sys import sys ### sys.path.append('IFS_git/csst_ifs_sim/csst_ifs_sim') # sys.path.append('IFS_git/csst_ifs_sim/csst_ifs_sim') class TestDemoFunction(unittest.TestCase): class TestDemoFunction(unittest.TestCase): Loading Loading @@ -49,7 +49,8 @@ class TestDemoFunction(unittest.TestCase): result_path = dir_path+'ifs_sim_result' result_path = dir_path+'ifs_sim_result' csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug,'no') csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'no') self.assertEqual( self.assertEqual( 1, 1, 1, 1, Loading Loading @@ -86,7 +87,8 @@ class TestDemoFunction(unittest.TestCase): debug = True debug = True result_path = dir_path+'ifs_sim_result' result_path = dir_path+'ifs_sim_result' csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug,'no') csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'no') self.assertEqual( self.assertEqual( 1, 1, 1, 1, Loading Loading @@ -123,7 +125,8 @@ class TestDemoFunction(unittest.TestCase): debug = True debug = True result_path = dir_path+'ifs_sim_result' result_path = dir_path+'ifs_sim_result' csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug,'no') csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'no') self.assertEqual( self.assertEqual( 1, 1, 1, 1, Loading Loading @@ -161,7 +164,8 @@ class TestDemoFunction(unittest.TestCase): result_path = dir_path+'ifs_sim_result' result_path = dir_path+'ifs_sim_result' csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug,'no') csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'no') self.assertEqual( self.assertEqual( 1, 1, 1, 1, Loading Loading @@ -198,7 +202,8 @@ class TestDemoFunction(unittest.TestCase): debug = True debug = True result_path = dir_path+'ifs_sim_result' result_path = dir_path+'ifs_sim_result' csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug,'yes') csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'yes') self.assertEqual( self.assertEqual( 1, 1, 1, 1, "case 5: sim passes.", "case 5: sim passes.", Loading Loading @@ -235,10 +240,9 @@ class TestDemoFunction(unittest.TestCase): result_path = dir_path+'ifs_sim_result' result_path = dir_path+'ifs_sim_result' csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'no') csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'no') self.assertEqual( self.assertEqual( 1, 1, 1, 1, "case 6: sim passes.", "case 6: sim passes.", ) ) Loading
csst_ifs_sim/CTI/CTI.py +31 −34 Original line number Original line Diff line number Diff line Loading @@ -27,6 +27,7 @@ class CDM03bidir(): :param log: instance to Python logging :param log: instance to Python logging :type log: logging instance :type log: logging instance """ """ def __init__(self, settings, data, log=None): def __init__(self, settings, data, log=None): """ """ Class constructor. Class constructor. Loading @@ -39,7 +40,8 @@ class CDM03bidir(): :type log: logging instance :type log: logging instance """ """ self.data = data 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.values.update(settings) self.log = log self.log = log self._setupLogger() self._setupLogger() Loading @@ -55,7 +57,8 @@ class CDM03bidir(): self.params.update(self.values) self.params.update(self.values) # read in trap information # read in trap information trapdata = np.loadtxt(self.values['dir_path']+self.values['paralleltrapfile']) trapdata = np.loadtxt( self.values['dir_path']+self.values['paralleltrapfile']) if trapdata.ndim > 1: if trapdata.ndim > 1: self.nt_p = trapdata[:, 0] self.nt_p = trapdata[:, 0] self.sigma_p = trapdata[:, 1] self.sigma_p = trapdata[:, 1] Loading @@ -66,7 +69,8 @@ class CDM03bidir(): self.sigma_p = [trapdata[1],] self.sigma_p = [trapdata[1],] self.taur_p = [trapdata[2],] 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: if trapdata.ndim > 1: self.nt_s = trapdata[:, 0] self.nt_s = trapdata[:, 0] self.sigma_s = trapdata[:, 1] self.sigma_s = trapdata[:, 1] Loading @@ -85,7 +89,6 @@ class CDM03bidir(): self.nt_s *= 0.576 # thibaut's values traps / pixel #should be division? 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.sigma_s *= 1.e4 # thibaut's values in m**2 def _setupLogger(self): def _setupLogger(self): """ """ Set up the logger. Set up the logger. Loading @@ -94,7 +97,6 @@ class CDM03bidir(): # if self.log is None: # if self.log is None: # self.logger = False # self.logger = False def applyRadiationDamage(self, data, iquadrant=0): def applyRadiationDamage(self, data, iquadrant=0): """ """ Apply radian damage based on FORTRAN CDM03 model. The method assumes that Apply radian damage based on FORTRAN CDM03 model. The method assumes that Loading Loading @@ -158,7 +160,7 @@ class CDM03bidir(): self.log.info('jflip=%i' % jflip) self.log.info('jflip=%i' % jflip) ################################################################################# ################################################################################# ###modify # modify # sys.path.append('../so') # sys.path.append('../so') from ifs_so import cdm03bidir from ifs_so import cdm03bidir # from ifs_so.cdm03.cpython-38-x86_64-linux-gnu import cdm03bidir # from ifs_so.cdm03.cpython-38-x86_64-linux-gnu import cdm03bidir Loading @@ -171,14 +173,9 @@ class CDM03bidir(): params, params, [data.shape[0], data.shape[1], len(self.nt_p), len(self.nt_s), len(self.params)]) [data.shape[0], data.shape[1], len(self.nt_p), len(self.nt_s), len(self.params)]) return np.asanyarray(CTIed) return np.asanyarray(CTIed) ################################################################################################################# ################################################################################################################# ################################################################################################################# #################################################################################################################
csst_ifs_sim/csst_ifs_sim.py +292 −284 Original line number Original line Diff line number Diff line Loading @@ -5,6 +5,9 @@ Created on Thu Apr 11 15:18:57 2024 @author: yan @author: yan """ """ from scipy.interpolate import InterpolatedUnivariateSpline import logging.handlers import logging from astropy.utils.iers import conf from astropy.utils.iers import conf import galsim import galsim from scipy.integrate import simps from scipy.integrate import simps Loading @@ -28,7 +31,7 @@ import astropy.coordinates as coord import ctypes import ctypes import sys import sys ##sys.path.append('./csst_ifs_sim') # sys.path.append('./csst_ifs_sim') conf.auto_max_age = None conf.auto_max_age = None """ """ Loading Loading @@ -104,6 +107,7 @@ class CDM03bidir(): :param log: instance to Python logging :param log: instance to Python logging :type log: logging instance :type log: logging instance """ """ def __init__(self, settings, data, log=None): def __init__(self, settings, data, log=None): """ """ Class constructor. Class constructor. Loading @@ -116,7 +120,8 @@ class CDM03bidir(): :type log: logging instance :type log: logging instance """ """ self.data = data 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.values.update(settings) self.log = log self.log = log self._setupLogger() self._setupLogger() Loading @@ -132,7 +137,8 @@ class CDM03bidir(): self.params.update(self.values) self.params.update(self.values) # read in trap information # read in trap information trapdata = np.loadtxt(self.values['dir_path']+self.values['paralleltrapfile']) trapdata = np.loadtxt( self.values['dir_path']+self.values['paralleltrapfile']) if trapdata.ndim > 1: if trapdata.ndim > 1: self.nt_p = trapdata[:, 0] self.nt_p = trapdata[:, 0] self.sigma_p = trapdata[:, 1] self.sigma_p = trapdata[:, 1] Loading @@ -143,7 +149,8 @@ class CDM03bidir(): self.sigma_p = [trapdata[1],] self.sigma_p = [trapdata[1],] self.taur_p = [trapdata[2],] 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: if trapdata.ndim > 1: self.nt_s = trapdata[:, 0] self.nt_s = trapdata[:, 0] self.sigma_s = trapdata[:, 1] self.sigma_s = trapdata[:, 1] Loading @@ -162,14 +169,12 @@ class CDM03bidir(): self.nt_s *= 0.576 # thibaut's values traps / pixel #should be division? 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.sigma_s *= 1.e4 # thibaut's values in m**2 def _setupLogger(self): def _setupLogger(self): """ """ Set up the logger. Set up the logger. """ """ self.logger = True self.logger = True def applyRadiationDamage(self, data, iquadrant=0): def applyRadiationDamage(self, data, iquadrant=0): """ """ Apply radian damage based on FORTRAN CDM03 model. The method assumes that Apply radian damage based on FORTRAN CDM03 model. The method assumes that Loading Loading @@ -235,7 +240,7 @@ class CDM03bidir(): ############################################ ############################################ ################################################################################# ################################################################################# ###modify # modify # sys.path.append('../so') # sys.path.append('../so') #from .ifs_so import cdm03bidir #from .ifs_so import cdm03bidir try: try: Loading @@ -253,13 +258,13 @@ class CDM03bidir(): params, params, [data.shape[0], data.shape[1], len(self.nt_p), len(self.nt_s), len(self.params)]) [data.shape[0], data.shape[1], len(self.nt_p), len(self.nt_s), len(self.params)]) return np.asanyarray(CTIed) return np.asanyarray(CTIed) ################################################################################################################# ################################################################################################################# ################################################################################################################# ################################################################################################################# """ """ These functions can be used for logging information. These functions can be used for logging information. Loading @@ -267,8 +272,6 @@ These functions can be used for logging information. :version: 0.3 :version: 0.3 """ """ import logging import logging.handlers def lg(log_filename, loggername='logger'): def lg(log_filename, loggername='logger'): Loading @@ -287,7 +290,8 @@ def lg(log_filename, loggername='logger'): handler = logging.handlers.RotatingFileHandler(log_filename) handler = logging.handlers.RotatingFileHandler(log_filename) # maxBytes=20, backupCount=5) # maxBytes=20, backupCount=5) # create formatter # create formatter formatter = logging.Formatter('%(asctime)s - %(module)s - %(funcName)s - %(levelname)s - %(message)s') formatter = logging.Formatter( '%(asctime)s - %(module)s - %(funcName)s - %(levelname)s - %(message)s') # add formatter to ch # add formatter to ch handler.setFormatter(formatter) handler.setFormatter(formatter) # add handler to logger # add handler to logger Loading Loading @@ -343,7 +347,6 @@ def CCDnonLinearityModel(data, beta=6e-7): ############################################################################# ############################################################################# from scipy.interpolate import InterpolatedUnivariateSpline class cosmicrays(): class cosmicrays(): """ """ Loading @@ -369,6 +372,7 @@ class cosmicrays(): :param information: cosmic ray track information (file containing track length and energy information) and :param information: cosmic ray track information (file containing track length and energy information) and exposure time. exposure time. """ """ def __init__(self, log, image, crInfo=None, information=None): def __init__(self, log, image, crInfo=None, information=None): """ """ Cosmic ray generation class. Can either draw events from distributions or Cosmic ray generation class. Can either draw events from distributions or Loading Loading @@ -518,8 +522,6 @@ class cosmicrays(): return crImage return crImage def _drawEventsToCoveringFactor(self, coveringFraction=3.0, limit=1000, verbose=False): def _drawEventsToCoveringFactor(self, coveringFraction=3.0, limit=1000, verbose=False): """ """ Generate cosmic ray events up to a covering fraction and include it to a cosmic ray map (self.cosmicrayMap). Generate cosmic ray events up to a covering fraction and include it to a cosmic ray map (self.cosmicrayMap). Loading @@ -541,11 +543,11 @@ class cosmicrays(): raise ValueError( raise ValueError( 'coveringFraction error, it shoub be in [0.1, 1]!') 'coveringFraction error, it shoub be in [0.1, 1]!') self.cosmicrayMap = np.zeros((self.ysize, self.xsize)) self.cosmicrayMap = np.zeros((self.ysize, self.xsize)) # how many events to draw at once, too large number leads to exceeding the covering fraction # how many events to draw at once, too large number leads to exceeding the covering fraction cr_n = int(295 * self.information['exptime'] / 565. * coveringFraction / 1.4) cr_n = int( 295 * self.information['exptime'] / 565. * coveringFraction / 1.4) covering = 0.0 covering = 0.0 Loading @@ -555,11 +557,13 @@ class cosmicrays(): luck = np.random.rand(cr_n) luck = np.random.rand(cr_n) # draw the length of the tracks # draw the length of the tracks ius = InterpolatedUnivariateSpline(self.cr['cr_cdf'], self.cr['cr_u']) ius = InterpolatedUnivariateSpline( self.cr['cr_cdf'], self.cr['cr_u']) self.cr['cr_l'] = ius(luck) self.cr['cr_l'] = ius(luck) if limit is None: if limit is None: ius = InterpolatedUnivariateSpline(self.cr['cr_cde'], self.cr['cr_v']) ius = InterpolatedUnivariateSpline( self.cr['cr_cde'], self.cr['cr_v']) self.cr['cr_e'] = ius(luck) self.cr['cr_e'] = ius(luck) else: else: # set the energy directly to the limit # set the energy directly to the limit Loading @@ -576,13 +580,13 @@ class cosmicrays(): cr_phi = np.pi * np.random.rand(int(np.floor(cr_n))) cr_phi = np.pi * np.random.rand(int(np.floor(cr_n))) # find the intercepts # find the intercepts self.cosmicrayMap += self._cosmicRayIntercepts(self.cr['cr_e'], cr_x, cr_y, self.cr['cr_l'], cr_phi) self.cosmicrayMap += self._cosmicRayIntercepts( self.cr['cr_e'], cr_x, cr_y, self.cr['cr_l'], cr_phi) # count the covering factor # count the covering factor area_cr = np.count_nonzero(self.cosmicrayMap) area_cr = np.count_nonzero(self.cosmicrayMap) covering = 100.*area_cr / (self.xsize*self.ysize) covering = 100.*area_cr / (self.xsize*self.ysize) def addUpToFraction(self, coveringFraction, limit=None, verbose=False): def addUpToFraction(self, coveringFraction, limit=None, verbose=False): """ """ Add cosmic ray events up to the covering Fraction. Add cosmic ray events up to the covering Fraction. Loading @@ -597,7 +601,8 @@ class cosmicrays(): :return: image with cosmic rays :return: image with cosmic rays :rtype: ndarray :rtype: ndarray """ """ self._drawEventsToCoveringFactor(coveringFraction, limit=limit, verbose=verbose) self._drawEventsToCoveringFactor( coveringFraction, limit=limit, verbose=verbose) # paste cosmic rays # paste cosmic rays self.image += self.cosmicrayMap self.image += self.cosmicrayMap Loading Loading @@ -1148,6 +1153,8 @@ def beta_angle(x_sat, y_sat, z_sat, vx_sat, vy_sat, vz_sat, ra_obj, dec_obj): return angle return angle ############################################################################### ############################################################################### def find_min(arr): def find_min(arr): min_val = arr[0] min_val = arr[0] min_index = 0 min_index = 0 Loading @@ -1158,6 +1165,8 @@ def find_min(arr): return min_val, min_index return min_val, min_index ################################# ################################# def find_max(arr): def find_max(arr): max_val = arr[0] max_val = arr[0] max_index = 0 max_index = 0 Loading Loading @@ -1558,8 +1567,9 @@ def get_dx_dy_blue(wave): # dxdl = 0.2*np.array([-9.1519, -1.00000000e-06, 3.50000000e-08, -5.00000000e-09, # dxdl = 0.2*np.array([-9.1519, -1.00000000e-06, 3.50000000e-08, -5.00000000e-09, # -1.70000000e-11, 4.00949787e-12, -6.16873452e-15]) # -1.70000000e-11, 4.00949787e-12, -6.16873452e-15]) ##### update @2024.10.16 # update @2024.10.16 dydl=np.array([ 2447.9, -1/0.141, 0.0000075, 0.00000078, -0.000000000007] ) ; #色散方向 dydl = np.array([2447.9, -1/0.141, 0.0000075, 0.00000078, -0.000000000007]) # 色散方向 dxdl = np.array([5.46, -1.5e-02, 3.5e-08, -5.0e-09]) # 垂直方向 dxdl = np.array([5.46, -1.5e-02, 3.5e-08, -5.0e-09]) # 垂直方向 dx = 0.0 dx = 0.0 Loading Loading @@ -1593,8 +1603,9 @@ def get_dx_dy_red(wave): # 0.0000028, -0.0000000000007, 0.0, 0.0]) # 色散方向 # 0.0000028, -0.0000000000007, 0.0, 0.0]) # 色散方向 # dxdl = 0.00325*np.array([-1638.8, 4.0e-2, 5.500e-3, - # dxdl = 0.00325*np.array([-1638.8, 4.0e-2, 5.500e-3, - # 5.2e-10, 1.7000e-10, 7.1e-13, -5.16e-15]) # 垂直方向 # 5.2e-10, 1.7000e-10, 7.1e-13, -5.16e-15]) # 垂直方向 ## update @2014.10.17 # update @2014.10.17 dydl=np.array([3519.78622, -1/0.1555, 0.0000048, 0.00000028, -0.0000000000007] ) #色散方向 dydl = np.array([3519.78622, -1/0.1555, 0.0000048, 0.00000028, -0.0000000000007]) # 色散方向 dxdl = np.array([-5.6305, 1.0e-2, 5.500e-7, -5.2e-10]) # 垂直方向 dxdl = np.array([-5.6305, 1.0e-2, 5.500e-7, -5.2e-10]) # 垂直方向 dx = 0.0 dx = 0.0 Loading Loading @@ -2019,7 +2030,6 @@ class IFSsimulator(): result_day = now.strftime("%Y-%m-%d") result_day = now.strftime("%Y-%m-%d") if self.source == 'LAMP': if self.source == 'LAMP': if applyhole == 'yes': if applyhole == 'yes': ss = '_with_hole_' ss = '_with_hole_' Loading @@ -2042,9 +2052,8 @@ class IFSsimulator(): # else: # else: # self.result_path = '/data/ifspip/CCD_ima/'+self.source+ss+result_day # self.result_path = '/data/ifspip/CCD_ima/'+self.source+ss+result_day self.result_path = self.information['result_path'] + \ '/'+self.source+ss+result_day self.result_path= self.information['result_path']+'/'+self.source+ss+result_day print(self.information['result_path']) print(self.information['result_path']) if os.path.isdir(self.result_path) == False: if os.path.isdir(self.result_path) == False: Loading Loading @@ -2163,7 +2172,7 @@ class IFSsimulator(): slice_red['py'][i] = 50+250+randRedpos[i]*4 slice_red['py'][i] = 50+250+randRedpos[i]*4 slice_red['px'][i] = 3.55/0.015*(i-16)+1190.0+118 slice_red['px'][i] = 3.55/0.015*(i-16)+1190.0+118 ####### ####### ###### flip the fringe up to down,down to up@2024.10.16 # flip the fringe up to down,down to up@2024.10.16 self.slice_blue = dict() self.slice_blue = dict() self.slice_red = dict() self.slice_red = dict() self.slice_blue['py'] = 2000-slice_blue['py'] self.slice_blue['py'] = 2000-slice_blue['py'] Loading Loading @@ -2420,7 +2429,6 @@ class IFSsimulator(): self.log.info('Added dark current to bule and red channel') self.log.info('Added dark current to bule and red channel') if self.information['dark1_b'] > 0.001 or self.information['dark1_b'] > 0.001: if self.information['dark1_b'] > 0.001 or self.information['dark1_b'] > 0.001: self.log.error( self.log.error( 'dark1_b value error, it shoub be in [0.0001, 0.001]!') 'dark1_b value error, it shoub be in [0.0001, 0.001]!') Loading Loading @@ -2739,9 +2747,7 @@ class IFSsimulator(): 'rn4_r value error, it shoub be in [3, 10]!') 'rn4_r value error, it shoub be in [3, 10]!') raise ValueError( raise ValueError( 'rn4_r value error, it shoub be in [3, 10]!') 'rn4_r value error, it shoub be in [3, 10]!') ########################################################33 # 33 # blue zone 1 # blue zone 1 np.random.seed() np.random.seed() Loading Loading @@ -2910,7 +2916,6 @@ class IFSsimulator(): raise ValueError('gain4_r value error, it shoub be in [1, 2]!') raise ValueError('gain4_r value error, it shoub be in [1, 2]!') #################################################################### #################################################################### self.log.info( self.log.info( 'Converting from electrons to ADUs using a factor of gain') 'Converting from electrons to ADUs using a factor of gain') Loading @@ -2936,7 +2941,7 @@ class IFSsimulator(): ##########third part, means old zone 1 ################### ##########third part, means old zone 1 ################### self.image_b[0:1344, 2418*2:2418*3] /= self.information['gain3_b'] self.image_b[0:1344, 2418*2:2418*3] /= self.information['gain3_b'] #### fourth part, means old zone 2 # fourth part, means old zone 2 self.image_b[0:1344, 2418*3:2418*4] /= self.information['gain4_b'] self.image_b[0:1344, 2418*3:2418*4] /= self.information['gain4_b'] ############################################################################ ############################################################################ Loading Loading @@ -3264,7 +3269,6 @@ class IFSsimulator(): # def applyImageShift(self): # def applyImageShift(self): # """ # """ # Returns # Returns # ------- # ------- # None. # None. Loading Loading @@ -3368,7 +3372,7 @@ class IFSsimulator(): # y2 = y1+2048 # y2 = y1+2048 # temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgb[1024:2048, 2048:4096])) # temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgb[1024:2048, 2048:4096])) ### update 2024.10.18 # update 2024.10.18 # first part, old OSG part ,## shift: left to right # first part, old OSG part ,## shift: left to right x1 = 0 x1 = 0 x2 = x1+1024 x2 = x1+1024 Loading Loading @@ -3400,7 +3404,6 @@ class IFSsimulator(): y2 = y1+2048 y2 = y1+2048 temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgb[1024:2048, 2048:4096])) temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgb[1024:2048, 2048:4096])) self.image_b = temp self.image_b = temp ####################################################################### ####################################################################### Loading Loading @@ -3438,7 +3441,7 @@ class IFSsimulator(): # y2 = y1+3072 # y2 = y1+3072 # temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgr[1536:3072, 3072:6144])) # temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgr[1536:3072, 3072:6144])) ###### update @2024.10.18 # update @2024.10.18 # readout image ,first part, old OSG, shift: left to right # readout image ,first part, old OSG, shift: left to right x1 = 0 x1 = 0 x2 = x1+1536 x2 = x1+1536 Loading Loading @@ -3470,7 +3473,6 @@ class IFSsimulator(): y2 = y1+3072 y2 = y1+3072 temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgr[1536:3072, 3072:6144])) temp[x1:x2, y1:y2] = np.flipud(np.fliplr(imgr[1536:3072, 3072:6144])) self.image_r = temp self.image_r = temp return return Loading Loading @@ -3498,16 +3500,14 @@ class IFSsimulator(): """ """ ###### ###### ###### add random pointing error to telescope, the telescope poingt parameter in # add random pointing error to telescope, the telescope poingt parameter in ###### fits header have random pointing error # fits header have random pointing error ud_ra = np.random.random() # Choose a random shift in arcsec ud_ra = np.random.random() # Choose a random shift in arcsec self.information['ra_pnt0'] = self.information['dec_pnt0']+0.01*ud_ra self.information['ra_pnt0'] = self.information['dec_pnt0']+0.01*ud_ra ud_dec = np.random.random() ud_dec = np.random.random() self.information['dec_pnt0'] = self.information['dec_pnt0']+0.01*ud_dec self.information['dec_pnt0'] = self.information['dec_pnt0']+0.01*ud_dec HeaderTest = 'no' HeaderTest = 'no' sim_ver = str(self.information['sim_ver']) sim_ver = str(self.information['sim_ver']) Loading Loading @@ -4677,7 +4677,6 @@ class IFSsimulator(): ####################################################### ####################################################### # CCD quantum efficiency # CCD quantum efficiency CCD_Qe_lam = np.interp(lam, self.CCD_Qe[:, 0], self.CCD_Qe[:, 1]) CCD_Qe_lam = np.interp(lam, self.CCD_Qe[:, 0], self.CCD_Qe[:, 1]) Loading Loading @@ -4769,7 +4768,6 @@ class IFSsimulator(): photons_blue.addTo(blue_img) photons_blue.addTo(blue_img) # fits.writeto('blueImg.fits',blue_img.array,overwrite=True) # fits.writeto('blueImg.fits',blue_img.array,overwrite=True) if (lam >= 560.0) & (lam <= 1000.0): if (lam >= 560.0) & (lam <= 1000.0): Loading Loading @@ -4896,7 +4894,8 @@ class IFSsimulator(): ############### calculate the earthshine and zodiacal noise ,new code 2023.11.1 ############ ############### calculate the earthshine and zodiacal noise ,new code 2023.11.1 ############ ############### ############### self.log.info('Real telescope pointing in Ra = %f, Dec = %f' % (self.information['ra_pnt0'], self.information['dec_pnt0'])) self.log.info('Real telescope pointing in Ra = %f, Dec = %f' % ( self.information['ra_pnt0'], self.information['dec_pnt0'])) ra = self.information['ra_pnt0'] ra = self.information['ra_pnt0'] dec = self.information['dec_pnt0'] dec = self.information['dec_pnt0'] Loading @@ -4905,11 +4904,13 @@ class IFSsimulator(): if self.appbianpai: if self.appbianpai: sn = self.simnumber-1 sn=self.simnumber-1; x_sat = float(self.bianpai_data['x_sat'] x_sat = float(self.bianpai_data['x_sat'][sn*5+self.exptime_start_index]) [sn*5+self.exptime_start_index]) y_sat = float(self.bianpai_data['y_sat'][sn*5+self.exptime_start_index]) y_sat = float(self.bianpai_data['y_sat'] z_sat = float(self.bianpai_data['z_sat'][sn*5+self.exptime_start_index]) [sn*5+self.exptime_start_index]) z_sat = float(self.bianpai_data['z_sat'] [sn*5+self.exptime_start_index]) ### ### else: else: Loading Loading @@ -4997,14 +4998,20 @@ class IFSsimulator(): ############## doppler effect to photons.wavelength ############# ############## doppler effect to photons.wavelength ############# if self.appbianpai: if self.appbianpai: sn=self.simnumber-1; sn = self.simnumber-1 x_sat = float(self.bianpai_data['x_sat'][sn*5+self.exptime_start_index]) x_sat = float(self.bianpai_data['x_sat'] y_sat = float(self.bianpai_data['y_sat'][sn*5+self.exptime_start_index]) [sn*5+self.exptime_start_index]) z_sat = float(self.bianpai_data['z_sat'][sn*5+self.exptime_start_index]) y_sat = float(self.bianpai_data['y_sat'] [sn*5+self.exptime_start_index]) vx_sat = float(self.bianpai_data['vx_sat'][sn*5+self.exptime_start_index]) z_sat = float(self.bianpai_data['z_sat'] vy_sat = float(self.bianpai_data['vy_sat'][sn*5+self.exptime_start_index]) [sn*5+self.exptime_start_index]) vz_sat = float(self.bianpai_data['vz_sat'][sn*5+self.exptime_start_index]) vx_sat = float( self.bianpai_data['vx_sat'][sn*5+self.exptime_start_index]) vy_sat = float( self.bianpai_data['vy_sat'][sn*5+self.exptime_start_index]) vz_sat = float( self.bianpai_data['vz_sat'][sn*5+self.exptime_start_index]) else: else: Loading Loading @@ -5033,15 +5040,21 @@ class IFSsimulator(): ################################################# ################################################# if self.appbianpai: if self.appbianpai: sn=self.simnumber-1; sn = self.simnumber-1 p1x = float(self.bianpai_data['x_sat'][sn*5+self.exptime_end_index]) p1x = float(self.bianpai_data['x_sat'] p1y = float(self.bianpai_data['y_sat'][sn*5+self.exptime_end_index]) [sn*5+self.exptime_end_index]) p1z = float(self.bianpai_data['z_sat'][sn*5+self.exptime_end_index]) p1y = float(self.bianpai_data['y_sat'] [sn*5+self.exptime_end_index]) p1vx = float(self.bianpai_data['vx_sat'][sn*5+self.exptime_end_index]) p1z = float(self.bianpai_data['z_sat'] p1vy = float(self.bianpai_data['vy_sat'][sn*5+self.exptime_end_index]) [sn*5+self.exptime_end_index]) p1vz = float(self.bianpai_data['vz_sat'][sn*5+self.exptime_end_index]) p1vx = float(self.bianpai_data['vx_sat'] [sn*5+self.exptime_end_index]) p1vy = float(self.bianpai_data['vy_sat'] [sn*5+self.exptime_end_index]) p1vz = float(self.bianpai_data['vz_sat'] [sn*5+self.exptime_end_index]) else: else: Loading @@ -5052,7 +5065,8 @@ class IFSsimulator(): t2jd = time2jd(t2) t2jd = time2jd(t2) if self.orbit_pars[-1, 0] < t2jd: # orbit parameters are not in currenct txt file # orbit parameters are not in currenct txt file if self.orbit_pars[-1, 0] < t2jd: self.orbit_file_num = self.orbit_file_num+1 self.orbit_file_num = self.orbit_file_num+1 fn = self.information['dir_path'] + \ fn = self.information['dir_path'] + \ 'IFS_inputdata/TianCe/orbit20160925/' + \ 'IFS_inputdata/TianCe/orbit20160925/' + \ Loading Loading @@ -5394,7 +5408,6 @@ class IFSsimulator(): energy_blue = energy_blue+sum(photons_blue.flux) energy_blue = energy_blue+sum(photons_blue.flux) ################# ################# # fits.writeto('blueImg.fits',blue_img.array,overwrite=True) # fits.writeto('blueImg.fits',blue_img.array,overwrite=True) Loading Loading @@ -5856,9 +5869,6 @@ class IFSsimulator(): self.debug = self.information['debug'] self.debug = self.information['debug'] if self.information['exptime'] > 2000 or self.information['exptime'] < 0: if self.information['exptime'] > 2000 or self.information['exptime'] < 0: self.log.error( self.log.error( 'exptime value error, it shoub be in [0, 2000]!') 'exptime value error, it shoub be in [0, 2000]!') Loading @@ -5885,27 +5895,28 @@ class IFSsimulator(): ################################################################### ################################################################### if self.appbianpai: if self.appbianpai: ### load yunxingbianpai csv file # load yunxingbianpai csv file ############ load star data catlog ##################### ############ load star data catlog ##################### starcat = self.information['bianpai_file'] starcat = self.information['bianpai_file'] ##starcat='selection_20230517_concat.fits' # starcat='selection_20230517_concat.fits' ################################################### ################################################### self.log.info('Stat catlog file name is %s' % (starcat)) self.log.info('Stat catlog file name is %s' % (starcat)) ########################################## ########################################## df=pd.read_csv(self.information['dir_path']+'IFS_inputdata/TianCe/'+starcat) df = pd.read_csv( self.information['dir_path']+'IFS_inputdata/TianCe/'+starcat) ################################################################### ################################################################### sn=self.simnumber-1; sn = self.simnumber-1 arr=np.array(df['time'][sn*5:sn*5+5]); arr = np.array(df['time'][sn*5:sn*5+5]) self.exptime_start_jd,self.exptime_start_index=find_min(arr); self.exptime_start_jd, self.exptime_start_index = find_min(arr) self.exptime_end_jd, self.exptime_end_index =find_max(arr); self.exptime_end_jd, self.exptime_end_index = find_max(arr) ###self.earthshine_theta=df['earth_angle'][sn*5+index] # in degree # self.earthshine_theta=df['earth_angle'][sn*5+index] # in degree self.dt = jd2time(self.exptime_start_jd); self.dt = jd2time(self.exptime_start_jd) self.bianpai_data=df; self.bianpai_data = df ################################################################## ################################################################## else: else: Loading @@ -5917,8 +5928,6 @@ class IFSsimulator(): now_dt = datetime.utcnow() now_dt = datetime.utcnow() now_jd = time2jd(now_dt) now_jd = time2jd(now_dt) for k in range(1, 50, 1): for k in range(1, 50, 1): # fn=father_path+'/IFS_inputdata/TianCe/orbit20160925/'+str(k)+'.txt'; # fn=father_path+'/IFS_inputdata/TianCe/orbit20160925/'+str(k)+'.txt'; Loading Loading @@ -5958,7 +5967,6 @@ class IFSsimulator(): ################################################################## ################################################################## ################################################################## ################################################################## self.TianCe_day = self.dt.strftime("%Y-%m-%d") self.TianCe_day = self.dt.strftime("%Y-%m-%d") self.TianCe_exp_start = dt2hmd(self.dt) self.TianCe_exp_start = dt2hmd(self.dt) Loading Loading @@ -6182,8 +6190,8 @@ def runIFSsim(sourcein, configfile, dir_path, result_path, iLoop, debug, applyho simulate = dict() simulate = dict() simulate[iLoop] = IFSsimulator(configfile) simulate[iLoop] = IFSsimulator(configfile) simulate[iLoop].configure(sourcein, dir_path, result_path, iLoop, debug, applyhole) # load the configfile; simulate[iLoop].configure(sourcein, dir_path, result_path, iLoop, debug, applyhole) # load the configfile; if applyhole == 'yes' and sourcein == 'LAMP': if applyhole == 'yes' and sourcein == 'LAMP': simulate[iLoop].information['holemask'] = 'yes' simulate[iLoop].information['holemask'] = 'yes' Loading
tests/test_ifs_sim.py +80 −76 Original line number Original line Diff line number Diff line Loading @@ -15,7 +15,7 @@ from csst_ifs_sim import csst_ifs_sim import sys import sys ### sys.path.append('IFS_git/csst_ifs_sim/csst_ifs_sim') # sys.path.append('IFS_git/csst_ifs_sim/csst_ifs_sim') class TestDemoFunction(unittest.TestCase): class TestDemoFunction(unittest.TestCase): Loading Loading @@ -49,7 +49,8 @@ class TestDemoFunction(unittest.TestCase): result_path = dir_path+'ifs_sim_result' result_path = dir_path+'ifs_sim_result' csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug,'no') csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'no') self.assertEqual( self.assertEqual( 1, 1, 1, 1, Loading Loading @@ -86,7 +87,8 @@ class TestDemoFunction(unittest.TestCase): debug = True debug = True result_path = dir_path+'ifs_sim_result' result_path = dir_path+'ifs_sim_result' csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug,'no') csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'no') self.assertEqual( self.assertEqual( 1, 1, 1, 1, Loading Loading @@ -123,7 +125,8 @@ class TestDemoFunction(unittest.TestCase): debug = True debug = True result_path = dir_path+'ifs_sim_result' result_path = dir_path+'ifs_sim_result' csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug,'no') csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'no') self.assertEqual( self.assertEqual( 1, 1, 1, 1, Loading Loading @@ -161,7 +164,8 @@ class TestDemoFunction(unittest.TestCase): result_path = dir_path+'ifs_sim_result' result_path = dir_path+'ifs_sim_result' csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug,'no') csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'no') self.assertEqual( self.assertEqual( 1, 1, 1, 1, Loading Loading @@ -198,7 +202,8 @@ class TestDemoFunction(unittest.TestCase): debug = True debug = True result_path = dir_path+'ifs_sim_result' result_path = dir_path+'ifs_sim_result' csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug,'yes') csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'yes') self.assertEqual( self.assertEqual( 1, 1, 1, 1, "case 5: sim passes.", "case 5: sim passes.", Loading Loading @@ -235,10 +240,9 @@ class TestDemoFunction(unittest.TestCase): result_path = dir_path+'ifs_sim_result' result_path = dir_path+'ifs_sim_result' csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'no') csst_ifs_sim.runIFSsim(sourcein, configfile, dir_path, result_path, 1, debug, 'no') self.assertEqual( self.assertEqual( 1, 1, 1, 1, "case 6: sim passes.", "case 6: sim passes.", ) )