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
Wu Jin
CSST simulation
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