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
Liu Dezi
csst_msc_sim
Commits
29ac5666
Commit
29ac5666
authored
Apr 07, 2021
by
Fang Yuedong
Browse files
Baseline
parents
Changes
830
Hide whitespace changes
Inline
Side-by-side
ObservationSim/MockObject/_util.py
0 → 100755
View file @
29ac5666
import
numpy
as
np
import
os
from
datetime
import
datetime
from
scipy.interpolate
import
InterpolatedUnivariateSpline
,
UnivariateSpline
,
interp1d
from
scipy
import
interpolate
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
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
)
pav
=
lambda
av
:
(
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
)
elif
model
==
4
:
# Prevot et al (1984) and Bouchet (1985) for the Small Magellanic Cloud (SMC)
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
fun1
=
lambda
x
:
2.659
*
(
-
2.156
+
1.509
/
x
-
0.198
/
x
**
2
+
0.011
/
x
**
3
)
+
Rv
fun2
=
lambda
x
:
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
fun1
=
lambda
x
:
-
5.726
+
4.004
/
x
-
0.525
/
x
**
2
+
0.029
/
x
**
3
+
Rv
fun2
=
lambda
x
:
-
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
:
print
(
"!!! Please select a proper reddening model"
)
sys
.
exit
(
0
)
return
flux
###########################################
def
__red
(
alan
,
al0
,
ga
,
c1
,
c2
,
c3
,
c4
):
fun1
=
lambda
x
:
c3
/
(((
x
-
(
al0
**
2
/
x
))
**
2
)
+
ga
*
ga
)
fun2
=
lambda
x
,
cc
:
cc
*
(
0.539
*
((
x
-
5.9
)
**
2
)
+
0.0564
*
((
x
-
5.9
)
**
3
))
fun
=
lambda
x
,
cc
:
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
)
# 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
\ No newline at end of file
ObservationSim/ObservationSim.py
0 → 100755
View file @
29ac5666
from
Config
import
ConfigDir
,
ReadConfig
,
ChipOutput
from
Config.Header
import
generatePrimaryHeader
,
generateExtensionHeader
from
Instrument
import
Telescope
,
Filter
,
FilterParam
,
FocalPlane
,
Chip
from
MockObject
import
Catalog
,
MockObject
,
Star
,
Galaxy
,
Quasar
,
calculateSkyMap_split_g
from
PSF
import
PSFGauss
,
PSFInterp
,
FieldDistortion
from
_util
import
makeSubDir
,
getShearFiled
,
makeSubDir_PointingList
from
astropy.time
import
Time
as
asTime
from
astropy.io
import
fits
import
numpy
as
np
import
mpi4py.MPI
as
MPI
import
galsim
import
os
,
sys
import
logging
import
psutil
class
Observation
(
object
):
def
__init__
(
self
,
input_cat_dir
=
None
,
work_dir
=
None
,
data_dir
=
None
):
self
.
path_dict
=
ConfigDir
(
input_cat_dir
,
work_dir
,
data_dir
)
self
.
config
=
ReadConfig
(
self
.
path_dict
[
"config_file"
])
self
.
tel
=
Telescope
(
optEffCurve_path
=
self
.
path_dict
[
"mirror_file"
])
# Currently the default values are hard coded in
self
.
focal_plane
=
FocalPlane
(
survey_type
=
self
.
config
[
"survey_type"
])
# Currently the default values are hard coded in
self
.
filter_param
=
FilterParam
(
filter_dir
=
self
.
path_dict
[
"filter_dir"
])
# Currently the default values are hard coded in
self
.
chip_list
=
[]
self
.
filter_list
=
[]
# if we want to apply field distortion?
if
self
.
config
[
"field_dist"
].
lower
()
==
"y"
:
self
.
fd_model
=
FieldDistortion
()
else
:
self
.
fd_model
=
None
# Construct chips & filters:
nchips
=
self
.
focal_plane
.
nchip_x
*
self
.
focal_plane
.
nchip_y
for
i
in
range
(
nchips
):
chipID
=
i
+
1
if
self
.
focal_plane
.
isIgnored
(
chipID
=
chipID
):
continue
# Make Chip & Filter lists
chip
=
Chip
(
chipID
,
ccdEffCurve_dir
=
self
.
path_dict
[
"ccd_dir"
],
CRdata_dir
=
self
.
path_dict
[
"CRdata_dir"
],
normalize_dir
=
self
.
path_dict
[
"normalize_dir"
],
sls_dir
=
self
.
path_dict
[
"sls_dir"
],
config
=
self
.
config
)
# currently there is no config file for chips
filter_id
,
filter_type
=
chip
.
getChipFilter
()
filt
=
Filter
(
filter_id
=
filter_id
,
filter_type
=
filter_type
,
filter_param
=
self
.
filter_param
,
ccd_bandpass
=
chip
.
effCurve
)
self
.
chip_list
.
append
(
chip
)
self
.
filter_list
.
append
(
filt
)
# Read catalog and shear(s)
self
.
g1_field
,
self
.
g2_field
,
self
.
nshear
=
getShearFiled
(
config
=
self
.
config
)
def
runOneChip
(
self
,
chip
,
filt
,
chip_output
,
wcs_fp
=
None
,
psf_model
=
None
,
pointing_ID
=
0
,
ra_cen
=
None
,
dec_cen
=
None
,
img_rot
=
None
,
exptime
=
150.
,
input_cat_name
=
None
,
shear_cat_file
=
None
,
cat_dir
=
None
,
sed_dir
=
None
):
if
(
ra_cen
is
None
)
or
(
dec_cen
is
None
):
ra_cen
=
self
.
config
[
"ra_center"
]
dec_cen
=
self
.
config
[
"dec_center"
]
if
img_rot
is
None
:
img_rot
=
self
.
config
[
"image_rot"
]
if
self
.
config
[
"psf_model"
]
==
"Gauss"
:
psf_model
=
PSFGauss
(
chip
=
chip
)
elif
self
.
config
[
"psf_model"
]
==
"Interp"
:
psf_model
=
PSFInterp
(
chip
=
chip
)
else
:
print
(
"unrecognized PSF model type!!"
,
flush
=
True
)
# Get (extra) shear fields
if
shear_cat_file
is
not
None
:
self
.
g1_field
,
self
.
g2_field
,
self
.
nshear
=
getShearFiled
(
config
=
self
.
config
,
shear_cat_file
=
shear_cat_file
)
# Get WCS for the focal plane
if
wcs_fp
==
None
:
wcs_fp
=
self
.
focal_plane
.
getTanWCS
(
ra_cen
,
dec_cen
,
img_rot
,
chip
.
pix_scale
)
# Create chip Image
chip
.
img
=
galsim
.
ImageF
(
chip
.
npix_x
,
chip
.
npix_y
)
chip
.
img
.
setOrigin
(
chip
.
bound
.
xmin
,
chip
.
bound
.
ymin
)
chip
.
img
.
wcs
=
wcs_fp
if
chip
.
survey_type
==
"photometric"
:
sky_map
=
None
elif
chip
.
survey_type
==
"spectroscopic"
:
skyfile
=
os
.
path
.
join
(
self
.
path_dict
[
"data_dir"
],
'skybackground/sky_emiss_hubble_50_50_A.dat'
)
sky_map
=
calculateSkyMap_split_g
(
xLen
=
chip
.
npix_x
,
yLen
=
chip
.
npix_y
,
blueLimit
=
filt
.
blue_limit
,
redLimit
=
filt
.
red_limit
,
skyfn
=
skyfile
,
conf
=
chip
.
sls_conf
,
pixelSize
=
chip
.
pix_scale
,
isAlongY
=
0
)
# Load catalogues and templates
self
.
cat
=
Catalog
(
config
=
self
.
config
,
chip
=
chip
,
cat_dir
=
cat_dir
,
sed_dir
=
sed_dir
,
pRa
=
ra_cen
,
pDec
=
dec_cen
,
rotation
=
img_rot
,
template_dir
=
self
.
path_dict
[
"template_dir"
])
self
.
nobj
=
len
(
self
.
cat
.
objs
)
# Loop over objects
missed_obj
=
0
bright_obj
=
0
dim_obj
=
0
for
j
in
range
(
self
.
nobj
):
# if j >= 20:
# break
obj
=
self
.
cat
.
objs
[
j
]
# Load SED
if
obj
.
type
==
'star'
:
normF
=
chip
.
normF_star
try
:
obj
.
load_SED
(
survey_type
=
chip
.
survey_type
,
normFilter
=
normF
,
target_filt
=
filt
,
sed_lib
=
self
.
cat
.
tempSED_star
)
except
Exception
as
e
:
print
(
e
)
continue
elif
obj
.
type
==
'galaxy'
:
# or obj.type == quasar
normF
=
chip
.
normF_galaxy
obj
.
load_SED
(
sed_path
=
sed_dir
,
survey_type
=
chip
.
survey_type
,
sed_templates
=
self
.
cat
.
tempSed_gal
,
normFilter
=
normF
,
target_filt
=
filt
)
elif
obj
.
type
==
'quasar'
:
normF
=
chip
.
normF_galaxy
obj
.
load_SED
(
sed_path
=
sed_dir
,
survey_type
=
chip
.
survey_type
,
sed_templates
=
self
.
cat
.
tempSed_gal
,
normFilter
=
normF
,
target_filt
=
filt
)
# Exclude very bright/dim objects (for now)
if
filt
.
is_too_bright
(
mag
=
obj
.
getMagFilter
(
filt
)):
# print("obj too birght!!", flush=True)
if
obj
.
type
!=
'galaxy'
:
bright_obj
+=
1
obj
.
unload_SED
()
continue
if
filt
.
is_too_dim
(
mag
=
obj
.
getMagFilter
(
filt
)):
# print("obj too dim!!", flush=True)
dim_obj
+=
1
obj
.
unload_SED
()
# print(obj.getMagFilter(filt))
continue
if
self
.
config
[
"shear_method"
]
==
"constant"
:
if
obj
.
type
==
'star'
:
g1
,
g2
=
0
,
0
else
:
g1
,
g2
=
self
.
g1_field
,
self
.
g2_field
elif
self
.
config
[
"shear_method"
]
==
"extra"
:
# TODO: every object with individual shear from input catalog(s)
g1
,
g2
=
self
.
g1_field
[
j
],
self
.
g2_field
[
j
]
pos_img
,
offset
,
local_wcs
=
obj
.
getPosImg_Offset_WCS
(
img
=
chip
.
img
,
fdmodel
=
self
.
fd_model
,
chip
=
chip
,
verbose
=
False
)
if
pos_img
.
x
==
-
1
or
pos_img
.
y
==
-
1
:
# Exclude object which is outside the chip area (after field distortion)
# print("obj missed!!")
missed_obj
+=
1
obj
.
unload_SED
()
continue
# Draw object & update output catalog
try
:
if
chip
.
survey_type
==
"photometric"
:
isUpdated
,
pos_shear
=
obj
.
drawObj_multiband
(
tel
=
self
.
tel
,
pos_img
=
pos_img
,
psf_model
=
psf_model
,
bandpass_list
=
filt
.
bandpass_sub_list
,
filt
=
filt
,
chip
=
chip
,
g1
=
g1
,
g2
=
g2
,
exptime
=
exptime
)
elif
chip
.
survey_type
==
"spectroscopic"
:
isUpdated
,
pos_shear
=
obj
.
drawObj_slitless
(
tel
=
self
.
tel
,
pos_img
=
pos_img
,
psf_model
=
psf_model
,
bandpass_list
=
filt
.
bandpass_sub_list
,
filt
=
filt
,
chip
=
chip
,
g1
=
g1
,
g2
=
g2
,
exptime
=
exptime
,
normFilter
=
normF
)
if
isUpdated
:
# TODO: add up stats
chip_output
.
cat_add_obj
(
obj
,
pos_img
,
pos_shear
,
g1
,
g2
)
pass
else
:
# print("object omitted", flush=True)
continue
except
Exception
as
e
:
print
(
e
)
pass
# Unload SED:
obj
.
unload_SED
()
del
obj
del
psf_model
del
self
.
cat
print
(
"check running:1: pointing-{:} chip-{:} pid-{:} memory-{:6.2}GB"
.
format
(
pointing_ID
,
chip
.
chipID
,
os
.
getpid
(),
(
psutil
.
Process
(
os
.
getpid
()).
memory_info
().
rss
/
1024
/
1024
/
1024
)
),
flush
=
True
)
# Detector Effects
# ===========================================================
chip
.
img
=
chip
.
addNoise
(
config
=
self
.
config
,
tel
=
self
.
tel
,
filt
=
filt
,
img
=
chip
.
img
,
sky_map
=
sky_map
)
chip
.
img
=
chip
.
addEffects
(
config
=
self
.
config
,
img
=
chip
.
img
,
chip_output
=
chip_output
,
filt
=
filt
,
pointing_ID
=
pointing_ID
)
h_prim
=
generatePrimaryHeader
(
xlen
=
chip
.
npix_x
,
ylen
=
chip
.
npix_y
,
pointNum
=
str
(
pointing_ID
),
ra
=
ra_cen
,
dec
=
dec_cen
,
psize
=
chip
.
pix_scale
,
row_num
=
chip
.
rowID
,
col_num
=
chip
.
colID
,
date
=
self
.
config
[
"date_obs"
],
time_obs
=
self
.
config
[
"time_obs"
])
h_ext
=
generateExtensionHeader
(
xlen
=
chip
.
npix_x
,
ylen
=
chip
.
npix_y
,
ra
=
ra_cen
,
dec
=
dec_cen
,
pa
=
img_rot
.
deg
,
gain
=
chip
.
gain
,
readout
=
chip
.
read_noise
,
dark
=
chip
.
dark_noise
,
saturation
=
90000
,
psize
=
chip
.
pix_scale
,
row_num
=
chip
.
rowID
,
col_num
=
chip
.
colID
)
chip
.
img
=
galsim
.
Image
(
chip
.
img
.
array
,
dtype
=
np
.
uint16
)
hdu1
=
fits
.
PrimaryHDU
(
header
=
h_prim
)
hdu2
=
fits
.
ImageHDU
(
chip
.
img
.
array
,
header
=
h_ext
)
hdu1
=
fits
.
HDUList
([
hdu1
,
hdu2
])
fname
=
os
.
path
.
join
(
chip_output
.
subdir
,
h_prim
[
'FILENAME'
]
+
'.fits'
)
hdu1
.
writeto
(
fname
,
output_verify
=
'ignore'
,
overwrite
=
True
)
del
chip
.
img
print
(
"check running:2: pointing-{:} chip-{:} pid-{:} memory-{:6.2}GB"
.
format
(
pointing_ID
,
chip
.
chipID
,
os
.
getpid
(),
(
psutil
.
Process
(
os
.
getpid
()).
memory_info
().
rss
/
1024
/
1024
/
1024
)
),
flush
=
True
)
print
(
"# objects that are too bright %d out of %d"
%
(
bright_obj
,
self
.
nobj
))
print
(
"# objects that are too dim %d out of %d"
%
(
dim_obj
,
self
.
nobj
))
print
(
"# objects that are missed %d out of %d"
%
(
missed_obj
,
self
.
nobj
))
def
runExposure
(
self
,
ra_cen
=
None
,
dec_cen
=
None
,
pointing_ID
=
0
,
img_rot
=
None
,
exptime
=
150.
,
input_cat_name
=
None
,
shear_cat_file
=
None
,
oneChip
=
None
):
if
(
ra_cen
==
None
)
or
(
dec_cen
==
None
):
ra_cen
=
self
.
config
[
"ra_center"
]
dec_cen
=
self
.
config
[
"dec_center"
]
if
img_rot
==
None
:
img_rot
=
self
.
config
[
"image_rot"
]
sub_img_dir
,
prefix
=
makeSubDir_PointingList
(
path_dict
=
self
.
path_dict
,
config
=
self
.
config
,
pointing_ID
=
pointing_ID
)
# Loop over chips
for
i
in
range
(
len
(
self
.
chip_list
)):
chip
=
self
.
chip_list
[
i
]
filt
=
self
.
filter_list
[
i
]
# Just run one chip
if
oneChip
is
not
None
:
if
chip
.
chipID
!=
oneChip
:
continue
# Prepare output files
chip_output
=
ChipOutput
(
config
=
self
.
config
,
focal_plane
=
self
.
focal_plane
,
chip
=
chip
,
filt
=
filt
,
exptime
=
exptime
,
pointing_ID
=
pointing_ID
,
subdir
=
sub_img_dir
,
prefix
=
prefix
)
self
.
runOneChip
(
chip
=
chip
,
filt
=
filt
,
chip_output
=
chip_output
,
pointing_ID
=
pointing_ID
,
ra_cen
=
ra_cen
,
dec_cen
=
dec_cen
,
img_rot
=
img_rot
,
exptime
=
exptime
,
cat_dir
=
self
.
path_dict
[
"cat_dir"
],
sed_dir
=
self
.
path_dict
[
"SED_dir"
])
print
(
"finished running chip#%d..."
%
(
chip
.
chipID
),
flush
=
True
)
def
runExposure_MPI_PointingList
(
self
,
ra_cen
=
None
,
dec_cen
=
None
,
pRange
=
None
,
img_rot
=
None
,
exptime
=
150.
,
input_cat_name
=
None
,
shear_cat_file
=
None
):
comm
=
MPI
.
COMM_WORLD
ind_thread
=
comm
.
Get_rank
()
num_thread
=
comm
.
Get_size
()
nchips_per_fp
=
len
(
self
.
chip_list
)
ra_cen
=
ra_cen
[
pRange
]
dec_cen
=
dec_cen
[
pRange
]
# The Starting pointing ID
if
pRange
is
not
None
:
pStart
=
pRange
[
0
]
else
:
pStart
=
0
for
ipoint
in
range
(
len
(
ra_cen
)):
for
ichip
in
range
(
nchips_per_fp
):
i
=
ipoint
*
nchips_per_fp
+
ichip
pointing_ID
=
pStart
+
ipoint
if
i
%
num_thread
!=
ind_thread
:
continue
pid
=
os
.
getpid
()
sub_img_dir
,
prefix
=
makeSubDir_PointingList
(
path_dict
=
self
.
path_dict
,
config
=
self
.
config
,
pointing_ID
=
pointing_ID
)
chip
=
self
.
chip_list
[
ichip
]
filt
=
self
.
filter_list
[
ichip
]
print
(
"running pointing#%d, chip#%d, at PID#%d..."
%
(
pointing_ID
,
chip
.
chipID
,
pid
),
flush
=
True
)
chip_output
=
ChipOutput
(
config
=
self
.
config
,
focal_plane
=
self
.
focal_plane
,
chip
=
chip
,
filt
=
filt
,
exptime
=
exptime
,
pointing_ID
=
pointing_ID
,
subdir
=
sub_img_dir
,
prefix
=
prefix
)
self
.
runOneChip
(
chip
=
chip
,
filt
=
filt
,
chip_output
=
chip_output
,
pointing_ID
=
pointing_ID
,
ra_cen
=
ra_cen
[
ipoint
],
dec_cen
=
dec_cen
[
ipoint
],
img_rot
=
img_rot
,
exptime
=
exptime
,
cat_dir
=
self
.
path_dict
[
"cat_dir"
],
sed_dir
=
self
.
path_dict
[
"SED_dir"
])
print
(
"finished running chip#%d..."
%
(
chip
.
chipID
),
flush
=
True
)
\ No newline at end of file
ObservationSim/PSF/FieldDistortion.py
0 → 100644
View file @
29ac5666
import
galsim
import
numpy
as
np
class
FieldDistortion
(
object
):
def
__init__
(
self
,
fdModel
=
None
,
fdModel_path
=
None
):
if
fdModel
is
None
:
import
pickle
if
fdModel_path
is
not
None
:
with
open
(
fdModel_path
,
"rb"
)
as
f
:
self
.
fdModel
=
pickle
.
load
(
f
)
else
:
# with open("/data/simudata/CSSOSDataProductsSims/data/FieldDistModelv1.0.pickle", "rb") as f:
with
open
(
"/data/simudata/CSSOSDataProductsSims/data/FieldDistModelv2.0.pickle"
,
"rb"
)
as
f
:
self
.
fdModel
=
pickle
.
load
(
f
)
else
:
self
.
fdModel
=
fdModel
def
isContainObj_FD
(
self
,
chip
,
pos_img
):
ifdModel
=
self
.
fdModel
[
"ccd"
+
chip
.
getChipLabel
(
chipID
=
chip
.
chipID
)][
"wave1"
]
x
,
y
=
pos_img
.
x
,
pos_img
.
y
xLowI
,
xUpI
,
yLowI
,
yUpI
=
ifdModel
[
"InterpLim"
]
if
(
xLowI
-
x
)
*
(
xUpI
-
x
)
>
0
or
(
yLowI
-
y
)
*
(
yUpI
-
y
)
>
0
:
return
False
return
True
def
get_Distorted
(
self
,
chip
,
pos_img
,
bandpass
=
None
):
""" Get the distored position for an undistorted image position
Parameters:
chip: A 'Chip' object representing the
chip we want to extract PSF from.
pos_img: A 'galsim.Position' object representing
the image position.
bandpass: A 'galsim.Bandpass' object representing
the wavelength range.
Returns:
pos_distorted: A 'galsim.Position' object representing
the distored position.
"""
if
not
self
.
isContainObj_FD
(
chip
=
chip
,
pos_img
=
pos_img
):
return
galsim
.
PositionD
(
-
1
,
-
1
)
ifdModel
=
self
.
fdModel
[
"ccd"
+
chip
.
getChipLabel
(
chipID
=
chip
.
chipID
)][
"wave1"
]
x
,
y
=
pos_img
.
x
,
pos_img
.
y
x
=
ifdModel
[
"xImagePos"
](
x
,
y
)[
0
][
0
]
y
=
ifdModel
[
"yImagePos"
](
x
,
y
)[
0
][
0
]
return
galsim
.
PositionD
(
x
,
y
)
ObservationSim/PSF/PSFGauss.py
0 → 100644
View file @
29ac5666
import
galsim
import
sep
import
numpy
as
np
from
scipy.interpolate
import
interp1d
from
.PSFModel
import
PSFModel
import
os
,
sys
class
PSFGauss
(
PSFModel
):
def
__init__
(
self
,
chip
,
fwhm
=
0.187
,
sigSpin
=
0.
,
psfRa
=
0.15
):
self
.
pix_size
=
chip
.
pix_scale
self
.
chip
=
chip
self
.
fwhm
=
fwhm
self
.
sigSpin
=
sigSpin
self
.
sigGauss
=
psfRa
# 80% light radius
self
.
psf
=
galsim
.
Gaussian
(
flux
=
1.0
,
fwhm
=
fwhm
)
def
perfGauss
(
self
,
r
,
sig
):
"""
pseudo-error function, i.e. Cumulative distribution function of Gaussian distribution
Parameter:
r: radius
sig: sigma of the Gaussian distribution
Return:
the value of the pseudo CDF
"""
gaussFun
=
lambda
sigma
,
r
:
1.0
/
(
np
.
sqrt
(
2.0
*
np
.
pi
)
*
sigma
)
*
np
.
exp
(
-
r
**
2
/
(
2.0
*
sigma
**
2
))
nxx
=
1000
rArr
=
np
.
linspace
(
0.0
,
r
,
nxx
)
gauss
=
gaussFun
(
sig
,
rArr
)
erf
=
2.0
*
np
.
trapz
(
gauss
,
rArr
)
return
erf
def
fracGauss
(
self
,
sig
,
r
=
0.15
,
pscale
=
None
):
"""
For a given Gaussian PSF with sigma=sig,
derive the flux ratio ar the given radius r
Parameters:
sig: sigma of the Gauss PSF Function in arcsec
r: radius in arcsec
pscale: pixel scale
Return: the flux ratio
"""
if
pscale
==
None
:
pscale
=
self
.
pix_size
gaussx
=
galsim
.
Gaussian
(
flux
=
1.0
,
sigma
=
sig
)
gaussImg
=
gaussx
.
drawImage
(
scale
=
pscale
,
method
=
'no_pixel'
)
gaussImg
=
gaussImg
.
array
size
=
np
.
size
(
gaussImg
,
axis
=
0
)
cxy
=
0.5
*
(
size
-
1
)
flux
,
ferr
,
flag
=
sep
.
sum_circle
(
gaussImg
,
cxy
,
cxy
,
r
/
pscale
,
subpix
=
0
)
frac
=
flux
.
tolist
()
return
frac
def
fwhmGauss
(
self
,
r
=
0.15
,
fr
=
0.8
,
pscale
=
None
):
"""
Given a total flux ratio 'fr' within a fixed radius 'r',
estimate the fwhm of the Gaussian function
return the fwhm in arcsec
"""
if
pscale
==
None
:
pscale
=
self
.
pix_size
err
=
1.0e-3
nxx
=
100
sig
=
np
.
linspace
(
0.5
*
pscale
,
1.0
,
nxx
)
frA
=
np
.
zeros
(
nxx
)
for
i
in
range
(
nxx
):
frA
[
i
]
=
self
.
fracGauss
(
sig
[
i
],
r
=
r
,
pscale
=
pscale
)
index
=
[
i
for
i
in
range
(
nxx
-
1
)
if
(
fr
-
frA
[
i
])
*
(
fr
-
frA
[
i
+
1
])
<=
0.0
][
0
]
while
abs
(
frA
[
index
]
-
fr
)
>
1.0e-3
:
sig
=
np
.
linspace
(
sig
[
index
],
sig
[
index
+
1
],
nxx
)
for
i
in
range
(
nxx
):
frA
[
i
]
=
self
.
fracGauss
(
sig
[
i
],
r
=
r
,
pscale
=
pscale
)
index
=
[
i
for
i
in
range
(
nxx
-
1
)
if
(
fr
-
frA
[
i
])
*
(
fr
-
frA
[
i
+
1
])
<=
0.0
][
0
]
fwhm
=
2.35482
*
sig
[
index
]
return
fwhm
def
get_PSF
(
self
,
pos_img
,
chip
=
None
,
bandpass
=
None
,
folding_threshold
=
5.e-3
):
dx
=
pos_img
.
x
-
self
.
chip
.
cen_pix_x
dy
=
pos_img
.
y
-
self
.
chip
.
cen_pix_y
return
self
.
PSFspin
(
dx
,
dy
)
def
PSFspin
(
self
,
x
,
y
):
"""
The PSF profile at a given image position relative to the axis center
Parameters:
theta : spin angles in a given exposure in unit of [arcsecond]
dx, dy: relative position to the axis center in unit of [pixels]
Return:
Spinned PSF: g1, g2 and axis ratio 'a/b'
"""
a2Rad
=
np
.
pi
/
(
60.0
*
60.0
*
180.0
)
ff
=
self
.
sigGauss
*
0.107
*
(
1000.0
/
10.0
)
# in unit of [pixels]
rc
=
np
.
sqrt
(
x
*
x
+
y
*
y
)
cpix
=
rc
*
(
self
.
sigSpin
*
a2Rad
)
beta
=
(
np
.
arctan2
(
y
,
x
)
+
np
.
pi
/
2
)
ell
=
cpix
**
2
/
(
2.0
*
ff
**
2
+
cpix
**
2
)
#ell *= 10.0
qr
=
np
.
sqrt
((
1.0
+
ell
)
/
(
1.0
-
ell
))
#psfShape = galsim.Shear(e=ell, beta=beta)
#g1, g2 = psfShape.g1, psfShape.g2
#qr = np.sqrt((1.0+ell)/(1.0-ell))
#return ell, beta, qr
PSFshear
=
galsim
.
Shear
(
e
=
ell
,
beta
=
beta
*
galsim
.
radians
)
return
self
.
psf
.
shear
(
PSFshear
),
PSFshear
\ No newline at end of file
ObservationSim/PSF/PSFInterp/PSFConfig.py
0 → 100644
View file @
29ac5666
import
sys
import
numpy
as
np
import
scipy.io
from
itertools
import
islice
from
PSF.PSFInterp.PSFUtil
import
*
###加载PSF信息###
def
LoadPSF
(
iccd
,
iwave
,
ipsf
,
psfPath
,
InputMaxPixelPos
=
True
,
PSFCentroidWgt
=
False
,
PixSizeInMicrons
=
2.5
,
PSFBinning
=
False
,
PSFConvGauss
=
False
):
"""
load psf informations from psf matrix.
Parameters:
iccd (int): ccd number [1,30].
iwave(int): wave-index [1,4].
ipsf (int): psf number [1, 100].
psfPath (int): path to psf matrix
InputMaxPixelPos(bool-optional): only True for 30*30 psf-matrix
PSFCentroidWgt(bool-optional): True for using psfMat with libCentroid.lib
Returns:
psfInfo (dirctionary)
"""
if
iccd
not
in
np
.
linspace
(
1
,
30
,
30
,
dtype
=
'int'
):
print
(
'Error - iccd should be in [1, 30].'
)
sys
.
exit
()
if
iwave
not
in
np
.
linspace
(
1
,
4
,
4
,
dtype
=
'int'
):
print
(
'Error - iwave should be in [1, 4].'
)
sys
.
exit
()
if
ipsf
not
in
np
.
linspace
(
1
,
900
,
900
,
dtype
=
'int'
):
print
(
'Error - ipsf should be in [1, 900].'
)
sys
.
exit
()
psfInfo
=
{}
fpath
=
psfPath
+
'/'
+
'ccd{:}'
.
format
(
iccd
)
+
'/'
+
'wave_{:}'
.
format
(
iwave
)
#获取ipsf矩阵
'''
if not PSFCentroidWgt:
##读取PSF原数据
fpathMat = fpath +'/' +'5_psf_array' +'/' +'psf_{:}.mat'.format(ipsf)
data = scipy.io.loadmat(fpathMat)
psfInfo['psfMat'] = data['psf']
if PSFCentroidWgt:
##读取PSFCentroidWgt
ffpath = psfPath +'_proc/' +'ccd{:}'.format(iccd) +'/' + 'wave_{:}'.format(iwave)
ffpathMat = ffpath +'/' +'5_psf_array' +'/' +'psf_{:}_centroidWgt.mat'.format(ipsf)
data = scipy.io.loadmat(ffpathMat)
psfInfo['psfMat'] = data['psf']
'''
if
not
PSFCentroidWgt
:
ffpath
=
fpath
ffpathMat
=
ffpath
+
'/5_psf_array/psf_{:}.mat'
.
format
(
ipsf
)
if
PSFCentroidWgt
:
ffpath
=
psfPath
+
'_proc/ccd{:}/wave_{:}'
.
format
(
iccd
,
iwave
)
ffpathMat
=
ffpath
+
'/5_psf_array/psf_{:}_centroidWgt.mat'
.
format
(
ipsf
)
if
PSFBinning
and
(
not
PSFConvGauss
):
ffpath
=
psfPath
+
'_bin256x256/ccd{:}/wave_{:}'
.
format
(
iccd
,
iwave
)
ffpathMat
=
ffpath
+
'/5_psf_array/psf_{:}_centroidWgt.mat'
.
format
(
ipsf
)
if
(
not
PSFBinning
)
and
PSFConvGauss
:
ffpath
=
psfPath
+
'_convGauss/ccd{:}/wave_{:}'
.
format
(
iccd
,
iwave
)
ffpathMat
=
ffpath
+
'/5_psf_array/psf_{:}_centroidWgt.mat'
.
format
(
ipsf
)
if
PSFBinning
and
PSFConvGauss
:
ffpath
=
psfPath
+
'_convGauss/ccd{:}/wave_{:}'
.
format
(
iccd
,
iwave
)
ffpathMat
=
ffpath
+
'/5_psf_array/psf_{:}_centroidWgt_BC.mat'
.
format
(
ipsf
)
data
=
scipy
.
io
.
loadmat
(
ffpathMat
)
psfInfo
[
'psfMat'
]
=
data
[
'psf'
]
psfInfo
[
'pixsize'
]
=
PixSizeInMicrons
#microns
if
PSFBinning
:
psfInfo
[
'pixsize'
]
=
PixSizeInMicrons
*
2.0
#获取ipsf波长
fpathWave
=
fpath
+
'/'
+
'1_wavelength.txt'
f
=
open
(
fpathWave
,
'r'
)
wavelength
=
np
.
float
(
f
.
readline
())
f
.
close
()
psfInfo
[
'wavelength'
]
=
wavelength
#获取ipsf位置
fpathCoordinate
=
fpath
+
'/'
+
'4_PSF_coordinate.txt'
f
=
open
(
fpathCoordinate
,
'r'
)
header
=
f
.
readline
()
for
line
in
islice
(
f
,
ipsf
-
1
,
ipsf
):
line
=
line
.
strip
()
columns
=
line
.
split
()
f
.
close
()
icol
=
0
psfInfo
[
'field_x'
]
=
float
(
columns
[
icol
])
#deg, 视场采样位置
icol
+=
1
psfInfo
[
'field_y'
]
=
float
(
columns
[
icol
])
#deg
icol
+=
1
psfInfo
[
'centroid_x'
]
=
float
(
columns
[
icol
])
#mm, psf质心相对主光线的偏移量
icol
+=
1
psfInfo
[
'centroid_y'
]
=
float
(
columns
[
icol
])
#mm
icol
+=
1
if
InputMaxPixelPos
==
True
:
psfInfo
[
'max_x'
]
=
float
(
columns
[
icol
])
#mm, max pixel postion
icol
+=
1
psfInfo
[
'max_y'
]
=
float
(
columns
[
icol
])
#mm
icol
+=
1
psfInfo
[
'image_x'
]
=
float
(
columns
[
icol
])
#mm, 主光线位置
icol
+=
1
psfInfo
[
'image_y'
]
=
float
(
columns
[
icol
])
#mm
if
PSFCentroidWgt
:
psfInfo
[
'centroid_x'
]
=
data
[
'cx'
][
0
][
0
]
#mm, psfCentroidWgt质心相对主光线的偏移量
psfInfo
[
'centroid_y'
]
=
data
[
'cy'
][
0
][
0
]
#mm
if
PSFBinning
:
psfInfo
[
'centroid_x'
]
=
data
[
'cx'
][
0
][
0
]
+
0.0025
/
2
#binning引起的主光线漂移
psfInfo
[
'centroid_y'
]
=
data
[
'cy'
][
0
][
0
]
+
0.0025
/
2
return
psfInfo
###插值PSF图像-IDW方法###
def
psfMaker_IDW
(
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
IDWindex
=
2
,
OnlyNeighbors
=
True
,
hoc
=
None
,
hoclist
=
None
,
PSFCentroidWgt
=
False
):
"""
psf interpolation by IDW
Parameters:
px, py (float, float): position of the target
PSFMat (numpy.array): image
cen_col, cen_row (numpy.array, numpy.array): potions of the psf centers
IDWindex (int-optional): the power index of IDW
OnlyNeighbors (bool-optional): only neighbors are used for psf interpolation
Returns:
psfMaker (numpy.array)
"""
minimum_psf_weight
=
1e-8
ref_col
=
px
ref_row
=
py
ngy
,
ngx
=
PSFMat
[
0
,
:,
:].
shape
npsf
=
PSFMat
[:,
:,
:].
shape
[
0
]
psfWeight
=
np
.
zeros
([
npsf
])
if
OnlyNeighbors
==
True
:
if
hoc
is
None
:
neigh
=
findNeighbors
(
px
,
py
,
cen_col
,
cen_row
,
dr
=
5.
,
dn
=
4
,
OnlyDistance
=
False
)
if
hoc
is
not
None
:
neigh
=
findNeighbors_hoclist
(
cen_col
,
cen_row
,
tx
=
px
,
ty
=
py
,
dn
=
4
,
hoc
=
hoc
,
hoclist
=
hoclist
)
neighFlag
=
np
.
zeros
(
npsf
)
neighFlag
[
neigh
]
=
1
for
ipsf
in
range
(
npsf
):
if
OnlyNeighbors
==
True
:
if
neighFlag
[
ipsf
]
!=
1
:
continue
dist
=
np
.
sqrt
((
ref_col
-
cen_col
[
ipsf
])
**
2
+
(
ref_row
-
cen_row
[
ipsf
])
**
2
)
if
IDWindex
==
1
:
psfWeight
[
ipsf
]
=
dist
if
IDWindex
==
2
:
psfWeight
[
ipsf
]
=
dist
**
2
if
IDWindex
==
3
:
psfWeight
[
ipsf
]
=
dist
**
3
if
IDWindex
==
4
:
psfWeight
[
ipsf
]
=
dist
**
4
psfWeight
[
ipsf
]
=
max
(
psfWeight
[
ipsf
],
minimum_psf_weight
)
psfWeight
[
ipsf
]
=
1.
/
psfWeight
[
ipsf
]
psfWeight
/=
np
.
sum
(
psfWeight
)
psfMaker
=
np
.
zeros
([
ngy
,
ngx
],
dtype
=
np
.
float32
)
for
ipsf
in
range
(
npsf
):
if
OnlyNeighbors
==
True
:
if
neighFlag
[
ipsf
]
!=
1
:
continue
iPSFMat
=
PSFMat
[
ipsf
,
:,
:].
copy
()
ipsfWeight
=
psfWeight
[
ipsf
]
psfMaker
+=
iPSFMat
*
ipsfWeight
psfMaker
/=
np
.
nansum
(
psfMaker
)
return
psfMaker
###TEST###
if
__name__
==
'__main__'
:
iccd
=
1
iwave
=
1
ipsf
=
1
psfPath
=
'/data/simudata/CSSOSDataProductsSims/data/csstPSFdata/CSSOS_psf_20210108/CSST_psf_ciomp_2p5um_cycle3_ccr90'
psfInfo
=
LoadPSF
(
iccd
,
iwave
,
ipsf
,
psfPath
,
InputMaxPixelPos
=
True
,
PSFCentroidWgt
=
True
)
print
(
'psfInfo.keys:'
,
psfInfo
.
keys
())
print
(
psfInfo
)
ObservationSim/PSF/PSFInterp/PSFInterp.py
0 → 100644
View file @
29ac5666
'''
PSF interpolation for CSST-Sim
NOTE: [iccd, iwave, ipsf] are counted from 1 to n, but [tccd, twave, tpsf] are counted from 0 to n-1
'''
import
galsim
import
numpy
as
np
import
os
import
time
import
copy
import
PSF.PSFInterp.PSFConfig
as
myConfig
import
PSF.PSFInterp.PSFUtil
as
myUtil
from
PSF.PSFModel
import
PSFModel
LOG_DEBUG
=
False
#***#
NPSF
=
900
#***# 30*30
iccdTest
=
1
#***#
class
PSFInterp
(
PSFModel
):
# def __init__(self, PSF_data=None, params=None, PSF_data_file=None):
def
__init__
(
self
,
chip
,
PSF_data
=
None
,
PSF_data_file
=
None
,
sigSpin
=
0
,
psfRa
=
0.15
):
"""
The PSF data matrix is either given by a object parameter or read in from a file.
Parameters:
PSF_data: The PSF data matrix object
params: Other parameters?
PSF_data_file: The file for PSF data matrix (optional).
"""
if
LOG_DEBUG
:
print
(
'==================================================='
)
print
(
'DEBUG: psf module for csstSim '
\
+
time
.
strftime
(
"(%Y-%m-%d %H:%M:%S)"
,
time
.
localtime
()),
flush
=
True
)
print
(
'==================================================='
)
self
.
sigSpin
=
sigSpin
self
.
sigGauss
=
psfRa
self
.
iccd
=
int
(
chip
.
getChipLabel
(
chipID
=
chip
.
chipID
))
if
PSF_data_file
==
None
:
PSF_data_file
=
'/data/simudata/CSSOSDataProductsSims/data/csstPSFdata/CSSOS_psf_20210108/CSST_psf_ciomp_2p5um_cycle3_ccr90'
self
.
nwave
=
self
.
_getPSFwave
(
self
.
iccd
,
PSF_data_file
)
self
.
PSF_data
=
self
.
_loadPSF
(
self
.
iccd
,
PSF_data_file
)
if
LOG_DEBUG
:
print
(
'nwave-{:} on ccd-{:}::'
.
format
(
self
.
nwave
,
self
.
iccd
),
flush
=
True
)
print
(
'self.PSF_data ... ok'
,
flush
=
True
)
print
(
'Preparing self.[psfMat,cen_col,cen_row] for psfMaker ... '
,
end
=
''
,
flush
=
True
)
ngy
,
ngx
=
self
.
PSF_data
[
0
][
0
][
'psfMat'
].
shape
self
.
psfMat
=
np
.
zeros
([
self
.
nwave
,
NPSF
,
ngy
,
ngx
],
dtype
=
np
.
float32
)
self
.
cen_col
=
np
.
zeros
([
self
.
nwave
,
NPSF
],
dtype
=
np
.
float32
)
self
.
cen_row
=
np
.
zeros
([
self
.
nwave
,
NPSF
],
dtype
=
np
.
float32
)
self
.
hoc
=
[]
self
.
hoclist
=
[]
for
twave
in
range
(
self
.
nwave
):
for
tpsf
in
range
(
NPSF
):
self
.
psfMat
[
twave
,
tpsf
,
:,
:]
=
self
.
PSF_data
[
twave
][
tpsf
][
'psfMat'
]
self
.
PSF_data
[
twave
][
tpsf
][
'psfMat'
]
=
0
###free psfMat
self
.
pixsize
=
self
.
PSF_data
[
twave
][
tpsf
][
'pixsize'
]
*
1e-3
##mm
self
.
cen_col
[
twave
,
tpsf
]
=
self
.
PSF_data
[
twave
][
tpsf
][
'image_x'
]
+
0.
*
self
.
pixsize
+
self
.
PSF_data
[
twave
][
tpsf
][
'centroid_x'
]
self
.
cen_row
[
twave
,
tpsf
]
=
self
.
PSF_data
[
twave
][
tpsf
][
'image_y'
]
+
0.
*
self
.
pixsize
+
self
.
PSF_data
[
twave
][
tpsf
][
'centroid_y'
]
#hoclist on twave for neighborsFinding
hoc
,
hoclist
=
myUtil
.
findNeighbors_hoclist
(
self
.
cen_col
[
twave
],
self
.
cen_row
[
twave
])
self
.
hoc
.
append
(
hoc
)
self
.
hoclist
.
append
(
hoclist
)
if
LOG_DEBUG
:
print
(
'ok'
,
flush
=
True
)
def
_getPSFwave
(
self
,
iccd
,
PSF_data_file
):
"""
Get # of sampling waves on iccd
Parameters:
iccd: The chip of i-th ccd
PSF_data_file: The file for PSF data matrix
Returns:
nwave: The number of the sampling waves
"""
strs
=
os
.
listdir
(
PSF_data_file
+
'/ccd{:}'
.
format
(
iccd
))
nwave
=
0
for
_
in
strs
:
if
'wave_'
in
_
:
nwave
+=
1
return
nwave
def
_loadPSF
(
self
,
iccd
,
PSF_data_file
):
"""
load psf-matrix on iccd
Parameters:
iccd: The chip of i-th ccd
PSF_data_file: The file for PSF data matrix
Returns:
psfSet: The matrix of the csst-psf
"""
psfSet
=
[]
for
ii
in
range
(
self
.
nwave
):
iwave
=
ii
+
1
if
LOG_DEBUG
:
print
(
'self._loadPSF: iwave::'
,
iwave
,
flush
=
True
)
psfWave
=
[]
for
jj
in
range
(
NPSF
):
ipsf
=
jj
+
1
psfInfo
=
myConfig
.
LoadPSF
(
iccd
,
iwave
,
ipsf
,
PSF_data_file
,
InputMaxPixelPos
=
True
,
PSFCentroidWgt
=
True
,
PSFBinning
=
True
,
PSFConvGauss
=
True
)
psfWave
.
append
(
psfInfo
)
psfSet
.
append
(
psfWave
)
if
LOG_DEBUG
:
print
(
'psfSet has been loaded:'
,
flush
=
True
)
print
(
'psfSet[iwave][ipsf][keys]:'
,
psfSet
[
0
][
0
].
keys
(),
flush
=
True
)
return
psfSet
def
_preprocessPSF
(
self
):
pass
def
_findWave
(
self
,
bandpass
):
for
twave
in
range
(
self
.
nwave
):
bandwave
=
self
.
PSF_data
[
twave
][
0
][
'wavelength'
]
if
bandpass
.
blue_limit
<
bandwave
and
bandwave
<
bandpass
.
red_limit
:
return
twave
return
-
1
def
get_PSF
(
self
,
chip
,
pos_img
,
bandpass
,
pixSize
=
0.0184
,
galsimGSObject
=
True
,
findNeighMode
=
'treeFind'
,
folding_threshold
=
5.e-3
):
"""
Get the PSF at a given image position
Parameters:
chip: A 'Chip' object representing the chip we want to extract PSF from.
pos_img: A 'galsim.Position' object representing the image position.
bandpass: A 'galsim.Bandpass' object representing the wavelength range.
pixSize: The pixels size of psf matrix
findNeighMode: 'treeFind' or 'hoclistFind'
Returns:
PSF: A 'galsim.GSObject'.
"""
pixSize
=
np
.
rad2deg
(
self
.
pixsize
*
1e-3
/
28
)
*
3600
#set psf pixsize
#***# assert self.iccd == chip.chipID, 'ERROR: self.iccd != chip.chipID'
# twave = bandpass-1 #***# ??? #self.findWave(bandpass) ###twave=iwave-1 as that in NOTE
assert
self
.
iccd
==
int
(
chip
.
getChipLabel
(
chipID
=
chip
.
chipID
)),
'ERROR: self.iccd != chip.chipID'
twave
=
self
.
_findWave
(
bandpass
)
if
twave
==
-
1
:
print
(
"!!!PSF bandpass does not match."
)
exit
()
PSFMat
=
self
.
psfMat
[
twave
]
cen_col
=
self
.
cen_col
[
twave
]
cen_row
=
self
.
cen_row
[
twave
]
# px = pos_img[0]
# py = pos_img[1]
px
=
(
pos_img
.
x
-
chip
.
cen_pix_x
)
*
0.01
py
=
(
pos_img
.
y
-
chip
.
cen_pix_y
)
*
0.01
if
findNeighMode
==
'treeFind'
:
imPSF
=
myConfig
.
psfMaker_IDW
(
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
IDWindex
=
2
,
OnlyNeighbors
=
True
,
PSFCentroidWgt
=
True
)
if
findNeighMode
==
'hoclistFind'
:
imPSF
=
myConfig
.
psfMaker_IDW
(
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
IDWindex
=
2
,
OnlyNeighbors
=
True
,
hoc
=
self
.
hoc
[
twave
],
hoclist
=
self
.
hoclist
[
twave
],
PSFCentroidWgt
=
True
)
if
galsimGSObject
:
img
=
galsim
.
ImageF
(
imPSF
,
scale
=
pixSize
)
gsp
=
galsim
.
GSParams
(
folding_threshold
=
folding_threshold
)
self
.
psf
=
galsim
.
InterpolatedImage
(
img
,
gsparams
=
gsp
)
gaussPSF
=
galsim
.
Gaussian
(
sigma
=
0.04
,
gsparams
=
gsp
)
self
.
psf
=
galsim
.
Convolve
(
gaussPSF
,
self
.
psf
)
return
self
.
PSFspin
(
x
=
px
/
0.01
,
y
=
py
/
0.01
)
return
imPSF
def
PSFspin
(
self
,
x
,
y
):
"""
The PSF profile at a given image position relative to the axis center
Parameters:
theta : spin angles in a given exposure in unit of [arcsecond]
dx, dy: relative position to the axis center in unit of [pixels]
Return:
Spinned PSF: g1, g2 and axis ratio 'a/b'
"""
a2Rad
=
np
.
pi
/
(
60.0
*
60.0
*
180.0
)
ff
=
self
.
sigGauss
*
0.107
*
(
1000.0
/
10.0
)
# in unit of [pixels]
rc
=
np
.
sqrt
(
x
*
x
+
y
*
y
)
cpix
=
rc
*
(
self
.
sigSpin
*
a2Rad
)
beta
=
(
np
.
arctan2
(
y
,
x
)
+
np
.
pi
/
2
)
ell
=
cpix
**
2
/
(
2.0
*
ff
**
2
+
cpix
**
2
)
qr
=
np
.
sqrt
((
1.0
+
ell
)
/
(
1.0
-
ell
))
PSFshear
=
galsim
.
Shear
(
e
=
ell
,
beta
=
beta
*
galsim
.
radians
)
return
self
.
psf
.
shear
(
PSFshear
),
PSFshear
if
__name__
==
'__main__'
:
if
True
:
psfPath
=
'/data/simudata/CSSOSDataProductsSims/data/csstPSFdata/CSSOS_psf_20210108/CSST_psf_ciomp_2p5um_cycle3_ccr90'
psfCSST
=
PSFInterp
(
PSF_data_file
=
psfPath
)
iwave
=
1
ipsf
=
665
pos_img
=
[
psfCSST
.
cen_col
[
iwave
,
ipsf
],
psfCSST
.
cen_row
[
iwave
,
ipsf
]]
img
=
psfCSST
.
get_PSF
(
1
,
pos_img
,
iwave
,
galsimGSObject
=
True
)
print
(
'haha'
)
if
False
:
#old version (discarded)
#plot check-1
import
matplotlib.pyplot
as
plt
fig
=
plt
.
figure
(
figsize
=
(
18
,
5
))
ax
=
plt
.
subplot
(
1
,
3
,
1
)
plt
.
imshow
(
img
)
plt
.
colorbar
()
ax
=
plt
.
subplot
(
1
,
3
,
2
)
imgx
=
psfCSST
.
itpPSF_data
[
iwave
][
ipsf
][
'psfMat'
]
imgx
/=
np
.
sum
(
imgx
)
plt
.
imshow
(
imgx
)
plt
.
colorbar
()
ax
=
plt
.
subplot
(
1
,
3
,
3
)
plt
.
imshow
(
img
-
imgx
)
plt
.
colorbar
()
plt
.
savefig
(
'test/figs/test1.jpg'
)
if
False
:
#old version (discarded)
#plot check-2: 注意图像坐标和全局坐标
fig
=
plt
.
figure
(
figsize
=
(
8
,
8
),
dpi
=
200
)
img
=
psfCSST
.
PSF_data
[
iwave
][
ipsf
][
'psfMat'
]
npix
=
img
.
shape
[
0
]
dng
=
105
imgg
=
img
[
dng
:
-
dng
,
dng
:
-
dng
]
plt
.
imshow
(
imgg
)
imgX
=
psfCSST
.
PSF_data
[
iwave
][
ipsf
][
'image_x'
]
#in mm
imgY
=
psfCSST
.
PSF_data
[
iwave
][
ipsf
][
'image_y'
]
#in mm
deltX
=
psfCSST
.
PSF_data
[
iwave
][
ipsf
][
'centroid_x'
]
#in mm
deltY
=
psfCSST
.
PSF_data
[
iwave
][
ipsf
][
'centroid_y'
]
#in mm
maxX
=
psfCSST
.
PSF_data
[
iwave
][
ipsf
][
'max_x'
]
maxY
=
psfCSST
.
PSF_data
[
iwave
][
ipsf
][
'max_y'
]
cenPix_X
=
npix
/
2
+
deltX
/
0.005
cenPix_Y
=
npix
/
2
-
deltY
/
0.005
maxPix_X
=
npix
/
2
+
maxX
/
0.005
-
1
maxPix_Y
=
npix
/
2
-
maxY
/
0.005
-
1
plt
.
plot
([
cenPix_X
-
dng
],[
cenPix_Y
-
dng
],
'rx'
,
ms
=
20
)
plt
.
plot
([
maxPix_X
-
dng
],[
maxPix_Y
-
dng
],
'b+'
,
ms
=
20
)
from
scipy
import
ndimage
y
,
x
=
ndimage
.
center_of_mass
(
img
)
plt
.
plot
([
x
-
dng
],[
y
-
dng
],
'rx'
,
ms
=
10
,
mew
=
4
)
x
,
y
=
myUtil
.
findMaxPix
(
img
)
plt
.
plot
([
x
-
dng
],[
y
-
dng
],
'b+'
,
ms
=
10
,
mew
=
4
)
plt
.
savefig
(
'test/figs/test2.jpg'
)
ObservationSim/PSF/PSFInterp/PSFProcess.py
0 → 100644
View file @
29ac5666
import
os
,
sys
import
numpy
as
np
import
scipy.io
import
mpi4py.MPI
as
MPI
#sys.path.append("/public/home/weichengliang/lnData/CSST_new_framwork/csstPSF_20201222")
import
PSFConfig
as
myConfig
import
PSFUtil
as
myUtil
def
mkdir
(
path
):
isExists
=
os
.
path
.
exists
(
path
)
if
not
isExists
:
os
.
mkdir
(
path
)
############################################
comm
=
MPI
.
COMM_WORLD
ThisTask
=
comm
.
Get_rank
()
NTasks
=
comm
.
Get_size
()
npsf
=
900
psfPath
=
'/data/simudata/CSSOSDataProductsSims/data/csstPSFdata/CSSOS_psf_20210108/CSST_psf_ciomp_2p5um_cycle3_ccr90'
npsfPerTasks
=
int
(
npsf
/
NTasks
)
iStart
=
0
+
npsfPerTasks
*
ThisTask
iEnd
=
npsfPerTasks
+
npsfPerTasks
*
ThisTask
if
ThisTask
==
NTasks
:
iEnd
=
npsf
for
iccd
in
range
(
1
,
31
):
iccdPath
=
psfPath
+
'_proc/ccd{:}'
.
format
(
iccd
)
if
ThisTask
==
0
:
mkdir
(
iccdPath
)
comm
.
barrier
()
for
iwave
in
range
(
1
,
5
):
iwavePath
=
iccdPath
+
'/wave_{:}'
.
format
(
iwave
)
if
ThisTask
==
0
:
mkdir
(
iwavePath
)
comm
.
barrier
()
psfMatPath
=
iwavePath
+
'/5_psf_array'
if
ThisTask
==
0
:
mkdir
(
psfMatPath
)
comm
.
barrier
()
for
ii
in
range
(
iStart
,
iEnd
):
ipsf
=
ii
+
1
if
ThisTask
==
0
:
print
(
'iccd-iwave-ipsf: {:4}{:4}{:4}'
.
format
(
iccd
,
iwave
,
ipsf
),
end
=
'
\r
'
,
flush
=
True
)
#if iccd != 1 or iwave !=1 or ipsf != 1:
# continue
ipsfOutput
=
psfMatPath
+
'/psf_{:}_centroidWgt.mat'
.
format
(
ipsf
)
psfInfo
=
myConfig
.
LoadPSF
(
iccd
,
iwave
,
ipsf
,
psfPath
,
InputMaxPixelPos
=
True
)
ipsfMat
=
psfInfo
[
'psfMat'
]
npix_y
,
npix_x
=
ipsfMat
.
shape
#if npsf == 100:
# ncut = 160
#if npsf == 900:
# ncut = 200
ncut
=
int
(
npix_y
*
0.90
)
ncut
=
ncut
+
ncut
%
2
#even pixs
img
,
cx
,
cy
=
myUtil
.
centroidWgt
(
ipsfMat
,
nt
=
ncut
)
dcx
=
cx
-
npix_x
/
2
#pixel coords -> global coords
dcy
=
cy
-
npix_y
/
2
#pixel coords -> global coords
dcx
*=
psfInfo
[
'pixsize'
]
*
1e-3
#5e-3 #pixels -> mm
dcy
*=
psfInfo
[
'pixsize'
]
*
1e-3
#5e-3 #pixels -> mm
nn
=
npix_y
dn
=
int
((
nn
-
ncut
)
/
2
)
imgt
=
np
.
zeros
([
nn
,
nn
],
dtype
=
np
.
float32
)
imgt
[
dn
:
-
dn
,
dn
:
-
dn
]
=
img
scipy
.
io
.
savemat
(
ipsfOutput
,
{
'cx'
:
dcx
,
'cy'
:
dcy
,
'psf'
:
imgt
})
if
iccd
!=
1
or
iwave
!=
1
or
ipsf
!=
1
:
if
ThisTask
==
0
:
print
(
'CHECK::'
,
dcx
,
dcy
,
psfInfo
[
'centroid_x'
],
psfInfo
[
'centroid_y'
])
ObservationSim/PSF/PSFInterp/PSFUtil.py
0 → 100644
View file @
29ac5666
import
sys
import
ctypes
import
numpy
as
np
from
scipy
import
ndimage
import
scipy.spatial
as
spatial
###定义PSF像素的全局坐标###
def
psfPixelLayout
(
nrows
,
ncols
,
cenPosRow
,
cenPosCol
,
pixSizeInMicrons
=
5.0
):
"""
convert psf pixels to physical position
Parameters:
nrows, ncols (int, int): psf sampling with [nrows, ncols].
cenPosRow, cenPosCol (float, float): A physical position of the chief ray for a given psf.
pixSizeInMicrons (float-optional): The pixel size in microns from the psf sampling.
Returns:
psfPixelPos (numpy.array-float): [posx, posy] in mm for [irow, icol]
Notes:
1. show positions on ccd, but not position on image only [+/- dy]
"""
psfPixelPos
=
np
.
zeros
([
2
,
nrows
,
ncols
])
if
nrows
%
2
!=
0
:
sys
.
exit
()
if
ncols
%
2
!=
0
:
sys
.
exit
()
cenPix_row
=
nrows
/
2
+
1
#中心主光线对应pixle [由长光定义]
cenPix_col
=
ncols
/
2
+
1
for
irow
in
range
(
nrows
):
for
icol
in
range
(
ncols
):
delta_row
=
((
irow
+
1
)
-
cenPix_row
)
*
pixSizeInMicrons
*
1e-3
delta_col
=
((
icol
+
1
)
-
cenPix_col
)
*
pixSizeInMicrons
*
1e-3
psfPixelPos
[
0
,
irow
,
icol
]
=
cenPosCol
+
delta_col
psfPixelPos
[
1
,
irow
,
icol
]
=
cenPosRow
-
delta_row
#note-1:in CCD全局坐标
return
psfPixelPos
###查找最大pixel位置###
def
findMaxPix
(
img
):
"""
get the pixel position of the maximum-value
Parameters:
img (numpy.array-float): image
Returns:
imgMaxPix_x, imgMaxPix_y (int, int): pixel position in columns & rows
"""
maxIndx
=
np
.
argmax
(
img
)
maxIndx
=
np
.
unravel_index
(
maxIndx
,
np
.
array
(
img
).
shape
)
imgMaxPix_x
=
maxIndx
[
1
]
imgMaxPix_y
=
maxIndx
[
0
]
return
imgMaxPix_x
,
imgMaxPix_y
###查找neighbors位置###
def
findNeighbors
(
tx
,
ty
,
px
,
py
,
dr
=
0.1
,
dn
=
1
,
OnlyDistance
=
True
):
"""
find nearest neighbors by 2D-KDTree
Parameters:
tx, ty (float, float): a given position
px, py (numpy.array, numpy.array): position data for tree
dr (float-optional): distance
dn (int-optional): nearest-N
OnlyDistance (bool-optional): only use distance to find neighbors. Default: True
Returns:
dataq (numpy.array): index
"""
datax
=
px
datay
=
py
tree
=
spatial
.
KDTree
(
list
(
zip
(
datax
.
ravel
(),
datay
.
ravel
())))
dataq
=
[]
rr
=
dr
if
OnlyDistance
==
True
:
dataq
=
tree
.
query_ball_point
([
tx
,
ty
],
rr
)
if
OnlyDistance
==
False
:
while
len
(
dataq
)
<
dn
:
dataq
=
tree
.
query_ball_point
([
tx
,
ty
],
rr
)
rr
+=
dr
dd
=
np
.
hypot
(
datax
[
dataq
]
-
tx
,
datay
[
dataq
]
-
ty
)
ddSortindx
=
np
.
argsort
(
dd
)
dataq
=
np
.
array
(
dataq
)[
ddSortindx
[
0
:
dn
]]
return
dataq
###查找neighbors位置-hoclist###
def
hocBuild
(
partx
,
party
,
nhocx
,
nhocy
,
dhocx
,
dhocy
):
if
np
.
max
(
partx
)
>
nhocx
*
dhocx
:
print
(
'ERROR'
)
sys
.
exit
()
if
np
.
max
(
party
)
>
nhocy
*
dhocy
:
print
(
'ERROR'
)
sys
.
exit
()
npart
=
partx
.
size
hoclist
=
np
.
zeros
(
npart
,
dtype
=
np
.
int32
)
-
1
hoc
=
np
.
zeros
([
nhocy
,
nhocx
],
dtype
=
np
.
int32
)
-
1
for
ipart
in
range
(
npart
):
ix
=
int
(
partx
[
ipart
]
/
dhocx
)
iy
=
int
(
party
[
ipart
]
/
dhocy
)
hoclist
[
ipart
]
=
hoc
[
iy
,
ix
]
hoc
[
iy
,
ix
]
=
ipart
return
hoc
,
hoclist
def
hocFind
(
px
,
py
,
dhocx
,
dhocy
,
hoc
,
hoclist
):
ix
=
int
(
px
/
dhocx
)
iy
=
int
(
py
/
dhocy
)
neigh
=
[]
it
=
hoc
[
iy
,
ix
]
while
it
!=
-
1
:
neigh
.
append
(
it
)
it
=
hoclist
[
it
]
return
neigh
def
findNeighbors_hoclist
(
px
,
py
,
tx
=
None
,
ty
=
None
,
dn
=
4
,
hoc
=
None
,
hoclist
=
None
):
nhocy
=
nhocx
=
20
pxMin
=
np
.
min
(
px
)
pxMax
=
np
.
max
(
px
)
pyMin
=
np
.
min
(
py
)
pyMax
=
np
.
max
(
py
)
dhocx
=
(
pxMax
-
pxMin
)
/
(
nhocx
-
1
)
dhocy
=
(
pyMax
-
pyMin
)
/
(
nhocy
-
1
)
partx
=
px
-
pxMin
+
dhocx
/
2
party
=
py
-
pyMin
+
dhocy
/
2
if
hoc
is
None
:
hoc
,
hoclist
=
hocBuild
(
partx
,
party
,
nhocx
,
nhocy
,
dhocx
,
dhocy
)
return
hoc
,
hoclist
if
hoc
is
not
None
:
tx
=
tx
-
pxMin
+
dhocx
/
2
ty
=
ty
-
pyMin
+
dhocy
/
2
itx
=
int
(
tx
/
dhocx
)
ity
=
int
(
ty
/
dhocy
)
ps
=
[
-
1
,
0
,
1
]
neigh
=
[]
for
ii
in
range
(
3
):
for
jj
in
range
(
3
):
ix
=
itx
+
ps
[
ii
]
iy
=
ity
+
ps
[
jj
]
if
ix
<
0
:
continue
if
iy
<
0
:
continue
if
ix
>
nhocx
-
1
:
continue
if
iy
>
nhocy
-
1
:
continue
#neightt = myUtil.hocFind(ppx, ppy, dhocx, dhocy, hoc, hoclist)
it
=
hoc
[
iy
,
ix
]
while
it
!=
-
1
:
neigh
.
append
(
it
)
it
=
hoclist
[
it
]
#neigh.append(neightt)
#ll = [i for k in neigh for i in k]
if
dn
!=
-
1
:
ptx
=
np
.
array
(
partx
[
neigh
])
pty
=
np
.
array
(
party
[
neigh
])
dd
=
np
.
hypot
(
ptx
-
tx
,
pty
-
ty
)
idx
=
np
.
argsort
(
dd
)
neigh
=
np
.
array
(
neigh
)[
idx
[
0
:
dn
]]
return
neigh
###PSF中心对齐###
def
psfCentering
(
img
,
apSizeInArcsec
=
0.5
,
psfSampleSizeInMicrons
=
5
,
focalLengthInMeters
=
28
,
CenteringMode
=
1
):
"""
centering psf within an aperture
Parameters:
img (numpy.array): image
apSizeInArcsec (float-optional): aperture size in arcseconds.
psfSampleSizeInMicrons (float-optional): psf pixel size in microns.
focalLengthInMeters (float-optional): csst focal length im meters.
CenteringMode (int-optional): how to center psf images
Returns:
imgT (numpy.array)
"""
if
CenteringMode
==
1
:
imgMaxPix_x
,
imgMaxPix_y
=
findMaxPix
(
img
)
if
CenteringMode
==
2
:
y
,
x
=
ndimage
.
center_of_mass
(
img
)
#y-rows, x-cols
imgMaxPix_x
=
int
(
x
)
imgMaxPix_y
=
int
(
y
)
apSizeInMicrons
=
np
.
deg2rad
(
apSizeInArcsec
/
3600.
)
*
focalLengthInMeters
*
1e6
apSizeInPix
=
apSizeInMicrons
/
psfSampleSizeInMicrons
apSizeInPix
=
np
.
int
(
np
.
ceil
(
apSizeInPix
))
imgT
=
np
.
zeros_like
(
img
)
ngy
,
ngx
=
img
.
shape
cy
=
int
(
ngy
/
2
)
cx
=
int
(
ngx
/
2
)
imgT
[
cy
-
apSizeInPix
:
cy
+
apSizeInPix
+
1
,
cx
-
apSizeInPix
:
cx
+
apSizeInPix
+
1
]
=
\
img
[
imgMaxPix_y
-
apSizeInPix
:
imgMaxPix_y
+
apSizeInPix
+
1
,
imgMaxPix_x
-
apSizeInPix
:
imgMaxPix_x
+
apSizeInPix
+
1
]
return
imgT
###插值对齐-fft###
def
psfCentering_FFT
(
image
):
"""
centering psf within an aperture by FFT
"""
ny
,
nx
=
image
.
shape
py
,
px
=
ndimage
.
center_of_mass
(
image
)
dx
=
(
px
-
nx
/
2
)
dy
=
(
py
-
ny
/
2
)
k
=
np
.
zeros
((
nx
,
ny
,
2
),
dtype
=
float
)
fg
=
np
.
fft
.
fft2
(
image
)
ge
=
np
.
zeros_like
(
fg
)
inx
=
int
(
nx
/
2
)
jny
=
int
(
ny
/
2
)
#prepare for the phase multiply matrix
#left bottom
for
i
in
range
(
inx
+
1
):
for
j
in
range
(
jny
+
1
):
k
[
i
][
j
][
0
]
=
i
;
k
[
i
][
j
][
1
]
=
j
;
#top right
for
i
in
range
(
inx
-
1
):
for
j
in
range
(
jny
-
1
):
k
[
i
+
inx
+
1
][
j
+
jny
+
1
][
0
]
=
(
-
(
nx
/
2
-
1
)
+
i
)
k
[
i
+
inx
+
1
][
j
+
jny
+
1
][
1
]
=
(
-
(
ny
/
2
-
1
)
+
j
)
#bottom right
for
i
in
range
(
inx
+
1
):
for
j
in
range
(
jny
-
1
):
k
[
i
][
j
+
jny
+
1
][
0
]
=
i
k
[
i
][
j
+
jny
+
1
][
1
]
=
(
-
(
ny
/
2
-
1
)
+
j
)
#top left
for
i
in
range
(
inx
-
1
):
for
j
in
range
(
int
(
jny
+
1
)):
k
[
i
+
inx
+
1
][
j
][
0
]
=
(
-
(
nx
/
2
-
1
)
+
i
)
k
[
i
+
inx
+
1
][
j
][
1
]
=
j
for
i
in
range
(
nx
):
for
j
in
range
(
ny
):
ge
[
i
][
j
]
=
fg
[
i
][
j
]
*
np
.
exp
(
2.
*
np
.
pi
*
(
dx
*
k
[
i
][
j
][
0
]
/
nx
+
dy
*
k
[
i
][
j
][
1
]
/
ny
)
*
1j
)
get
=
np
.
fft
.
ifft2
(
ge
).
real
return
(
get
)
###图像叠加###
def
psfStack
(
*
psfMat
):
"""
stacked image from the different psfs
Parameters:
*psfMat (numpy.array): the different psfs for stacking
Returns:
img (numpy.array): image
"""
nn
=
len
(
psfMat
)
img
=
np
.
zeros_like
(
psfMat
[
0
])
for
ii
in
range
(
nn
):
img
+=
psfMat
[
ii
]
/
np
.
sum
(
psfMat
[
ii
])
img
/=
np
.
sum
(
img
)
return
img
###计算PSF椭率-接口###
def
psfSizeCalculator
(
psfMat
,
psfSampleSize
=
2.5
,
CalcPSFcenter
=
True
,
SigRange
=
True
,
TailorScheme
=
2
,
cenPix
=
None
):
"""
calculate psf size & ellipticity
Parameters:
psfMat (numpy.array): image
psfSampleSize (float-optional): psf size in microns.
CalcPSFcenter (bool-optional): whether calculate psf center. Default: True
SigRange (bool-optional): whether use psf tailor. Default: False
TailorScheme (int-optional): which method for psf tailor. Default: 1
Returns:
cenX, cenY (float, float): the pixel position of the mass center
sz (float): psf size
e1, e2 (float, float): psf ellipticity
REE80 (float): radius of REE80 in arcseconds
"""
psfSampleSize
=
psfSampleSize
*
1e-3
#mm
REE80
=
-
1.0
##encircling 80% energy
if
SigRange
is
True
:
if
TailorScheme
==
1
:
psfMat
=
imSigRange
(
psfMat
,
fraction
=
0.80
)
psfInfo
[
'psfMat'
]
=
psfMat
#set on/off
if
TailorScheme
==
2
:
#img = psfTailor(psfMat, apSizeInArcsec=0.5)
imgX
,
REE80
=
psfEncircle
(
psfMat
,
cenPix
=
cenPix
)
#psfMat = img
REE80
=
REE80
[
0
]
if
CalcPSFcenter
is
True
:
img
=
psfMat
/
np
.
sum
(
psfMat
)
y
,
x
=
ndimage
.
center_of_mass
(
img
)
#y-rows, x-cols
cenX
=
x
cenY
=
y
if
CalcPSFcenter
is
False
:
cenPix_X
=
psfMat
.
shape
[
1
]
/
2
#90
cenPix_Y
=
psfMat
.
shape
[
0
]
/
2
#90
cenX
=
cenPix_X
+
psfInfo
[
'centroid_x'
]
/
psfSampleSize
cenY
=
cenPix_Y
-
psfInfo
[
'centroid_y'
]
/
psfSampleSize
pixSize
=
1
sz
,
e1
,
e2
=
psfSecondMoments
(
psfMat
,
cenX
,
cenY
,
pixSize
=
pixSize
)
return
cenX
,
cenY
,
sz
,
e1
,
e2
,
REE80
###计算PSF椭率###
def
psfSecondMoments
(
psfMat
,
cenX
,
cenY
,
pixSize
=
1
):
"""
estimate the psf ellipticity by the second moment of surface brightness
Parameters:
psfMat (numpy.array-float): image
cenX, cenY (float, float): pixel position of the psf center
pixSize (float-optional): pixel size
Returns:
sz (float): psf size
e1, e2 (float, float): psf ellipticity
"""
apr
=
0.5
#arcsec, 0.5角秒内测量
fl
=
28.
#meters
pxs
=
5.0
#microns
apr
=
np
.
deg2rad
(
apr
/
3600.
)
*
fl
*
1e6
apr
=
apr
/
pxs
apr
=
np
.
int
(
np
.
ceil
(
apr
))
I
=
psfMat
ncol
=
I
.
shape
[
1
]
nrow
=
I
.
shape
[
0
]
w
=
0.0
w11
=
0.0
w12
=
0.0
w22
=
0.0
for
icol
in
range
(
ncol
):
for
jrow
in
range
(
nrow
):
x
=
icol
*
pixSize
-
cenX
y
=
jrow
*
pixSize
-
cenY
rr
=
np
.
sqrt
(
x
*
x
+
y
*
y
)
wgt
=
0.0
if
rr
<=
apr
:
wgt
=
1.0
w
+=
I
[
jrow
,
icol
]
*
wgt
w11
+=
x
*
x
*
I
[
jrow
,
icol
]
*
wgt
w12
+=
x
*
y
*
I
[
jrow
,
icol
]
*
wgt
w22
+=
y
*
y
*
I
[
jrow
,
icol
]
*
wgt
w11
/=
w
w12
/=
w
w22
/=
w
sz
=
w11
+
w22
e1
=
(
w11
-
w22
)
/
sz
e2
=
2.0
*
w12
/
sz
return
sz
,
e1
,
e2
###计算REE80###
def
psfEncircle
(
img
,
fraction
=
0.8
,
psfSampleSizeInMicrons
=
2.5
,
focalLengthInMeters
=
28
,
cenPix
=
None
):
"""
psf tailor within a given percentage.
Parameters:
img (numpy.array-float): image
fraction (float-optional): a percentage for psf tailor.
psfSampleSizeInMicrons (float-optional): psf pixel size in microns.
focalLengthInMeters (float-optional): csst focal length im meters.
Returns:
img*wgt (numpy.array-float): image
REE80 (float): radius of REE80 in arcseconds.
"""
#imgMaxPix_x, imgMaxPix_y = findMaxPix(img)
y
,
x
=
ndimage
.
center_of_mass
(
img
)
#y-rows, x-cols
imgMaxPix_x
=
x
#int(x)
imgMaxPix_y
=
y
#int(y)
if
cenPix
!=
None
:
imgMaxPix_x
=
cenPix
[
0
]
imgMaxPix_y
=
cenPix
[
1
]
im1
=
img
.
copy
()
im1size
=
im1
.
shape
dis
=
np
.
zeros_like
(
img
)
for
irow
in
range
(
im1size
[
0
]):
for
icol
in
range
(
im1size
[
1
]):
dx
=
icol
-
imgMaxPix_x
dy
=
irow
-
imgMaxPix_y
dis
[
irow
,
icol
]
=
np
.
hypot
(
dx
,
dy
)
nn
=
im1size
[
1
]
*
im1size
[
0
]
disX
=
dis
.
reshape
(
nn
)
disXsortId
=
np
.
argsort
(
disX
)
imgX
=
img
.
reshape
(
nn
)
imgY
=
imgX
[
disXsortId
]
psfFrac
=
np
.
cumsum
(
imgY
)
/
np
.
sum
(
imgY
)
ind
=
np
.
where
(
psfFrac
>
fraction
)[
0
][
0
]
wgt
=
np
.
ones_like
(
dis
)
#wgt[np.where(dis > dis[np.where(img == imgY[ind])])] = 0
REE80
=
np
.
rad2deg
(
dis
[
np
.
where
(
img
==
imgY
[
ind
])]
*
psfSampleSizeInMicrons
*
1e-6
/
focalLengthInMeters
)
*
3600
return
img
*
wgt
,
REE80
###图像能量百分比查找###
def
imSigRange
(
img
,
fraction
=
0.80
):
"""
extract the image within x-percent (DISCARD)
Parameters:
img (numpy.array-float): image
fraction (float-optional): a percentage
Returns:
im1 (numpy.array-float): image
"""
im1
=
img
.
copy
()
im1size
=
im1
.
shape
im2
=
np
.
sort
(
im1
.
reshape
(
im1size
[
0
]
*
im1size
[
1
]))
im2
=
im2
[::
-
1
]
im3
=
np
.
cumsum
(
im2
)
/
np
.
sum
(
im2
)
loc
=
np
.
where
(
im3
>
fraction
)
#print(im3[loc[0][0]], im2[loc[0][0]])
im1
[
np
.
where
(
im1
<=
im2
[
loc
[
0
][
0
]])]
=
0
return
im1
###孔径内图像裁剪###
def
psfTailor
(
img
,
apSizeInArcsec
=
0.5
,
psfSampleSizeInMicrons
=
5
,
focalLengthInMeters
=
28
,
cenPix
=
None
):
"""
psf tailor within a given aperture size
Parameters:
img (numpy.array-float): image
apSizeInArcsec (float-optional): aperture size in arcseconds.
psfSampleSizeInMicrons (float-optional): psf pixel size in microns.
focalLengthInMeters (float-optional): csst focal length im meters.
Returns:
imgT (numpy.array-float): image
"""
#imgMaxPix_x, imgMaxPix_y = findMaxPix(img)
y
,
x
=
ndimage
.
center_of_mass
(
img
)
#y-rows, x-cols
imgMaxPix_x
=
int
(
x
)
imgMaxPix_y
=
int
(
y
)
if
cenPix
!=
None
:
imgMaxPix_x
=
int
(
cenPix
[
0
])
imgMaxPix_y
=
int
(
cenPix
[
1
])
apSizeInMicrons
=
np
.
deg2rad
(
apSizeInArcsec
/
3600.
)
*
focalLengthInMeters
*
1e6
apSizeInPix
=
apSizeInMicrons
/
psfSampleSizeInMicrons
apSizeInPix
=
np
.
int
(
np
.
ceil
(
apSizeInPix
))
print
(
'apSizeInPix='
,
apSizeInPix
)
imgT
=
np
.
zeros_like
(
img
)
imgT
[
imgMaxPix_y
-
apSizeInPix
:
imgMaxPix_y
+
apSizeInPix
+
1
,
imgMaxPix_x
-
apSizeInPix
:
imgMaxPix_x
+
apSizeInPix
+
1
]
=
\
img
[
imgMaxPix_y
-
apSizeInPix
:
imgMaxPix_y
+
apSizeInPix
+
1
,
imgMaxPix_x
-
apSizeInPix
:
imgMaxPix_x
+
apSizeInPix
+
1
]
return
imgT
###centroid with a window###
def
centroidWgt
(
img
,
nt
=
160
):
#libCentroid = ctypes.CDLL('/public/home/weichengliang/lnData/CSST_new_framwork/csstPSF/libCentroid/libCentroid.so') # CDLL加载库
libCentroid
=
ctypes
.
CDLL
(
'/public/home/weichengliang/lnData/CSST_new_framwork/csstPSF_20210108/libCentroid/libCentroid.so'
)
# CDLL加载库
libCentroid
.
centroidWgt
.
argtypes
=
[
ctypes
.
POINTER
(
ctypes
.
c_float
),
ctypes
.
c_int
,
ctypes
.
c_int
,
ctypes
.
POINTER
(
ctypes
.
c_double
)]
libCentroid
.
imSplint
.
argtypes
=
[
ctypes
.
POINTER
(
ctypes
.
c_float
),
ctypes
.
c_int
,
ctypes
.
c_int
,
ctypes
.
POINTER
(
ctypes
.
c_double
),
ctypes
.
c_int
,
ctypes
.
c_int
,
ctypes
.
POINTER
(
ctypes
.
c_float
)]
imx
=
img
/
np
.
sum
(
img
)
ny
,
nx
=
imx
.
shape
#imx centroid
nn
=
nx
*
ny
arr
=
(
ctypes
.
c_float
*
nn
)()
arr
[:]
=
imx
.
reshape
(
nn
)
para
=
(
ctypes
.
c_double
*
10
)()
libCentroid
.
centroidWgt
(
arr
,
ny
,
nx
,
para
)
imx_cy
=
para
[
3
]
#irow
imx_cx
=
para
[
4
]
#icol
#imx -> imy
nxt
=
nyt
=
nt
nn
=
nxt
*
nyt
yat
=
(
ctypes
.
c_float
*
nn
)()
libCentroid
.
imSplint
(
arr
,
ny
,
nx
,
para
,
nxt
,
nyt
,
yat
)
imy
=
np
.
array
(
yat
[:]).
reshape
([
nxt
,
nyt
])
return
imy
,
imx_cx
,
imx_cy
'''
def psfCentering_wgt(ipsfMat, psf_image_x, psf_image_y, psfSampleSizeInMicrons=5.0):
img, cx, cy = centroidWgt(ipsfMat, nt=160)
nrows, ncols = ipsfMat.shape
cyt = (cy + nrows/2)*psfSampleSizeInMicrons*1e-3 +psf_image_y
cxt = (cx + ncols/2)*psfSampleSizeInMicrons*1e-3 +psf_image_x
return img, cxt, cyt
'''
###binning image###
def
binningPSF
(
img
,
ngg
):
imgX
=
img
.
reshape
(
ngg
,
img
.
shape
[
0
]
//
ngg
,
ngg
,
img
.
shape
[
1
]
//
ngg
).
mean
(
-
1
).
mean
(
1
)
return
imgX
ObservationSim/PSF/PSFInterp/__init__.py
0 → 100644
View file @
29ac5666
from
.PSFInterp
import
PSFInterp
\ No newline at end of file
ObservationSim/PSF/PSFInterp/__pycache__/PSFConfig.cpython-37.pyc
0 → 100644
View file @
29ac5666
File added
ObservationSim/PSF/PSFInterp/__pycache__/PSFConfig.cpython-38.pyc
0 → 100644
View file @
29ac5666
File added
ObservationSim/PSF/PSFInterp/__pycache__/PSFInterp.cpython-38.pyc
0 → 100644
View file @
29ac5666
File added
ObservationSim/PSF/PSFInterp/__pycache__/PSFUtil.cpython-37.pyc
0 → 100644
View file @
29ac5666
File added
ObservationSim/PSF/PSFInterp/__pycache__/PSFUtil.cpython-38.pyc
0 → 100644
View file @
29ac5666
File added
ObservationSim/PSF/PSFInterp/__pycache__/__init__.cpython-38.pyc
0 → 100644
View file @
29ac5666
File added
ObservationSim/PSF/PSFInterp/libCentroid/.DS_Store
0 → 100644
View file @
29ac5666
File added
ObservationSim/PSF/PSFInterp/libCentroid/Makefile
0 → 100644
View file @
29ac5666
#OPTS += -D
CC
=
gcc
OPTIMIZE
=
-fPIC
-g
-O3
#-Wall -wd981 #-wd1419 -wd810
#GSLI = -I/home/alex/opt/gsl/include
#GSLL = -L/home/alex/opt/gsl/lib -lgsl -lgslcblas
#FFTWI = -I/home/alex/opt/fftw/include
#FFTWL = -L/home/alex/opt/fftw/lib -lfftw3 -lfftw3f
#HDF5I = -I/home/alex/opt/hdf5/include
#HDF5L = -L/home/alex/opt/hdf5/lib -lhdf5_hl -lhdf5
#FITSI = -I/home/alex/opt/cfitsio/include
#FITSL = -L/home/alex/opt/cfitsio/lib -lcfitsio
#EXTRACFLAGS =
#EXTRACLIB =
CLINK
=
$(CC)
CFLAGS
=
$(OPTIMIZE)
#
$(EXTRACFLAGS)
$(OPTS)
CLIB
=
-shared
-lm
#
$(EXTRACLIB)
OBJS
=
centroidWgt.o nrutil.o
EXEC
=
libCentroid.so
all
:
$(EXEC)
$(EXEC)
:
$(OBJS)
$(CLINK)
$(CFLAGS)
-o
$@
$(OBJS)
$(CLIB)
$(OBJS)
:
nrutil.h Makefile
.PHONY
:
clean
clean
:
rm
-f
*
.o
$(EXEC)
ObservationSim/PSF/PSFInterp/libCentroid/centroidWgt.c
0 → 100644
View file @
29ac5666
#include
<math.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
"nrutil.h"
//y is the input image, nx and ny are the pixels along x and y axis;
//yt and residu are the required matrix for the function
//para contains the needed parameters: centx=para[3], centy=para[4]
void
star_gaus
(
float
**
y
,
int
nx
,
int
ny
,
double
*
para
);
void
Interp_bicubic
(
int
nx
,
int
ny
,
float
**
a0
,
int
nbound
,
int
nxt
,
int
nyt
,
float
**
at
,
double
*
xcen
);
void
splie2
(
float
**
ya
,
int
m
,
int
n
,
float
**
y2a
);
void
spline
(
float
y
[],
int
n
,
float
yp1
,
float
ypn
,
float
y2
[]);
void
splint
(
float
ya
[],
float
y2a
[],
int
n
,
float
x
,
float
*
y
);
void
centroidWgt
(
float
*
y
,
int
nx
,
int
ny
,
double
*
para
)
{
int
i
,
j
,
k
;
float
**
yy
;
double
**
basef
;
double
**
coff
;
double
ccol
,
crow
;
yy
=
matrix
(
0
,
nx
-
1
,
0
,
ny
-
1
);
for
(
i
=
0
;
i
<
nx
;
i
++
)
for
(
j
=
0
;
j
<
ny
;
j
++
)
{
k
=
j
+
i
*
nx
;
yy
[
i
][
j
]
=
y
[
k
];
}
star_gaus
(
yy
,
nx
,
ny
,
para
);
//ccol = para[4];
//crow = para[3];
}
void
imSplint
(
float
*
y
,
int
nx
,
int
ny
,
double
*
para
,
int
nxt
,
int
nyt
,
float
*
yat
)
{
int
i
,
j
,
k
;
float
**
yy
;
double
**
basef
;
double
**
coff
;
double
ccol
,
crow
;
yy
=
matrix
(
0
,
nx
-
1
,
0
,
ny
-
1
);
for
(
i
=
0
;
i
<
nx
;
i
++
)
for
(
j
=
0
;
j
<
ny
;
j
++
)
{
k
=
j
+
i
*
nx
;
yy
[
i
][
j
]
=
y
[
k
];
}
crow
=
para
[
3
];
ccol
=
para
[
4
];
int
nbound
;
float
**
at
;
double
xcen
[
2
];
at
=
matrix
(
0
,
nxt
-
1
,
0
,
nyt
-
1
);
nbound
=
(
int
)((
nx
-
nxt
)
/
2
);
xcen
[
0
]
=
crow
;
xcen
[
1
]
=
ccol
;
Interp_bicubic
(
nx
,
ny
,
yy
,
nbound
,
nxt
,
nyt
,
at
,
xcen
);
for
(
i
=
0
;
i
<
nxt
;
i
++
)
for
(
j
=
0
;
j
<
nyt
;
j
++
)
{
k
=
j
+
i
*
nxt
;
yat
[
k
]
=
at
[
i
][
j
];
}
}
//void star_gaus(float **y,int nx,int ny,float **yt,float **residu,double *para)
void
star_gaus
(
float
**
y
,
int
nx
,
int
ny
,
double
*
para
)
{
void
gasfit_2D
(
double
**
x
,
double
*
y
,
int
np
,
double
*
para
,
double
bg0
,
int
fbg
);
double
**
xs
,
*
ys
,
ymax
;
int
i
,
j
,
np
,
npt
,
im
,
jm
,
**
xi
,
k
;
double
kc
,
bgc
,
sigmac
,
xc
,
yc
,
sigma2v
,
det
;
double
bg0
=
0
;
int
fbg
=
0
;
np
=
nx
*
ny
;
xs
=
dmatrix
(
0
,
np
-
1
,
0
,
1
);
ys
=
dvector
(
0
,
np
-
1
);
xi
=
imatrix
(
0
,
np
-
1
,
0
,
1
);
ymax
=
y
[
0
][
0
];
for
(
i
=
0
;
i
<
nx
;
i
++
)
for
(
j
=
0
;
j
<
ny
;
j
++
){
if
(
ymax
<
y
[
i
][
j
]){
ymax
=
y
[
i
][
j
];
im
=
i
;
jm
=
j
;}
}
int
cutPix
;
cutPix
=
23
;
npt
=
0
;
for
(
i
=-
cutPix
;
i
<=
cutPix
;
i
++
){
for
(
j
=-
cutPix
;
j
<=
cutPix
;
j
++
){
xs
[
npt
][
0
]
=
xi
[
npt
][
0
]
=
i
+
im
;
xs
[
npt
][
1
]
=
xi
[
npt
][
1
]
=
j
+
jm
;
ys
[
npt
]
=
y
[
im
+
i
][
jm
+
j
];
npt
++
;
}
}
gasfit_2D
(
xs
,
ys
,
npt
,
para
,
bg0
,
fbg
);
kc
=
para
[
0
];
sigmac
=
para
[
1
];
bgc
=
para
[
2
];
xc
=
para
[
3
];
yc
=
para
[
4
];
// printf("%e %e %e %e %e\n",kc,sigmac,bgc,xc,yc);
/*
sigma2v=-1./(2.*sigmac*sigmac);
for(i=0;i<nx;i++){
for(j=0;j<ny;j++){
det=DSQR(i-xc)+DSQR(j-yc);
yt[i][j]=kc*exp(det*sigma2v)+bgc;
residu[i][j]=y[i][j]-yt[i][j];
}
}
*/
free_dmatrix
(
xs
,
0
,
np
-
1
,
0
,
1
);
free_imatrix
(
xi
,
0
,
np
-
1
,
0
,
1
);
free_dvector
(
ys
,
0
,
np
-
1
);
}
void
gasfit_2D
(
double
**
x
,
double
*
y
,
int
np
,
double
*
para
,
double
bg0
,
int
fbg
)
{
void
search_2D
(
double
**
x
,
double
*
y
,
int
np
,
double
kc
,
double
kd
,
double
sigmac
,
double
sigmad
,
double
bgc
,
double
bgd
,
double
xc
,
double
xd
,
double
yc
,
double
yd
,
double
*
para
,
double
bg0
,
int
fbg
);
int
i
,
j
,
k
,
imax
=
0
,
isigma
;
double
ymax
,
ymin
,
kc
,
kd
,
sigmac
,
sigmad
,
bgc
,
bgd
,
ysigma
,
xc
,
yc
,
xd
,
yd
;
double
det
,
dett
;
ymin
=
ymax
=
y
[
imax
];
for
(
i
=
1
;
i
<
np
;
i
++
){
if
(
ymax
<
y
[
i
]){
imax
=
i
;
ymax
=
y
[
i
];}
if
(
ymin
>
y
[
i
])
ymin
=
y
[
i
];
}
kc
=
ymax
;
kd
=
ymax
/
12
.;
det
=
ysigma
=
kc
*
exp
(
-
0
.
5
);
for
(
i
=
0
;
i
<
np
;
i
++
){
dett
=
fabs
(
ysigma
-
y
[
i
]);
if
(
dett
<
det
&&
y
[
i
]
!=
kc
){
det
=
dett
;
isigma
=
i
;}
//if(dett<det){det=dett;isigma=i;}
}
xc
=
x
[
imax
][
0
];
yc
=
x
[
imax
][
1
];
sigmac
=
sqrt
(
DSQR
(
xc
-
x
[
isigma
][
0
])
+
DSQR
(
yc
-
x
[
isigma
][
1
]))
*
1
.;
xd
=
yd
=
sigmac
*
0
.
25
;
sigmad
=
0
.
25
*
sigmac
;
bgc
=
0
.;
bgd
=
fabs
(
ymin
);
for
(
i
=
0
;
i
<
4
;
i
++
){
search_2D
(
x
,
y
,
np
,
kc
,
kd
,
sigmac
,
sigmad
,
bgc
,
bgd
,
xc
,
xd
,
yc
,
yd
,
para
,
bg0
,
fbg
);
kd
*=
0
.
33
;
sigmad
*=
0
.
33
;
bgd
*=
0
.
33
;
xd
*=
0
.
33
;
yd
*=
0
.
33
;
kc
=
para
[
0
];
sigmac
=
para
[
1
];
bgc
=
para
[
2
];
xc
=
para
[
3
];
yc
=
para
[
4
];
}
if
(
fbg
==
0
)
para
[
2
]
=
bg0
;
}
void
search_2D
(
double
**
x
,
double
*
y
,
int
np
,
double
kc
,
double
kd
,
double
sigmac
,
double
sigmad
,
double
bgc
,
double
bgd
,
double
xc
,
double
xd
,
double
yc
,
double
yd
,
double
*
para
,
double
bg0
,
int
fbg
)
{
double
k
,
sigma
,
bg
,
k2
,
k20
,
sigma2v
,
det
,
xt
,
yt
;
int
i
,
j
,
l
,
m
,
p
,
q
;
sigma2v
=-
1
.
/
(
2
.
*
sigmac
*
sigmac
);
bg
=
bgc
;
k20
=
0
;
for
(
m
=
0
;
m
<
np
;
m
++
){
det
=
DSQR
(
x
[
m
][
0
]
-
xc
)
+
DSQR
(
x
[
m
][
1
]
-
yc
);
det
=
kc
*
exp
(
det
*
sigma2v
)
+
bgc
-
y
[
m
];
k20
+=
det
*
det
;
}
for
(
i
=-
4
;
i
<=
4
;
i
++
){
k
=
kc
+
i
*
kd
;
if
(
k
>
0
){
for
(
j
=-
4
;
j
<=
4
;
j
++
){
sigma
=
sigmac
+
j
*
sigmad
;
if
(
sigma
>
0
){
sigma2v
=-
1
.
/
(
2
.
*
sigma
*
sigma
);
for
(
p
=-
4
;
p
<=
4
;
p
++
){
xt
=
xc
+
p
*
xd
;
for
(
q
=-
4
;
q
<=
4
;
q
++
){
yt
=
yc
+
q
*
yd
;
k2
=
0
;
if
(
fbg
==
0
){
bg
=
bg0
;
for
(
m
=
0
;
m
<
np
;
m
++
){
det
=
DSQR
(
x
[
m
][
0
]
-
xt
)
+
DSQR
(
x
[
m
][
1
]
-
yt
);
det
=
k
*
exp
(
det
*
sigma2v
)
+
bg
-
y
[
m
];
k2
+=
det
*
det
;
}
}
else
{
for
(
l
=-
4
;
l
<=
4
;
l
++
){
bg
=
bgc
+
l
*
bgd
;
for
(
m
=
0
;
m
<
np
;
m
++
){
det
=
DSQR
(
x
[
m
][
0
]
-
xt
)
+
DSQR
(
x
[
m
][
1
]
-
yt
);
det
=
k
*
exp
(
det
*
sigma2v
)
+
bg
-
y
[
m
];
k2
+=
det
*
det
;
}
}
}
//printf("k20=%e k2=%e\n",k20,k2);
if
(
k2
<=
k20
){
k20
=
k2
;
para
[
5
]
=
k2
;
para
[
0
]
=
k
;
para
[
1
]
=
sigma
;
para
[
2
]
=
bg
;
para
[
3
]
=
xt
;
para
[
4
]
=
yt
;}
}
}
}
}
}
}
}
/////////////////////////////
//#include <math.h>
//#include <stdio.h>
//#include <stdlib.h>
//#include "nrutil.h"
//nx,ny is the pixels of x and y direction
//a0 is the input image in nx*ny
//nbound is the boundary limit
//nxt,nyt is out put image dimentions
//at is the output image and cen represent the required center
void
Interp_bicubic
(
int
nx
,
int
ny
,
float
**
a0
,
int
nbound
,
int
nxt
,
int
nyt
,
float
**
at
,
double
*
xcen
)
{
void
splie2
(
float
**
ya
,
int
m
,
int
n
,
float
**
y2a
);
void
spline
(
float
y
[],
int
n
,
float
yp1
,
float
ypn
,
float
y2
[]);
void
splint
(
float
ya
[],
float
y2a
[],
int
n
,
float
x
,
float
*
y
);
int
i
,
j
,
m
,
n
,
ic
,
jc
;
float
*
ytmp
,
*
yytmp
,
**
y2a
,
x1
,
x2
,
shift1
,
shift2
;
y2a
=
matrix
(
0
,
nx
,
0
,
ny
);
ytmp
=
vector
(
0
,
ny
);
yytmp
=
vector
(
0
,
ny
);
splie2
(
a0
,
nx
,
ny
,
y2a
);
ic
=
nx
*
0
.
5
;
jc
=
ny
*
0
.
5
;
shift1
=
xcen
[
0
]
-
ic
;
//-0.5;
shift2
=
xcen
[
1
]
-
jc
;
//-0.5;
if
(
fabs
(
shift1
)
>
nbound
||
fabs
(
shift2
)
>
nbound
){
printf
(
"bicubic shifts too much %e %e
\n
"
,
shift1
,
shift2
);
getchar
();
}
for
(
n
=
0
;
n
<
nyt
;
n
++
){
x2
=
n
+
nbound
+
shift2
;
for
(
i
=
0
;
i
<
nx
;
i
++
){
splint
(
a0
[
i
],
y2a
[
i
],
ny
,
x2
,
&
yytmp
[
i
]);
spline
(
yytmp
,
ny
,
1.0e30
,
1.0e30
,
ytmp
);
}
for
(
m
=
0
;
m
<
nxt
;
m
++
){
x1
=
m
+
nbound
+
shift1
;
splint
(
yytmp
,
ytmp
,
ny
,
x1
,
&
at
[
m
][
n
]);
}
}
free_vector
(
yytmp
,
0
,
ny
);
free_vector
(
ytmp
,
0
,
ny
);
free_matrix
(
y2a
,
0
,
nx
,
0
,
ny
);
}
void
splie2
(
float
**
ya
,
int
m
,
int
n
,
float
**
y2a
)
{
void
spline
(
float
y
[],
int
n
,
float
yp1
,
float
ypn
,
float
y2
[]);
int
j
;
for
(
j
=
0
;
j
<
m
;
j
++
)
spline
(
ya
[
j
],
n
,
1.0e30
,
1.0e30
,
y2a
[
j
]);
}
void
spline
(
float
y
[],
int
n
,
float
yp1
,
float
ypn
,
float
y2
[])
{
int
i
,
k
;
float
p
,
qn
,
sig
,
un
,
*
u
;
u
=
vector
(
0
,
n
-
1
);
if
(
yp1
>
0.99e30
)
y2
[
0
]
=
u
[
0
]
=
0
.
0
;
else
{
y2
[
0
]
=
-
0
.
5
;
u
[
0
]
=
3
.
0
*
(
y
[
1
]
-
y
[
0
]
-
yp1
);
}
sig
=
0
.
5
;
for
(
i
=
1
;
i
<=
n
-
2
;
i
++
)
{
p
=
sig
*
y2
[
i
-
1
]
+
2
.
0
;
y2
[
i
]
=
(
sig
-
1
.
0
)
/
p
;
u
[
i
]
=
(
y
[
i
+
1
]
-
2
.
*
y
[
i
]
+
y
[
i
-
1
]);
u
[
i
]
=
(
3
.
0
*
u
[
i
]
-
sig
*
u
[
i
-
1
])
/
p
;
}
if
(
ypn
>
0.99e30
)
qn
=
un
=
0
.
0
;
else
{
qn
=
0
.
5
;
un
=
3
.
0
*
(
ypn
-
y
[
n
-
1
]
+
y
[
n
-
2
]);
}
y2
[
n
-
1
]
=
(
un
-
qn
*
u
[
n
-
2
])
/
(
qn
*
y2
[
n
-
2
]
+
1
.
0
);
for
(
k
=
n
-
2
;
k
>=
0
;
k
--
)
y2
[
k
]
=
y2
[
k
]
*
y2
[
k
+
1
]
+
u
[
k
];
free_vector
(
u
,
0
,
n
-
1
);
}
void
splint
(
float
ya
[],
float
y2a
[],
int
n
,
float
x
,
float
*
y
)
{
void
nrerror
(
char
error_text
[]);
int
klo
,
khi
,
k
;
float
h
,
b
,
a
;
klo
=
x
;
if
(
klo
<
0
)
klo
=
0
;
if
(
klo
==
n
-
1
)
klo
=
n
-
2
;
khi
=
klo
+
1
;
if
(
klo
<
0
||
khi
>=
n
)
printf
(
"error:klo, khi, n: %d %d %d
\n
"
,
klo
,
khi
,
n
);
if
(
klo
<
0
||
khi
>=
n
)
nrerror
(
"Bad xa input to routine splint"
);
a
=
(
khi
-
x
);
b
=
(
x
-
klo
);
*
y
=
a
*
ya
[
klo
]
+
b
*
ya
[
khi
]
+
((
a
*
a
*
a
-
a
)
*
y2a
[
klo
]
+
(
b
*
b
*
b
-
b
)
*
y2a
[
khi
])
/
6
.
0
;
}
ObservationSim/PSF/PSFInterp/libCentroid/centroidWgt.o
0 → 100644
View file @
29ac5666
File added
ObservationSim/PSF/PSFInterp/libCentroid/libCentroid.so
0 → 100755
View file @
29ac5666
File added
Prev
1
2
3
4
5
6
7
8
9
10
…
42
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