Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
csst-sims
csst_ifs_sim
Commits
d6274e12
Commit
d6274e12
authored
May 11, 2024
by
Yan Zhaojun
Browse files
debug
parent
91e3a59d
Pipeline
#4461
failed with stage
in 0 seconds
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
csst_ifs_sim/csst_ifs_sim.py
View file @
d6274e12
...
...
@@ -5,6 +5,27 @@ Created on Thu Apr 11 15:18:57 2024
@author: yan
"""
from
astropy.utils.iers
import
conf
import
galsim
from
scipy.integrate
import
simps
import
pandas
as
pd
from
datetime
import
datetime
,
timedelta
from
astropy.coordinates
import
get_sun
from
astropy.time
import
Time
from
astropy
import
units
as
u
from
astropy.coordinates
import
SkyCoord
,
EarthLocation
from
scipy
import
interpolate
import
numpy
as
np
import
scipy.io
as
sio
from
astropy.io
import
fits
from
scipy.signal
import
fftconvolve
from
scipy
import
ndimage
import
cmath
import
configparser
as
ConfigParser
from
support
import
IFSinstrumentModel
from
support
import
cosmicrays
from
support
import
logger
as
lg
from
CTI
import
CTI
import
os
from
scipy.interpolate
import
interp1d
import
astropy.coordinates
as
coord
...
...
@@ -15,27 +36,6 @@ import sys
# from csst_ifs_sim.support import logger as lg
# from csst_ifs_sim.CTI import CTI
sys
.
path
.
append
(
'./csst_ifs_sim'
)
from
CTI
import
CTI
from
support
import
logger
as
lg
from
support
import
cosmicrays
from
support
import
IFSinstrumentModel
import
configparser
as
ConfigParser
import
cmath
from
scipy
import
ndimage
from
scipy.signal
import
fftconvolve
from
astropy.io
import
fits
import
scipy.io
as
sio
import
numpy
as
np
from
scipy
import
interpolate
from
astropy.coordinates
import
SkyCoord
,
EarthLocation
from
astropy
import
units
as
u
from
astropy.time
import
Time
from
astropy.coordinates
import
get_sun
from
datetime
import
datetime
,
timedelta
import
pandas
as
pd
from
scipy.integrate
import
simps
import
galsim
from
astropy.utils.iers
import
conf
conf
.
auto_max_age
=
None
"""
...
...
@@ -56,10 +56,7 @@ The approximate sequence of events in the simulator is as follows:
#. Read in another file containing charge trap definitions (for CTI modelling).
#. Read in a file defining the cosmic rays (trail lengths and
cumulative distributions).
#. Load the wavefront aberration data used to calculate PSF with defined
wavelength and field of view.
#. Apply calibration unit flux to mimic flat field exposures [optional].
#. Load the wavefront aberration data used to calculate PSF .
#. Apply a multiplicative flat-field map to emulate pixel-to-pixel
non-uniformity.
#. Add cosmic ray tracks onto the CCD with random positions but known
...
...
@@ -67,12 +64,11 @@ distribution.
#. Apply detector charge bleeding in column direction.
#. Add constant dark current and background light from Zodiacal
light.
#. Include spatially uniform scattered light to the pixel grid.
#. Add photon (Poisson) noise
#. Add cosmetic defects from an input file.
#. Add pre- and overscan regions in the serial direction.
#. Apply the CDM03 radiation damage model
[optional]
.
#. Apply
CCD273
non-linearity model to the pixel data.
#. Apply the CDM03 radiation damage model.
#. Apply non-linearity model to the pixel data.
#. Add readout noise selected from a Gaussian distribution.
#. Convert from electrons to ADUs using a given gain factor.
#. Add a given bias level and discretise the counts
...
...
@@ -82,17 +78,17 @@ 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
please report any weird or inconsistent simulations to the author.
Note:: This class is Python 3 compatible.
2023.06.13 , add new lamp hole simulation
2023.12.26
add date frame transfer effect and software version
2023.12.26 add date frame transfer effect and software version
2024.1.19 add multiple exposure mode function;
2024.3.20 --- update the fits header as defined order 0 data format
2024.5.10 ---updata and correct the bug of frame transfer effect simulation
"""
#### functions definition #####
def
transRaDec2D
(
ra
,
dec
):
"""
...
...
@@ -116,52 +112,6 @@ def transRaDec2D(ra, dec):
return
np
.
array
([
x1
,
y1
,
z1
])
###############################################################################
# def flux2ill(wave, flux):
# """
# Parameters
# ----------
# wave : TYPE
# DESCRIPTION.
# flux : TYPE
# DESCRIPTION.
# Returns
# -------
# E : TYPE
# DESCRIPTION.
# """
# # erg/s/cm^2/A/arcsec^2 to W/m^2
# # 1 W/m^2/sr/μm = 0.10 erg/cm^2/s/sr/A
# # 1 sr = 1 rad^2 = 4.25452e10 arcsec^2
# # 1 J/s = 1 W
# # 1 J = 10^7 erg
# # convert erg/s/cm^2/A/arcsec^2 to erg/s/cm^2/A/sr
# flux1 = flux / (1/4.25452e10)
# # convert erg/s/cm^2/A/sr to W/m^2/sr/um
# flux2 = flux1 * 10
# # 对接收面积积分,输出单位 W/m^2/nm
# D = 2 # meter
# f = 28 # meter
# flux3 = flux2 * np.pi * D**2 / 4 / f**2 / 10**3
# # 对波长积分
# f = interp1d(wave, flux3)
# wave_interp = np.arange(3800, 7800)
# flux3_interp = f(wave_interp)
# # 输出单位 W/m^2
# delta_lamba = 0.1 # nm
# E = np.sum(flux3_interp * delta_lamba)
# return E
################################################################
...
...
@@ -214,7 +164,8 @@ def ill2flux(path, E):
##############################################################
##########################################################################################
##############################################################################
def
earth_angle
(
time_jd
,
x_sat
,
y_sat
,
z_sat
,
ra_obj
,
dec_obj
):
"""
...
...
@@ -268,6 +219,7 @@ def earth_angle(time_jd, x_sat, y_sat, z_sat, ra_obj, dec_obj):
#####################################################################
class
StrayLight
(
object
):
def
__init__
(
self
,
path
,
jtime
=
2460843.
,
sat
=
np
.
array
([
0
,
0
,
0
]),
radec
=
np
.
array
([
0
,
0
])):
...
...
@@ -311,6 +263,7 @@ class StrayLight(object):
self
.
slcdll
.
Init
(
str
.
encode
(
self
.
deFn
),
str
.
encode
(
self
.
PSTFn
),
str
.
encode
(
self
.
RFn
),
str
.
encode
(
self
.
ZolFn
))
############################################################################
def
caculateStarLightFilter
(
self
,
filter
=
'i'
):
"""
...
...
@@ -326,7 +279,8 @@ class StrayLight(object):
DESCRIPTION.
"""
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
...
...
@@ -349,6 +303,7 @@ class StrayLight(object):
return
max
(
band_star_e1
,
band_star_e2
)
###############################################################################
def
caculateEarthShineFilter
(
self
,
filter
=
'i'
):
"""
#
...
...
@@ -364,7 +319,8 @@ class StrayLight(object):
DESCRIPTION.
"""
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
...
...
@@ -377,7 +333,7 @@ class StrayLight(object):
earth_e1
=
(
ctypes
.
c_double
*
7
)()
self
.
slcdll
.
EarthShine
(
self
.
jtime
,
sat
,
ob
,
py1
,
earth_e1
)
# e[7]代表7个波段的照度
# e[7]代表7个波段的照度
earth_e2
=
(
ctypes
.
c_double
*
7
)()
self
.
slcdll
.
EarthShine
(
self
.
jtime
,
sat
,
ob
,
py2
,
earth_e2
)
...
...
@@ -391,29 +347,6 @@ class StrayLight(object):
###############################################################################
# def str2time(strTime):
# """
# Parameters
# ----------
# strTime : TYPE
# DESCRIPTION.
# Returns
# -------
# TYPE
# DESCRIPTION.
# """
# if len(strTime) > 20: # 暂时未用到
# msec = int(float('0.'+strTime[20:])*1000000) # 微秒
# str2 = strTime[0:19]+' '+str(msec)
# return datetime.strptime(str2, '%Y %m %d %H %M %S %f')
# datetime类转mjd
##########################################################################
def
time2mjd
(
dateT
):
"""
...
...
@@ -436,6 +369,8 @@ def time2mjd(dateT):
return
mjd
+
mjd_s
/
86400.0
###########################################################################
def
time2jd
(
dateT
):
"""
...
...
@@ -460,6 +395,7 @@ def time2jd(dateT):
# mjd转datetime类
#############################################################################
def
mjd2time
(
mjd
):
"""
...
...
@@ -479,6 +415,8 @@ def mjd2time(mjd):
return
t0
+
timedelta
(
days
=
mjd
)
#############################################################################
def
jd2time
(
jd
):
"""
...
...
@@ -500,6 +438,8 @@ def jd2time(jd):
# mjd和jd互转
############################################################################
def
mjd2jd
(
mjd
):
"""
...
...
@@ -518,6 +458,8 @@ def mjd2jd(mjd):
return
mjd
+
2400000.5
###########################################################################
def
jd2mjd
(
jd
):
"""
...
...
@@ -536,6 +478,8 @@ def jd2mjd(jd):
return
jd
-
2400000.5
##########################################################################
def
dt2hmd
(
dt
):
"""
...
...
@@ -573,36 +517,9 @@ def dt2hmd(dt):
return
str_h
+
':'
+
str_m
+
':'
+
str_d
###############################################################################
# def float2char(a, z):
# """
# Parameters
# ----------
# a : TYPE
# DESCRIPTION.
# z : TYPE
# DESCRIPTION.
# Returns
# -------
# TYPE
# DESCRIPTION.
# """
# # a is input float value
# # transfer float a to chars and save z bis
# b = str(a)
# n = len(b)
# if z >= n:
# return b
# else:
# return b[:z]
###############################################################################
def
deg2HMS
(
ra0
,
dec0
):
"""
...
...
@@ -715,6 +632,8 @@ def beta_angle(x_sat, y_sat, z_sat, vx_sat, vy_sat, vz_sat, ra_obj, dec_obj):
###############################################################################
##########################################################
def
LSR_velocity
(
ra
,
dec
,
velocity
,
Obstime
):
"""
...
...
@@ -822,42 +741,7 @@ def centroid(data):
return
float
(
cx
),
float
(
cy
)
###############################################################################
# def centroidN(data):
# """
# Parameters
# ----------
# data : TYPE
# DESCRIPTION.
# Returns
# -------
# cx : TYPE
# DESCRIPTION.
# cy : TYPE
# DESCRIPTION.
# """
# '''
# calculate the centroid of the input two-dimentional image data
# Parameters
# ----------
# data : input image.
# Returns
# -------
# cx: the centroid column number, in horizontal direction definet in python image show
# cy: the centroid row number , in vertical direction
# '''
# ###
# from scipy import ndimage
# cy, cx = ndimage.center_of_mass(data)
# return cx, cy
####################################################################
def
SpecCube2photon
(
data
,
wave
):
"""
...
...
@@ -891,6 +775,8 @@ def SpecCube2photon(data, wave):
######################################################################
######################################################################
def
mag2flux
(
starmag
,
lam
):
"""
...
...
@@ -927,6 +813,7 @@ def mag2flux(starmag, lam):
###############################################################################
def
flux2photons
(
flux
,
lam
):
"""
...
...
@@ -954,6 +841,8 @@ def flux2photons(flux, lam):
return
photonu
###############################################################################
def
fftrange
(
n
,
dtype
=
float
):
"""
...
...
@@ -975,6 +864,8 @@ def fftrange(n, dtype=float):
return
np
.
arange
(
-
n
//
2
,
-
n
//
2
+
n
,
dtype
=
dtype
)
###############################################################################
def
dft2
(
ary
,
Q
,
samples
,
shift
=
None
):
"""
...
...
@@ -1041,6 +932,8 @@ def dft2(ary, Q, samples, shift=None):
return
out
##############################################################################
###############################################################################
def
anySampledPSFnew
(
wavefront
,
pupil
,
Q
,
sizeout
):
"""
...
...
@@ -1091,7 +984,7 @@ def anySampledPSFnew(wavefront, pupil, Q, sizeout):
cx
,
cy
=
centroid
(
psfout
)
Nt
=
sizeout
# for convolve method
psf
=
ndimage
.
shift
(
psfout
,
[
Nt
/
2
-
cy
-
1
,
Nt
/
2
-
cx
-
1
],
order
=
1
,
mode
=
'nearest'
)
...
...
@@ -1103,6 +996,7 @@ def anySampledPSFnew(wavefront, pupil, Q, sizeout):
##############################################################################
def
get_dx_dy_blue
(
wave
):
"""
...
...
@@ -1136,6 +1030,7 @@ def get_dx_dy_blue(wave):
return
dx
,
dy
##############################################################################
def
get_dx_dy_red
(
wave
):
"""
...
...
@@ -1168,6 +1063,7 @@ def get_dx_dy_red(wave):
##############################################################################################
def
getSpectrum
(
Spectrum0
,
lam
,
sigma
):
"""
...
...
@@ -1241,7 +1137,7 @@ class IFSsimulator():
self
.
information
.
update
(
dict
(
quadrant
=
int
(
0
),
ccdx
=
int
(
0
),
ccdy
=
int
(
0
),
ccdxgap
=
1.643
,
ccdygap
=
8.116
,
bluesize
=
4000
,
...
...
@@ -1286,11 +1182,10 @@ class IFSsimulator():
self
.
config
.
read_file
(
open
(
self
.
configfile
))
#
self.log.info(self.information)
self
.
log
.
info
(
self
.
information
)
###############################################################################
def
processConfigs
(
self
):
"""
Processes configuration information and save the information to a dictionary self.information.
...
...
@@ -1334,30 +1229,18 @@ class IFSsimulator():
self
.
section
,
'save_cosmicrays'
)
self
.
sky_noise
=
self
.
config
.
getboolean
(
self
.
section
,
'sky_noise'
)
self
.
nonlinearity
=
self
.
config
.
getboolean
(
self
.
section
,
'nonlinearity'
)
self
.
flatfieldM
=
self
.
config
.
getboolean
(
self
.
section
,
'flatfieldM'
)
self
.
readoutNoise
=
self
.
config
.
getboolean
(
self
.
section
,
'readoutnoise'
)
self
.
intscale
=
True
###self.config.getboolean(self.section, 'intscale')
self
.
intscale
=
True
######################################################################
# 3
self
.
information
[
'variablePSF'
]
=
False
self
.
booleans
=
dict
(
nonlinearity
=
self
.
nonlinearity
,
...
...
@@ -1372,8 +1255,6 @@ class IFSsimulator():
intscale
=
self
.
intscale
,
save_cosmicrays
=
self
.
save_cosmicrays
)
#####################################################################
############################################################################
def
_createEmpty
(
self
):
...
...
@@ -1393,6 +1274,7 @@ class IFSsimulator():
##############################################################################
##############################################################################
def
zodiacal
(
self
,
ra
,
dec
,
time
):
"""
...
...
@@ -1489,7 +1371,6 @@ class IFSsimulator():
# def smoothingWithChargeDiffusion(self, image, sigma=(0.32, 0.32)):
# """
# Parameters
# ----------
# image : TYPE
...
...
@@ -1540,7 +1421,7 @@ class IFSsimulator():
"""
self
.
log
.
info
(
'Reading in cosmic ray information from %s and %s'
%
(
self
.
information
[
'cosmicraylengths'
],
self
.
information
[
'cosmicraydistance'
]))
#
###
print(self.information)
# print(self.information)
crLengths
=
np
.
loadtxt
(
self
.
information
[
'dir_path'
]
+
self
.
information
[
'cosmicraylengths'
])
...
...
@@ -1551,88 +1432,6 @@ class IFSsimulator():
cr_v
=
crDists
[:,
0
],
cr_cde
=
crDists
[:,
1
],
cr_cden
=
np
.
shape
(
crDists
)[
0
])
###############################################################################
# def _writeFITSfile(self, image, filename):
# """
# :param image: image array to save
# :type image: ndarray
# :param filename: name of the output file, e.g. file.fits
# :type filename: str
# :return: None
# """
# if os.path.isfile(filename):
# os.remove(filename)
# # create a new FITS file, using HDUList instance
# ofd = fits.HDUList(fits.PrimaryHDU())
# # new image HDU
# hdu = fits.ImageHDU(data=image)
# # update and verify the header
# hdu.header.add_history('Created by IFSsim at %s' %
# datetime.isoformat(datetime.utcnow()))
# hdu.verify('fix')
# ofd.append(hdu)
# # write the actual file
# ofd.writeto(filename)
###############################################################################
# def writeFITSfile(self, data, filename, unsigned16bit=False):
# """
# Writes out a simple FITS file.
# :param data: data to be written
# :type data: ndarray
# :param filename: name of the output file
# :type filename: str
# :param unsigned16bit: whether to scale the data using bzero=32768
# :type unsigned16bit: bool
# :return: None
# """
# if os.path.isfile(filename):
# os.remove(filename)
# # create a new FITS file, using HDUList instance
# ofd = fits.HDUList(fits.PrimaryHDU())
# # new image HDU
# hdu = fits.ImageHDU(data=data)
# # add input keywords to the header
# for key, value in self.information.items():
# # truncate long keys
# if len(key) > 8:
# key = key[:7]
# try:
# hdu.header.set(key.upper(), value)
# except:
# try:
# hdu.header.set(key.upper(), str(value))
# except:
# pass
# # write booleans
# for key, value in self.booleans.items():
# # truncate long keys
# if len(key) > 8:
# key = key[:7]
# hdu.header.set(key.upper(), str(value), 'Boolean Flags')
# # update and verify the header
# hdu.header.add_history(
# 'This is an itermediate data product no the final output!')
# hdu.verify('fix')
# ofd.append(hdu)
# # write the actual file
# ofd.writeto(filename)
###############################################################################
def
configure
(
self
,
simnumber
):
"""
...
...
@@ -1826,94 +1625,11 @@ class IFSsimulator():
self
.
maskSlit
=
maskSlit
######################################################################
##############################################################################
# def generateflat(self, ave=1.0, sigma=0.01):
# """
# Parameters
# ----------
# ave : TYPE, optional
# DESCRIPTION. The default is 1.0.
# sigma : TYPE, optional
# DESCRIPTION. The default is 0.01.
# Returns
# -------
# TYPE
# DESCRIPTION.
# TYPE
# DESCRIPTION.
# """
# """
# Creates a flat field image with given properties.
# :return: flat field image
# :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)
# np.random.seed(5*self.simnumber)
# self.flat_b = np.random.normal(loc=ave, scale=sigma, size=(2048, 4096))
# np.random.seed(55*self.simnumber)
# self.flat_r = np.random.normal(loc=ave, scale=sigma, size=(3072, 6144))
# s1 = self.flat_b
# hdu1 = fits.PrimaryHDU(s1)
# hdu1.header.set('sigma', sigma)
# dtime = datetime.utcnow().strftime('%Y -%m -%d %H: %M: %S')
# hdu1.header.add_history(
# 'flat image of blue channel is generated on :'+dtime)
# f1 = '../flat_Blue_'+str(sigma)+'.fits'
# fits.writeto(f1, s1, header=hdu1.header, overwrite=True)
# s2 = self.flat_r
# hdu1 = fits.PrimaryHDU(s2)
# hdu1.header.set('sigma', sigma)
# dtime = datetime.utcnow().strftime('%Y -%m -%d %H: %M: %S')
# hdu1.header.add_history(
# 'flat image of red channel is generated on :'+dtime)
# f2 = '../flat_Red_'+str(sigma)+'.fits'
# fits.writeto(f2, s2, header=hdu1.header, overwrite=True)
# return self.flat_b, self.flat_r
##########################################################################
# def addLampFlux(self):
# """
# Returns
# -------
# None.
# """
# """
# Include flux from the calibration source.
# """
# self.image_b += fits.getdata(self.information['flatflux'])
# self.image_r += fits.getdata(self.information['flatflux'])
# self.log.info('Flux from the calibration unit included (%s)' %
# self.information['flatflux'])
#############################################################################
#############################################################################
def
MakeFlatMatrix
(
self
,
img
,
seed
):
"""
Parameters
----------
...
...
@@ -1949,7 +1665,7 @@ class IFSsimulator():
def
getFrameTransferImg
(
self
):
"""
Returns
-------
...
...
@@ -1971,17 +1687,18 @@ class IFSsimulator():
# blue channle
b_4
=
np
.
sum
(
self
.
image_b
[
0
:
1024
,
0
:
2048
],
axis
=
0
)
#
#####
flip right to left of part3 and part2
temp_b_3
=
np
.
fliplr
(
self
.
image_b
[
0
:
1024
,
2048
:
4096
])
#
# left to right
# flip right to left of part3 and part2
temp_b_3
=
np
.
fliplr
(
self
.
image_b
[
0
:
1024
,
2048
:
4096
])
# left to right
b_3
=
np
.
sum
(
temp_b_3
,
axis
=
0
)
temp_b_2
=
np
.
fliplr
(
self
.
image_b
[
1024
:
1024
+
1024
,
2048
:
2048
+
2048
])
## left to right
temp_b_2
=
np
.
fliplr
(
self
.
image_b
[
1024
:
1024
+
1024
,
2048
:
2048
+
2048
])
# left to right
b_2
=
np
.
sum
(
temp_b_2
,
axis
=
0
)
b_1
=
np
.
sum
(
self
.
image_b
[
1024
:
1024
+
1024
,
0
:
2048
],
axis
=
0
)
####
for
k
in
range
(
1024
+
320
):
# part
self
.
frame_b_4
[
k
,
:]
+=
b_4
*
0.09216
/
self
.
information
[
'exptime'
]
...
...
@@ -1992,21 +1709,19 @@ class IFSsimulator():
###################
# red channle
r_4
=
np
.
sum
(
self
.
image_r
[
0
:
1536
,
0
:
3072
],
axis
=
0
)
###### flip right to left of part3 and part2
temp_r_3
=
np
.
fliplr
(
self
.
image_r
[
0
:
1536
,
3072
:
6144
])
## left to right
# flip right to left of part3 and part2
temp_r_3
=
np
.
fliplr
(
self
.
image_r
[
0
:
1536
,
3072
:
6144
])
# left to right
r_3
=
np
.
sum
(
temp_r_3
,
axis
=
0
)
temp_r_2
=
np
.
fliplr
(
self
.
image_r
[
1536
:
1536
+
1536
,
3072
:
6144
])
## left to right
temp_r_2
=
np
.
fliplr
(
self
.
image_r
[
1536
:
1536
+
1536
,
3072
:
6144
])
# left to right
r_2
=
np
.
sum
(
temp_r_2
,
axis
=
0
)
#r_3 = np.sum(self.image_r[0:1536, 3072:6144], axis=0)
#r_2 = np.sum(self.image_r[1536:1536+1536, 3072:6144], axis=0)
r_1
=
np
.
sum
(
self
.
image_r
[
1536
:
1536
+
1536
,
0
:
3072
],
axis
=
0
)
for
k
in
range
(
1536
+
320
):
...
...
@@ -2020,7 +1735,7 @@ class IFSsimulator():
###############################################################################
def
applyflatfield
(
self
,
simnumber
):
"""
Parameters
----------
...
...
@@ -2058,7 +1773,7 @@ class IFSsimulator():
###############################################################################
def
addCosmicRays
(
self
,
idk
):
"""
Parameters
----------
...
...
@@ -2121,75 +1836,12 @@ class IFSsimulator():
##########################################################
#########################################################################
# def addReadoutTrails(self):
# """
# Returns
# -------
# None.
# """
# """
# Add readout trails resulting from reading out the shutter open.
# Quadrants assumed to be numbered:
# 2 3
# 0 1
# """
# flux_ratio = self.information['readouttime'] / float(
# self.information['bluesize']) / self.information['exptime']
# # make a copy, this will be updated
# data = self.image_b.copy()
# # Amplifier at different positions depending on the quadrant number !
# # left side is 0, 2 and right side is 1, 3 starting from bottom i.e.
# # going clock wise from lower left we have 0, 2, 3, and 1 quadrants.
# if self.information['quadrant'] in (2, 3):
# data = data[::-1, :]
# data_shift = data.copy() * flux_ratio
# size1, size2 = data.shape
# for i in range(1, size2, 1):
# data_shift2 = np.roll(data_shift, i, axis=0)
# data_shift2[:i, :] = 0.0
# data += data_shift2
# if self.information['quadrant'] in (2, 3):
# self.image_b = data[::-1, :]
# else:
# self.image_b = data
# flux_ratio = self.information['readouttime'] / float(
# self.information['redsize']) / self.information['exptime']
# # make a copy, this will be updated
# data = self.image_r.copy()
# # Amplifier at different positions depending on the quadrant number !
# # left side is 0, 2 and right side is 1, 3 starting from bottom i.e.
# # going clock wise from lower left we have 0, 2, 3, and 1 quadrants.
# if self.information['quadrant'] in (2, 3):
# data = data[::-1, :]
# data_shift = data.copy() * flux_ratio
# size1, size2 = data.shape
# for i in range(1, size2, 1):
# data_shift2 = np.roll(data_shift, i, axis=0)
# data_shift2[:i, :] = 0.0
# data += data_shift2
# if self.information['quadrant'] in (2, 3):
# self.image_r = data[::-1, :]
# else:
# self.image_r = data
##############################################################################
def
applyDarkCurrent
(
self
):
"""
Returns
-------
...
...
@@ -2238,60 +1890,11 @@ class IFSsimulator():
##############################################################################
# def applyCosmicBackground(self):
# """
# Returns
# -------
# None.
# """
# """
# Apply dark the cosmic background. Scales the background with the exposure time.
# Additionally saves the image without noise to a FITS file.
# """
# # add background
# bcgr = self.information['exptime'] * self.information['cosmic_bkgd']
# self.image_b += bcgr
# self.image_r += bcgr
# self.log.info('Added cosmic background = %f' % bcgr)
# if self.cosmicRays:
# self.imagenoCR_b += bcgr
# self.imagenoCR_r += bcgr
##########################################################################
# def applyScatteredLight(self):
# """
# Returns
# -------
# None.
# """
# """
# Adds spatially uniform scattered light to the image.
# """
# sl = self.information['exptime'] * self.information['scattered_light']
# self.image_b += sl
# self.image_r += sl
# self.log.info('Added scattered light = %f' % sl)
##############################################################################
def
applyPoissonNoise
(
self
):
"""
Returns
-------
...
...
@@ -2322,11 +1925,11 @@ class IFSsimulator():
self
.
image_r
+=
residual
##############################################################################
#####################################
##############################################################################
def
applyCosmetics
(
self
):
"""
Returns
-------
...
...
@@ -2399,7 +2002,7 @@ class IFSsimulator():
def
applyRadiationDamage
(
self
):
"""
Returns
-------
...
...
@@ -2415,13 +2018,11 @@ class IFSsimulator():
self
.
log
.
debug
(
'Starting to apply radiation damage model...'
)
# at this point we can give fake data...
cti
=
CTI
.
CDM03bidir
(
self
.
information
,
[],
log
=
self
.
log
)
#
##
here we need the right input data
# here we need the right input data
self
.
image_b
=
cti
.
applyRadiationDamage
(
self
.
image_b
.
copy
(
).
transpose
(),
iquadrant
=
self
.
information
[
'quadrant'
]).
transpose
()
self
.
log
.
info
(
'Radiation damage added.'
)
self
.
log
.
debug
(
'Starting to apply radiation damage model...'
)
# at this point we can give fake data...
...
...
@@ -2434,7 +2035,7 @@ class IFSsimulator():
def
applyNonlinearity
(
self
):
"""
Returns
-------
...
...
@@ -2460,7 +2061,7 @@ class IFSsimulator():
def
applyReadoutNoise
(
self
):
"""
Returns
-------
...
...
@@ -2497,7 +2098,6 @@ class IFSsimulator():
self
.
image_b
[
0
:
1024
+
overscan
,
2418
*
3
:
2418
*
3
+
2048
+
prescan
+
overscan
]
+=
np
.
random
.
normal
(
loc
=
0.0
,
scale
=
self
.
information
[
'rn2_b'
],
size
=
(
1344
,
2418
))
self
.
log
.
info
(
'readnoise added in blue channel'
)
# red zone 4 , OSH### 1536* 3072
...
...
@@ -2524,7 +2124,7 @@ class IFSsimulator():
def
appFrameTransferEffect
(
self
):
"""
Returns
-------
...
...
@@ -2583,7 +2183,7 @@ class IFSsimulator():
def
electrons2ADU
(
self
):
"""
Returns
-------
...
...
@@ -2628,7 +2228,7 @@ class IFSsimulator():
def
applyBias
(
self
):
"""
Returns
-------
...
...
@@ -2679,7 +2279,7 @@ class IFSsimulator():
###############################################################################
def
addPreOverScans
(
self
):
"""
Returns
-------
...
...
@@ -2735,7 +2335,7 @@ class IFSsimulator():
def
applyBleeding_yan
(
self
):
"""
Returns
-------
...
...
@@ -2837,7 +2437,7 @@ class IFSsimulator():
def
discretise
(
self
,
max
=
2
**
16
-
1
):
"""
Parameters
----------
...
...
@@ -2878,39 +2478,38 @@ class IFSsimulator():
##################################################################################################
def
applyImageShift
(
self
):
"""
# def applyImageShift(self):
# """
Returns
-------
None.
"""
# Returns
# -------
# None.
np
.
random
.
seed
(
9
*
self
.
simnumber
)
ud
=
np
.
random
.
random
()
# Choose a random rotation
dx
=
2
*
(
ud
-
0.5
)
*
self
.
information
[
'shiftmax'
]
# """
np
.
random
.
seed
(
9
9
*
self
.
simnumber
)
ud
=
np
.
random
.
random
()
# Choose a random rotation
d
y
=
2
*
(
ud
-
0.5
)
*
self
.
information
[
'shiftmax'
]
#
np.random.seed(9*self.simnumber)
#
ud = np.random.random() # Choose a random rotation
#
d
x
= 2 * (ud-0.5) * self.information['shiftmax']
self
.
image_b
=
ndimage
.
shift
(
self
.
image_b
.
copy
(),
[
dy
+
self
.
information
[
'shift_b_y'
],
dx
+
self
.
information
[
'shift_b_x'
]],
order
=
0
,
mode
=
'nearest'
)
self
.
image_r
=
ndimage
.
shift
(
self
.
image_r
.
copy
(),
[
dy
+
self
.
information
[
'shift_r_y'
],
dx
+
self
.
information
[
'shift_r_x'
]],
order
=
0
,
mode
=
'nearest'
)
# np.random.seed(99*self.simnumber)
# ud = np.random.random() # Choose a random rotation
# dy = 2 * (ud-0.5) * self.information['shiftmax']
# self.image_b = ndimage.shift(self.image_b.copy(), [
# dy+self.information['shift_b_y'], dx+self.information['shift_b_x']], order=0, mode='nearest')
# self.image_r = ndimage.shift(self.image_r.copy(), [
# dy+self.information['shift_r_y'], dx+self.information['shift_r_x']], order=0, mode='nearest')
self
.
log
.
info
(
'Applied image shifting to g r i channels.'
)
self
.
information
[
'ra'
]
=
dx
*
self
.
information
[
'pixel_size'
]
self
.
information
[
'dec'
]
=
dy
*
self
.
information
[
'pixel_size'
]
#
self.log.info('Applied image shifting to g r i channels.')
#
self.information['ra'] = dx*self.information['pixel_size']
#
self.information['dec'] = dy*self.information['pixel_size']
##############################################################################
# def applyImageRotate(self):
# """
# Returns
# -------
...
...
@@ -2939,9 +2538,10 @@ class IFSsimulator():
# 'Applied telescope rotation with angle (in degree)= %f.', angle)
###############################################################################
def
CCDreadout
(
self
):
"""
Returns
-------
...
...
@@ -3029,7 +2629,7 @@ class IFSsimulator():
def
writeOutputs
(
self
,
obnum
):
"""
Parameters
----------
...
...
@@ -3301,8 +2901,8 @@ class IFSsimulator():
hdu_b
.
header
[
'NAXIS1'
]
=
(
np
.
int32
(
1344
),
'length of first data axis'
)
hdu_b
.
header
[
'NAXIS2'
]
=
(
np
.
int32
(
9672
),
'length of second data axis'
)
if
self
.
information
[
'exposuretimes'
]
>
1
:
if
self
.
information
[
'exposuretimes'
]
>
1
:
hdu_b
.
header
[
'NAXIS3'
]
=
(
np
.
int32
(
self
.
information
[
'exposuretimes'
]),
'length of third data axis'
)
...
...
@@ -3681,8 +3281,8 @@ class IFSsimulator():
hdu_r
.
header
[
'NAXIS2'
]
=
(
np
.
int32
(
13768
),
'length of second data axis'
)
if
self
.
information
[
'exposuretimes'
]
>
1
:
if
self
.
information
[
'exposuretimes'
]
>
1
:
hdu_r
.
header
[
'NAXIS3'
]
=
(
np
.
int32
(
self
.
information
[
'exposuretimes'
]),
'length of third data axis'
)
...
...
@@ -3993,10 +3593,9 @@ class IFSsimulator():
###################################################################################
##################################################################################
def
CalskyNoise
(
self
,
lam
):
"""
Parameters
----------
...
...
@@ -4042,7 +3641,7 @@ class IFSsimulator():
def
sim_lamp_hole_img
(
self
,
exposuretime
):
"""
Parameters
----------
...
...
@@ -4217,8 +3816,7 @@ class IFSsimulator():
#######################################################
# energy=energy+img0[500-302:500+320,500-320:500+320].sum() ## calculate the slice image energy;
# CCD quantum efficiency
CCD_Qe_lam
=
np
.
interp
(
lam
,
self
.
CCD_Qe
[:,
0
],
self
.
CCD_Qe
[:,
1
])
...
...
@@ -4310,11 +3908,6 @@ class IFSsimulator():
photons_blue
.
addTo
(
blue_img
)
# zblue=blue_img.array
# energy_blue=energy_blue+sum(photons_blue.flux)
width_blue
=
width_blue
+
Width_lambda
/
32.0
# fits.writeto('blueImg.fits',blue_img.array,overwrite=True)
...
...
@@ -4380,7 +3973,7 @@ class IFSsimulator():
def
sim_sky_img
(
self
,
skyfitsfilename
,
skyRa
,
skyDec
,
sky_rot
,
telRa
,
telDec
,
exposuretime
,
simnumber
):
"""
Parameters
----------
...
...
@@ -4901,8 +4494,7 @@ class IFSsimulator():
energy_blue
=
energy_blue
+
sum
(
photons_blue
.
flux
)
width_blue
=
width_blue
+
deltalam
/
32.0
#################
# fits.writeto('blueImg.fits',blue_img.array,overwrite=True)
...
...
@@ -4965,7 +4557,7 @@ class IFSsimulator():
#################################################################################################
def
sim_calibration_img
(
self
,
exposuretime
,
source
):
"""
Parameters
----------
...
...
@@ -5144,18 +4736,6 @@ class IFSsimulator():
conv
[
conv
<
0.0
]
=
0.0
img0
=
conv
# temp=img0*maskSlice['31']*maskSlit['31']
# print(image0.array.sum())
# print(img1.sum())
# fits.writeto('img.fits',image0.array,overwrite=True)
# fits.writeto('convimg.fits',img0,overwrite=True)
#######
#######################################################
# energy=energy+img0[50-32:50+32,50-32:50+32].sum() ## calculate the slice image energy;
# CCD quantum efficiency
CCD_Qe_lam
=
np
.
interp
(
lam
,
self
.
CCD_Qe
[:,
0
],
self
.
CCD_Qe
[:,
1
])
...
...
@@ -5263,9 +4843,8 @@ class IFSsimulator():
photons_blue
.
y
=
photons_blue
.
y
/
self
.
pixelscale
+
\
dy_blue
+
self
.
slice_blue
[
'py'
][
k
]
#photons_blue.y =2048-photons_blue.y
#photons_blue.y =2048-photons_blue.y
blue_sensor
.
accumulate
(
photons_blue
,
blue_img
)
...
...
@@ -5287,8 +4866,7 @@ class IFSsimulator():
photons_red
.
y
=
photons_red
.
y
/
self
.
pixelscale
+
\
dy_red
+
self
.
slice_red
[
'py'
][
k
]
#photons_red.y =3072-photons_red.y
red_sensor
.
accumulate
(
photons_red
,
red_img
)
...
...
@@ -5348,7 +4926,7 @@ class IFSsimulator():
def
simulate
(
self
,
sourcein
,
simnumber
):
"""
Parameters
----------
...
...
@@ -5370,19 +4948,18 @@ class IFSsimulator():
:return: None
"""
self
.
source
=
sourcein
self
.
simnumber
=
simnumber
self
.
configure
(
simnumber
)
# print the configfile name and path;
self
.
debug
=
self
.
information
[
'debug'
]
self
.
debug
=
self
.
information
[
'debug'
]
self
.
dt
=
datetime
.
utcnow
()
if
self
.
source
==
'SCI'
or
self
.
source
==
'COMP'
:
if
simnumber
<=
50
and
simnumber
>
20
:
if
simnumber
<=
50
and
simnumber
>
20
:
self
.
information
[
'exptime'
]
=
300
if
simnumber
<=
100
and
simnumber
>
50
:
...
...
@@ -5536,20 +5113,18 @@ class IFSsimulator():
exptimes
=
self
.
information
[
'exposuretimes'
]
else
:
exptimes
=
1
self
.
information
[
'exposuretimes'
]
=
1
self
.
information
[
'exposuretimes'
]
=
1
# if self.debug:
# exptimes=1
if
exptimes
>
1
:
if
exptimes
>
1
:
self
.
image_b_N
=
np
.
zeros
((
1344
,
9672
,
exptimes
))
self
.
image_r_N
=
np
.
zeros
((
1856
,
13768
,
exptimes
))
else
:
self
.
image_b_N
=
np
.
zeros
((
1344
,
9672
))
self
.
image_r_N
=
np
.
zeros
((
1856
,
13768
))
for
idk
in
range
(
exptimes
):
...
...
@@ -5617,16 +5192,14 @@ class IFSsimulator():
print
(
'Applying cosmetics finished.......'
)
self
.
discretise
()
if
exptimes
>
1
:
if
exptimes
>
1
:
self
.
image_b_N
[:,
:,
idk
]
=
self
.
image_b
[:,
:].
copy
()
self
.
image_r_N
[:,
:,
idk
]
=
self
.
image_r
[:,
:].
copy
()
else
:
self
.
image_b_N
[:,
:]
=
self
.
image_b
[:,
:].
copy
()
self
.
image_r_N
[:,
:]
=
self
.
image_r
[:,
:].
copy
()
self
.
writeOutputs
(
simnumber
)
...
...
@@ -5650,7 +5223,7 @@ class IFSsimulator():
def
runIFSsim
(
sourcein
,
configfile
,
dir_path
,
iLoop
,
debug
,
applyhole
=
'no'
):
"""
Parameters
----------
...
...
@@ -5680,11 +5253,11 @@ def runIFSsim(sourcein, configfile, dir_path, iLoop, debug, applyhole='no'):
### dir_path = os.path.join(os.environ['UNIT_TEST_DATA_ROOT'], 'ifs_sim/')
simulate
[
iLoop
].
information
[
'dir_path'
]
=
dir_path
simulate
[
iLoop
].
information
[
'debug'
]
=
debug
simulate
[
iLoop
].
information
[
'debug'
]
=
debug
simulate
[
iLoop
].
simulate
(
sourcein
,
iLoop
)
return
1
############################## end ##########################################
\ No newline at end of file
############################## end ##########################################
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment