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_cpic_sim
Commits
190f1129
Commit
190f1129
authored
Oct 26, 2024
by
GZhao
Browse files
pep 8 check.
parent
b6e8bc32
Pipeline
#7115
failed with stage
in 0 seconds
Changes
20
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
csst_cpic_sim/__init__.py
View file @
190f1129
...
@@ -15,4 +15,4 @@ __all__ = [
...
@@ -15,4 +15,4 @@ __all__ = [
"quick_run_v2"
,
"quick_run_v2"
,
"vis_observation"
,
"vis_observation"
,
"__version__"
"__version__"
]
]
\ No newline at end of file
csst_cpic_sim/camera.py
View file @
190f1129
...
@@ -2,7 +2,6 @@ import math
...
@@ -2,7 +2,6 @@ import math
import
numpy
as
np
import
numpy
as
np
import
scipy.ndimage
as
nd
import
scipy.ndimage
as
nd
from
astropy.io
import
fits
from
astropy.io
import
fits
import
matplotlib.pyplot
as
plt
from
.config
import
config
,
S
from
.config
import
config
,
S
from
.utils
import
region_replace
,
random_seed_select
from
.utils
import
region_replace
,
random_seed_select
...
@@ -13,6 +12,8 @@ cpism_refdata = config['cpism_refdata']
...
@@ -13,6 +12,8 @@ cpism_refdata = config['cpism_refdata']
MAG_SYSTEM
=
config
[
'mag_system'
]
MAG_SYSTEM
=
config
[
'mag_system'
]
solar_spectrum
=
S
.
FileSpectrum
(
config
[
'solar_spectrum'
])
solar_spectrum
=
S
.
FileSpectrum
(
config
[
'solar_spectrum'
])
solar_spectrum
.
convert
(
'photlam'
)
solar_spectrum
.
convert
(
'photlam'
)
def
sky_frame_maker
(
band
,
skybg
,
platescale
,
shape
):
def
sky_frame_maker
(
band
,
skybg
,
platescale
,
shape
):
"""
"""
generate a sky background frame.
generate a sky background frame.
...
@@ -22,7 +23,7 @@ def sky_frame_maker(band, skybg, platescale, shape):
...
@@ -22,7 +23,7 @@ def sky_frame_maker(band, skybg, platescale, shape):
band : str
band : str
The band of the sky background.
The band of the sky background.
skybg : str
skybg : str
The sky background file name.
The sky background file name.
platescale : float
platescale : float
The platescale of the camera in arcsec/pixel.
The platescale of the camera in arcsec/pixel.
shape : tuple
shape : tuple
...
@@ -288,7 +289,7 @@ class CpicVisEmccd(object):
...
@@ -288,7 +289,7 @@ class CpicVisEmccd(object):
"""
"""
def
__init__
(
self
,
config_dict
=
None
):
def
__init__
(
self
,
config_dict
=
None
):
"""Initialize the camera.
"""Initialize the camera.
Parameters
Parameters
----------
----------
config_dict : dict, optional
config_dict : dict, optional
...
@@ -301,7 +302,7 @@ class CpicVisEmccd(object):
...
@@ -301,7 +302,7 @@ class CpicVisEmccd(object):
self
.
_defaut_config
()
self
.
_defaut_config
()
if
config_dict
is
not
None
:
if
config_dict
is
not
None
:
old_switch
=
self
.
switch
old_switch
=
self
.
switch
self
.
__dict__
.
update
(
config_dict
)
#
not safe, be careful
self
.
__dict__
.
update
(
config_dict
)
#
not safe, be careful
old_switch
.
update
(
self
.
switch
)
old_switch
.
update
(
self
.
switch
)
self
.
switch
=
old_switch
self
.
switch
=
old_switch
self
.
config_init
()
self
.
config_init
()
...
@@ -345,17 +346,17 @@ class CpicVisEmccd(object):
...
@@ -345,17 +346,17 @@ class CpicVisEmccd(object):
self
.
cic
=
None
self
.
cic
=
None
self
.
dark
=
None
self
.
dark
=
None
self
.
flat
=
None
self
.
flat
=
None
self
.
fullwell
=
80_000
self
.
fullwell
=
80_000
self
.
em_fullwell
=
500_000
#
780_000
self
.
em_fullwell
=
500_000
#
780_000
self
.
em_cte
=
0.9996
self
.
em_cte
=
0.9996
self
.
emreg_cal_num
=
10
# 用来加速计算
self
.
emreg_cal_num
=
10
# 用来加速计算
self
.
emreg_num
=
604
self
.
emreg_num
=
604
self
.
readout_speed
=
6.25e6
# Hz
self
.
readout_speed
=
6.25e6
# Hz
self
.
readout_time
=
0.365
# s
self
.
readout_time
=
0.365
# s
self
.
heat_speed
=
1
/
1000
# voltage / 1000 degree per frame
self
.
heat_speed
=
1
/
1000
# voltage / 1000 degree per frame
self
.
temper_speed
=
0.05
# degree per second
self
.
temper_speed
=
0.05
# degree per second
self
.
cooler_temp
=
-
80
self
.
cooler_temp
=
-
80
self
.
readout_noise
=
160
self
.
readout_noise
=
160
...
@@ -372,14 +373,12 @@ class CpicVisEmccd(object):
...
@@ -372,14 +373,12 @@ class CpicVisEmccd(object):
self
.
nonlinear_coefficient
=
-
0.1
self
.
nonlinear_coefficient
=
-
0.1
self
.
detector_name
=
'
EM
CCD'
self
.
detector_name
=
'CCD
201-20-EM
'
self
.
ccd_label
=
'CCD
201-20
'
self
.
ccd_label
=
'
EM
CCD'
self
.
pitch_size
=
13
self
.
pitch_size
=
13
def
config_init
(
self
):
def
config_init
(
self
):
"""initialize the camera.
"""initialize the camera.
If the config is set, call this function to update the config.
If the config is set, call this function to update the config.
"""
"""
...
@@ -418,7 +417,7 @@ class CpicVisEmccd(object):
...
@@ -418,7 +417,7 @@ class CpicVisEmccd(object):
CTI
=
1
-
CTE
CTI
=
1
-
CTE
S_0_n
=
S_0
*
((
N_p
*
CTI
)
**
n
)
/
math
.
factorial
(
n
)
*
math
.
exp
(
-
N_p
*
CTI
)
S_0_n
=
S_0
*
((
N_p
*
CTI
)
**
n
)
/
math
.
factorial
(
n
)
*
math
.
exp
(
-
N_p
*
CTI
)
return
S_0_n
return
S_0_n
def
cte_201
(
cte
,
start
=
0
,
length
=
10
):
def
cte_201
(
cte
,
start
=
0
,
length
=
10
):
N_p
=
604
N_p
=
604
S_0
=
1
S_0
=
1
...
@@ -431,7 +430,6 @@ class CpicVisEmccd(object):
...
@@ -431,7 +430,6 @@ class CpicVisEmccd(object):
cti_trail
=
cte_201
(
self
.
em_cte
,
start
=
0
,
length
=
10
)
cti_trail
=
cte_201
(
self
.
em_cte
,
start
=
0
,
length
=
10
)
self
.
cti_trail
=
cti_trail
/
cti_trail
.
sum
()
self
.
cti_trail
=
cti_trail
/
cti_trail
.
sum
()
def
em_fix_fuc_fit
(
self
,
emgain
):
def
em_fix_fuc_fit
(
self
,
emgain
):
"""Calculate the emgain fix coeficient to fix the gamma distribution.
"""Calculate the emgain fix coeficient to fix the gamma distribution.
The coeficient is from fixing of ideal emgain distribution.
The coeficient is from fixing of ideal emgain distribution.
...
@@ -440,7 +438,7 @@ class CpicVisEmccd(object):
...
@@ -440,7 +438,7 @@ class CpicVisEmccd(object):
----------
----------
emgain : float
emgain : float
The emgain.
The emgain.
Returns
Returns
-------
-------
float
float
...
@@ -448,6 +446,7 @@ class CpicVisEmccd(object):
...
@@ -448,6 +446,7 @@ class CpicVisEmccd(object):
"""
"""
emgain
=
np
.
array
([
emgain
]).
flatten
()
emgain
=
np
.
array
([
emgain
]).
flatten
()
p
=
[
0.01014486
,
-
0.00712984
,
-
0.17163414
,
0.09523666
,
-
0.53926089
]
p
=
[
0.01014486
,
-
0.00712984
,
-
0.17163414
,
0.09523666
,
-
0.53926089
]
def
kernel
(
em
):
def
kernel
(
em
):
log_em
=
np
.
log10
(
em
)
log_em
=
np
.
log10
(
em
)
loglog_g
=
np
.
log10
(
log_em
)
loglog_g
=
np
.
log10
(
log_em
)
...
@@ -465,10 +464,9 @@ class CpicVisEmccd(object):
...
@@ -465,10 +464,9 @@ class CpicVisEmccd(object):
output
.
append
(
kernel
(
em
))
output
.
append
(
kernel
(
em
))
return
np
.
array
(
output
)
return
np
.
array
(
output
)
def
bias_frame
(
self
):
def
bias_frame
(
self
):
"""Generate bias frame
"""Generate bias frame
The bias frame contains vertical, horizontal, peper-salt noise, bias drift effect.
The bias frame contains vertical, horizontal, peper-salt noise, bias drift effect.
Can be configurable using self.switch.
Can be configurable using self.switch.
Returns
Returns
...
@@ -479,7 +477,7 @@ class CpicVisEmccd(object):
...
@@ -479,7 +477,7 @@ class CpicVisEmccd(object):
shape
=
self
.
bias_shape
shape
=
self
.
bias_shape
TPI
=
np
.
pi
*
2
TPI
=
np
.
pi
*
2
# vertical pattern
# vertical pattern
# 使用一维的曲线描述竖条纹的截面
# 使用一维的曲线描述竖条纹的截面
vp_1d
=
np
.
zeros
(
shape
[
1
])
vp_1d
=
np
.
zeros
(
shape
[
1
])
...
@@ -505,11 +503,11 @@ class CpicVisEmccd(object):
...
@@ -505,11 +503,11 @@ class CpicVisEmccd(object):
# horizontal pattern
# horizontal pattern
# 图像上的横条纹是梳状,分为两个部分,左边大约77个像素是周期小一点,其余的会大一点
# 图像上的横条纹是梳状,分为两个部分,左边大约77个像素是周期小一点,其余的会大一点
boundary
=
77
# boundary between left and width
boundary
=
77
# boundary between left and width
boundary_width
=
5
# 左右需要平滑过度一下
boundary_width
=
5
# 左右需要平滑过度一下
y
=
np
.
arange
(
self
.
bias_shape
[
0
])
y
=
np
.
arange
(
self
.
bias_shape
[
0
])
hp_left_param
=
self
.
horizontal1_param
# 实测数据拟合得到的
hp_left_param
=
self
.
horizontal1_param
# 实测数据拟合得到的
hp_left_1d
=
hp_left_param
[
0
]
*
np
.
sin
(
TPI
*
(
y
/
hp_left_param
[
1
]
+
np
.
random
.
rand
()))
hp_left_1d
=
hp_left_param
[
0
]
*
np
.
sin
(
TPI
*
(
y
/
hp_left_param
[
1
]
+
np
.
random
.
rand
()))
hp_left_1d
+=
hp_left_param
[
2
]
*
np
.
sin
(
TPI
*
(
y
/
hp_left_param
[
3
]
+
np
.
random
.
rand
()))
hp_left_1d
+=
hp_left_param
[
2
]
*
np
.
sin
(
TPI
*
(
y
/
hp_left_param
[
3
]
+
np
.
random
.
rand
()))
hp_left_frame
=
np
.
broadcast_to
(
hp_left_1d
,
[
boundary
+
boundary_width
,
len
(
hp_left_1d
),]).
T
hp_left_frame
=
np
.
broadcast_to
(
hp_left_1d
,
[
boundary
+
boundary_width
,
len
(
hp_left_1d
),]).
T
...
@@ -518,10 +516,10 @@ class CpicVisEmccd(object):
...
@@ -518,10 +516,10 @@ class CpicVisEmccd(object):
hp_right_1d
=
hp_right_param
[
0
]
*
np
.
sin
(
TPI
*
(
y
/
hp_right_param
[
1
]
+
np
.
random
.
rand
()))
hp_right_1d
=
hp_right_param
[
0
]
*
np
.
sin
(
TPI
*
(
y
/
hp_right_param
[
1
]
+
np
.
random
.
rand
()))
hp_right_1d
+=
hp_right_param
[
2
]
*
np
.
sin
(
TPI
*
(
y
/
hp_right_param
[
3
]
+
np
.
random
.
rand
()))
hp_right_1d
+=
hp_right_param
[
2
]
*
np
.
sin
(
TPI
*
(
y
/
hp_right_param
[
3
]
+
np
.
random
.
rand
()))
hp_right_frame
=
np
.
broadcast_to
(
hp_right_1d
,
[
shape
[
1
]
-
boundary
,
len
(
hp_right_1d
)]).
T
hp_right_frame
=
np
.
broadcast_to
(
hp_right_1d
,
[
shape
[
1
]
-
boundary
,
len
(
hp_right_1d
)]).
T
combine_profile_left
=
np
.
ones
(
boundary
+
boundary_width
)
combine_profile_left
=
np
.
ones
(
boundary
+
boundary_width
)
combine_profile_left
[
-
boundary_width
:]
=
(
boundary_width
-
np
.
arange
(
boundary_width
)
-
1
)
/
boundary_width
combine_profile_left
[
-
boundary_width
:]
=
(
boundary_width
-
np
.
arange
(
boundary_width
)
-
1
)
/
boundary_width
combine_profile_right
=
np
.
ones
(
shape
[
1
]
-
boundary
)
combine_profile_right
=
np
.
ones
(
shape
[
1
]
-
boundary
)
combine_profile_right
[:
boundary_width
]
=
np
.
arange
(
boundary_width
)
/
boundary_width
combine_profile_right
[:
boundary_width
]
=
np
.
arange
(
boundary_width
)
/
boundary_width
...
@@ -565,22 +563,22 @@ class CpicVisEmccd(object):
...
@@ -565,22 +563,22 @@ class CpicVisEmccd(object):
# plt.title('vertical pattern')
# plt.title('vertical pattern')
# 接上制冷机后,会有亮暗点
# 接上制冷机后,会有亮暗点
#cooler interfence effect
#
cooler interfence effect
ci_position
=
10
ci_position
=
10
ci_sub_struct
=
80
ci_sub_struct
=
80
ci_sub_exp
=
2.5
ci_sub_exp
=
2.5
ci_x_shft
=
3
ci_x_shft
=
3
ci_interval
=
250
# 6.25MHz readout / 2.5KHz interfence
ci_interval
=
250
# 6.25MHz readout / 2.5KHz interfence
ci_dn
=
self
.
cooler_interfence
ci_dn
=
self
.
cooler_interfence
npix
=
shape
[
0
]
*
shape
[
1
]
npix
=
shape
[
0
]
*
shape
[
1
]
n_ci_event
=
npix
//
ci_interval
n_ci_event
=
npix
//
ci_interval
ci_align
=
np
.
zeros
((
n_ci_event
,
ci_interval
))
ci_align
=
np
.
zeros
((
n_ci_event
,
ci_interval
))
ci_align
[:,
ci_position
]
=
np
.
random
.
randn
(
n_ci_event
)
*
ci_dn
ci_align
[:,
ci_position
]
=
np
.
random
.
randn
(
n_ci_event
)
*
ci_dn
ci_align
[:,
ci_position
+
1
]
=
np
.
random
.
randn
(
n_ci_event
)
*
ci_dn
ci_align
[:,
ci_position
+
1
]
=
np
.
random
.
randn
(
n_ci_event
)
*
ci_dn
yi0
=
np
.
random
.
randint
(
0
,
ci_sub_struct
)
yi0
=
np
.
random
.
randint
(
0
,
ci_sub_struct
)
xs0
=
(
ci_interval
-
ci_position
)
/
(
ci_sub_struct
/
2
)
**
ci_sub_exp
xs0
=
(
ci_interval
-
ci_position
)
/
(
ci_sub_struct
/
2
)
**
ci_sub_exp
for
yi
in
range
(
n_ci_event
):
for
yi
in
range
(
n_ci_event
):
sub_yi
=
(
yi
-
yi0
)
%
ci_sub_struct
sub_yi
=
(
yi
-
yi0
)
%
ci_sub_struct
sub_yi
=
abs
(
sub_yi
-
ci_sub_struct
/
2
)
sub_yi
=
abs
(
sub_yi
-
ci_sub_struct
/
2
)
...
@@ -589,7 +587,7 @@ class CpicVisEmccd(object):
...
@@ -589,7 +587,7 @@ class CpicVisEmccd(object):
ci_align
=
np
.
pad
(
ci_align
.
flatten
(),
(
0
,
npix
-
n_ci_event
*
ci_interval
))
ci_align
=
np
.
pad
(
ci_align
.
flatten
(),
(
0
,
npix
-
n_ci_event
*
ci_interval
))
ci_frame
=
ci_align
.
reshape
(
shape
[
0
],
shape
[
1
])
ci_frame
=
ci_align
.
reshape
(
shape
[
0
],
shape
[
1
])
for
yi
in
range
(
shape
[
0
]):
for
yi
in
range
(
shape
[
0
]):
ci_frame
[
yi
,
:]
=
np
.
roll
(
ci_frame
[
yi
,
:],
yi
*
ci_x_shft
)
ci_frame
[
yi
,
:]
=
np
.
roll
(
ci_frame
[
yi
,
:],
yi
*
ci_x_shft
)
...
@@ -607,7 +605,7 @@ class CpicVisEmccd(object):
...
@@ -607,7 +605,7 @@ class CpicVisEmccd(object):
bias_frame
+=
rn_adu
*
np
.
random
.
randn
(
shape
[
0
],
shape
[
1
])
+
bias_shift
bias_frame
+=
rn_adu
*
np
.
random
.
randn
(
shape
[
0
],
shape
[
1
])
+
bias_shift
return
bias_frame
return
bias_frame
def
nonlinear_effect
(
self
,
image
):
def
nonlinear_effect
(
self
,
image
):
"""
"""
nonlinear effect
nonlinear effect
...
@@ -619,11 +617,11 @@ class CpicVisEmccd(object):
...
@@ -619,11 +617,11 @@ class CpicVisEmccd(object):
image
+=
(
image
/
fullwell
)
**
2
*
nonlinear_coefficient
*
fullwell
image
+=
(
image
/
fullwell
)
**
2
*
nonlinear_coefficient
*
fullwell
return
image
return
image
def
time_syn
(
self
,
t
,
readout
=
True
,
initial
=
False
):
def
time_syn
(
self
,
t
,
readout
=
True
,
initial
=
False
):
"""
"""
time synchronization and update the system time and ccd temperature
time synchronization and update the system time and ccd temperature
Parameters
Parameters
----------
----------
t : float
t : float
...
@@ -633,26 +631,26 @@ class CpicVisEmccd(object):
...
@@ -633,26 +631,26 @@ class CpicVisEmccd(object):
if True, the ccd temperature will increase, otherwise, it will decrease
if True, the ccd temperature will increase, otherwise, it will decrease
initial : bool, optional
initial : bool, optional
If inital is True, the ccd will be intialized to the cooler temperature
If inital is True, the ccd will be intialized to the cooler temperature
"""
"""
if
initial
:
if
initial
:
self
.
ccd_temp
=
self
.
cooler_temp
self
.
ccd_temp
=
self
.
cooler_temp
self
.
system_time
=
t
self
.
system_time
=
t
return
return
dt
=
np
.
maximum
(
t
,
0
)
dt
=
np
.
maximum
(
t
,
0
)
heat
=
0
heat
=
0
if
readout
:
if
readout
:
heat
=
self
.
volt
*
self
.
heat_speed
heat
=
self
.
volt
*
self
.
heat_speed
self
.
ccd_temp
=
heat
+
self
.
cooler_temp
+
(
self
.
ccd_temp
-
self
.
cooler_temp
)
*
np
.
exp
(
-
dt
*
self
.
temper_speed
)
self
.
ccd_temp
=
heat
+
self
.
cooler_temp
+
(
self
.
ccd_temp
-
self
.
cooler_temp
)
*
np
.
exp
(
-
dt
*
self
.
temper_speed
)
if
self
.
ccd_temp
<
self
.
cooler_temp
:
#
if
self
.
ccd_temp
<
self
.
cooler_temp
:
self
.
ccd_temp
=
self
.
cooler_temp
self
.
ccd_temp
=
self
.
cooler_temp
self
.
system_time
+=
dt
self
.
system_time
+=
dt
# def em_cte(self, img):
# def em_cte(self, img):
# i_shift = 1
# i_shift = 1
# cte_coe = 0.1
# cte_coe = 0.1
# img_shift_i = np.zeros_like(img)
# img_shift_i = np.zeros_like(img)
...
@@ -672,14 +670,15 @@ class CpicVisEmccd(object):
...
@@ -672,14 +670,15 @@ class CpicVisEmccd(object):
if True, update the emgain and emset. Default is True.
if True, update the emgain and emset. Default is True.
if False, only return the emgain.
if False, only return the emgain.
"""
"""
if
ccd_temp
is
None
:
if
ccd_temp
is
None
:
ccd_temp
=
self
.
ccd_temp
ccd_temp
=
self
.
ccd_temp
volt_coe_a
=
-
0.01828
volt_coe_a
=
-
0.01828
volt_coe_b
=
43.61
volt_coe_b
=
43.61
volt_func
=
lambda
es
:
volt_coe_a
*
es
+
volt_coe_b
def
volt_func
(
es
):
return
volt_coe_a
*
es
+
volt_coe_b
self
.
volt
=
volt_func
(
em_set
)
self
.
volt
=
volt_func
(
em_set
)
...
@@ -692,16 +691,16 @@ class CpicVisEmccd(object):
...
@@ -692,16 +691,16 @@ class CpicVisEmccd(object):
# fitting from the ccd test result
# fitting from the ccd test result
ln_g190
=
(
-
ccd_temp
-
7
)
*
0.0325
ln_g190
=
(
-
ccd_temp
-
7
)
*
0.0325
em_coe_b
=
ln_g190
/
constant
em_coe_b
=
ln_g190
/
constant
emgain
=
np
.
exp
(
em_coe_b
*
np
.
exp
(
em_coe_c
*
self
.
volt
))
emgain
=
np
.
exp
(
em_coe_b
*
np
.
exp
(
em_coe_c
*
self
.
volt
))
emgain
=
np
.
maximum
(
1
,
emgain
)
emgain
=
np
.
maximum
(
1
,
emgain
)
# print(emgain, em_coe_b, em_coe_c * self.volt, self.volt, np.exp(em_coe_c * self.volt))
# print(emgain, em_coe_b, em_coe_c * self.volt, self.volt, np.exp(em_coe_c * self.volt))
if
self_update
:
if
self_update
:
self
.
emgain
=
emgain
self
.
emgain
=
emgain
self
.
emset
=
em_set
self
.
emset
=
em_set
return
emgain
return
emgain
def
vertical_blooming
(
self
,
image
):
def
vertical_blooming
(
self
,
image
):
"""
"""
vertical blooming effect
vertical blooming effect
...
@@ -764,7 +763,7 @@ class CpicVisEmccd(object):
...
@@ -764,7 +763,7 @@ class CpicVisEmccd(object):
def
readout
(
self
,
image_focal
,
em_set
,
expt_set
,
image_cosmic_ray
=
False
,
emgain
=
None
):
def
readout
(
self
,
image_focal
,
em_set
,
expt_set
,
image_cosmic_ray
=
False
,
emgain
=
None
):
"""From focal planet image to ccd output.
"""From focal planet image to ccd output.
Interface function for emccd. Simulate the readout process.
Interface function for emccd. Simulate the readout process.
Parameters
Parameters
----------
----------
image_focal : np.ndarray
image_focal : np.ndarray
...
@@ -787,7 +786,7 @@ class CpicVisEmccd(object):
...
@@ -787,7 +786,7 @@ class CpicVisEmccd(object):
expt
=
expt_set
expt
=
expt_set
if
expt_set
==
0
:
if
expt_set
==
0
:
expt
=
0.001
expt
=
0.001
dt
=
self
.
readout_time
+
expt
dt
=
self
.
readout_time
+
expt
self
.
time_syn
(
dt
,
readout
=
True
)
self
.
time_syn
(
dt
,
readout
=
True
)
...
@@ -832,7 +831,7 @@ class CpicVisEmccd(object):
...
@@ -832,7 +831,7 @@ class CpicVisEmccd(object):
image
[
deadpix_y
:,
deadpix_x
]
=
0
image
[
deadpix_y
:,
deadpix_x
]
=
0
img_bias
=
np
.
zeros
(
self
.
bias_shape
,
dtype
=
int
)
img_bias
=
np
.
zeros
(
self
.
bias_shape
,
dtype
=
int
)
img_bias
[
img_bias
[
self
.
pscan2
:
-
self
.
oscan2
,
self
.
pscan2
:
-
self
.
oscan2
,
self
.
pscan1
:
-
self
.
oscan1
self
.
pscan1
:
-
self
.
oscan1
...
@@ -845,8 +844,7 @@ class CpicVisEmccd(object):
...
@@ -845,8 +844,7 @@ class CpicVisEmccd(object):
image_shutter
=
image_shutter
/
self
.
flat_shape
[
1
]
*
self
.
shift_time
image_shutter
=
image_shutter
/
self
.
flat_shape
[
1
]
*
self
.
shift_time
image_shutter
=
np
.
random
.
poisson
(
image_shutter
)
image_shutter
=
np
.
random
.
poisson
(
image_shutter
)
image
[:,
self
.
pscan1
+
self
.
ldark
:
-
self
.
oscan1
-
self
.
rdark
]
+=
image_shutter
image
[:,
self
.
pscan1
+
self
.
ldark
:
-
self
.
oscan1
-
self
.
rdark
]
+=
image_shutter
if
self
.
switch
[
'cic'
]:
if
self
.
switch
[
'cic'
]:
cic_frame
=
np
.
zeros
((
self
.
dark_shape
[
0
],
self
.
bias_shape
[
1
]))
+
self
.
cic
cic_frame
=
np
.
zeros
((
self
.
dark_shape
[
0
],
self
.
bias_shape
[
1
]))
+
self
.
cic
image
[
self
.
pscan2
:
-
self
.
oscan2
,
:]
+=
np
.
random
.
poisson
(
cic_frame
)
image
[
self
.
pscan2
:
-
self
.
oscan2
,
:]
+=
np
.
random
.
poisson
(
cic_frame
)
...
@@ -857,11 +855,10 @@ class CpicVisEmccd(object):
...
@@ -857,11 +855,10 @@ class CpicVisEmccd(object):
# >>> for _ in range(self.emreg_num):
# >>> for _ in range(self.emreg_num):
# >>> image += np.random.binomial(image, pEM)
# >>> image += np.random.binomial(image, pEM)
# This code is too slow, so we used a modified gamma
# This code is too slow, so we used a modified gamma
em_fix
=
self
.
em_fix_fuc_fit
(
emgain
)
*
emgain
em_fix
=
self
.
em_fix_fuc_fit
(
emgain
)
*
emgain
image
=
np
.
random
.
gamma
(
image
,
em_fix
)
+
image
*
(
emgain
-
em_fix
)
image
=
np
.
random
.
gamma
(
image
,
em_fix
)
+
image
*
(
emgain
-
em_fix
)
if
self
.
switch
[
'em_blooming'
]:
if
self
.
switch
[
'em_blooming'
]:
image
=
self
.
emregester_blooming
(
image
)
image
=
self
.
emregester_blooming
(
image
)
...
...
csst_cpic_sim/config.py
View file @
190f1129
import
os
,
yaml
import
os
import
yaml
import
warnings
import
warnings
from
datetime
import
datetime
from
datetime
import
datetime
import
numpy
as
np
import
numpy
as
np
...
@@ -16,7 +17,7 @@ config_aim = os.path.join(config_aim, 'data/refdata_path.yaml')
...
@@ -16,7 +17,7 @@ config_aim = os.path.join(config_aim, 'data/refdata_path.yaml')
# with open(config_aim, 'w') as f:
# with open(config_aim, 'w') as f:
# yaml.dump(refdata_path, f)
# yaml.dump(refdata_path, f)
# return refdata_path
# return refdata_path
# try:
# try:
# with open(config_aim, 'r') as f:
# with open(config_aim, 'r') as f:
...
@@ -37,8 +38,6 @@ def load_refdata_path(config_aim):
...
@@ -37,8 +38,6 @@ def load_refdata_path(config_aim):
----------
----------
config_aim : str
config_aim : str
config_aim file path
config_aim file path
"""
"""
with
open
(
config_aim
,
'r'
)
as
f
:
with
open
(
config_aim
,
'r'
)
as
f
:
refdata_list
=
yaml
.
load
(
f
,
Loader
=
yaml
.
FullLoader
)
refdata_list
=
yaml
.
load
(
f
,
Loader
=
yaml
.
FullLoader
)
...
@@ -46,7 +45,7 @@ def load_refdata_path(config_aim):
...
@@ -46,7 +45,7 @@ def load_refdata_path(config_aim):
for
refdata
in
refdata_list
:
for
refdata
in
refdata_list
:
if
os
.
path
.
isdir
(
refdata
):
if
os
.
path
.
isdir
(
refdata
):
return
refdata
return
refdata
print
(
"csst_cpic_sim refdata folder not found, please input cpism refencence data folder"
)
print
(
"csst_cpic_sim refdata folder not found, please input cpism refencence data folder"
)
refdata
=
input
()
refdata
=
input
()
refdata
=
os
.
path
.
abspath
(
refdata
)
refdata
=
os
.
path
.
abspath
(
refdata
)
...
@@ -55,7 +54,7 @@ def load_refdata_path(config_aim):
...
@@ -55,7 +54,7 @@ def load_refdata_path(config_aim):
with
open
(
config_aim
,
'w'
)
as
f
:
with
open
(
config_aim
,
'w'
)
as
f
:
yaml
.
dump
(
refdata_list
,
f
)
yaml
.
dump
(
refdata_list
,
f
)
exit
()
exit
()
cpism_refdata
=
load_refdata_path
(
config_aim
)
cpism_refdata
=
load_refdata_path
(
config_aim
)
...
@@ -80,13 +79,13 @@ config['bands'] = {
...
@@ -80,13 +79,13 @@ config['bands'] = {
'f850'
:
f
'
{
cpism_refdata
}
/throughtput/f850.fits'
,
'f850'
:
f
'
{
cpism_refdata
}
/throughtput/f850.fits'
,
'f720'
:
f
'
{
cpism_refdata
}
/throughtput/f720.fits'
,
'f720'
:
f
'
{
cpism_refdata
}
/throughtput/f720.fits'
,
}
}
config
[
'diameter'
]
=
2
# in meters
config
[
'diameter'
]
=
2
# in meters
config
[
'platescale'
]
=
0.016153
config
[
'platescale'
]
=
0.016153
config
[
'datamodel'
]
=
f
'
{
cpism_refdata
}
/io/csst-cpic-l0.yaml'
config
[
'datamodel'
]
=
f
'
{
cpism_refdata
}
/io/csst-cpic-l0.yaml'
config
[
'log_dir'
]
=
f
'
{
cpism_refdata
}
/log'
config
[
'log_dir'
]
=
f
'
{
cpism_refdata
}
/log'
config
[
'log_level'
]
=
f
'info'
config
[
'log_level'
]
=
'info'
config
[
'output'
]
=
f
'./'
config
[
'output'
]
=
'./'
config
[
'sp2teff_model'
]
=
f
'
{
cpism_refdata
}
/target_model/sptype2teff_lut.json'
config
[
'sp2teff_model'
]
=
f
'
{
cpism_refdata
}
/target_model/sptype2teff_lut.json'
config
[
'dm_pickle'
]
=
f
'
{
cpism_refdata
}
/optics/dm_model.pkl'
config
[
'dm_pickle'
]
=
f
'
{
cpism_refdata
}
/optics/dm_model.pkl'
config
[
'pysyn_refdata'
]
=
f
'
{
cpism_refdata
}
/starmodel/grp/redcat/trds'
config
[
'pysyn_refdata'
]
=
f
'
{
cpism_refdata
}
/starmodel/grp/redcat/trds'
...
@@ -95,22 +94,25 @@ config['csst_format'] = True
...
@@ -95,22 +94,25 @@ config['csst_format'] = True
config
[
'nsample'
]
=
5
config
[
'nsample'
]
=
5
update_able_keys
=
[
update_able_keys
=
[
'apm_file'
,
'actuator_file'
,
'aberration'
,
'log_dir'
,
'log_level'
,
'catalog_folder'
,
'nsample'
,
'csst_format'
,
'output'
,
'check_fits_header'
'apm_file'
,
'actuator_file'
,
'aberration'
,
'log_dir'
,
'log_level'
,
'catalog_folder'
,
'nsample'
,
'csst_format'
,
'output'
,
'check_fits_header'
]
]
def
replace_cpism_refdata
(
def
replace_cpism_refdata
(
config
:
dict
,
config
:
dict
,
output
:
str
=
'$'
)
->
None
:
output
:
str
=
'$'
)
->
None
:
"""Replace the cpism_refdata in the config.
"""Replace the cpism_refdata in the config.
In the config file, we use ${cpism_refdata} to indicate the cpism_refdata.
In the config file, we use ${cpism_refdata} to indicate the cpism_refdata.
This function is used to replace the cpism_refdata in the config, or replace back.
This function is used to replace the cpism_refdata in the config, or replace back.
Parameters
Parameters
----------
----------
config: dict
config: dict
config dict.
config dict.
output: str
output: str
'$' or 'other'. If output is '$', then replace the cpism_refdata in the config with ${cpism_refdata}.
'$' or 'other'. If output is '$', then replace the cpism_refdata in the config with ${cpism_refdata}.
If output is 'other', then replace the ${cpism_refdata} in the config file with the real path.
If output is 'other', then replace the ${cpism_refdata} in the config file with the real path.
'$' is used meanly to generate a demo config file.
'$' is used meanly to generate a demo config file.
"""
"""
...
@@ -138,17 +140,18 @@ __version__ = '2.0.0'
...
@@ -138,17 +140,18 @@ __version__ = '2.0.0'
with
warnings
.
catch_warnings
():
# pragma: no cover
with
warnings
.
catch_warnings
():
# pragma: no cover
warnings
.
filterwarnings
(
"ignore"
)
warnings
.
filterwarnings
(
"ignore"
)
import
pysynphot
as
S
import
pysynphot
as
S
_
=
S
# S will be used in other modules, but I need to use it once here to pass the lint.
def
setup_config
(
new_config
):
def
setup_config
(
new_config
):
"""Set up config from a dict.
"""Set up config from a dict.
Some of the configs need to calcuate.
Some of the configs need to calcuate.
Parameters
Parameters
----------
----------
new_config: dict
new_config: dict
new config dict.
new config dict.
Returns
Returns
-------
-------
None
None
...
@@ -156,12 +159,14 @@ def setup_config(new_config):
...
@@ -156,12 +159,14 @@ def setup_config(new_config):
config
.
update
(
new_config
)
config
.
update
(
new_config
)
config
[
'utc0_float'
]
=
datetime
.
timestamp
(
datetime
.
fromisoformat
(
config
[
'utc0'
]))
config
[
'utc0_float'
]
=
datetime
.
timestamp
(
datetime
.
fromisoformat
(
config
[
'utc0'
]))
config
[
'solar_spectrum'
]
=
f
"
{
os
.
environ
[
'PYSYN_CDBS'
]
}
/grid/solsys/solar_spec.fits"
config
[
'solar_spectrum'
]
=
f
"
{
os
.
environ
[
'PYSYN_CDBS'
]
}
/grid/solsys/solar_spec.fits"
config
[
'aperature_area'
]
=
(
config
[
'diameter'
]
*
50
)
**
2
*
np
.
pi
# cm^2
config
[
'aperature_area'
]
=
(
config
[
'diameter'
]
*
50
)
**
2
*
np
.
pi
# cm^2
config
[
'default_band'
]
=
list
(
config
[
'bands'
].
keys
())[
0
]
config
[
'default_band'
]
=
list
(
config
[
'bands'
].
keys
())[
0
]
config
[
'default_filter'
]
=
config
[
'bands'
][
config
[
'default_band'
]]
config
[
'default_filter'
]
=
config
[
'bands'
][
config
[
'default_band'
]]
setup_config
({})
setup_config
({})
def
which_focalplane
(
band
):
def
which_focalplane
(
band
):
"""
"""
Return the name of the focalplane which the band belongs to.
Return the name of the focalplane which the band belongs to.
...
@@ -171,7 +176,6 @@ def which_focalplane(band):
...
@@ -171,7 +176,6 @@ def which_focalplane(band):
-----------
-----------
band: str
band: str
The name of the band.
The name of the band.
Returns
Returns
--------
--------
...
@@ -194,30 +198,32 @@ def which_focalplane(band):
...
@@ -194,30 +198,32 @@ def which_focalplane(band):
return
'vis'
return
'vis'
# raise ValueError(f"未知的波段{band}")
# raise ValueError(f"未知的波段{band}")
def
iso_time
(
time
):
def
iso_time
(
time
):
"""Transfer relative time to iso time format
"""Transfer relative time to iso time format
Parameters
Parameters
----------
----------
time: str or float
time: str or float
The relative time in seconds.
The relative time in seconds.
Returns
Returns
-------
-------
str
str
The iso time format.
The iso time format.
"""
"""
if
isinstance
(
time
,
str
):
if
isinstance
(
time
,
str
):
_
=
datetime
.
fromisoformat
(
time
)
_
=
datetime
.
fromisoformat
(
time
)
# check if it is a iso time
return
time
return
time
utc0
=
config
[
'utc0'
]
utc0
=
config
[
'utc0'
]
time0
=
datetime
.
timestamp
(
datetime
.
fromisoformat
(
utc0
))
time0
=
datetime
.
timestamp
(
datetime
.
fromisoformat
(
utc0
))
time
=
datetime
.
fromtimestamp
(
time0
+
time
)
time
=
datetime
.
fromtimestamp
(
time0
+
time
)
return
time
.
isoformat
()
return
time
.
isoformat
()
def
relative_time
(
time
):
def
relative_time
(
time
):
"""Transfer iso time format to relative time in seconds
"""Transfer iso time format to relative time in seconds
...
@@ -225,7 +231,7 @@ def relative_time(time):
...
@@ -225,7 +231,7 @@ def relative_time(time):
----------
----------
time: str or float
time: str or float
The iso time format.
The iso time format.
Returns
Returns
-------
-------
float
float
...
@@ -236,8 +242,7 @@ def relative_time(time):
...
@@ -236,8 +242,7 @@ def relative_time(time):
return
time
return
time
if
isinstance
(
time
,
int
):
if
isinstance
(
time
,
int
):
return
float
(
time
)
return
float
(
time
)
utc0
=
config
[
'utc0'
]
utc0
=
config
[
'utc0'
]
time0
=
datetime
.
timestamp
(
datetime
.
fromisoformat
(
utc0
))
time0
=
datetime
.
timestamp
(
datetime
.
fromisoformat
(
utc0
))
return
datetime
.
timestamp
(
datetime
.
fromisoformat
(
time
))
-
time0
return
datetime
.
timestamp
(
datetime
.
fromisoformat
(
time
))
-
time0
\ No newline at end of file
csst_cpic_sim/io.py
View file @
190f1129
import
yaml
,
os
,
re
import
yaml
import
os
from
datetime
import
datetime
from
datetime
import
datetime
import
numpy
as
np
import
numpy
as
np
import
pandas
as
pd
import
pandas
as
pd
from
astropy.io
import
fits
from
astropy.io
import
fits
from
astropy.coordinates
import
SkyCoord
from
astropy.coordinates
import
SkyCoord
import
astropy.units
as
u
from
.config
import
__version__
,
which_focalplane
from
.config
import
__version__
,
which_focalplane
from
.utils
import
Logger
from
.utils
import
Logger
from
.config
import
config
,
iso_time
from
.config
import
config
,
iso_time
...
@@ -14,13 +16,16 @@ default_output_dir = config['output']
...
@@ -14,13 +16,16 @@ default_output_dir = config['output']
log_level
=
config
[
'log_level'
]
log_level
=
config
[
'log_level'
]
header_check
=
config
[
'check_fits_header'
]
header_check
=
config
[
'check_fits_header'
]
def
set_up_logger
(
log_dir
):
def
set_up_logger
(
log_dir
):
if
not
os
.
path
.
exists
(
log_dir
):
if
not
os
.
path
.
exists
(
log_dir
):
os
.
makedirs
(
log_dir
)
os
.
makedirs
(
log_dir
)
return
Logger
(
log_dir
+
'/cpism_pack.log'
,
log_level
).
logger
return
Logger
(
log_dir
+
'/cpism_pack.log'
,
log_level
).
logger
log
=
set_up_logger
(
config
[
'log_dir'
])
log
=
set_up_logger
(
config
[
'log_dir'
])
def
check_and_update_fits_header
(
header
):
def
check_and_update_fits_header
(
header
):
"""
"""
Check the header keywords and update the description according to the data model.
Check the header keywords and update the description according to the data model.
...
@@ -43,7 +48,7 @@ def check_and_update_fits_header(header):
...
@@ -43,7 +48,7 @@ def check_and_update_fits_header(header):
data_model
=
yaml
.
load
(
fid
,
Loader
=
yaml
.
FullLoader
)
data_model
=
yaml
.
load
(
fid
,
Loader
=
yaml
.
FullLoader
)
if
'FILETYPE'
in
header
.
keys
():
if
'FILETYPE'
in
header
.
keys
():
header_model
=
data_model
[
'HDU0'
]
header_model
=
data_model
[
'HDU0'
]
hdu
=
'hdu0'
hdu
=
'hdu0'
else
:
else
:
header_model
=
data_model
[
'HDU1'
]
header_model
=
data_model
[
'HDU1'
]
...
@@ -88,9 +93,14 @@ def check_and_update_fits_header(header):
...
@@ -88,9 +93,14 @@ def check_and_update_fits_header(header):
else
:
else
:
key_type
=
'ukn'
key_type
=
'ukn'
# print(f"keyword: {keyword} type: {key_type}, datamodel: {dtype}, value: {value}")
if
key_type
!=
dtype
[
0
:
3
]:
if
key_type
!=
dtype
[
0
:
3
]:
print_warning
(
if
key_type
==
'int'
and
dtype
[
0
:
3
]
==
'flo'
:
f
"Keyword
{
keyword
}
has wrong type in [
{
hdu
}
].
{
dtype
}
expected,
{
key_type
}
found."
)
header
[
keyword
]
=
float
(
header
[
keyword
])
# print('transfer int to float with header keyword:', keyword)
else
:
print_warning
(
f
"Keyword
{
keyword
}
has wrong type in [
{
hdu
}
].
{
dtype
}
expected,
{
key_type
}
found."
)
# check if there are extral keyword in header, and update the comment
# check if there are extral keyword in header, and update the comment
for
keyword
in
header
.
keys
():
for
keyword
in
header
.
keys
():
...
@@ -98,7 +108,7 @@ def check_and_update_fits_header(header):
...
@@ -98,7 +108,7 @@ def check_and_update_fits_header(header):
if
keyword
not
in
dm_comment
.
keys
():
if
keyword
not
in
dm_comment
.
keys
():
print_warning
(
print_warning
(
f
"Keyword
{
keyword
}
not found in the [
{
hdu
}
] data model."
)
f
"Keyword
{
keyword
}
not found in the [
{
hdu
}
] data model."
)
elif
keyword
!=
'COMMENT'
:
# comment keyword is not allowed to be updated
elif
keyword
!=
'COMMENT'
:
# comment keyword is not allowed to be updated
header
[
keyword
]
=
(
header
[
keyword
],
dm_comment
[
keyword
])
header
[
keyword
]
=
(
header
[
keyword
],
dm_comment
[
keyword
])
return
header
return
header
...
@@ -146,6 +156,27 @@ def obsid_parser(
...
@@ -146,6 +156,27 @@ def obsid_parser(
return
obstype
return
obstype
def
datetime_obj_to_iso
(
time_obj
):
"""
transfer datetime object to iso format used in csst fits file
example '2014-02-10T12:32:12.4'
Parameters
----------
time_obj: datetime.datetime
The datetime object.
Returns
-------
str
The iso format of the datetime object.
"""
isotime
=
time_obj
.
isoformat
(
sep
=
'T'
,
timespec
=
'milliseconds'
)
subsec
=
str
(
round
(
float
(
isotime
[
19
:
22
]),
1
))
return
isotime
[:
18
]
+
subsec
def
datetime_obj_to_mjd
(
time_obj
):
def
datetime_obj_to_mjd
(
time_obj
):
"""
"""
transfer datetime object to mean julian date (MJD).
transfer datetime object to mean julian date (MJD).
...
@@ -225,7 +256,7 @@ def primary_hdu(
...
@@ -225,7 +256,7 @@ def primary_hdu(
header
[
'NEXTEND'
]
=
1
# + parameters['nframe']
header
[
'NEXTEND'
]
=
1
# + parameters['nframe']
# header['GROUPS'] = False
# header['GROUPS'] = False
header
[
'DATE'
]
=
datetime
.
now
().
isoform
at
(
time
spec
=
'seconds'
)
header
[
'DATE'
]
=
datetime
_obj_to_iso
(
d
at
e
time
.
now
()
)
heaer_filename
=
filename
[:
-
4
]
heaer_filename
=
filename
[:
-
4
]
if
len
(
heaer_filename
)
>
68
:
if
len
(
heaer_filename
)
>
68
:
heaer_filename
=
heaer_filename
[:
68
]
heaer_filename
=
heaer_filename
[:
68
]
...
@@ -243,8 +274,10 @@ def primary_hdu(
...
@@ -243,8 +274,10 @@ def primary_hdu(
cstar
=
obs_info
[
'target'
][
'cstar'
]
cstar
=
obs_info
[
'target'
][
'cstar'
]
radec
=
SkyCoord
(
cstar
[
'ra'
],
cstar
[
'dec'
])
radec
=
SkyCoord
(
cstar
[
'ra'
],
cstar
[
'dec'
])
target_name
=
radec
.
to_string
(
'hmsdms'
)
ra_str
=
radec
.
ra
.
to_string
(
unit
=
u
.
hour
,
sep
=
''
,
precision
=
1
,
pad
=
True
)
target_name
=
re
.
sub
(
R
'[hdms\s]'
,
''
,
target_name
)
dec_str
=
radec
.
dec
.
to_string
(
unit
=
u
.
deg
,
sep
=
''
,
alwayssign
=
True
,
pad
=
True
)
target_name
=
ra_str
+
dec_str
header
[
'OBJECT'
]
=
cstar
.
get
(
'name'
,
target_name
)
header
[
'OBJECT'
]
=
cstar
.
get
(
'name'
,
target_name
)
header
[
'TARGET'
]
=
target_name
header
[
'TARGET'
]
=
target_name
header
[
'OBSID'
]
=
str
(
obsid
)
header
[
'OBSID'
]
=
str
(
obsid
)
...
@@ -253,7 +286,7 @@ def primary_hdu(
...
@@ -253,7 +286,7 @@ def primary_hdu(
# telescope information
# telescope information
header
[
'REFFRAME'
]
=
'CSSTGSC-1.0'
header
[
'REFFRAME'
]
=
'CSSTGSC-1.0'
header
[
'DATE-OBS'
]
=
exp_start
.
isoformat
(
timespec
=
'seconds'
)
header
[
'DATE-OBS'
]
=
datetime_obj_to_iso
(
exp_start
)
header
[
'SATESWV'
]
=
'1'
header
[
'SATESWV'
]
=
'1'
header
[
'EXPSTART'
]
=
datetime_obj_to_mjd
(
exp_start
)
header
[
'EXPSTART'
]
=
datetime_obj_to_mjd
(
exp_start
)
...
@@ -299,10 +332,10 @@ def primary_hdu(
...
@@ -299,10 +332,10 @@ def primary_hdu(
header
[
'EULER1_3'
]
=
gnc_info
.
get
(
'EULER1_3'
,
header
[
'EULER0_3'
])
header
[
'EULER1_3'
]
=
gnc_info
.
get
(
'EULER1_3'
,
header
[
'EULER0_3'
])
header
[
'RA_PNT1'
]
=
gnc_info
.
get
(
'RA_PNT1'
,
header
[
'RA_PNT0'
])
header
[
'RA_PNT1'
]
=
gnc_info
.
get
(
'RA_PNT1'
,
header
[
'RA_PNT0'
])
header
[
'DEC_PNT1'
]
=
gnc_info
.
get
(
'DEC_PNT1'
,
header
[
'DEC_PNT0'
])
header
[
'DEC_PNT1'
]
=
gnc_info
.
get
(
'DEC_PNT1'
,
header
[
'DEC_PNT0'
])
header
[
'EPOCH'
]
=
float
(
exp_start
.
year
)
header
[
'EPOCH'
]
=
float
(
exp_start
.
year
)
header
[
'EXPTIME'
]
=
(
exp_end
-
exp_start
).
total_seconds
()
header
[
'EXPTIME'
]
=
(
exp_end
-
exp_start
).
total_seconds
()
header
[
'CHECKSUM'
]
=
'0000000000000000'
header
[
'CHECKSUM'
]
=
'0000000000000000'
header
[
'DATASUM'
]
=
'0000000000'
header
[
'DATASUM'
]
=
'0000000000'
...
@@ -368,12 +401,12 @@ def frame_header(obs_info, index, primary_header, camera_dict):
...
@@ -368,12 +401,12 @@ def frame_header(obs_info, index, primary_header, camera_dict):
header
[
'BUNIT'
]
=
'ADU'
header
[
'BUNIT'
]
=
'ADU'
header
[
'FILTER'
]
=
obs_info
[
'band'
]
header
[
'FILTER'
]
=
obs_info
[
'band'
]
header
[
'DETSN'
]
=
'0'
header
[
'DETSN'
]
=
'0
0000000000
'
header
[
'DETNAME'
]
=
camera_config
[
'detector_name'
]
header
[
'DETNAME'
]
=
camera_config
[
'detector_name'
]
header
[
'CHIPLAB'
]
=
camera_config
[
'ccd_label'
]
header
[
'CHIPLAB'
]
=
camera_config
[
'ccd_label'
]
header
[
'DEWTEMP'
]
=
float
(
camera_config
[
'cooler_temp'
])
header
[
'DEWTEMP'
]
=
float
(
camera_config
[
'cooler_temp'
])
+
273.15
frame_info
=
obs_info
[
'frame_info'
][
index
]
frame_info
=
obs_info
[
'frame_info'
][
index
]
header
[
'CHIPTEMP'
]
=
float
(
frame_info
[
'chiptemp'
])
header
[
'CHIPTEMP'
]
=
float
(
frame_info
[
'chiptemp'
])
+
273.15
header
[
'DETSIZE'
]
=
f
"
{
imgszx
}
*
{
imgszy
}
"
header
[
'DETSIZE'
]
=
f
"
{
imgszx
}
*
{
imgszy
}
"
header
[
'IMGINDEX'
]
=
index
+
1
header
[
'IMGINDEX'
]
=
index
+
1
...
@@ -513,7 +546,6 @@ def save_fits_simple(images, obs_info, output_folder='./'):
...
@@ -513,7 +546,6 @@ def save_fits_simple(images, obs_info, output_folder='./'):
shift
=
obs_info
[
'shift'
]
shift
=
obs_info
[
'shift'
]
header
[
'shift'
]
=
f
"x:
{
shift
[
0
]
}
,y:
{
shift
[
1
]
}
"
header
[
'shift'
]
=
f
"x:
{
shift
[
0
]
}
,y:
{
shift
[
1
]
}
"
fullname
=
os
.
path
.
join
(
output_folder
,
filename
)
fullname
=
os
.
path
.
join
(
output_folder
,
filename
)
print
(
fullname
)
print
(
fullname
)
if
not
os
.
path
.
exists
(
output_folder
):
if
not
os
.
path
.
exists
(
output_folder
):
...
...
csst_cpic_sim/main.py
View file @
190f1129
import
argparse
,
sys
,
tqdm
,
time
,
os
,
yaml
import
argparse
import
tqdm
import
time
import
os
import
yaml
from
glob
import
glob
from
glob
import
glob
from
datetime
import
datetime
from
datetime
import
datetime
import
traceback
import
traceback
...
@@ -25,8 +30,8 @@ def vis_observation(
...
@@ -25,8 +30,8 @@ def vis_observation(
shift
:
list
=
[
0
,
0
],
shift
:
list
=
[
0
,
0
],
gnc_info
:
dict
=
{},
gnc_info
:
dict
=
{},
csst_format
:
bool
=
True
,
csst_format
:
bool
=
True
,
camera
=
CpicVisEmccd
(),
camera
=
CpicVisEmccd
(),
crmaker
=
CosmicRayFrameMaker
(),
crmaker
=
CosmicRayFrameMaker
(),
nsample
:
int
=
1
,
nsample
:
int
=
1
,
emgain
=
None
,
emgain
=
None
,
prograss_bar
=
None
,
prograss_bar
=
None
,
...
@@ -49,7 +54,8 @@ def vis_observation(
...
@@ -49,7 +54,8 @@ def vis_observation(
emset: int
emset: int
EM gain setting value. 1023(0x3FF) for ~1.0× EM gain.
EM gain setting value. 1023(0x3FF) for ~1.0× EM gain.
obsid: int
obsid: int
observation ID. Start from 4 for CPIC, 01 for science observation. See the input of io.obsid_parser for more details.
observation ID. Start from 4 for CPIC, 01 for science observation.
See the input of io.obsid_parser for more details.
rotation: float
rotation: float
rotation of the telescope. in unit of degree. 0 means North is up.
rotation of the telescope. in unit of degree. 0 means North is up.
shift: list
shift: list
...
@@ -174,6 +180,7 @@ def vis_observation(
...
@@ -174,6 +180,7 @@ def vis_observation(
print
(
f
'
\r
Done [
{
time
.
time
()
-
start_time
:
.
1
f
}
s] '
)
print
(
f
'
\r
Done [
{
time
.
time
()
-
start_time
:
.
1
f
}
s] '
)
return
image_cube
return
image_cube
def
quick_run_v2
(
def
quick_run_v2
(
target_str
:
str
,
target_str
:
str
,
band
:
str
,
band
:
str
,
...
@@ -183,12 +190,12 @@ def quick_run_v2(
...
@@ -183,12 +190,12 @@ def quick_run_v2(
skybg
:
float
=
None
,
skybg
:
float
=
None
,
rotation
:
float
=
0
,
rotation
:
float
=
0
,
shift
:
list
=
[
0
,
0
],
shift
:
list
=
[
0
,
0
],
emset_input
:
bool
=
False
,
emset_input
:
bool
=
False
,
cr_frame
:
bool
=
True
,
cr_frame
:
bool
=
True
,
camera_effect
:
bool
=
True
,
camera_effect
:
bool
=
True
,
prograss_bar
=
False
,
prograss_bar
=
False
,
output
=
'./'
)
->
np
.
ndarray
:
output
=
'./'
)
->
np
.
ndarray
:
"""A quick run function for CPIC.
"""A quick run function for CPIC.
Parameters
Parameters
...
@@ -226,7 +233,6 @@ def quick_run_v2(
...
@@ -226,7 +233,6 @@ def quick_run_v2(
"""
"""
print
(
f
'Quick Run:
{
target_str
}
'
)
print
(
f
'Quick Run:
{
target_str
}
'
)
log
.
debug
(
log
.
debug
(
f
"""input parameters:
f
"""input parameters:
target_str:
{
target_str
}
target_str:
{
target_str
}
...
@@ -257,7 +263,7 @@ def quick_run_v2(
...
@@ -257,7 +263,7 @@ def quick_run_v2(
camera
.
switch
[
'bias_vp'
]
=
False
camera
.
switch
[
'bias_vp'
]
=
False
camera
.
switch
[
'bias_hp'
]
=
False
camera
.
switch
[
'bias_hp'
]
=
False
camera
.
switch
[
'bias_ci'
]
=
False
camera
.
switch
[
'bias_ci'
]
=
False
camera
.
switch
[
'bias_shift'
]
=
False
camera
.
switch
[
'bias_shift'
]
=
False
camera
.
switch
[
'badcolumn'
]
=
False
camera
.
switch
[
'badcolumn'
]
=
False
camera
.
switch
[
'flat'
]
=
False
camera
.
switch
[
'flat'
]
=
False
camera
.
switch
[
'cte'
]
=
False
camera
.
switch
[
'cte'
]
=
False
...
@@ -283,10 +289,9 @@ def quick_run_v2(
...
@@ -283,10 +289,9 @@ def quick_run_v2(
)
)
def
deduplicate_names_add_count
(
names
:
list
):
def
deduplicate_names_add_count
(
names
:
list
):
"""remove duplicate names and add count"""
"""remove duplicate names and add count"""
for
i
in
range
(
len
(
names
)
-
1
,
-
1
,
-
1
):
for
i
in
range
(
len
(
names
)
-
1
,
-
1
,
-
1
):
if
names
.
count
(
names
[
i
])
>
1
:
if
names
.
count
(
names
[
i
])
>
1
:
names
[
i
]
=
names
[
i
]
+
'_'
+
str
(
names
.
count
(
names
[
i
]))
names
[
i
]
=
names
[
i
]
+
'_'
+
str
(
names
.
count
(
names
[
i
]))
...
@@ -302,7 +307,7 @@ def observation_simulation_from_config(obs_file, config_file):
...
@@ -302,7 +307,7 @@ def observation_simulation_from_config(obs_file, config_file):
config file.
config file.
Examples:
Examples:
see examples in `example` folder.
see examples in `example` folder.
"""
"""
config
=
{}
config
=
{}
if
config_file
:
if
config_file
:
...
@@ -315,17 +320,17 @@ def observation_simulation_from_config(obs_file, config_file):
...
@@ -315,17 +320,17 @@ def observation_simulation_from_config(obs_file, config_file):
for
c_config
in
camera_config
:
for
c_config
in
camera_config
:
all_camera
.
append
(
CpicVisEmccd
(
c_config
))
all_camera
.
append
(
CpicVisEmccd
(
c_config
))
all_camera_name
.
append
(
c_config
.
get
(
'name'
,
'camera'
))
all_camera_name
.
append
(
c_config
.
get
(
'name'
,
'camera'
))
deduplicate_names_add_count
(
all_camera_name
)
deduplicate_names_add_count
(
all_camera_name
)
for
key
in
config
.
keys
():
for
key
in
config
.
keys
():
if
key
in
update_able_keys
:
if
key
in
update_able_keys
:
default_config
[
key
]
=
config
[
key
]
default_config
[
key
]
=
config
[
key
]
output_folder
=
default_config
[
'output'
]
output_folder
=
default_config
[
'output'
]
csst_format
=
default_config
[
'csst_format'
]
csst_format
=
default_config
[
'csst_format'
]
nsample
=
default_config
[
'nsample'
]
nsample
=
default_config
[
'nsample'
]
obs_file
=
os
.
path
.
abspath
(
obs_file
)
obs_file
=
os
.
path
.
abspath
(
obs_file
)
file_list
=
[]
file_list
=
[]
...
@@ -333,11 +338,10 @@ def observation_simulation_from_config(obs_file, config_file):
...
@@ -333,11 +338,10 @@ def observation_simulation_from_config(obs_file, config_file):
file_list
=
glob
(
f
"
{
obs_file
}
/*.yaml"
)
file_list
=
glob
(
f
"
{
obs_file
}
/*.yaml"
)
elif
'.yaml'
==
obs_file
[
-
5
:]:
elif
'.yaml'
==
obs_file
[
-
5
:]:
file_list
=
[
obs_file
]
file_list
=
[
obs_file
]
if
not
file_list
:
if
not
file_list
:
log
.
warning
(
f
"No observation file found in
{
obs_file
}
"
)
log
.
warning
(
f
"No observation file found in
{
obs_file
}
"
)
for
ind_target
,
file
in
enumerate
(
file_list
):
for
ind_target
,
file
in
enumerate
(
file_list
):
try
:
try
:
with
open
(
file
,
'r'
)
as
fid
:
with
open
(
file
,
'r'
)
as
fid
:
...
@@ -405,15 +409,16 @@ def observation_simulation_from_config(obs_file, config_file):
...
@@ -405,15 +409,16 @@ def observation_simulation_from_config(obs_file, config_file):
except
Exception
as
e
:
except
Exception
as
e
:
log
.
error
(
f
"
{
info_text
}
failed with
{
type
(
e
).
__name__
}{
e
}
.
\n\n
{
traceback
.
format_exc
()
}
"
)
log
.
error
(
f
"
{
info_text
}
failed with
{
type
(
e
).
__name__
}{
e
}
.
\n\n
{
traceback
.
format_exc
()
}
"
)
def
main
(
argv
=
None
):
def
main
(
argv
=
None
):
"""
"""
Command line interface of csst_cpic_sim
Command line interface of csst_cpic_sim
Parameters
Parameters
-----------
-----------
argv: list
argv: list
input arguments. Default is None. If None, sys.argv is used.
input arguments. Default is None. If None, sys.argv is used.
"""
"""
parser
=
argparse
.
ArgumentParser
(
description
=
'Cpic obsevation image simulation'
)
parser
=
argparse
.
ArgumentParser
(
description
=
'Cpic obsevation image simulation'
)
parser
.
set_defaults
(
func
=
lambda
_
:
parser
.
print_usage
())
parser
.
set_defaults
(
func
=
lambda
_
:
parser
.
print_usage
())
...
@@ -426,10 +431,18 @@ def main(argv=None):
...
@@ -426,10 +431,18 @@ def main(argv=None):
parser_quickrun
.
add_argument
(
'nframe'
,
type
=
int
,
help
=
'number of frames'
)
parser_quickrun
.
add_argument
(
'nframe'
,
type
=
int
,
help
=
'number of frames'
)
parser_quickrun
.
add_argument
(
'-b'
,
'--band'
,
type
=
str
,
default
=
'f661'
,
help
=
'band, one of f565/f661/f743/f883'
)
parser_quickrun
.
add_argument
(
'-b'
,
'--band'
,
type
=
str
,
default
=
'f661'
,
help
=
'band, one of f565/f661/f743/f883'
)
parser_quickrun
.
add_argument
(
'-r'
,
'--rotation'
,
type
=
float
,
default
=
0
,
help
=
'rotation angle [degree]'
)
parser_quickrun
.
add_argument
(
'-r'
,
'--rotation'
,
type
=
float
,
default
=
0
,
help
=
'rotation angle [degree]'
)
parser_quickrun
.
add_argument
(
'-s'
,
'--skybk'
,
type
=
float
,
default
=
21
,
help
=
'magnitude of sky background [mag/arcsec^2]'
)
parser_quickrun
.
add_argument
(
parser_quickrun
.
add_argument
(
'-f'
,
'--cr_frame'
,
action
=
'store_true'
,
help
=
'if True, cosmic ray frame will be added'
)
'-s'
,
'--skybk'
,
type
=
float
,
default
=
21
,
parser_quickrun
.
add_argument
(
'-e'
,
'--emset'
,
action
=
'store_true'
,
help
=
'if True, emgain set value will be used as input'
)
help
=
'magnitude of sky background [mag/arcsec^2]'
)
parser_quickrun
.
add_argument
(
'-c'
,
'--camera_effect'
,
action
=
'store_true'
,
help
=
'if True, camera effect will be added'
)
parser_quickrun
.
add_argument
(
'-f'
,
'--cr_frame'
,
action
=
'store_true'
,
help
=
'if True, cosmic ray frame will be added'
)
parser_quickrun
.
add_argument
(
'-e'
,
'--emset'
,
action
=
'store_true'
,
help
=
'if True, emgain set value will be used as input'
)
parser_quickrun
.
add_argument
(
'-c'
,
'--camera_effect'
,
action
=
'store_true'
,
help
=
'if True, camera effect will be added'
)
parser_quickrun
.
add_argument
(
'-o'
,
'--output'
,
type
=
str
,
default
=
'./'
,
help
=
'output folder'
)
parser_quickrun
.
add_argument
(
'-o'
,
'--output'
,
type
=
str
,
default
=
'./'
,
help
=
'output folder'
)
def
quick_run_call
(
args
):
def
quick_run_call
(
args
):
...
@@ -464,7 +477,7 @@ def main(argv=None):
...
@@ -464,7 +477,7 @@ def main(argv=None):
args
=
parser
.
parse_args
(
argv
)
args
=
parser
.
parse_args
(
argv
)
args
.
func
(
args
)
args
.
func
(
args
)
# if __name__ == '__main__': # pragma: no cover
# if __name__ == '__main__': # pragma: no cover
# sys.exit(main())
# sys.exit(main())
...
...
csst_cpic_sim/optics.py
View file @
190f1129
...
@@ -79,9 +79,9 @@ def ideal_focus_image(
...
@@ -79,9 +79,9 @@ def ideal_focus_image(
np.ndarray
np.ndarray
The ideal focus image.
The ideal focus image.
"""
"""
focal_image
=
np
.
zeros
(
platesize
)
focal_image
=
np
.
zeros
(
platesize
)
focal_shape
=
np
.
array
(
platesize
)[::
-
1
]
# x, y
focal_shape
=
np
.
array
(
platesize
)[::
-
1
]
# x, y
if
not
targets
:
if
not
targets
:
return
focal_image
return
focal_image
...
@@ -109,7 +109,7 @@ def ideal_focus_image(
...
@@ -109,7 +109,7 @@ def ideal_focus_image(
sub
=
np
.
array
([
sub
=
np
.
array
([
[
dx0
*
dy0
,
dx1
*
dy0
],
[
dx0
*
dy0
,
dx1
*
dy0
],
[
dx0
*
dy1
,
dx1
*
dy1
]])
*
sed
[
dx0
*
dy1
,
dx1
*
dy1
]])
*
sed
focal_image
[
int_y
:
int_y
+
2
,
int_x
:
int_x
+
2
]
+=
sub
focal_image
[
int_y
:
int_y
+
2
,
int_x
:
int_x
+
2
]
+=
sub
else
:
else
:
# sub_image = sub_image
# sub_image = sub_image
...
@@ -133,9 +133,9 @@ def focal_convolve(
...
@@ -133,9 +133,9 @@ def focal_convolve(
rotation
:
float
=
0
,
rotation
:
float
=
0
,
nsample
:
int
=
5
,
nsample
:
int
=
5
,
error
:
float
=
0
,
error
:
float
=
0
,
platesize
:
list
=
[
1024
,
1024
])
->
np
.
ndarray
:
platesize
:
list
=
[
1024
,
1024
])
->
np
.
ndarray
:
"""PSF convolution of the ideal focus image.
"""PSF convolution of the ideal focus image.
Parameters
Parameters
----------
----------
band: str
band: str
...
@@ -163,10 +163,10 @@ def focal_convolve(
...
@@ -163,10 +163,10 @@ def focal_convolve(
area
=
config
[
'aperature_area'
]
area
=
config
[
'aperature_area'
]
filter
=
filter_throughput
(
band
)
filter
=
filter_throughput
(
band
)
throughput
=
filter
.
throughput
throughput
=
filter
.
throughput
wave
=
filter
.
wave
wave
=
filter
.
wave
throughput_criterion
=
throughput
.
max
()
*
0.1
throughput_criterion
=
throughput
.
max
()
*
0.1
wave_criterion
=
wave
[
throughput
>
throughput_criterion
]
wave_criterion
=
wave
[
throughput
>
throughput_criterion
]
min_wave
=
wave_criterion
[
0
]
min_wave
=
wave_criterion
[
0
]
...
@@ -179,33 +179,33 @@ def focal_convolve(
...
@@ -179,33 +179,33 @@ def focal_convolve(
if
abs
(
init_shifts
[
0
])
>
4
or
abs
(
init_shifts
[
1
])
>
4
:
if
abs
(
init_shifts
[
0
])
>
4
or
abs
(
init_shifts
[
1
])
>
4
:
print
(
'Input shifts are too large, and are set to zero'
)
print
(
'Input shifts are too large, and are set to zero'
)
init_shifts
=
[
0
,
0
]
init_shifts
=
[
0
,
0
]
all_fp_image
=
[]
all_fp_image
=
[]
if
not
targets
:
if
not
targets
:
return
np
.
zeros
((
platesize
[
1
],
platesize
[
0
]))
return
np
.
zeros
((
platesize
[
1
],
platesize
[
0
]))
for
i_wave
in
range
(
nsample
):
for
i_wave
in
range
(
nsample
):
d_wave
=
(
max_wave
-
min_wave
)
/
nsample
d_wave
=
(
max_wave
-
min_wave
)
/
nsample
wave0
=
min_wave
+
i_wave
*
d_wave
wave0
=
min_wave
+
i_wave
*
d_wave
wave1
=
min_wave
+
(
i_wave
+
1
)
*
d_wave
wave1
=
min_wave
+
(
i_wave
+
1
)
*
d_wave
center_wavelength
=
(
wave0
+
wave1
)
/
2
*
1e-10
center_wavelength
=
(
wave0
+
wave1
)
/
2
*
1e-10
i_throughput
=
throughput
.
copy
()
i_throughput
=
throughput
.
copy
()
i_throughput
[(
wave
>
wave1
)
|
(
wave
<
wave0
)]
=
0
i_throughput
[(
wave
>
wave1
)
|
(
wave
<
wave0
)]
=
0
i_band
=
S
.
ArrayBandpass
(
wave
,
i_throughput
,
waveunits
=
'angstrom'
)
i_band
=
S
.
ArrayBandpass
(
wave
,
i_throughput
,
waveunits
=
'angstrom'
)
i_fp_image
=
ideal_focus_image
(
i_band
,
targets
[
1
:],
platescale
,
platesize
,
init_shifts
,
rotation
)
i_fp_image
=
ideal_focus_image
(
i_band
,
targets
[
1
:],
platescale
,
platesize
,
init_shifts
,
rotation
)
psf
=
single_band_psf
(
center_wavelength
,
error
=
error
)
psf
=
single_band_psf
(
center_wavelength
,
error
=
error
)
_
,
_
,
cstar_sp
,
_
=
targets
[
0
]
_
,
_
,
cstar_sp
,
_
=
targets
[
0
]
cstar_flux
=
(
cstar_sp
*
i_band
).
integrate
()
cstar_flux
=
(
cstar_sp
*
i_band
).
integrate
()
cstar_psf
=
single_band_masked_psf
(
center_wavelength
,
error
=
error
,
shift
=
init_shifts
)
cstar_psf
=
single_band_masked_psf
(
center_wavelength
,
error
=
error
,
shift
=
init_shifts
)
c_fp_image
=
fftconvolve
(
i_fp_image
,
psf
,
mode
=
'same'
)
c_fp_image
=
fftconvolve
(
i_fp_image
,
psf
,
mode
=
'same'
)
c_fp_image
=
focal_mask
(
c_fp_image
,
iwa
,
platescale
)
c_fp_image
=
focal_mask
(
c_fp_image
,
iwa
,
platescale
)
c_fp_image
=
c_fp_image
+
cstar_flux
*
cstar_psf
c_fp_image
=
c_fp_image
+
cstar_flux
*
cstar_psf
all_fp_image
.
append
(
c_fp_image
*
area
)
# trans to photon/second
all_fp_image
.
append
(
c_fp_image
*
area
)
# trans to photon/second
return
np
.
array
(
all_fp_image
).
sum
(
axis
=
0
)
return
np
.
array
(
all_fp_image
).
sum
(
axis
=
0
)
...
...
csst_cpic_sim/psf_simulation.py
View file @
190f1129
import
os
,
pickle
import
os
import
pickle
import
numpy
as
np
import
numpy
as
np
from
astropy.io
import
fits
from
astropy.io
import
fits
...
@@ -23,12 +24,12 @@ pupil_diameter = 2 # m
...
@@ -23,12 +24,12 @@ pupil_diameter = 2 # m
F_number
=
83
F_number
=
83
focal_length
=
pupil_diameter
*
F_number
focal_length
=
pupil_diameter
*
F_number
pupil_shape
=
apm
.
shape
pupil_shape
=
apm
.
shape
pupil_rate
=
apm_header
[
'PHRATE'
]
# meter/pixel
pupil_rate
=
apm_header
[
'PHRATE'
]
# meter/pixel
pupil_grid
=
make_pupil_grid
(
pupil_shape
[
0
],
pupil_shape
[
0
]
*
pupil_rate
)
pupil_grid
=
make_pupil_grid
(
pupil_shape
[
0
],
pupil_shape
[
0
]
*
pupil_rate
)
aperture
=
make_circular_aperture
(
pupil_diameter
)(
pupil_grid
)
aperture
=
make_circular_aperture
(
pupil_diameter
)(
pupil_grid
)
aperture
=
aperture
*
Field
(
apm
.
flatten
(),
pupil_grid
)
aperture
=
aperture
*
Field
(
apm
.
flatten
(),
pupil_grid
)
second_pupil_size
=
pupil_diameter
*
2
# just gauss a number
second_pupil_size
=
pupil_diameter
*
2
# just gauss a number
second_aperture
=
make_circular_aperture
(
second_pupil_size
)(
pupil_grid
)
second_aperture
=
make_circular_aperture
(
second_pupil_size
)(
pupil_grid
)
lyot_stop
=
ComplexSurfaceApodizer
(
second_aperture
,
second_aperture
*
0
,
lambda
_
:
2
)
lyot_stop
=
ComplexSurfaceApodizer
(
second_aperture
,
second_aperture
*
0
,
lambda
_
:
2
)
...
@@ -73,12 +74,13 @@ aberration = SurfaceApodizer(
...
@@ -73,12 +74,13 @@ aberration = SurfaceApodizer(
aberration_distance
=
80
*
focal_length
aberration_distance
=
80
*
focal_length
aberration
=
SurfaceAberrationAtDistance
(
aberration
,
aberration_distance
)
aberration
=
SurfaceAberrationAtDistance
(
aberration
,
aberration_distance
)
def
single_band_masked_psf
(
def
single_band_masked_psf
(
wavelength
:
float
,
wavelength
:
float
,
error
:
float
=
0
,
error
:
float
=
0
,
shift
:
list
=
[
0
,
0
])
->
np
.
ndarray
:
shift
:
list
=
[
0
,
0
])
->
np
.
ndarray
:
"""CPIC PSF considering the focal plane mask.
"""CPIC PSF considering the focal plane mask.
Parameters
Parameters
-----------
-----------
wavelength : float
wavelength : float
...
@@ -91,7 +93,7 @@ def single_band_masked_psf(
...
@@ -91,7 +93,7 @@ def single_band_masked_psf(
Returns
Returns
----------
----------
psf : np.ndarray
psf : np.ndarray
psf in the focal plane. Normalized as the input flux is 1.
psf in the focal plane. Normalized as the input flux is 1.
(Note that total flux of the psf is not 1, because it is masked)
(Note that total flux of the psf is not 1, because it is masked)
"""
"""
error
=
np
.
random
.
normal
(
0
,
error
*
1e-9
,
actuator
.
shape
)
error
=
np
.
random
.
normal
(
0
,
error
*
1e-9
,
actuator
.
shape
)
...
@@ -99,8 +101,10 @@ def single_band_masked_psf(
...
@@ -99,8 +101,10 @@ def single_band_masked_psf(
wf
=
Wavefront
(
aperture
,
wavelength
)
wf
=
Wavefront
(
aperture
,
wavelength
)
shift
=
np
.
array
(
shift
)
*
ARCSEC2RAD
/
2
shift
=
np
.
array
(
shift
)
*
ARCSEC2RAD
/
2
tiptilt_mirror
.
actuators
=
shift
tiptilt_mirror
.
actuators
=
shift
wf
=
tiptilt_mirror
(
wf
)
wf
=
aberration
(
wf
)
wf
=
aberration
(
wf
)
wf
=
tiptilt_mirror
(
wf
)
first_focal
=
prop_full_frame
(
deformable_mirror
(
wf
))
first_focal
=
prop_full_frame
(
deformable_mirror
(
wf
))
strength
=
first_focal
.
intensity
.
shaped
.
sum
()
strength
=
first_focal
.
intensity
.
shaped
.
sum
()
...
@@ -109,8 +113,43 @@ def single_band_masked_psf(
...
@@ -109,8 +113,43 @@ def single_band_masked_psf(
psf
=
second_focal
.
intensity
.
shaped
psf
=
second_focal
.
intensity
.
shaped
return
psf
/
strength
return
psf
/
strength
def
single_band_shift_psf
(
wavelength
:
float
,
error
:
float
=
0
,
shift
:
list
=
[
0
,
0
])
->
np
.
ndarray
:
"""CPIC PSF considering the focal plane mask.
Parameters
-----------
wavelength : float
observation wavelength in meter
error : float
deformable mirror control error in nm
shift : list
angular shift of the target in arcsec.
Returns
----------
psf : np.ndarray
psf in the focal plane. Normalized as the input flux is 1.
(Note that total flux of the psf is not 1, because it is masked)
"""
error
=
np
.
random
.
normal
(
0
,
error
*
1e-9
,
actuator
.
shape
)
deformable_mirror
.
actuators
=
actuator
+
error
wf
=
Wavefront
(
aperture
,
wavelength
)
shift
=
np
.
array
(
shift
)
*
ARCSEC2RAD
/
2
tiptilt_mirror
.
actuators
=
shift
wf
=
aberration
(
wf
)
wf
=
tiptilt_mirror
(
wf
)
first_focal
=
prop_full_frame
(
deformable_mirror
(
wf
))
image
=
np
.
array
(
first_focal
.
intensity
.
shaped
)
return
image
/
image
.
sum
()
def
single_band_psf
(
def
single_band_psf
(
wavelength
:
float
,
wavelength
:
float
,
error
:
float
=
0
)
->
np
.
ndarray
:
error
:
float
=
0
)
->
np
.
ndarray
:
"""CPIC PSF without considering the focal plane mask.
"""CPIC PSF without considering the focal plane mask.
Used to simulate the off-axis PSF.
Used to simulate the off-axis PSF.
...
@@ -126,7 +165,6 @@ def single_band_psf(
...
@@ -126,7 +165,6 @@ def single_band_psf(
----------
----------
psf : np.ndarray
psf : np.ndarray
psf in the focal plane. Normalized. The total flux is 1.
psf in the focal plane. Normalized. The total flux is 1.
"""
"""
error
=
np
.
random
.
normal
(
0
,
error
*
1e-9
,
actuator
.
shape
)
error
=
np
.
random
.
normal
(
0
,
error
*
1e-9
,
actuator
.
shape
)
deformable_mirror
.
actuators
=
actuator
+
error
deformable_mirror
.
actuators
=
actuator
+
error
...
@@ -136,7 +174,6 @@ def single_band_psf(
...
@@ -136,7 +174,6 @@ def single_band_psf(
image
=
np
.
array
(
first_focal
.
intensity
.
shaped
)
image
=
np
.
array
(
first_focal
.
intensity
.
shaped
)
return
image
/
image
.
sum
()
return
image
/
image
.
sum
()
# def single_band_psf(wavelength, error=0, aber_phase=None):
# def single_band_psf(wavelength, error=0, aber_phase=None):
# error = np.random.normal(0, error*1e-9, actuator.shape)
# error = np.random.normal(0, error*1e-9, actuator.shape)
# deformable_mirror.actuators = actuator + error
# deformable_mirror.actuators = actuator + error
...
@@ -148,4 +185,4 @@ def single_band_psf(
...
@@ -148,4 +185,4 @@ def single_band_psf(
# wf = other_error(wf)
# wf = other_error(wf)
# first_focal = prop_full_frame(deformable_mirror(wf))
# first_focal = prop_full_frame(deformable_mirror(wf))
# image = np.array(first_focal.intensity.shaped)
# image = np.array(first_focal.intensity.shaped)
# return image / image.sum()
# return image / image.sum()
\ No newline at end of file
csst_cpic_sim/target.py
View file @
190f1129
import
os
,
re
,
json
,
yaml
import
os
import
re
import
json
import
yaml
from
typing
import
Union
from
typing
import
Union
import
numpy
as
np
import
numpy
as
np
from
scipy
import
constants
from
scipy
import
constants
...
@@ -24,9 +27,10 @@ BCC_MODEL_FOLDER = config['bcc_model']
...
@@ -24,9 +27,10 @@ BCC_MODEL_FOLDER = config['bcc_model']
MAG_SYSTEM
=
config
[
'mag_system'
]
MAG_SYSTEM
=
config
[
'mag_system'
]
CATALOG_CACHE
=
{}
CATALOG_CACHE
=
{}
class
AlbedoCat
(
S
.
spectrum
.
TabularSpectralElement
,
S
.
catalog
.
Icat
):
class
AlbedoCat
(
S
.
spectrum
.
TabularSpectralElement
,
S
.
catalog
.
Icat
):
"""Generate albedo spectrum from the planet reflection model in Batalha et al. 2018
"""Generate albedo spectrum from the planet reflection model in Batalha et al. 2018
Parameters
Parameters
----------
----------
phase : float
phase : float
...
@@ -45,16 +49,17 @@ class AlbedoCat(S.spectrum.TabularSpectralElement, S.catalog.Icat):
...
@@ -45,16 +49,17 @@ class AlbedoCat(S.spectrum.TabularSpectralElement, S.catalog.Icat):
---------
---------
Color Classification of Extrasolar Giant Planets: Prospects and Cautions
Color Classification of Extrasolar Giant Planets: Prospects and Cautions
Natasha E. Batalha et al 2018 AJ 156 158
Natasha E. Batalha et al 2018 AJ 156 158
"""
"""
def
__init__
(
self
,
def
__init__
(
phase
:
float
,
self
,
metallicity
:
float
,
phase
:
float
,
f_sed
:
float
,
metallicity
:
float
,
):
f_sed
:
float
,
):
catname
=
'BCCalbedo'
catname
=
'BCCalbedo'
self
.
isAnalytic
=
False
self
.
isAnalytic
=
False
self
.
name
=
f
"
{
catname
}
_
{
phase
}
_
{
metallicity
}
_
{
f_sed
}
"
self
.
name
=
f
"
{
catname
}
_
{
phase
}
_
{
metallicity
}
_
{
f_sed
}
"
self
.
parameter_names
=
[
'phase'
,
'metallicity'
,
'f_sed'
]
self
.
parameter_names
=
[
'phase'
,
'metallicity'
,
'f_sed'
]
self
.
catalog_folder
=
BCC_MODEL_FOLDER
self
.
catalog_folder
=
BCC_MODEL_FOLDER
...
@@ -66,19 +71,19 @@ class AlbedoCat(S.spectrum.TabularSpectralElement, S.catalog.Icat):
...
@@ -66,19 +71,19 @@ class AlbedoCat(S.spectrum.TabularSpectralElement, S.catalog.Icat):
with
fits
.
open
(
filename
)
as
table
:
with
fits
.
open
(
filename
)
as
table
:
indexList
=
table
[
1
].
data
.
field
(
'INDEX'
)
indexList
=
table
[
1
].
data
.
field
(
'INDEX'
)
filenameList
=
table
[
1
].
data
.
field
(
'FILENAME'
)
filenameList
=
table
[
1
].
data
.
field
(
'FILENAME'
)
indices
=
self
.
_getArgs
(
indexList
,
filenameList
)
indices
=
self
.
_getArgs
(
indexList
,
filenameList
)
CATALOG_CACHE
[
filename
]
=
indices
CATALOG_CACHE
[
filename
]
=
indices
list0
,
list1
=
self
.
_breakList
(
indices
,
0
,
phase
)
list0
,
list1
=
self
.
_breakList
(
indices
,
0
,
phase
)
list2
,
list3
=
self
.
_breakList
(
list0
,
1
,
metallicity
)
list2
,
list3
=
self
.
_breakList
(
list0
,
1
,
metallicity
)
list4
,
list5
=
self
.
_breakList
(
list1
,
1
,
metallicity
)
list4
,
list5
=
self
.
_breakList
(
list1
,
1
,
metallicity
)
list6
,
list7
=
self
.
_breakList
(
list2
,
2
,
f_sed
)
list6
,
list7
=
self
.
_breakList
(
list2
,
2
,
f_sed
)
list8
,
list9
=
self
.
_breakList
(
list3
,
2
,
f_sed
)
list8
,
list9
=
self
.
_breakList
(
list3
,
2
,
f_sed
)
list10
,
list11
=
self
.
_breakList
(
list4
,
2
,
f_sed
)
list10
,
list11
=
self
.
_breakList
(
list4
,
2
,
f_sed
)
list12
,
list13
=
self
.
_breakList
(
list5
,
2
,
f_sed
)
list12
,
list13
=
self
.
_breakList
(
list5
,
2
,
f_sed
)
sp1
,
wave
,
waveunits
=
self
.
_getSpectrum
(
list6
[
0
],
catname
,
wave_output
=
True
)
sp1
,
wave
,
waveunits
=
self
.
_getSpectrum
(
list6
[
0
],
catname
,
wave_output
=
True
)
sp2
=
self
.
_getSpectrum
(
list7
[
0
],
catname
)
sp2
=
self
.
_getSpectrum
(
list7
[
0
],
catname
)
...
@@ -113,7 +118,7 @@ class AlbedoCat(S.spectrum.TabularSpectralElement, S.catalog.Icat):
...
@@ -113,7 +118,7 @@ class AlbedoCat(S.spectrum.TabularSpectralElement, S.catalog.Icat):
column
=
name
.
split
(
'['
)[
1
][:
-
1
]
column
=
name
.
split
(
'['
)[
1
][:
-
1
]
filename
=
f
"
{
self
.
catalog_folder
}
/
{
filename
}
"
filename
=
f
"
{
self
.
catalog_folder
}
/
{
filename
}
"
# sp = S.spectrum.TabularSpectralElement(filename, thrucol=column)
# sp = S.spectrum.TabularSpectralElement(filename, thrucol=column)
with
fits
.
open
(
filename
)
as
td
:
with
fits
.
open
(
filename
)
as
td
:
...
@@ -255,21 +260,22 @@ def star_photlam(
...
@@ -255,21 +260,22 @@ def star_photlam(
star_sp
.
convert
(
'photlam'
)
star_sp
.
convert
(
'photlam'
)
return
star_sp
return
star_sp
def
standard_spectrum
(
def
standard_spectrum
(
magnitude
:
float
)
->
S
.
ArraySpectrum
:
magnitude
:
float
)
->
S
.
ArraySpectrum
:
"""Standard spectrum of magnitude system.
"""Standard spectrum of magnitude system.
For example, the standard_spectrum of vega megnitude is vega spectrum.
For example, the standard_spectrum of vega megnitude is vega spectrum.
The standard spectrum of ab magnitude is a flat spectrum.
The standard spectrum of ab magnitude is a flat spectrum.
Parameters
Parameters
-----------
-----------
magnitude : float
magnitude : float
magnitude of the standard spectrum
magnitude of the standard spectrum
Returns
Returns
----------
----------
star_sp : S.spectrum.Spectrum
star_sp : S.spectrum.Spectrum
"""
"""
inner_std
=
S
.
units
.
Units
(
MAG_SYSTEM
).
StdSpectrum
inner_std
=
S
.
units
.
Units
(
MAG_SYSTEM
).
StdSpectrum
std_spectrum
=
S
.
ArraySpectrum
(
std_spectrum
=
S
.
ArraySpectrum
(
...
@@ -282,7 +288,8 @@ def standard_spectrum(
...
@@ -282,7 +288,8 @@ def standard_spectrum(
std_spectrum
=
StdRenorm
(
std_spectrum
,
filter
,
magnitude
,
MAG_SYSTEM
)
std_spectrum
=
StdRenorm
(
std_spectrum
,
filter
,
magnitude
,
MAG_SYSTEM
)
std_spectrum
.
convert
(
'photlam'
)
std_spectrum
.
convert
(
'photlam'
)
return
std_spectrum
return
std_spectrum
def
bcc_spectrum
(
def
bcc_spectrum
(
coe_cloud
:
float
,
coe_cloud
:
float
,
coe_metalicity
:
float
)
->
S
.
spectrum
.
ArraySpectralElement
:
coe_metalicity
:
float
)
->
S
.
spectrum
.
ArraySpectralElement
:
...
@@ -407,7 +414,7 @@ def detect_template_path(template: str) -> str:
...
@@ -407,7 +414,7 @@ def detect_template_path(template: str) -> str:
----------
----------
template: str
template: str
template file name
template file name
Returns
Returns
-------
-------
str
str
...
@@ -417,14 +424,14 @@ def detect_template_path(template: str) -> str:
...
@@ -417,14 +424,14 @@ def detect_template_path(template: str) -> str:
if
os
.
path
.
isfile
(
template
):
if
os
.
path
.
isfile
(
template
):
return
os
.
path
.
abspath
(
template
)
return
os
.
path
.
abspath
(
template
)
catalog
=
config
[
'catalog_folder'
]
catalog
=
config
[
'catalog_folder'
]
cat_temp
=
os
.
path
.
join
(
catalog
,
template
)
cat_temp
=
os
.
path
.
join
(
catalog
,
template
)
if
os
.
path
.
isfile
(
cat_temp
):
if
os
.
path
.
isfile
(
cat_temp
):
return
cat_temp
return
cat_temp
raise
FileExistsError
(
f
'cant find
{
template
}
in ./ or catalog folder'
)
raise
FileExistsError
(
f
'cant find
{
template
}
in ./ or catalog folder'
)
class
TargetOjbect
(
object
):
class
TargetOjbect
(
object
):
"""A helper class to generate target spectrum and albedo spectrum
"""A helper class to generate target spectrum and albedo spectrum
...
@@ -459,7 +466,7 @@ class TargetOjbect(object):
...
@@ -459,7 +466,7 @@ class TargetOjbect(object):
center star object is used to calculate the projection x, y of each target according to its ra and dec
center star object is used to calculate the projection x, y of each target according to its ra and dec
also center star's distance is used to calculate seperation of planet
also center star's distance is used to calculate seperation of planet
Examples:
Examples:
--------
--------
cstar = {
cstar = {
...
@@ -470,7 +477,7 @@ class TargetOjbect(object):
...
@@ -470,7 +477,7 @@ class TargetOjbect(object):
'sptype': 'G0III'
'sptype': 'G0III'
'sp_model': 'star'
'sp_model': 'star'
}
}
stars = {
stars = {
'magnitude': 15,
'magnitude': 15,
'ra': '120.001d',
'ra': '120.001d',
...
@@ -478,27 +485,27 @@ class TargetOjbect(object):
...
@@ -478,27 +485,27 @@ class TargetOjbect(object):
'sptype': 'F0III',
'sptype': 'F0III',
'sp_model': 'blackbody'
'sp_model': 'blackbody'
}
}
planets = {
planets = {
'radius': 2,
'radius': 2,
'pangle': 60,
'pangle': 60,
'coe_cloud': 0.3,
'coe_cloud': 0.3,
'coe_metal': 0.7,
'coe_metal': 0.7,
'separation': 0.5,
'separation': 0.5,
'phase_angle': 90,
'phase_angle': 90,
'sp_model': 'hybrid_planet',
'sp_model': 'hybrid_planet',
'image': 'extend_planet.fits'
'image': 'extend_planet.fits'
}
}
# planet using input costum albedo spectrum!
# planet using input costum albedo spectrum!
# Note that the albedo spectrum is not normalized!
# Note that the albedo spectrum is not normalized!
# so the contrast of the planet sould be considered in the input file by user!
# so the contrast of the planet sould be considered in the input file by user!
# The input file is in pysynphot.FileSpectralElement format.
# The input file is in pysynphot.FileSpectralElement format.
# See the documentation of pysynphot for details.
# See the documentation of pysynphot for details.
planets = {
planets = {
'pangle': 60,
'pangle': 60,
'separation': 0.5,
'separation': 0.5,
'sp_spectrum': 'template_planet',
'sp_spectrum': 'template_planet',
'template': 'planet_albedo.fits'
'template': 'planet_albedo.fits'
}
}
...
@@ -556,26 +563,27 @@ class TargetOjbect(object):
...
@@ -556,26 +563,27 @@ class TargetOjbect(object):
phase_angle
,
phase_angle
,
radius
,
radius
,
)
)
if
sp_model
==
'hybrid_planet'
:
if
sp_model
==
'hybrid_planet'
:
coe_blue
,
coe_red
=
planet
.
get
(
'coe_b'
,
1
),
planet
.
get
(
'coe_r'
,
1
)
coe_blue
,
coe_red
=
planet
.
get
(
'coe_b'
,
1
),
planet
.
get
(
'coe_r'
,
1
)
albedo_spect
=
hybrid_albedo_spectrum
(
coe_blue
,
coe_red
)
albedo_spect
=
hybrid_albedo_spectrum
(
coe_blue
,
coe_red
)
elif
sp_model
==
'bcc_planet'
:
elif
sp_model
==
'bcc_planet'
:
coe_c
,
coe_m
=
planet
.
get
(
'coe_cloud'
,
2
),
planet
.
get
(
'coe_metal'
,
0
)
coe_c
,
coe_m
=
planet
.
get
(
'coe_cloud'
,
2
),
planet
.
get
(
'coe_metal'
,
0
)
albedo_spect
=
bcc_spectrum
(
coe_c
,
coe_m
)
albedo_spect
=
bcc_spectrum
(
coe_c
,
coe_m
)
else
:
#
sp_model == 'template_planet'
else
:
#
sp_model == 'template_planet'
albedo_spect
=
S
.
FileBandpass
(
detect_template_path
(
planet
[
'template'
]))
albedo_spect
=
S
.
FileBandpass
(
detect_template_path
(
planet
[
'template'
]))
contrast
=
1
contrast
=
1
self
.
spectrum
=
cstar
.
spectrum
*
albedo_spect
*
contrast
self
.
spectrum
=
cstar
.
spectrum
*
albedo_spect
*
contrast
def
planet_contrast
(
def
planet_contrast
(
planet_x_au
:
float
,
planet_x_au
:
float
,
planet_y_au
:
float
,
planet_y_au
:
float
,
phase_angle
:
float
,
phase_angle
:
float
,
radius
:
float
)
->
float
:
radius
:
float
)
->
float
:
"""
"""
c
alculate the contrast of a planet
C
alculate the contrast of a planet
.
Parameters
Parameters
----------
----------
...
@@ -610,16 +618,17 @@ def planet_contrast(
...
@@ -610,16 +618,17 @@ def planet_contrast(
contrast
=
(
radius
/
sep_3d
*
R_JUPITER_METER
/
AU_METER
)
**
2
*
phase
contrast
=
(
radius
/
sep_3d
*
R_JUPITER_METER
/
AU_METER
)
**
2
*
phase
return
contrast
return
contrast
def
spectrum_generator
(
def
spectrum_generator
(
targets
:
dict
)
->
list
:
targets
:
dict
)
->
list
:
"""
"""
g
enerate the spectrum due to the input target list
G
enerate the spectrum due to the input target list
.
Parameters
Parameters
----------
----------
targets: dict
targets: dict
target dictionary which contains keyword 'cstar' (necessary), 'stars'(optional), 'planets' (optional).
target dictionary which contains keyword 'cstar' (necessary), 'stars'(optional), 'planets' (optional).
The values are:
The values are:
- cstar: dict
- cstar: dict
- center star information. must contain keywords ra, dec, distance, magnitude, sptype
- center star information. must contain keywords ra, dec, distance, magnitude, sptype
- objects: list of dict, optional, recommended! V2.0 new!
- objects: list of dict, optional, recommended! V2.0 new!
...
@@ -654,17 +663,17 @@ def target_file_load(
...
@@ -654,17 +663,17 @@ def target_file_load(
----------
----------
target: Union[dict, str]
target: Union[dict, str]
target file name, formated string or target dict.
target file name, formated string or target dict.
Outputs
Outputs
--------
--------
target: dict
target: dict
dictionary of target. Format of input
dictionary of target. Format of input
Note
Note
-------
-------
If target is a string start with *, it will be treated as a formatted string.
If target is a string start with *, it will be treated as a formatted string.
e.g. "*5.1/25.3(1.3,1.5)/22.1(2.3,-4.5)" which means a central object
e.g. "*5.1/25.3(1.3,1.5)/22.1(2.3,-4.5)" which means a central object
with magnitude 5.1, and two substellar with magnitude 25.3 and 22.1, respectively.
with magnitude 5.1, and two substellar with magnitude 25.3 and 22.1, respectively.
The spectrum of each object is standard refernece spectrum of ABmag.
The spectrum of each object is standard refernece spectrum of ABmag.
The first number in the parenthesis is the x position in arcsec, and the second is the y position.
The first number in the parenthesis is the x position in arcsec, and the second is the y position.
...
@@ -679,20 +688,20 @@ def target_file_load(
...
@@ -679,20 +688,20 @@ def target_file_load(
if
isinstance
(
target
,
dict
):
if
isinstance
(
target
,
dict
):
return
target
return
target
if
not
target
:
# None or empty string
if
not
target
:
# None or empty string
return
{}
return
{}
if
isinstance
(
target
,
str
):
#
filename or formatted string
if
isinstance
(
target
,
str
):
#
filename or formatted string
target
=
target
.
strip
()
target
=
target
.
strip
()
if
not
target
:
if
not
target
:
return
{}
return
{}
catalog_folder
=
config
[
'catalog_folder'
]
catalog_folder
=
config
[
'catalog_folder'
]
target_file
=
target
target_file
=
target
target_file
+=
'.yaml'
if
target_file
[
-
5
:].
lower
()
!=
'.yaml'
else
""
target_file
+=
'.yaml'
if
target_file
[
-
5
:].
lower
()
!=
'.yaml'
else
""
target_name
=
os
.
path
.
basename
(
target_file
)[:
-
5
]
target_name
=
os
.
path
.
basename
(
target_file
)[:
-
5
]
file_search
=
[
target_file
,
os
.
path
.
join
(
catalog_folder
,
target_file
)]
file_search
=
[
target_file
,
os
.
path
.
join
(
catalog_folder
,
target_file
)]
for
file
in
file_search
:
for
file
in
file_search
:
if
os
.
path
.
isfile
(
file
):
if
os
.
path
.
isfile
(
file
):
with
open
(
file
)
as
fid
:
with
open
(
file
)
as
fid
:
...
...
csst_cpic_sim/utils.py
View file @
190f1129
...
@@ -2,7 +2,7 @@ import numpy as np
...
@@ -2,7 +2,7 @@ import numpy as np
import
scipy.ndimage
as
nd
import
scipy.ndimage
as
nd
import
logging
import
logging
import
random
import
random
import
matplotlib.pyplot
as
plt
import
matplotlib.pyplot
as
plt
# DO NOT IMPORT CPICIMGSIM MODULES HERE
# DO NOT IMPORT CPICIMGSIM MODULES HERE
...
@@ -66,7 +66,7 @@ def region_replace(
...
@@ -66,7 +66,7 @@ def region_replace(
shift: list
shift: list
The [x, y] shift of the front image. Unit: pixel.
The [x, y] shift of the front image. Unit: pixel.
Relative to the lower-left corner of the background image.
Relative to the lower-left corner of the background image.
[0, 0] means the lower-left corner of the front image is at the lower-left corner of the background image.
[0, 0] means the lower-left corner of the front image is at the lower-left corner of the background image.
bmask: float
bmask: float
The mask of the background image. Default: 1.0
The mask of the background image. Default: 1.0
0.0 means the background image is masked.
0.0 means the background image is masked.
...
@@ -133,7 +133,7 @@ def psf_imshow(psf, vmin=1e-8, vmax=0.1, log=True, region=1):
...
@@ -133,7 +133,7 @@ def psf_imshow(psf, vmin=1e-8, vmax=0.1, log=True, region=1):
focal_img
=
(
focal_img
-
focal_img
.
min
())
/
(
focal_img
.
max
()
-
focal_img
.
min
())
focal_img
=
(
focal_img
-
focal_img
.
min
())
/
(
focal_img
.
max
()
-
focal_img
.
min
())
if
log
:
if
log
:
focal_img
=
np
.
log10
(
focal_img
*
9
+
1
)
focal_img
=
np
.
log10
(
focal_img
*
9
+
1
)
plt
.
imshow
(
focal_img
,
origin
=
'lower'
,
cmap
=
'gray'
,
vmin
=
vmin
,
vmax
=
vmax
)
plt
.
imshow
(
focal_img
,
origin
=
'lower'
,
cmap
=
'gray'
,
vmin
=
vmin
,
vmax
=
vmax
)
shape
=
psf
.
shape
shape
=
psf
.
shape
...
...
example/observations/01_bias.yaml
View file @
190f1129
band
:
f66
1
band
:
f66
2
emgain
:
1
emgain
:
1
emset
:
-1
emset
:
-1
expt
:
10
expt
:
10
...
...
example/observations/02_dark.yaml
View file @
190f1129
band
:
f66
1
band
:
f66
2
emgain
:
200
emgain
:
200
emset
:
-1
emset
:
-1
expt
:
100
expt
:
100
...
...
example/observations/03_flat.yaml
View file @
190f1129
band
:
f5
65
band
:
f5
20
emgain
:
1
emgain
:
1
emset
:
-1
emset
:
-1
expt
:
10
expt
:
10
...
...
example/observations/04_bkg.yaml
View file @
190f1129
band
:
f5
65
band
:
f5
20
emgain
:
50
emgain
:
50
emset
:
-1
emset
:
-1
expt
:
50
expt
:
50
...
...
example/observations/05_sci.yaml
View file @
190f1129
band
:
f66
1
band
:
f66
2
emgain
:
50
emgain
:
50
emset
:
-1
emset
:
-1
expt
:
20
expt
:
20
...
...
example/observations/06_density.yaml
View file @
190f1129
band
:
f5
65
band
:
f5
20
emgain
:
1
emgain
:
1
emset
:
-1
emset
:
-1
expt
:
10
expt
:
10
...
...
example/observations/07_cals.yaml
View file @
190f1129
band
:
f5
65
band
:
f5
20
emgain
:
2
emgain
:
2
emset
:
-1
emset
:
-1
expt
:
10
expt
:
10
...
...
example/observations/08_laser.yaml
View file @
190f1129
band
:
f
565
band
:
f
720
emgain
:
2
emgain
:
2
emset
:
-1
emset
:
-1
expt
:
10
expt
:
10
...
...
example/observations/09_disk.yaml
View file @
190f1129
band
:
f5
65
band
:
f5
20
emgain
:
50
emgain
:
50
emset
:
-1
emset
:
-1
expt
:
10
expt
:
10
...
...
refdata/cpism_config_default.yaml
View file @
190f1129
...
@@ -12,6 +12,10 @@ bands:
...
@@ -12,6 +12,10 @@ bands:
f743
:
${cpism_refdata}/throughtput/f743_total.fits
f743
:
${cpism_refdata}/throughtput/f743_total.fits
f883
:
${cpism_refdata}/throughtput/f883_total.fits
f883
:
${cpism_refdata}/throughtput/f883_total.fits
f565
:
${cpism_refdata}/throughtput/f565_total.fits
f565
:
${cpism_refdata}/throughtput/f565_total.fits
f520
:
${cpism_refdata}/throughtput/f520.fits
f662
:
${cpism_refdata}/throughtput/f662.fits
f850
:
${cpism_refdata}/throughtput/f850.fits
f720
:
${cpism_refdata}/throughtput/f720.fits
diameter
:
2
diameter
:
2
platescale
:
0.016153
platescale
:
0.016153
datamodel
:
${cpism_refdata}/io/csst-cpic-l0.yaml
datamodel
:
${cpism_refdata}/io/csst-cpic-l0.yaml
...
...
script/cpicsim.py
View file @
190f1129
import
sys
import
sys
from
csst_cpic_sim.main
import
main
from
csst_cpic_sim.main
import
main
sys
.
exit
(
main
())
sys
.
exit
(
main
())
\ No newline at end of file
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