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_msc_sim
Commits
4afd1181
Commit
4afd1181
authored
May 12, 2024
by
Fang Yuedong
Browse files
add renamed files
parent
4c9c940a
Changes
220
Hide whitespace changes
Inline
Side-by-side
observation_sim/mock_objects/__init__.py
0 → 100755
View file @
4afd1181
from
.MockObject
import
MockObject
from
.Galaxy
import
Galaxy
from
.CatalogBase
import
CatalogBase
from
.Quasar
import
Quasar
from
.Star
import
Star
from
.Stamp
import
Stamp
from
.FlatLED
import
FlatLED
observation_sim/mock_objects/_util.py
0 → 100755
View file @
4afd1181
import
numpy
as
np
import
os
from
scipy.interpolate
import
InterpolatedUnivariateSpline
,
interp1d
from
scipy
import
interpolate
,
integrate
from
astropy.table
import
Table
import
galsim
VC_A
=
2.99792458e+18
# speed of light: A/s
VC_M
=
2.99792458e+8
# speed of light: m/s
H_PLANK
=
6.626196e-27
# Plank constant: erg s
def
comoving_dist
(
z
,
om_m
=
0.3111
,
om_L
=
0.6889
,
h
=
0.6766
):
# Return comving distance in pc
H0
=
h
*
100.
# km / (s Mpc)
def
dist_int
(
z
):
return
1.
/
np
.
sqrt
(
om_m
*
(
1.
+
z
)
**
3
+
om_L
)
res
,
err
=
integrate
.
quad
(
dist_int
,
0.
,
z
)
return
[
res
*
(
VC_M
/
1e3
/
H0
)
*
1e6
,
err
*
(
VC_M
/
1e3
/
H0
)
*
1e6
]
def
magToFlux
(
mag
):
"""
flux of a given AB magnitude
Parameters:
mag: magnitude in unit of AB
Return:
flux: flux in unit of erg/s/cm^2/Hz
"""
flux
=
10
**
(
-
0.4
*
(
mag
+
48.6
))
return
flux
def
extAv
(
nav
,
seed
=
1212123
):
"""
Generate random intrinsic extinction Av
following the distribution from Holwerda et al, 2015
"""
np
.
random
.
seed
(
seed
)
tau
=
0.4
peak
,
a
=
0.1
,
0.5
b
=
a
*
(
tau
-
peak
)
def
pav
(
av
):
return
(
a
*
av
+
b
)
*
np
.
exp
(
-
av
/
tau
)
avmin
,
avmax
=
0.
,
3.
avs
=
np
.
linspace
(
avmin
,
avmax
,
int
((
avmax
-
avmin
)
/
0.001
)
+
1
)
norm
=
np
.
trapz
(
pav
(
avs
),
avs
)
pav_base
=
pav
(
avs
)
/
np
.
sum
(
pav
(
avs
))
rav
=
np
.
random
.
choice
(
avs
,
nav
,
p
=
pav_base
)
return
rav
###########################################
def
seds
(
sedlistn
,
seddir
=
"./"
,
unit
=
"A"
):
"""
read SEDs and save into Python dictionary
Parameters:
sedlistn: filename of the sed template list and corresponding intrinsic
extinction model, see tmag_dz.py for detailes
listdir: directory of the list
unit: wavelength unit of the input templates
Return:
SED dictionary, the output wavelength unit is 'A'
"""
seds
=
{}
reds
=
{}
sedlist
=
seddir
+
sedlistn
sedn
=
open
(
sedlist
).
read
().
splitlines
()
sedtype
=
range
(
1
,
len
(
sedn
)
+
1
)
for
i
in
range
(
len
(
sedn
)):
xxx
=
sedn
[
i
].
split
()
isedn
=
seddir
+
xxx
[
0
]
itype
=
sedtype
[
i
]
ised
=
np
.
loadtxt
(
isedn
)
if
unit
==
"nm"
:
ised
[:,
0
]
*=
10.0
seds
[
itype
]
=
ised
reds
[
itype
]
=
int
(
xxx
[
1
])
return
seds
,
reds
def
sed_assign
(
phz
,
btt
,
rng
):
"""
assign SED template to a galaxy.
"""
sedid
=
list
(
range
(
1
,
34
))
lzid
=
sedid
[
0
:
13
]
+
sedid
[
23
:
28
]
hzid
=
sedid
[
13
:
23
]
if
btt
==
1.0
:
sedtype
=
rng
.
sample
(
sedid
[
0
:
5
]
+
sedid
[
28
:
33
],
1
)[
0
]
if
phz
>
2.0
and
sedtype
in
sedid
[
0
:
5
]:
sedtype
=
rng
.
sample
(
sedid
[
28
:
33
],
1
)[
0
]
elif
btt
>
0.3
and
btt
<
1.0
:
sedtype
=
rng
.
sample
(
sedid
,
1
)[
0
]
if
phz
>
2.0
and
sedtype
in
lzid
:
sedtype
=
rng
.
sample
(
hzid
,
1
)[
0
]
elif
btt
>=
0.1
and
btt
<
0.3
:
sedtype
=
rng
.
sample
(
sedid
[
5
:
28
],
1
)[
0
]
if
phz
>
1.5
and
sedtype
in
lzid
:
sedtype
=
rng
.
sample
(
hzid
,
1
)[
0
]
elif
btt
>=
0.0
and
btt
<
0.1
:
sedtype
=
rng
.
sample
(
sedid
[
5
:
23
],
1
)[
0
]
if
phz
>
1.5
and
sedtype
in
lzid
:
sedtype
=
rng
.
sample
(
hzid
,
1
)[
0
]
else
:
sedtype
=
0
return
sedtype
###########################################
def
tflux
(
filt
,
sed
,
redshift
=
0.0
,
av
=
0.0
,
redden
=
0
):
"""
calculate the theoretical SED for given filter set and template
Only AB magnitude is support!!!
Parameters:
filt: 2d array
fliter transmissions: lambda(A), T
sed: 2d array
sed templateL lambda (A), flux (erg s-1 cm-2 A-1)
redshift: float
redshift of the corresponding source, default is zero
av: float
extinction value for intrincal extinction
redden: int
reddening model, see Function 'reddening' for details
return:
tflux: float
theoretical flux
sedObs: array
SED in observed frame
"""
z
=
redshift
+
1.0
sw
,
sf
=
sed
[:,
0
],
sed
[:,
1
]
# reddening
sf
=
reddening
(
sw
,
sf
,
av
=
av
,
model
=
redden
)
sw
,
sf
=
sw
*
z
,
sf
*
(
z
**
3
)
# lyman forest correction
sf
=
lyman_forest
(
sw
,
sf
,
redshift
)
sedxx
=
(
sw
.
copy
(),
sf
.
copy
())
sw
=
VC_A
/
sw
sf
=
sf
*
(
VC_A
/
sw
**
2
)
# convert flux unit to erg/s/cm^s/Hz
sw
,
sf
=
sw
[::
-
1
],
sf
[::
-
1
]
sfun
=
interp1d
(
sw
,
sf
,
kind
=
'linear'
)
fwave
,
fresp
=
filt
[:,
0
],
filt
[:,
1
]
fwave
=
VC_A
/
fwave
fwave
,
fresp
=
fwave
[::
-
1
],
fresp
[::
-
1
]
tflux
=
sfun
(
fwave
)
zpflux
=
3.631
*
1.0e-20
tflux
=
np
.
trapz
(
tflux
*
fresp
/
fwave
,
fwave
)
/
\
np
.
trapz
(
zpflux
*
fresp
/
fwave
,
fwave
)
# tflux = np.trapz(tflux*fresp,fwave)/np.trapz(zpflux*fresp,fwave)
return
tflux
,
sedxx
###########################################
def
lyman_forest
(
wavelen
,
flux
,
z
):
"""
Compute the Lyman forest mean absorption of an input spectrum,
according to D_A and D_B evolution from Madau (1995).
The waveeln and flux are in observed frame
"""
if
z
<=
0
:
flux0
=
flux
else
:
nw
=
200
istep
=
np
.
linspace
(
0
,
nw
-
1
,
nw
)
w1a
,
w2a
=
1050.0
*
(
1.0
+
z
),
1170.0
*
(
1.0
+
z
)
w1b
,
w2b
=
920.0
*
(
1.0
+
z
),
1015.0
*
(
1.0
+
z
)
wstepa
=
(
w2a
-
w1a
)
/
float
(
nw
)
wstepb
=
(
w2b
-
w1b
)
/
float
(
nw
)
wtempa
=
w1a
+
istep
*
wstepa
ptaua
=
np
.
exp
(
-
3.6e-03
*
(
wtempa
/
1216.0
)
**
3.46
)
wtempb
=
w1b
+
istep
*
wstepb
ptaub
=
np
.
exp
(
-
1.7e-3
*
(
wtempb
/
1026.0
)
**
3.46
-
1.2e-3
*
(
wtempb
/
972.50
)
**
3.46
-
9.3e-4
*
(
wtempb
/
950.00
)
**
3.46
)
da
=
(
1.0
/
(
120.0
*
(
1.0
+
z
)))
*
np
.
trapz
(
ptaua
,
wtempa
)
db
=
(
1.0
/
(
95.0
*
(
1.0
+
z
)))
*
np
.
trapz
(
ptaub
,
wtempb
)
if
da
>
1.0
:
da
=
1.0
if
db
>
1.0
:
db
=
1.0
if
da
<
0.0
:
da
=
0.0
if
db
<
0.0
:
db
=
0.0
flux0
=
flux
.
copy
()
id0
=
wavelen
<=
1026.0
*
(
1.0
+
z
)
id1
=
np
.
logical_and
(
wavelen
<
1216.0
*
(
1.0
+
z
),
wavelen
>=
1026.0
*
(
1.0
+
z
))
flux0
[
id0
]
=
db
*
flux
[
id0
]
flux0
[
id1
]
=
da
*
flux
[
id1
]
return
flux0
###########################################
def
reddening
(
sw
,
sf
,
av
=
0.0
,
model
=
0
):
"""
calculate the intrinsic extinction of a given template
Parameters:
sw: array
wavelength
sf: array
flux
av: float or array
model: int
Five models will be used:
1: Allen (1976) for the Milky Way
2: Seaton (1979) fit by Fitzpatrick (1986) for the Milky Way
3: Fitzpatrick (1986) for the Large Magellanic Cloud (LMC)
4: Prevot et al (1984) and Bouchet (1985) for the Small Magellanic Cloud (SMC)
5: Calzetti et al (2000) for starburst galaxies
6: Reddy et al (2015) for star forming galaxies
Return:
reddening-corrected flux or observed flux
"""
if
model
==
0
or
av
==
0.0
:
flux
=
sf
elif
model
==
1
:
# Allen (1976) for the Milky Way
lambda0
=
np
.
array
([
1000
,
1110
,
1250
,
1430
,
1670
,
2000
,
2220
,
2500
,
2850
,
3330
,
3650
,
4000
,
4400
,
5000
,
5530
,
6700
,
9000
,
10000
,
20000
,
100000
],
dtype
=
float
)
kR
=
np
.
array
([
4.20
,
3.70
,
3.30
,
3.00
,
2.70
,
2.80
,
2.90
,
2.30
,
1.97
,
1.69
,
1.58
,
1.45
,
1.32
,
1.13
,
1.00
,
0.74
,
0.46
,
0.38
,
0.11
,
0.00
],
dtype
=
float
)
ext0
=
InterpolatedUnivariateSpline
(
lambda0
,
kR
,
k
=
1
)
A_lambda
=
av
*
ext0
(
sw
)
A_lambda
[
A_lambda
<
0.0
]
=
0.0
flux
=
sf
*
10
**
(
-
0.4
*
A_lambda
)
elif
model
==
2
:
# Seaton (1979) fit by Fitzpatrick (1986) for the Milky Way
Rv
=
3.1
al0
,
ga
,
c1
,
c2
,
c3
,
c4
=
4.595
,
1.051
,
-
0.38
,
0.74
,
3.96
,
0.26
ff11
=
__red
(
1100.0
,
al0
,
ga
,
c1
,
c2
,
c3
,
c4
)
ff12
=
__red
(
1200.0
,
al0
,
ga
,
c1
,
c2
,
c3
,
c4
)
slope
=
(
ff12
-
ff11
)
/
100.0
lambda0
=
np
.
array
([
3650
,
4000
,
4400
,
5000
,
5530
,
6700
,
9000
,
10000
,
20000
,
100000
],
dtype
=
float
)
kR
=
np
.
array
([
1.58
,
1.45
,
1.32
,
1.13
,
1.00
,
0.74
,
0.46
,
0.38
,
0.11
,
0.00
],
dtype
=
float
)
fun
=
interp1d
(
lambda0
,
kR
,
kind
=
'linear'
)
sw0
=
sw
[
sw
<
1200.0
]
A_lambda0
=
(
ff11
+
(
sw0
-
1100.0
)
*
slope
)
/
Rv
+
1.0
sw1
=
sw
[
np
.
logical_and
(
sw
>=
1200.0
,
sw
<=
3650.0
)]
ff
=
__red
(
sw1
,
al0
,
ga
,
c1
,
c2
,
c3
,
c4
)
A_lambda1
=
ff
/
Rv
+
1.0
sw2
=
sw
[
np
.
logical_and
(
sw
>
3650.0
,
sw
<=
100000.0
)]
A_lambda2
=
fun
(
sw2
)
A_lambda3
=
sw
[
sw
>
100000.0
]
*
0.0
A_lambda
=
av
*
np
.
hstack
([
A_lambda0
,
A_lambda1
,
A_lambda2
,
A_lambda3
])
A_lambda
[
A_lambda
<
0.0
]
=
0.0
flux
=
sf
*
10
**
(
-
0.4
*
A_lambda
)
elif
model
==
3
:
# Fitzpatrick (1986) for the Large Magellanic Cloud (LMC)
Rv
=
3.1
al0
,
ga
,
c1
,
c2
,
c3
,
c4
=
4.608
,
0.994
,
-
0.69
,
0.89
,
2.55
,
0.50
ff11
=
__red
(
1100.0
,
al0
,
ga
,
c1
,
c2
,
c3
,
c4
)
ff12
=
__red
(
1200.0
,
al0
,
ga
,
c1
,
c2
,
c3
,
c4
)
slope
=
(
ff12
-
ff11
)
/
100.0
lambda0
=
np
.
array
([
3330
,
3650
,
4000
,
4400
,
5000
,
5530
,
6700
,
9000
,
10000
,
20000
,
100000
],
dtype
=
float
)
kR
=
np
.
array
([
1.682
,
1.58
,
1.45
,
1.32
,
1.13
,
1.00
,
0.74
,
0.46
,
0.38
,
0.11
,
0.00
],
dtype
=
float
)
fun
=
interp1d
(
lambda0
,
kR
,
kind
=
'linear'
)
sw0
=
sw
[
sw
<
1200.0
]
A_lambda0
=
(
ff11
+
(
sw0
-
1100.0
)
*
slope
)
/
Rv
+
1.0
sw1
=
sw
[
np
.
logical_and
(
sw
>=
1200.0
,
sw
<=
3330.0
)]
ff
=
__red
(
sw1
,
al0
,
ga
,
c1
,
c2
,
c3
,
c4
)
A_lambda1
=
ff
/
Rv
+
1.0
sw2
=
sw
[
np
.
logical_and
(
sw
>
3330.0
,
sw
<=
100000.0
)]
A_lambda2
=
fun
(
sw2
)
A_lambda3
=
sw
[
sw
>
100000.0
]
*
0.0
A_lambda
=
av
*
np
.
hstack
([
A_lambda0
,
A_lambda1
,
A_lambda2
,
A_lambda3
])
A_lambda
[
A_lambda
<
0.0
]
=
0.0
flux
=
sf
*
10
**
(
-
0.4
*
A_lambda
)
# Prevot et al (1984) and Bouchet (1985) for the Small Magellanic Cloud (SMC)
elif
model
==
4
:
Rv
=
2.72
lambda0
=
np
.
array
([
1275
,
1330
,
1385
,
1435
,
1490
,
1545
,
1595
,
1647
,
1700
,
1755
,
1810
,
1860
,
1910
,
2000
,
2115
,
2220
,
2335
,
2445
,
2550
,
2665
,
2778
,
2890
,
2995
,
3105
,
3704
,
4255
,
5291
,
12500
,
16500
,
22000
],
dtype
=
float
)
kR
=
np
.
array
([
13.54
,
12.52
,
11.51
,
10.80
,
9.84
,
9.28
,
9.06
,
8.49
,
8.01
,
7.71
,
7.17
,
6.90
,
6.76
,
6.38
,
5.85
,
5.30
,
4.53
,
4.24
,
3.91
,
3.49
,
3.15
,
3.00
,
2.65
,
2.29
,
1.81
,
1.00
,
0.00
,
-
2.02
,
-
2.36
,
-
2.47
],
dtype
=
float
)
kR
=
kR
/
Rv
+
1.0
ext0
=
InterpolatedUnivariateSpline
(
lambda0
,
kR
,
k
=
1
)
A_lambda
=
av
*
ext0
(
sw
)
A_lambda
[
A_lambda
<
0.0
]
=
0.0
flux
=
sf
*
10
**
(
-
0.4
*
A_lambda
)
elif
model
==
5
:
# Calzetti et al (2000) for starburst galaxies
Rv
=
4.05
sw
=
sw
*
1.0e-04
# wavelength in microns
def
fun1
(
x
):
return
2.659
*
(
-
2.156
+
1.509
/
x
-
0.198
/
x
**
2
+
0.011
/
x
**
3
)
+
Rv
def
fun2
(
x
):
return
2.659
*
(
-
1.857
+
1.040
/
x
)
+
Rv
ff11
,
ff12
=
fun1
(
0.11
),
fun1
(
0.12
)
slope1
=
(
ff12
-
ff11
)
/
0.01
ff99
,
ff100
=
fun2
(
2.19
),
fun2
(
2.2
)
slope2
=
(
ff100
-
ff99
)
/
0.01
sw0
=
sw
[
sw
<
0.12
]
sw1
=
sw
[
np
.
logical_and
(
sw
>=
0.12
,
sw
<=
0.63
)]
sw2
=
sw
[
np
.
logical_and
(
sw
>
0.63
,
sw
<=
2.2
)]
sw3
=
sw
[
sw
>
2.2
]
k_lambda0
=
ff11
+
(
sw0
-
0.11
)
*
slope1
k_lambda1
,
k_lambda2
=
fun1
(
sw1
),
fun2
(
sw2
)
k_lambda3
=
ff99
+
(
sw3
-
2.19
)
*
slope2
A_lambda
=
av
*
np
.
hstack
([
k_lambda0
,
k_lambda1
,
k_lambda2
,
k_lambda3
])
/
Rv
A_lambda
[
A_lambda
<
0.0
]
=
0.0
flux
=
sf
*
10
**
(
-
0.4
*
A_lambda
)
elif
model
==
6
:
# Reddy et al (2015) for satr forming galaxies
Rv
=
2.505
sw
=
sw
*
1.0e-04
def
fun1
(
x
):
return
-
5.726
+
4.004
/
x
-
0.525
/
x
**
2
+
0.029
/
x
**
3
+
Rv
def
fun2
(
x
):
return
-
2.672
-
0.010
/
x
+
1.532
/
x
**
2
-
0.412
/
x
**
3
+
Rv
ff11
,
ff12
=
fun1
(
0.14
),
fun1
(
0.15
)
slope1
=
(
ff12
-
ff11
)
/
0.01
ff99
,
ff100
=
fun2
(
2.84
),
fun2
(
2.85
)
slope2
=
(
ff100
-
ff99
)
/
0.01
sw0
=
sw
[
sw
<
0.15
]
sw1
=
sw
[
np
.
logical_and
(
sw
>=
0.15
,
sw
<
0.60
)]
sw2
=
sw
[
np
.
logical_and
(
sw
>=
0.60
,
sw
<
2.85
)]
sw3
=
sw
[
sw
>=
2.85
]
k_lambda0
=
ff11
+
(
sw0
-
0.14
)
*
slope1
k_lambda1
,
k_lambda2
=
fun1
(
sw1
),
fun2
(
sw2
)
k_lambda3
=
ff99
+
(
sw3
-
2.84
)
*
slope2
A_lambda
=
av
*
np
.
hstack
([
k_lambda0
,
k_lambda1
,
k_lambda2
,
k_lambda3
])
/
Rv
A_lambda
[
A_lambda
<
0.0
]
=
0.0
flux
=
sf
*
10
**
(
-
0.4
*
A_lambda
)
else
:
raise
ValueError
(
"!!! Please select a proper reddening model"
)
return
flux
###########################################
def
__red
(
alan
,
al0
,
ga
,
c1
,
c2
,
c3
,
c4
):
def
fun1
(
x
):
return
c3
/
(((
x
-
(
al0
**
2
/
x
))
**
2
)
+
ga
*
ga
)
def
fun2
(
x
,
cc
):
return
cc
*
(
0.539
*
((
x
-
5.9
)
**
2
)
+
0.0564
*
((
x
-
5.9
)
**
3
))
def
fun
(
x
,
cc
):
return
c1
+
c2
*
x
+
fun1
(
x
)
+
fun2
(
x
,
cc
)
ala
=
alan
*
1.0e-04
# wavelength in microns
p
=
1.0
/
ala
if
np
.
size
(
p
)
>
1
:
p1
,
p2
=
p
[
p
>=
5.9
],
p
[
p
<
5.9
]
ff
=
np
.
append
(
fun
(
p1
,
c4
),
fun
(
p2
,
0.0
))
elif
np
.
size
(
p
)
==
1
:
if
p
<
5.9
:
c4
=
0.0
ff
=
fun
(
p
,
c4
)
else
:
return
return
ff
###########################################
def
sed2mag
(
mag_i
,
sedCat
,
filter_list
,
redshift
=
0.0
,
av
=
0.0
,
redden
=
0
):
# load the filters
nfilt
=
len
(
filter_list
)
aflux
=
np
.
zeros
(
nfilt
)
nid
=
-
1
for
k
in
range
(
nfilt
):
if
filter_list
[
k
].
filter_type
==
'i'
:
nid
=
k
bandpass
=
filter_list
[
k
].
bandpass_full
ktrans
=
np
.
transpose
(
np
.
array
([
bandpass
.
wave_list
*
10.0
,
bandpass
.
func
(
bandpass
.
wave_list
)]))
aflux
[
k
],
isedObs
=
tflux
(
ktrans
,
sedCat
,
redshift
=
redshift
,
av
=
av
,
redden
=
redden
)
# normalize to i-band
aflux
=
aflux
/
aflux
[
nid
]
# magnitudes in all filters
amag
=
-
2.5
*
np
.
log10
(
aflux
)
+
mag_i
spec
=
galsim
.
LookupTable
(
x
=
np
.
array
(
isedObs
[
0
]),
f
=
np
.
array
(
isedObs
[
1
]),
interpolant
=
'nearest'
)
isedObs
=
galsim
.
SED
(
spec
,
wave_type
=
'A'
,
flux_type
=
'1'
,
fast
=
False
)
return
amag
,
isedObs
def
eObs
(
e1
,
e2
,
g1
,
g2
):
"""
Calculate the sheared (observed) ellipticity using the
intrinsic ellipticity and cosmic shear components.
Parameters:
e1, e2: scalar or numpy array
g1, g2: scalar or numpy array
Return:
Sheared (observed) ellipticity components, absolute value, and orientation
in format of scalar or numpy array
** NOTE: e1, e2, g1, and g2 should have the same dimensions.
"""
if
np
.
isscalar
(
e1
):
e1
=
np
.
array
([
e1
])
e2
=
np
.
array
([
e2
])
g1
=
np
.
array
([
g1
])
g2
=
np
.
array
([
g2
])
else
:
e1
=
e1
.
flatten
()
e2
=
e2
.
flatten
()
g1
=
g1
.
flatten
()
g2
=
g2
.
flatten
()
# calculate the sheared (observed) ellipticity using complex rule
nobj
=
len
(
e1
)
e1obs
,
e2obs
=
[],
[]
eeobs
,
theta
=
[],
[]
for
i
in
range
(
nobj
):
e
=
complex
(
e1
[
i
],
e2
[
i
])
g
=
complex
(
g1
[
i
],
g2
[
i
])
e
,
gg
=
abs
(
e
),
abs
(
g
)
if
gg
<=
1.0
:
tt
=
e
+
g
bb
=
1.0
+
e
*
g
.
conjugate
()
eobs
=
tt
/
bb
else
:
tt
=
1.0
+
g
*
e
.
conjugate
()
bb
=
e
.
conjugate
()
+
g
.
conjugate
()
eobs
=
tt
/
bb
# derive the orientation
dd
=
0.5
*
np
.
arctan
(
abs
(
eobs
.
imag
/
eobs
.
real
))
*
180.0
/
np
.
pi
if
eobs
.
imag
>
0
and
eobs
.
real
>
0
:
dd
=
dd
if
eobs
.
imag
>
0
and
eobs
.
real
<
0
:
dd
=
90.0
-
dd
if
eobs
.
imag
<
0
and
eobs
.
real
>
0
:
dd
=
0.0
-
dd
if
eobs
.
imag
<
0
and
eobs
.
real
<
0
:
dd
=
dd
-
90.0
e1obs
+=
[
eobs
.
real
]
e2obs
+=
[
eobs
.
imag
]
eeobs
+=
[
abs
(
eobs
)]
theta
+=
[
dd
]
e1obs
,
e2obs
,
eeobs
,
theta
=
np
.
array
(
e1obs
),
np
.
array
(
e2obs
),
np
.
array
(
eeobs
),
np
.
array
(
theta
)
if
nobj
==
1
:
e1obs
,
e2obs
,
eeobs
,
theta
=
e1obs
[
0
],
e2obs
[
0
],
eeobs
[
0
],
theta
[
0
]
return
e1obs
,
e2obs
,
eeobs
,
theta
def
getObservedSED
(
sedCat
,
redshift
=
0.0
,
av
=
0.0
,
redden
=
0
):
z
=
redshift
+
1.0
sw
,
sf
=
sedCat
[:,
0
],
sedCat
[:,
1
]
# reddening
sf
=
reddening
(
sw
,
sf
,
av
=
av
,
model
=
redden
)
# sw, sf = sw*z, sf*(z**3)
sw
,
sf
=
sw
*
z
,
sf
/
z
# sw, sf = sw*z, sf
# lyman forest correction
sf
=
lyman_forest
(
sw
,
sf
,
redshift
)
isedObs
=
(
sw
.
copy
(),
sf
.
copy
())
return
isedObs
def
integrate_sed_bandpass
(
sed
,
bandpass
):
wave
=
np
.
linspace
(
bandpass
.
blue_limit
,
bandpass
.
red_limit
,
1000
)
# in nm
flux_normalized
=
sed
(
wave
)
*
bandpass
(
wave
)
# print('in integrate_sed_bandpass', bandpass.blue_limit, bandpass.red_limit)
int_flux
=
np
.
trapz
(
y
=
flux_normalized
,
x
=
wave
)
*
\
10.
# convert to photons s-1 m-2 A-1
return
int_flux
def
getABMAG
(
interFlux
,
bandpass
):
throughtput
=
Table
(
np
.
array
(
np
.
array
([
bandpass
.
wave_list
*
10.0
,
bandpass
.
func
(
bandpass
.
wave_list
)])).
T
,
names
=
([
'WAVELENGTH'
,
'SENSITIVITY'
]))
sWave
=
bandpass
.
blue_limit
*
10.0
eWave
=
bandpass
.
red_limit
*
10.0
# print('in getABMAG', sWave, eWave)
ABMAG_zero
=
getABMagAverageVal
(
ABmag
=
0
,
norm_thr
=
throughtput
,
sWave
=
sWave
,
eWave
=
eWave
)
flux_ave
=
interFlux
/
(
eWave
-
sWave
)
ABMAG_spec
=
-
2.5
*
np
.
log10
(
flux_ave
/
ABMAG_zero
)
return
ABMAG_spec
def
getABMagAverageVal
(
ABmag
=
20.
,
norm_thr
=
None
,
sWave
=
6840
,
eWave
=
8250
):
"""
norm_thr: astropy.table, 2 colum, 'WAVELENGTH', 'SENSITIVITY'
Return:
the integerate flux of AB magnitude in the norm_thr(the throughtput of band), photos s-1 m-2 A-1
"""
inverseLambda
=
norm_thr
[
'SENSITIVITY'
]
/
norm_thr
[
'WAVELENGTH'
]
norm_thr_i
=
interpolate
.
interp1d
(
norm_thr
[
'WAVELENGTH'
],
inverseLambda
)
x
=
np
.
linspace
(
sWave
,
eWave
,
int
(
eWave
)
-
int
(
sWave
)
+
1
)
y
=
norm_thr_i
(
x
)
AverageLamdaInverse
=
np
.
trapz
(
y
,
x
)
/
(
eWave
-
sWave
)
norm
=
54798696332.52474
*
pow
(
10.0
,
-
0.4
*
ABmag
)
*
AverageLamdaInverse
# print('AverageLamdaInverse = ', AverageLamdaInverse)
# print('norm = ', norm)
return
norm
def
getNormFactorForSpecWithABMAG
(
ABMag
=
20.
,
spectrum
=
None
,
norm_thr
=
None
,
sWave
=
6840
,
eWave
=
8250
):
"""
Use AB magnitude system (zero point, fv = 3631 janskys) in the normal band(norm_thr) normalize the spectrum by inpute ABMag
Parameters
----------
spectrum: astropy.table, 2 colum, 'WAVELENGTH', 'FLUX'
norm_thr: astropy.table, 2 colum, 'WAVELENGTH', 'SENSITIVITY'
sWave: the start of norm_thr
eWave: the end of norm_thr
Return:
the normalization factor flux of AB system(fix a band and magnitude ) /the flux of inpute spectrum(fix a band)
"""
spectrumi
=
interpolate
.
interp1d
(
spectrum
[
'WAVELENGTH'
],
spectrum
[
'FLUX'
])
norm_thri
=
interpolate
.
interp1d
(
norm_thr
[
'WAVELENGTH'
],
norm_thr
[
'SENSITIVITY'
])
x
=
np
.
linspace
(
sWave
,
eWave
,
int
(
eWave
)
-
int
(
sWave
)
+
1
)
y_spec
=
spectrumi
(
x
)
y_thr
=
norm_thri
(
x
)
y
=
y_spec
*
y_thr
specAve
=
np
.
trapz
(
y
,
x
)
/
(
eWave
-
sWave
)
norm
=
getABMagAverageVal
(
ABmag
=
ABMag
,
norm_thr
=
norm_thr
,
sWave
=
sWave
,
eWave
=
eWave
)
if
specAve
==
0
:
return
0
# print('specAve = ', specAve)
return
norm
/
specAve
def
tag_sed
(
h5file
,
model_tag
,
teff
=
5000
,
logg
=
2
,
feh
=
0
):
model_tag_str
=
model_tag
.
decode
(
"utf-8"
).
strip
()
teff_grid
=
np
.
unique
(
h5file
[
"teff"
][
model_tag_str
])
logg_grid
=
np
.
unique
(
h5file
[
"logg"
][
model_tag_str
])
feh_grid
=
np
.
unique
(
h5file
[
"feh"
][
model_tag_str
])
close_teff
=
teff_grid
[
np
.
argmin
(
np
.
abs
(
teff_grid
-
teff
))]
close_logg
=
logg_grid
[
np
.
argmin
(
np
.
abs
(
logg_grid
-
logg
))]
if
model_tag_str
==
"koester"
or
model_tag_str
==
"MC"
:
close_feh
=
99
else
:
close_feh
=
feh_grid
[
np
.
argmin
(
np
.
abs
(
feh_grid
-
feh
))]
path
=
model_tag_str
+
\
f
"_teff_
{
close_teff
:
.
1
f
}
_logg_
{
close_logg
:
.
2
f
}
_feh_
{
close_feh
:
.
1
f
}
"
wave
=
np
.
array
(
h5file
[
"wave"
][
model_tag_str
][()]).
ravel
()
flux
=
np
.
array
(
h5file
[
"sed"
][
path
][()]).
ravel
()
return
path
,
wave
,
flux
def
convolveGaussXorders
(
img
=
None
,
sigma
=
1
):
from
astropy.modeling.models
import
Gaussian2D
from
scipy
import
signal
offset
=
int
(
np
.
ceil
(
sigma
*
10
))
g_size
=
2
*
offset
+
1
m_cen
=
int
(
g_size
/
2
)
g_PSF_
=
Gaussian2D
(
1
,
m_cen
,
m_cen
,
sigma
,
sigma
)
yp
,
xp
=
np
.
mgrid
[
0
:
g_size
,
0
:
g_size
]
g_PSF
=
g_PSF_
(
xp
,
yp
)
psf
=
g_PSF
/
g_PSF
.
sum
()
convImg
=
signal
.
fftconvolve
(
img
,
psf
,
mode
=
'full'
,
axes
=
None
)
return
convImg
,
offset
def
convolveImg
(
img
=
None
,
psf
=
None
):
from
astropy.modeling.models
import
Gaussian2D
from
scipy
import
signal
convImg
=
signal
.
fftconvolve
(
img
,
psf
,
mode
=
'full'
,
axes
=
None
)
offset_x
=
int
(
psf
.
shape
[
1
]
/
2.
+
0.5
)
-
1
offset_y
=
int
(
psf
.
shape
[
0
]
/
2.
+
0.5
)
-
1
offset
=
[
offset_x
,
offset_y
]
return
convImg
,
offset
observation_sim/mock_objects/data/__init__.py
0 → 100644
View file @
4afd1181
observation_sim/mock_objects/data/led/__init__.py
0 → 100644
View file @
4afd1181
observation_sim/mock_objects/data/led/model_1050nm.fits
0 → 100644
View file @
4afd1181
File added
observation_sim/mock_objects/data/led/model_275nm.fits
0 → 100644
View file @
4afd1181
File added
observation_sim/mock_objects/data/led/model_310nm.fits
0 → 100644
View file @
4afd1181
File added
observation_sim/mock_objects/data/led/model_340nm.fits
0 → 100644
View file @
4afd1181
File added
observation_sim/mock_objects/data/led/model_365nm.fits
0 → 100644
View file @
4afd1181
File added
observation_sim/mock_objects/data/led/model_430nm.fits
0 → 100644
View file @
4afd1181
File added
observation_sim/mock_objects/data/led/model_505nm.fits
0 → 100644
View file @
4afd1181
File added
observation_sim/mock_objects/data/led/model_545nm.fits
0 → 100644
View file @
4afd1181
File added
observation_sim/mock_objects/data/led/model_590nm.fits
0 → 100644
View file @
4afd1181
File added
observation_sim/mock_objects/data/led/model_670nm.fits
0 → 100644
View file @
4afd1181
File added
observation_sim/mock_objects/data/led/model_760nm.fits
0 → 100644
View file @
4afd1181
File added
observation_sim/mock_objects/data/led/model_940nm.fits
0 → 100644
View file @
4afd1181
File added
observation_sim/sim_steps/__init__.py
0 → 100644
View file @
4afd1181
import
os
class
SimSteps
:
def
__init__
(
self
,
overall_config
,
chip_output
,
all_filters
):
self
.
overall_config
=
overall_config
self
.
chip_output
=
chip_output
self
.
all_filters
=
all_filters
from
.prepare_headers
import
prepare_headers
,
updateHeaderInfo
from
.add_sky_background
import
add_sky_background_sci
,
add_sky_flat_calibration
,
add_sky_background
from
.add_objects
import
add_objects
from
.add_cosmic_rays
import
add_cosmic_rays
from
.add_pattern_noise
import
apply_PRNU
,
add_poisson_and_dark
,
add_detector_defects
,
add_nonlinearity
,
add_blooming
,
add_bias
from
.add_brighter_fatter_CTE
import
add_brighter_fatter
,
apply_CTE
from
.readout_output
import
add_prescan_overscan
,
add_readout_noise
,
apply_gain
,
quantization_and_output
from
.add_LED_flat
import
add_LED_Flat
SIM_STEP_TYPES
=
{
"scie_obs"
:
"add_objects"
,
"sky_background"
:
"add_sky_background"
,
"cosmic_rays"
:
"add_cosmic_rays"
,
"PRNU_effect"
:
"apply_PRNU"
,
"poisson_and_dark"
:
"add_poisson_and_dark"
,
"bright_fatter"
:
"add_brighter_fatter"
,
"detector_defects"
:
"add_detector_defects"
,
"nonlinearity"
:
"add_nonlinearity"
,
"blooming"
:
"add_blooming"
,
"CTE_effect"
:
"apply_CTE"
,
"prescan_overscan"
:
"add_prescan_overscan"
,
"bias"
:
"add_bias"
,
"readout_noise"
:
"add_readout_noise"
,
"gain"
:
"apply_gain"
,
"quantization_and_output"
:
"quantization_and_output"
,
"led_calib_model"
:
"add_LED_Flat"
,
"sky_flatField"
:
"add_sky_flat_calibration"
,
}
\ No newline at end of file
observation_sim/sim_steps/add_LED_flat.py
0 → 100644
View file @
4afd1181
import
numpy
as
np
from
observation_sim.mock_objects
import
FlatLED
import
galsim
from
astropy.time
import
Time
from
datetime
import
datetime
,
timezone
import
gc
def
add_LED_Flat
(
self
,
chip
,
filt
,
tel
,
pointing
,
catalog
,
obs_param
):
if
not
hasattr
(
self
,
'h_ext'
):
_
,
_
=
self
.
prepare_headers
(
chip
=
chip
,
pointing
=
pointing
)
chip_wcs
=
galsim
.
FitsWCS
(
header
=
self
.
h_ext
)
pf_map
=
np
.
zeros_like
(
chip
.
img
.
array
)
if
obs_param
[
"LED_TYPE"
]
is
not
None
:
if
len
(
obs_param
[
"LED_TYPE"
])
!=
0
:
print
(
"LED OPEN--------"
)
led_obj
=
FlatLED
(
chip
,
filt
)
led_flat
,
ledstat
,
letts
=
led_obj
.
drawObj_LEDFlat
(
led_type_list
=
obs_param
[
"LED_TYPE"
],
exp_t_list
=
obs_param
[
"LED_TIME"
])
pf_map
=
led_flat
self
.
updateHeaderInfo
(
header_flag
=
'ext'
,
keys
=
[
'LEDSTAT'
],
values
=
[
ledstat
])
self
.
updateHeaderInfo
(
header_flag
=
'ext'
,
keys
=
[
'LEDT01'
,
'LEDT02'
,
'LEDT03'
,
'LEDT04'
,
'LEDT05'
,
'LEDT06'
,
'LEDT07'
,
'LEDT08'
,
'LEDT09'
,
'LEDT10'
,
'LEDT11'
,
'LEDT12'
,
'LEDT13'
,
'LEDT14'
],
values
=
letts
)
if
obs_param
[
"shutter_effect"
]
==
True
:
pf_map
=
pf_map
*
chip
.
shutter_img
pf_map
=
np
.
array
(
pf_map
,
dtype
=
'float32'
)
self
.
updateHeaderInfo
(
header_flag
=
'ext'
,
keys
=
[
'SHTSTAT'
],
values
=
[
True
])
else
:
self
.
updateHeaderInfo
(
header_flag
=
'ext'
,
keys
=
[
'SHTSTAT'
,
'SHTOPEN1'
,
'SHTCLOS0'
],
values
=
[
True
,
self
.
h_ext
[
'SHTCLOS1'
],
self
.
h_ext
[
'SHTOPEN0'
]])
chip
.
img
=
chip
.
img
+
pf_map
# renew header info
datetime_obs
=
datetime
.
utcfromtimestamp
(
pointing
.
timestamp
)
datetime_obs
=
datetime_obs
.
replace
(
tzinfo
=
timezone
.
utc
)
t_obs
=
Time
(
datetime_obs
)
# ccd刷新2s,等待0.5s,开灯后等待0.5s,开始曝光
t_obs_renew
=
Time
(
t_obs
.
mjd
-
(
2.
)
/
86400.
,
format
=
"mjd"
)
t_obs_utc
=
datetime
.
utcfromtimestamp
(
np
.
round
(
datetime
.
utcfromtimestamp
(
t_obs_renew
.
unix
).
replace
(
tzinfo
=
timezone
.
utc
).
timestamp
(),
1
))
self
.
updateHeaderInfo
(
header_flag
=
'prim'
,
keys
=
[
'DATE-OBS'
],
values
=
[
t_obs_utc
.
strftime
(
"%Y-%m-%dT%H:%M:%S.%f"
)[:
-
5
]])
# dark time :
self
.
updateHeaderInfo
(
header_flag
=
'ext'
,
keys
=
[
'DARKTIME'
],
values
=
[
pointing
.
exp_time
])
gc
.
collect
()
return
chip
,
filt
,
tel
,
pointing
observation_sim/sim_steps/add_brighter_fatter_CTE.py
0 → 100644
View file @
4afd1181
import
numpy
as
np
import
galsim
from
observation_sim.instruments.chip
import
chip_utils
from
observation_sim.instruments.chip.libCTI.CTI_modeling
import
CTI_sim
def
add_brighter_fatter
(
self
,
chip
,
filt
,
tel
,
pointing
,
catalog
,
obs_param
):
chip
.
img
=
chip_utils
.
add_brighter_fatter
(
img
=
chip
.
img
)
return
chip
,
filt
,
tel
,
pointing
def
apply_CTE
(
self
,
chip
,
filt
,
tel
,
pointing
,
catalog
,
obs_param
):
self
.
chip_output
.
Log_info
(
" Apply CTE Effect"
)
# 2*8 -> 1*16 img-layout
img
=
chip_utils
.
formatOutput
(
GSImage
=
chip
.
img
)
chip
.
nsecy
=
1
chip
.
nsecx
=
16
img_arr
=
img
.
array
ny
,
nx
=
img_arr
.
shape
dx
=
int
(
nx
/
chip
.
nsecx
)
dy
=
int
(
ny
/
chip
.
nsecy
)
newimg
=
galsim
.
Image
(
nx
,
int
(
ny
+
chip
.
overscan_y
),
init_value
=
0
)
for
ichannel
in
range
(
16
):
print
(
'
\n
***add CTI effects: pointing-{:} chip-{:} channel-{:}***'
.
format
(
pointing
.
id
,
chip
.
chipID
,
ichannel
+
1
))
noverscan
,
nsp
,
nmax
=
chip
.
overscan_y
,
3
,
10
beta
,
w
,
c
=
0.478
,
84700
,
0
t
=
np
.
array
([
0.74
,
7.7
,
37
],
dtype
=
np
.
float32
)
rho_trap
=
np
.
array
([
0.6
,
1.6
,
1.4
],
dtype
=
np
.
float32
)
trap_seeds
=
np
.
array
(
[
0
,
1000
,
10000
],
dtype
=
np
.
int32
)
+
ichannel
+
chip
.
chipID
*
16
release_seed
=
50
+
ichannel
+
pointing
.
id
*
30
+
chip
.
chipID
*
16
newimg
.
array
[:,
0
+
ichannel
*
dx
:
dx
+
ichannel
*
dx
]
=
CTI_sim
(
img_arr
[:,
0
+
ichannel
*
dx
:
dx
+
ichannel
*
dx
],
dx
,
dy
,
noverscan
,
nsp
,
nmax
,
beta
,
w
,
c
,
t
,
rho_trap
,
trap_seeds
,
release_seed
)
newimg
.
wcs
=
img
.
wcs
del
img
img
=
newimg
# 1*16 -> 2*8 img-layout
chip
.
img
=
chip_utils
.
formatRevert
(
GSImage
=
img
)
chip
.
nsecy
=
2
chip
.
nsecx
=
8
# [TODO] make overscan_y == 0
chip
.
overscan_y
=
0
return
chip
,
filt
,
tel
,
pointing
observation_sim/sim_steps/add_cosmic_rays.py
0 → 100644
View file @
4afd1181
from
observation_sim.instruments.chip
import
chip_utils
def
add_cosmic_rays
(
self
,
chip
,
filt
,
tel
,
pointing
,
catalog
,
obs_param
):
self
.
chip_output
.
Log_info
(
" Adding Cosmic-Ray"
)
# Get exposure time
if
(
obs_param
)
and
(
"exptime"
in
obs_param
)
and
(
obs_param
[
"exptime"
]
is
not
None
):
exptime
=
obs_param
[
"exptime"
]
else
:
exptime
=
pointing
.
exp_time
chip
.
img
,
crmap_gsimg
,
cr_event_num
=
chip_utils
.
add_cosmic_rays
(
img
=
chip
.
img
,
chip
=
chip
,
exptime
=
exptime
,
seed
=
self
.
overall_config
[
"random_seeds"
][
"seed_CR"
]
+
pointing
.
id
*
30
+
chip
.
chipID
)
# Save cosmic ray image
if
(
obs_param
)
and
(
"save_cosmic_img"
in
obs_param
)
and
(
obs_param
[
"save_cosmic_img"
]
is
not
None
):
if
obs_param
[
"save_cosmic_img"
]:
chip_utils
.
output_fits_image
(
chip
=
chip
,
pointing
=
pointing
,
img
=
crmap_gsimg
,
output_dir
=
self
.
chip_output
.
subdir
,
img_type
=
'CRS'
,
img_type_code
=
pointing
.
pointing_type_code
,
project_cycle
=
self
.
overall_config
[
"project_cycle"
],
run_counter
=
self
.
overall_config
[
"run_counter"
]
)
return
chip
,
filt
,
tel
,
pointing
Prev
1
…
5
6
7
8
9
10
11
Next
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