Skip to content
GitLab
Explore
Projects
Groups
Snippets
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
b4201fbc
Commit
b4201fbc
authored
11 months ago
by
Yan Zhaojun
Browse files
Options
Download
Email Patches
Plain Diff
more case test
parent
e985dd75
develop
main
master
No related merge requests found
Pipeline
#4002
passed with stage
in 0 seconds
Changes
1
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
csst_ifs_sim/csst_ifs_sim.py
+230
-230
csst_ifs_sim/csst_ifs_sim.py
with
230 additions
and
230 deletions
+230
-230
csst_ifs_sim/csst_ifs_sim.py
+
230
-
230
View file @
b4201fbc
...
@@ -117,50 +117,50 @@ def transRaDec2D(ra, dec):
...
@@ -117,50 +117,50 @@ def transRaDec2D(ra, dec):
###############################################################################
###############################################################################
def
flux2ill
(
wave
,
flux
):
#
def flux2ill(wave, flux):
"""
#
"""
Parameters
#
Parameters
----------
#
----------
wave : TYPE
#
wave : TYPE
DESCRIPTION.
#
DESCRIPTION.
flux : TYPE
#
flux : TYPE
DESCRIPTION.
#
DESCRIPTION.
Returns
#
Returns
-------
#
-------
E : TYPE
#
E : TYPE
DESCRIPTION.
#
DESCRIPTION.
"""
#
"""
# erg/s/cm^2/A/arcsec^2 to W/m^2
#
# 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 W/m^2/sr/μm = 0.10 erg/cm^2/s/sr/A
# 1 sr = 1 rad^2 = 4.25452e10 arcsec^2
#
# 1 sr = 1 rad^2 = 4.25452e10 arcsec^2
# 1 J/s = 1 W
#
# 1 J/s = 1 W
# 1 J = 10^7 erg
#
# 1 J = 10^7 erg
# convert erg/s/cm^2/A/arcsec^2 to erg/s/cm^2/A/sr
#
# convert erg/s/cm^2/A/arcsec^2 to erg/s/cm^2/A/sr
flux1
=
flux
/
(
1
/
4.25452e10
)
#
flux1 = flux / (1/4.25452e10)
# convert erg/s/cm^2/A/sr to W/m^2/sr/um
#
# convert erg/s/cm^2/A/sr to W/m^2/sr/um
flux2
=
flux1
*
10
#
flux2 = flux1 * 10
# 对接收面积积分,输出单位 W/m^2/nm
#
# 对接收面积积分,输出单位 W/m^2/nm
D
=
2
# meter
#
D = 2 # meter
f
=
28
# meter
#
f = 28 # meter
flux3
=
flux2
*
np
.
pi
*
D
**
2
/
4
/
f
**
2
/
10
**
3
#
flux3 = flux2 * np.pi * D**2 / 4 / f**2 / 10**3
# 对波长积分
#
# 对波长积分
f
=
interp1d
(
wave
,
flux3
)
#
f = interp1d(wave, flux3)
wave_interp
=
np
.
arange
(
3800
,
7800
)
#
wave_interp = np.arange(3800, 7800)
flux3_interp
=
f
(
wave_interp
)
#
flux3_interp = f(wave_interp)
# 输出单位 W/m^2
#
# 输出单位 W/m^2
delta_lamba
=
0.1
# nm
#
delta_lamba = 0.1 # nm
E
=
np
.
sum
(
flux3_interp
*
delta_lamba
)
#
E = np.sum(flux3_interp * delta_lamba)
return
E
#
return E
################################################################
################################################################
...
@@ -391,25 +391,25 @@ class StrayLight(object):
...
@@ -391,25 +391,25 @@ class StrayLight(object):
###############################################################################
###############################################################################
def
str2time
(
strTime
):
#
def str2time(strTime):
"""
#
"""
Parameters
#
Parameters
----------
#
----------
strTime : TYPE
#
strTime : TYPE
DESCRIPTION.
#
DESCRIPTION.
Returns
#
Returns
-------
#
-------
TYPE
#
TYPE
DESCRIPTION.
#
DESCRIPTION.
"""
#
"""
if
len
(
strTime
)
>
20
:
# 暂时未用到
#
if len(strTime) > 20: # 暂时未用到
msec
=
int
(
float
(
'0.'
+
strTime
[
20
:])
*
1000000
)
# 微秒
#
msec = int(float('0.'+strTime[20:])*1000000) # 微秒
str2
=
strTime
[
0
:
19
]
+
' '
+
str
(
msec
)
#
str2 = strTime[0:19]+' '+str(msec)
return
datetime
.
strptime
(
str2
,
'%Y %m %d %H %M %S %f'
)
#
return datetime.strptime(str2, '%Y %m %d %H %M %S %f')
# datetime类转mjd
# datetime类转mjd
##########################################################################
##########################################################################
...
@@ -822,40 +822,40 @@ def centroid(data):
...
@@ -822,40 +822,40 @@ def centroid(data):
return
float
(
cx
),
float
(
cy
)
return
float
(
cx
),
float
(
cy
)
###############################################################################
###############################################################################
def
centroidN
(
data
):
#
def centroidN(data):
"""
#
"""
Parameters
#
Parameters
----------
#
----------
data : TYPE
#
data : TYPE
DESCRIPTION.
#
DESCRIPTION.
Returns
#
Returns
-------
#
-------
cx : TYPE
#
cx : TYPE
DESCRIPTION.
#
DESCRIPTION.
cy : TYPE
#
cy : TYPE
DESCRIPTION.
#
DESCRIPTION.
"""
#
"""
'''
#
'''
calculate the centroid of the input two-dimentional image data
#
calculate the centroid of the input two-dimentional image data
Parameters
#
Parameters
----------
#
----------
data : input image.
#
data : input image.
Returns
#
Returns
-------
#
-------
cx: the centroid column number, in horizontal direction definet in python image show
#
cx: the centroid column number, in horizontal direction definet in python image show
cy: the centroid row number , in vertical direction
#
cy: the centroid row number , in vertical direction
'''
#
'''
###
#
###
from
scipy
import
ndimage
#
from scipy import ndimage
cy
,
cx
=
ndimage
.
center_of_mass
(
data
)
#
cy, cx = ndimage.center_of_mass(data)
return
cx
,
cy
#
return cx, cy
####################################################################
####################################################################
...
@@ -1494,42 +1494,42 @@ class IFSsimulator():
...
@@ -1494,42 +1494,42 @@ class IFSsimulator():
return
wave_A
,
spec_erg2
return
wave_A
,
spec_erg2
##########################################################################
##########################################################################
def
smoothingWithChargeDiffusion
(
self
,
image
,
sigma
=
(
0.32
,
0.32
)):
#
def smoothingWithChargeDiffusion(self, image, sigma=(0.32, 0.32)):
"""
#
"""
Parameters
#
Parameters
----------
#
----------
image : TYPE
#
image : TYPE
DESCRIPTION.
#
DESCRIPTION.
sigma : TYPE, optional
#
sigma : TYPE, optional
DESCRIPTION. The default is (0.32, 0.32).
#
DESCRIPTION. The default is (0.32, 0.32).
Returns
#
Returns
-------
#
-------
TYPE
#
TYPE
DESCRIPTION.
#
DESCRIPTION.
"""
#
"""
"""
#
"""
Smooths a given image with a gaussian kernel with widths given as sigmas.
#
Smooths a given image with a gaussian kernel with widths given as sigmas.
This smoothing can be used to mimic charge diffusion within the CCD.
#
This smoothing can be used to mimic charge diffusion within the CCD.
The default values are from Table 8-2 of CCD_273_Euclid_secification_1.0.130812.pdf converted
#
The default values are from Table 8-2 of CCD_273_Euclid_secification_1.0.130812.pdf converted
to sigmas (FWHM / (2sqrt(2ln2)) and rounded up to the second decimal.
#
to sigmas (FWHM / (2sqrt(2ln2)) and rounded up to the second decimal.
.. Note:: This method should not be called for the full image if the charge spreading
#
.. Note:: This method should not be called for the full image if the charge spreading
has already been taken into account in the system PSF to avoid double counting.
#
has already been taken into account in the system PSF to avoid double counting.
:param image: image array which is smoothed with the kernel
#
:param image: image array which is smoothed with the kernel
:type image: ndarray
#
:type image: ndarray
:param sigma: widths of the gaussian kernel that approximates the charge diffusion [0.32, 0.32].
#
:param sigma: widths of the gaussian kernel that approximates the charge diffusion [0.32, 0.32].
:param sigma: tuple
#
:param sigma: tuple
:return: smoothed image array
#
:return: smoothed image array
:rtype: ndarray
#
:rtype: ndarray
"""
#
"""
return
ndimage
.
filters
.
gaussian_filter
(
image
,
sigma
)
#
return ndimage.filters.gaussian_filter(image, sigma)
###############################################################################
###############################################################################
def
readCosmicRayInformation
(
self
):
def
readCosmicRayInformation
(
self
):
...
@@ -1835,88 +1835,88 @@ class IFSsimulator():
...
@@ -1835,88 +1835,88 @@ class IFSsimulator():
######################################################################
######################################################################
##############################################################################
##############################################################################
def
generateflat
(
self
,
ave
=
1.0
,
sigma
=
0.01
):
#
def generateflat(self, ave=1.0, sigma=0.01):
"""
#
"""
Parameters
#
Parameters
----------
#
----------
ave : TYPE, optional
#
ave : TYPE, optional
DESCRIPTION. The default is 1.0.
#
DESCRIPTION. The default is 1.0.
sigma : TYPE, optional
#
sigma : TYPE, optional
DESCRIPTION. The default is 0.01.
#
DESCRIPTION. The default is 0.01.
Returns
#
Returns
-------
#
-------
TYPE
#
TYPE
DESCRIPTION.
#
DESCRIPTION.
TYPE
#
TYPE
DESCRIPTION.
#
DESCRIPTION.
"""
#
"""
"""
#
"""
Creates a flat field image with given properties.
#
Creates a flat field image with given properties.
:return: flat field image
#
:return: flat field image
:rtype: ndarray
#
:rtype: ndarray
"""
#
"""
self
.
log
.
info
(
'Generating a flat field...'
)
#
self.log.info('Generating a flat field...')
self
.
log
.
info
(
'The flat field has mean value of 1 and a given fluctuations, usually either 1 or 2 percent defined by sigma= %d...'
%
sigma
)
#
self.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
)
#
np.random.seed(5*self.simnumber)
self
.
flat_b
=
np
.
random
.
normal
(
loc
=
ave
,
scale
=
sigma
,
size
=
(
2048
,
4096
))
#
self.flat_b = np.random.normal(loc=ave, scale=sigma, size=(2048, 4096))
np
.
random
.
seed
(
55
*
self
.
simnumber
)
#
np.random.seed(55*self.simnumber)
self
.
flat_r
=
np
.
random
.
normal
(
loc
=
ave
,
scale
=
sigma
,
size
=
(
3072
,
6144
))
#
self.flat_r = np.random.normal(loc=ave, scale=sigma, size=(3072, 6144))
s1
=
self
.
flat_b
#
s1 = self.flat_b
hdu1
=
fits
.
PrimaryHDU
(
s1
)
#
hdu1 = fits.PrimaryHDU(s1)
hdu1
.
header
.
set
(
'sigma'
,
sigma
)
#
hdu1.header.set('sigma', sigma)
dtime
=
datetime
.
utcnow
().
strftime
(
'%Y -%m -%d %H: %M: %S'
)
#
dtime = datetime.utcnow().strftime('%Y -%m -%d %H: %M: %S')
hdu1
.
header
.
add_history
(
#
hdu1.header.add_history(
'flat image of blue channel is generated on :'
+
dtime
)
#
'flat image of blue channel is generated on :'+dtime)
f1
=
'../flat_Blue_'
+
str
(
sigma
)
+
'.fits'
#
f1 = '../flat_Blue_'+str(sigma)+'.fits'
fits
.
writeto
(
f1
,
s1
,
header
=
hdu1
.
header
,
overwrite
=
True
)
#
fits.writeto(f1, s1, header=hdu1.header, overwrite=True)
s2
=
self
.
flat_r
#
s2 = self.flat_r
hdu1
=
fits
.
PrimaryHDU
(
s2
)
#
hdu1 = fits.PrimaryHDU(s2)
hdu1
.
header
.
set
(
'sigma'
,
sigma
)
#
hdu1.header.set('sigma', sigma)
dtime
=
datetime
.
utcnow
().
strftime
(
'%Y -%m -%d %H: %M: %S'
)
#
dtime = datetime.utcnow().strftime('%Y -%m -%d %H: %M: %S')
hdu1
.
header
.
add_history
(
#
hdu1.header.add_history(
'flat image of red channel is generated on :'
+
dtime
)
#
'flat image of red channel is generated on :'+dtime)
f2
=
'../flat_Red_'
+
str
(
sigma
)
+
'.fits'
#
f2 = '../flat_Red_'+str(sigma)+'.fits'
fits
.
writeto
(
f2
,
s2
,
header
=
hdu1
.
header
,
overwrite
=
True
)
#
fits.writeto(f2, s2, header=hdu1.header, overwrite=True)
return
self
.
flat_b
,
self
.
flat_r
#
return self.flat_b, self.flat_r
##########################################################################
##########################################################################
def
addLampFlux
(
self
):
#
def addLampFlux(self):
"""
#
"""
Returns
#
Returns
-------
#
-------
None.
#
None.
"""
#
"""
"""
#
"""
Include flux from the calibration source.
#
Include flux from the calibration source.
"""
#
"""
self
.
image_b
+=
fits
.
getdata
(
self
.
information
[
'flatflux'
])
#
self.image_b += fits.getdata(self.information['flatflux'])
self
.
image_r
+=
fits
.
getdata
(
self
.
information
[
'flatflux'
])
#
self.image_r += fits.getdata(self.information['flatflux'])
self
.
log
.
info
(
'Flux from the calibration unit included (%s)'
%
#
self.log.info('Flux from the calibration unit included (%s)' %
self
.
information
[
'flatflux'
])
#
self.information['flatflux'])
#############################################################################
#############################################################################
def
MakeFlatMatrix
(
self
,
img
,
seed
):
def
MakeFlatMatrix
(
self
,
img
,
seed
):
...
@@ -2111,69 +2111,69 @@ class IFSsimulator():
...
@@ -2111,69 +2111,69 @@ class IFSsimulator():
##########################################################
##########################################################
#########################################################################
#########################################################################
def
addReadoutTrails
(
self
):
# 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
# Returns
size1
,
size2
=
data
.
shape
# -------
# None.
for
i
in
range
(
1
,
size2
,
1
):
# """
data_shift2
=
np
.
roll
(
data_shift
,
i
,
axis
=
0
)
# """
data_shift2
[:
i
,
:]
=
0.0
# Add readout trails resulting from reading out the shutter open.
data
+=
data_shift2
if
self
.
information
[
'quadrant'
]
in
(
2
,
3
):
# Quadrants assumed to be numbered:
self
.
image_r
=
data
[::
-
1
,
:]
# 2 3
else
:
# 0 1
self
.
image_r
=
data
# """
# 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
##############################################################################
##############################################################################
...
@@ -2259,24 +2259,24 @@ class IFSsimulator():
...
@@ -2259,24 +2259,24 @@ class IFSsimulator():
##########################################################################
##########################################################################
def
applyScatteredLight
(
self
):
#
def applyScatteredLight(self):
"""
#
"""
Returns
#
Returns
-------
#
-------
None.
#
None.
"""
#
"""
"""
#
"""
Adds spatially uniform scattered light to the image.
#
Adds spatially uniform scattered light to the image.
"""
#
"""
sl
=
self
.
information
[
'exptime'
]
*
self
.
information
[
'scattered_light'
]
#
sl = self.information['exptime'] * self.information['scattered_light']
self
.
image_b
+=
sl
#
self.image_b += sl
self
.
image_r
+=
sl
#
self.image_r += sl
self
.
log
.
info
(
'Added scattered light = %f'
%
sl
)
#
self.log.info('Added scattered light = %f' % sl)
##############################################################################
##############################################################################
def
applyPoissonNoise
(
self
):
def
applyPoissonNoise
(
self
):
...
...
This diff is collapsed.
Click to expand it.
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
Menu
Explore
Projects
Groups
Snippets