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
883b7a77
Commit
883b7a77
authored
Nov 29, 2021
by
Fang Yuedong
Browse files
bug fixed
parent
e82a5dcc
Changes
392
Show whitespace changes
Inline
Side-by-side
ObservationSim/PSF/PSFInterp_deprecated/libPCA/svdcmp.c
deleted
100644 → 0
View file @
e82a5dcc
#include
<math.h>
#define NRANSI
#include
"nrutil.h"
void
svdcmp
(
double
**
a
,
int
m
,
int
n
,
double
*
w
,
double
**
v
)
{
int
flag
,
i
,
its
,
j
,
jj
,
k
,
l
,
nm
;
double
anorm
,
c
,
f
,
g
,
h
,
s
,
scale
,
x
,
y
,
z
,
*
rv1
;
double
pythag
(
double
a
,
double
b
);
rv1
=
dvector
(
1
,
n
);
g
=
scale
=
anorm
=
0
.
0
;
for
(
i
=
1
;
i
<=
n
;
i
++
)
{
l
=
i
+
1
;
rv1
[
i
]
=
scale
*
g
;
g
=
s
=
scale
=
0
.
0
;
if
(
i
<=
m
)
{
for
(
k
=
i
;
k
<=
m
;
k
++
)
scale
+=
fabs
(
a
[
k
][
i
]);
if
(
scale
)
{
for
(
k
=
i
;
k
<=
m
;
k
++
)
{
a
[
k
][
i
]
/=
scale
;
s
+=
a
[
k
][
i
]
*
a
[
k
][
i
];
}
f
=
a
[
i
][
i
];
g
=
-
SIGN
(
sqrt
(
s
),
f
);
h
=
f
*
g
-
s
;
a
[
i
][
i
]
=
f
-
g
;
for
(
j
=
l
;
j
<=
n
;
j
++
)
{
for
(
s
=
0
.
0
,
k
=
i
;
k
<=
m
;
k
++
)
s
+=
a
[
k
][
i
]
*
a
[
k
][
j
];
f
=
s
/
h
;
for
(
k
=
i
;
k
<=
m
;
k
++
)
a
[
k
][
j
]
+=
f
*
a
[
k
][
i
];
}
for
(
k
=
i
;
k
<=
m
;
k
++
)
a
[
k
][
i
]
*=
scale
;
}
}
w
[
i
]
=
scale
*
g
;
g
=
s
=
scale
=
0
.
0
;
if
(
i
<=
m
&&
i
!=
n
)
{
for
(
k
=
l
;
k
<=
n
;
k
++
)
scale
+=
fabs
(
a
[
i
][
k
]);
if
(
scale
)
{
for
(
k
=
l
;
k
<=
n
;
k
++
)
{
a
[
i
][
k
]
/=
scale
;
s
+=
a
[
i
][
k
]
*
a
[
i
][
k
];
}
f
=
a
[
i
][
l
];
g
=
-
SIGN
(
sqrt
(
s
),
f
);
h
=
f
*
g
-
s
;
a
[
i
][
l
]
=
f
-
g
;
for
(
k
=
l
;
k
<=
n
;
k
++
)
rv1
[
k
]
=
a
[
i
][
k
]
/
h
;
for
(
j
=
l
;
j
<=
m
;
j
++
)
{
for
(
s
=
0
.
0
,
k
=
l
;
k
<=
n
;
k
++
)
s
+=
a
[
j
][
k
]
*
a
[
i
][
k
];
for
(
k
=
l
;
k
<=
n
;
k
++
)
a
[
j
][
k
]
+=
s
*
rv1
[
k
];
}
for
(
k
=
l
;
k
<=
n
;
k
++
)
a
[
i
][
k
]
*=
scale
;
}
}
anorm
=
FMAX
(
anorm
,(
fabs
(
w
[
i
])
+
fabs
(
rv1
[
i
])));
}
for
(
i
=
n
;
i
>=
1
;
i
--
)
{
if
(
i
<
n
)
{
if
(
g
)
{
for
(
j
=
l
;
j
<=
n
;
j
++
)
v
[
j
][
i
]
=
(
a
[
i
][
j
]
/
a
[
i
][
l
])
/
g
;
for
(
j
=
l
;
j
<=
n
;
j
++
)
{
for
(
s
=
0
.
0
,
k
=
l
;
k
<=
n
;
k
++
)
s
+=
a
[
i
][
k
]
*
v
[
k
][
j
];
for
(
k
=
l
;
k
<=
n
;
k
++
)
v
[
k
][
j
]
+=
s
*
v
[
k
][
i
];
}
}
for
(
j
=
l
;
j
<=
n
;
j
++
)
v
[
i
][
j
]
=
v
[
j
][
i
]
=
0
.
0
;
}
v
[
i
][
i
]
=
1
.
0
;
g
=
rv1
[
i
];
l
=
i
;
}
for
(
i
=
IMIN
(
m
,
n
);
i
>=
1
;
i
--
)
{
l
=
i
+
1
;
g
=
w
[
i
];
for
(
j
=
l
;
j
<=
n
;
j
++
)
a
[
i
][
j
]
=
0
.
0
;
if
(
g
)
{
g
=
1
.
0
/
g
;
for
(
j
=
l
;
j
<=
n
;
j
++
)
{
for
(
s
=
0
.
0
,
k
=
l
;
k
<=
m
;
k
++
)
s
+=
a
[
k
][
i
]
*
a
[
k
][
j
];
f
=
(
s
/
a
[
i
][
i
])
*
g
;
for
(
k
=
i
;
k
<=
m
;
k
++
)
a
[
k
][
j
]
+=
f
*
a
[
k
][
i
];
}
for
(
j
=
i
;
j
<=
m
;
j
++
)
a
[
j
][
i
]
*=
g
;
}
else
for
(
j
=
i
;
j
<=
m
;
j
++
)
a
[
j
][
i
]
=
0
.
0
;
++
a
[
i
][
i
];
}
for
(
k
=
n
;
k
>=
1
;
k
--
)
{
for
(
its
=
1
;
its
<=
30
;
its
++
)
{
flag
=
1
;
for
(
l
=
k
;
l
>=
1
;
l
--
)
{
nm
=
l
-
1
;
if
((
double
)(
fabs
(
rv1
[
l
])
+
anorm
)
==
anorm
)
{
flag
=
0
;
break
;
}
if
((
double
)(
fabs
(
w
[
nm
])
+
anorm
)
==
anorm
)
break
;
}
if
(
flag
)
{
c
=
0
.
0
;
s
=
1
.
0
;
for
(
i
=
l
;
i
<=
k
;
i
++
)
{
f
=
s
*
rv1
[
i
];
rv1
[
i
]
=
c
*
rv1
[
i
];
if
((
double
)(
fabs
(
f
)
+
anorm
)
==
anorm
)
break
;
g
=
w
[
i
];
h
=
pythag
(
f
,
g
);
w
[
i
]
=
h
;
h
=
1
.
0
/
h
;
c
=
g
*
h
;
s
=
-
f
*
h
;
for
(
j
=
1
;
j
<=
m
;
j
++
)
{
y
=
a
[
j
][
nm
];
z
=
a
[
j
][
i
];
a
[
j
][
nm
]
=
y
*
c
+
z
*
s
;
a
[
j
][
i
]
=
z
*
c
-
y
*
s
;
}
}
}
z
=
w
[
k
];
if
(
l
==
k
)
{
if
(
z
<
0
.
0
)
{
w
[
k
]
=
-
z
;
for
(
j
=
1
;
j
<=
n
;
j
++
)
v
[
j
][
k
]
=
-
v
[
j
][
k
];
}
break
;
}
if
(
its
==
30
)
nrerror
(
"no convergence in 30 svdcmp iterations"
);
x
=
w
[
l
];
nm
=
k
-
1
;
y
=
w
[
nm
];
g
=
rv1
[
nm
];
h
=
rv1
[
k
];
f
=
((
y
-
z
)
*
(
y
+
z
)
+
(
g
-
h
)
*
(
g
+
h
))
/
(
2
.
0
*
h
*
y
);
g
=
pythag
(
f
,
1
.
0
);
f
=
((
x
-
z
)
*
(
x
+
z
)
+
h
*
((
y
/
(
f
+
SIGN
(
g
,
f
)))
-
h
))
/
x
;
c
=
s
=
1
.
0
;
for
(
j
=
l
;
j
<=
nm
;
j
++
)
{
i
=
j
+
1
;
g
=
rv1
[
i
];
y
=
w
[
i
];
h
=
s
*
g
;
g
=
c
*
g
;
z
=
pythag
(
f
,
h
);
rv1
[
j
]
=
z
;
c
=
f
/
z
;
s
=
h
/
z
;
f
=
x
*
c
+
g
*
s
;
g
=
g
*
c
-
x
*
s
;
h
=
y
*
s
;
y
*=
c
;
for
(
jj
=
1
;
jj
<=
n
;
jj
++
)
{
x
=
v
[
jj
][
j
];
z
=
v
[
jj
][
i
];
v
[
jj
][
j
]
=
x
*
c
+
z
*
s
;
v
[
jj
][
i
]
=
z
*
c
-
x
*
s
;
}
z
=
pythag
(
f
,
h
);
w
[
j
]
=
z
;
if
(
z
)
{
z
=
1
.
0
/
z
;
c
=
f
*
z
;
s
=
h
*
z
;
}
f
=
c
*
g
+
s
*
y
;
x
=
c
*
y
-
s
*
g
;
for
(
jj
=
1
;
jj
<=
m
;
jj
++
)
{
y
=
a
[
jj
][
j
];
z
=
a
[
jj
][
i
];
a
[
jj
][
j
]
=
y
*
c
+
z
*
s
;
a
[
jj
][
i
]
=
z
*
c
-
y
*
s
;
}
}
rv1
[
l
]
=
0
.
0
;
rv1
[
k
]
=
f
;
w
[
k
]
=
x
;
}
}
free_dvector
(
rv1
,
1
,
n
);
}
#undef NRANSI
/* (C) Copr. 1986-92 Numerical Recipes Software )1!. */
ObservationSim/PSF/PSFInterp_deprecated/libPCA/svdcmp.o
deleted
100644 → 0
View file @
e82a5dcc
File deleted
ObservationSim/PSF/PSFInterp_deprecated/libPCA/test/.DS_Store
deleted
100644 → 0
View file @
e82a5dcc
File deleted
ObservationSim/PSF/PSFInterp_deprecated/libPCA/test/Makefile
deleted
100644 → 0
View file @
e82a5dcc
#OPTS += -D
CC
=
gcc
OPTIMIZE
=
-fPIC
-shared
-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
=
-lm
#
$(EXTRACLIB)
OBJS
=
test.o
EXEC
=
libtest.so
all
:
$(EXEC)
$(EXEC)
:
$(OBJS)
$(CLINK)
$(CFLAGS)
-o
$@
$(OBJS)
$(CLIB)
$(OBJS)
:
Makefile
.PHONY
:
clean
clean
:
rm
-f
*
.o
$(EXEC)
ObservationSim/PSF/PSFInterp_deprecated/libPCA/test/test.c
deleted
100644 → 0
View file @
e82a5dcc
#include
<stdio.h>
int
sum
(
int
a
,
int
b
){
return
a
+
b
;
}
ObservationSim/PSF/PSFInterp_deprecated/libPCA/test/tt.py
deleted
100644 → 0
View file @
e82a5dcc
import
numpy
as
np
import
ctypes
libPCA
=
ctypes
.
CDLL
(
'../libPCA.so'
)
# CDLL加载库
print
(
'load libPCA'
)
npsf
=
2
npix
=
3
libPCA
.
psfPCA
.
argtypes
=
[
ctypes
.
POINTER
(
ctypes
.
c_float
),
ctypes
.
c_int
,
ctypes
.
c_int
,
ctypes
.
POINTER
(
ctypes
.
c_double
),
ctypes
.
POINTER
(
ctypes
.
c_double
)]
Nstar
=
npsf
Mp
=
npix
*
npix
NM
=
Nstar
*
Mp
NN
=
Nstar
*
Nstar
arr
=
(
ctypes
.
c_float
*
NM
)()
basef
=
(
ctypes
.
c_double
*
NM
)()
coeff
=
(
ctypes
.
c_double
*
NN
)()
#psf1 = np.random.random([npix, npix])
#psf2 = np.random.random([npix, npix])
psfT
=
np
.
random
.
random
(
Nstar
*
Mp
)
arr
[:]
=
psfT
libPCA
.
psfPCA
(
arr
,
Nstar
,
Mp
,
basef
,
coeff
)
print
(
'haha'
)
print
(
arr
[:])
ObservationSim/PSF/PSFInterp_deprecated/psfConfig.py
deleted
100644 → 0
View file @
e82a5dcc
"""
CSST image simulation module (in python3): Point Spread Function (PSF)
author:: Wei Chengliang <chengliangwei@pmo.ac.cn>
"""
import
sys
from
itertools
import
islice
import
numpy
as
np
import
matplotlib.pyplot
as
plt
import
scipy.io
from
scipy.io
import
loadmat
#import xlrd
from
scipy
import
ndimage
from
scipy.interpolate
import
RectBivariateSpline
#from astropy.modeling.models import Ellipse2D
#from astropy.coordinates import Angle
#import matplotlib.patches as mpatches
import
ctypes
import
galsim
def
setupPSFimg
(
iccd
,
iwave
,
psfPath
=
"/data/simudata/CSSOSDataProductsSims/data/csstPSFdata/CSSOS_psf_ciomp"
):
"""
psf model setup for csst-sim
Parameters:
iccd, iwave (int, int): psf model on iccd & iwave
psfPath (string, optional): path to psf matrix
Returns:
psf_model (psf_class): psf model
Methods:
psf_model.PSFinplace(self, px, py, interpScheme=1): psf interpolation
psf_model.PSFspin(self, psf, sigSpin, sigGauss, dx, dy): psf rotation (from Yudong)
"""
psf_model
=
PSFimg
(
iccd
,
iwave
,
psfPath
)
return
psf_model
##################################################
# A. psf matrix loading & checking #
##################################################
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
return
psfPixelPos
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
imPlotInRange
(
img
):
"""
plot image within a selected range
Parameters:
img (numpy.array-float): image
Returns:
"""
im1
=
img
.
copy
()
im1size
=
im1
.
shape
X
,
Y
=
np
.
meshgrid
(
range
(
im1size
[
1
]),
range
(
im1size
[
0
]))
Z
=
im1
resolution
=
25
f
=
lambda
x
,
y
:
Z
[
int
(
y
),
int
(
x
)
]
g
=
np
.
vectorize
(
f
)
x
=
np
.
linspace
(
0
,
Z
.
shape
[
1
],
Z
.
shape
[
1
]
*
resolution
)
y
=
np
.
linspace
(
0
,
Z
.
shape
[
0
],
Z
.
shape
[
0
]
*
resolution
)
X2
,
Y2
=
np
.
meshgrid
(
x
[:
-
1
],
y
[:
-
1
])
Z2
=
g
(
X2
,
Y2
)
#plt.pcolormesh(X,Y, Z)
#plt.imshow(img, origin='lower')
plt
.
contour
(
X2
-
0.5
,
Y2
-
0.5
,
Z2
,
[
0.
],
colors
=
'w'
,
linestyles
=
'--'
,
linewidths
=
[
1
])
return
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
def
psfTailor
(
img
,
apSizeInArcsec
=
0.5
,
psfSampleSizeInMicrons
=
5
,
focalLengthInMeters
=
28
):
"""
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
)
apSizeInMicrons
=
np
.
deg2rad
(
apSizeInArcsec
/
3600.
)
*
focalLengthInMeters
*
1e6
apSizeInPix
=
apSizeInMicrons
/
psfSampleSizeInMicrons
apSizeInPix
=
np
.
int
(
np
.
ceil
(
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
def
psfEncircle
(
img
,
fraction
=
0.8
,
psfSampleSizeInMicrons
=
5
,
focalLengthInMeters
=
28
):
"""
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
)
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
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
"""
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
w
+=
I
[
jrow
,
icol
]
w11
+=
x
*
x
*
I
[
jrow
,
icol
]
w12
+=
x
*
y
*
I
[
jrow
,
icol
]
w22
+=
y
*
y
*
I
[
jrow
,
icol
]
w11
/=
w
w12
/=
w
w22
/=
w
sz
=
w11
+
w22
e1
=
(
w11
-
w22
)
/
sz
e2
=
2.0
*
w12
/
sz
return
sz
,
e1
,
e2
def
LoadPSF
(
iccd
,
iwave
,
ipsf
,
psfPath
,
psfSampleSize
=
5
,
CalcPSFsize
=
True
,
CalcPSFcenter
=
True
,
SigRange
=
False
,
TailorScheme
=
1
,
InputMaxPixelPos
=
False
):
'''加载psf信息'''
"""
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
psfSampleSize (float-optional): psf size in microns.
CalcPSFsize (bool-optional): whether calculate psf size & ellipticity. Default: True
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:
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矩阵
fpathMat
=
fpath
+
'/'
+
'5_psf_array'
+
'/'
+
'psf_{:}.mat'
.
format
(
ipsf
)
data
=
scipy
.
io
.
loadmat
(
fpathMat
)
psfInfo
[
'psfMat'
]
=
data
[
'psf'
]
#获取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
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
#nrows = 180 #psf采样大小, in pixels
#ncols = 180
nrows
,
ncols
=
psfInfo
[
'psfMat'
].
shape
psfPos
=
psfPixelLayout
(
nrows
,
ncols
,
psfInfo
[
'image_y'
],
psfInfo
[
'image_x'
],
pixSizeInMicrons
=
5.0
)
imgMaxPix_x
,
imgMaxPix_y
=
findMaxPix
(
psfInfo
[
'psfMat'
])
psfInfo
[
'imgMaxPosx_ccd'
]
=
psfPos
[
0
,
imgMaxPix_y
,
imgMaxPix_x
]
#cx, psf最大值位置, in mm
psfInfo
[
'imgMaxPosy_ccd'
]
=
psfPos
[
1
,
imgMaxPix_y
,
imgMaxPix_x
]
#cy
#计算psf size & ellipticity
if
CalcPSFsize
is
True
:
psfMat
=
psfInfo
[
'psfMat'
].
copy
()
cenX
,
cenY
,
sz
,
e1
,
e2
,
REE80
=
psfSizeCalculator
(
psfMat
,
psfSampleSize
=
psfSampleSize
,
CalcPSFcenter
=
CalcPSFcenter
,
SigRange
=
SigRange
,
TailorScheme
=
TailorScheme
)
psfInfo
[
'psfCenX_img'
]
=
cenX
#in local pixels, psf质心位置, in pixels
psfInfo
[
'psfCenY_img'
]
=
cenY
#in local pixels
psfInfo
[
'psfSize'
]
=
sz
psfInfo
[
'psf_e1'
]
=
e1
psfInfo
[
'psf_e2'
]
=
e2
psfInfo
[
'REE80'
]
=
REE80
return
psfInfo
def
psfSizeCalculator
(
psfMat
,
psfSampleSize
=
5
,
CalcPSFcenter
=
True
,
SigRange
=
False
,
TailorScheme
=
1
):
"""
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
)
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
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
##################################################
# B. psf interpolation #
##################################################
def
img2fits
(
img
,
fitsName
=
None
):
"""
saving image to fits file
Parameters:
img (numpy.array): image
fitsName (string): path+filename of fits
Returns:
"""
from
astropy.io
import
fits
grey
=
fits
.
PrimaryHDU
(
img
)
greyHDU
=
fits
.
HDUList
([
grey
])
if
fitsName
!=
None
:
greyHDU
.
writeto
(
fitsName
)
def
psfMatLoad
(
iccd
,
iwave
,
psfPath
,
psfSampleSize
=
5
,
CalcPSFsize
=
False
,
CalcPSFcenter
=
True
):
"""
load psf for interpolation
Parameters:
iccd, iwave, psfPath: # of ccd/wave and path for psfs
CalcPSFsize (bool-optional): whether calculate psf size & ellipticity. Default: False
CalcPSFcenter (bool-optional): whether calculate psf center. Default: True
Returns:
PSFMat (numpy.array): images
cen_col, cen_row (numpy.array, numpy.array): position of psf center in the view field
"""
psfSet
=
[]
for
ipsf
in
range
(
1
,
101
):
psfInfo
=
LoadPSF
(
iccd
,
iwave
,
ipsf
,
psfPath
,
CalcPSFsize
=
CalcPSFsize
,
CalcPSFcenter
=
CalcPSFcenter
,
InputMaxPixelPos
=
False
)
psfSet
.
append
(
psfInfo
)
npsf
=
len
(
psfSet
)
ngy
,
ngx
=
psfSet
[
0
][
'psfMat'
].
shape
PSFMat
=
np
.
zeros
([
npsf
,
ngy
,
ngx
])
cen_col
=
np
.
zeros
(
npsf
)
cen_row
=
np
.
zeros
(
npsf
)
FieldPos
=
False
for
ipsf
in
range
(
npsf
):
PSFMat
[
ipsf
,
:,
:]
=
psfSet
[
ipsf
][
'psfMat'
]
if
FieldPos
==
True
:
cen_col
[
ipsf
]
=
psfSet
[
ipsf
][
'field_x'
]
#cx
cen_row
[
ipsf
]
=
psfSet
[
ipsf
][
'field_y'
]
#cy
if
FieldPos
==
False
:
cen_col
[
ipsf
]
=
psfSet
[
ipsf
][
'imgMaxPosx_ccd'
]
#cx
cen_row
[
ipsf
]
=
psfSet
[
ipsf
][
'imgMaxPosy_ccd'
]
#cy
return
PSFMat
,
cen_col
,
cen_row
def
findNeighbors
(
tx
,
ty
,
px
,
py
,
dr
=
0.1
,
dn
=
1
,
OnlyDistance
=
True
):
"""
find nearest meighbors 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
"""
import
scipy.spatial
as
spatial
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
def
psfCentering
(
img
,
apSizeInArcsec
=
4.
,
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
def
psfMaker_IDW
(
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
IDWindex
=
2
,
OnlyNeighbors
=
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
:
neigh
=
findNeighbors
(
px
,
py
,
cen_col
,
cen_row
,
dr
=
5.
,
dn
=
9
,
OnlyDistance
=
False
)
neighFlag
=
np
.
zeros
(
npsf
)
neighFlag
[
neigh
]
=
1
# print("neigh:", neigh)
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
=
'float64'
)
for
ipsf
in
range
(
npsf
):
if
OnlyNeighbors
==
True
:
if
neighFlag
[
ipsf
]
!=
1
:
continue
iPSFMat
=
PSFMat
[
ipsf
,
:,
:].
copy
()
iPSFMat
=
psfCentering
(
iPSFMat
,
CenteringMode
=
1
)
ipsfWeight
=
psfWeight
[
ipsf
]
psfMaker
+=
iPSFMat
*
ipsfWeight
psfMaker
/=
np
.
nansum
(
psfMaker
)
return
psfMaker
def
psfMaker_PCA
(
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
OnlyNeighbors
=
False
,
libPCApath
=
'libPCA/libPCA.so'
):
"""
psf interpolation by PCA
Parameters:
Returns:
"""
ref_col
=
px
ref_row
=
py
ngy
,
ngx
=
PSFMat
[
0
,
:,
:].
shape
npsf
=
PSFMat
[:,
:,
:].
shape
[
0
]
neigh
=
findNeighbors
(
px
,
py
,
cen_col
,
cen_row
,
dr
=
0.3
,
dn
=
5
,
OnlyDistance
=
False
)
npsfX
=
len
(
neigh
)
psfMatX
=
np
.
zeros
([
npsfX
,
ngy
,
ngx
])
cen_colX
=
np
.
zeros
(
npsfX
)
cen_rowX
=
np
.
zeros
(
npsfX
)
for
ipsf
in
range
(
npsfX
):
psfMatX
[
ipsf
,
:,
:]
=
PSFMat
[
neigh
[
ipsf
],
:,
:]
cen_colX
[
ipsf
]
=
cen_col
[
neigh
[
ipsf
]]
cen_rowX
[
ipsf
]
=
cen_row
[
neigh
[
ipsf
]]
psfMaker
=
np
.
zeros
((
ngy
,
ngx
),
dtype
=
'float64'
)
if
OnlyNeighbors
==
True
:
PCAbasef
,
PCAcoeff
=
psfPCA_generator
(
psfMatX
,
npsfX
,
ngx
,
libPCApath
)
nPCA
=
npsfX
for
iPCA
in
range
(
nPCA
):
coeffX
=
fitPoly
(
ref_col
,
ref_row
,
cen_colX
,
cen_rowX
,
PCAcoeff
[:,
iPCA
],
order
=
2
)
psfMaker
+=
coeffX
*
PCAbasef
[
iPCA
,
:,
:]
return
psfMaker
def
psfPCA_generator
(
psfMat
,
npsf
,
npix
,
libPCApath
):
"""
generate PCs from psfMat
Parameters:
Returns:
"""
libPCA
=
ctypes
.
CDLL
(
libPCApath
)
# CDLL加载库
libPCA
.
psfPCA
.
argtypes
=
[
ctypes
.
POINTER
(
ctypes
.
c_float
),
ctypes
.
c_int
,
ctypes
.
c_int
,
ctypes
.
POINTER
(
ctypes
.
c_double
),
ctypes
.
POINTER
(
ctypes
.
c_double
)]
Nstar
=
npsf
Mp
=
npix
*
npix
NM
=
Nstar
*
Mp
NN
=
Nstar
*
Nstar
arr
=
(
ctypes
.
c_float
*
NM
)()
basef
=
(
ctypes
.
c_double
*
NM
)()
coeff
=
(
ctypes
.
c_double
*
NN
)()
psfT
=
np
.
zeros
(
NM
)
for
ipsf
in
range
(
npsf
):
lp
=
0
+
ipsf
*
Mp
up
=
Mp
+
ipsf
*
Mp
ipsfMat
=
psfMat
[
ipsf
,
:,
:]
psfT
[
lp
:
up
]
=
ipsfMat
.
reshape
(
Mp
)
arr
[:]
=
psfT
libPCA
.
psfPCA
(
arr
,
Nstar
,
Mp
,
basef
,
coeff
)
PCAbasef
=
np
.
zeros
([
npsf
,
npix
,
npix
])
PCAcoeff
=
np
.
zeros
([
npsf
,
npsf
])
for
ipsf
in
range
(
npsf
):
lp
=
0
+
ipsf
*
Mp
up
=
Mp
+
ipsf
*
Mp
PCAbasef
[
ipsf
,
:,
:]
=
np
.
array
(
basef
[
lp
:
up
]).
reshape
(
npix
,
npix
)
lp
=
0
+
ipsf
*
npsf
up
=
npsf
+
ipsf
*
npsf
PCAcoeff
[
ipsf
,
:]
=
np
.
array
(
coeff
[
lp
:
up
])
return
PCAbasef
,
PCAcoeff
def
fitPoly
(
px
,
py
,
datax
,
datay
,
dataz
,
order
=
2
):
if
order
==
1
:
# best-fit linear plane
A
=
np
.
c_
[
datax
,
datay
,
np
.
ones
(
datax
.
shape
[
0
])]
C
,
_
,
_
,
_
=
scipy
.
linalg
.
lstsq
(
A
,
dataz
)
# coefficients
pz
=
C
[
0
]
*
px
+
C
[
1
]
*
py
+
C
[
2
]
elif
order
==
2
:
# best-fit quadratic curve
A
=
np
.
c_
[
np
.
ones
(
datax
.
shape
[
0
]),
np
.
c_
[
datax
,
datay
],
np
.
prod
(
np
.
c_
[
datax
,
datay
],
axis
=
1
),
np
.
c_
[
datax
,
datay
]
**
2
]
C
,
_
,
_
,
_
=
scipy
.
linalg
.
lstsq
(
A
,
dataz
)
pz
=
np
.
dot
(
np
.
c_
[
1
,
px
,
py
,
px
*
py
,
px
**
2
,
py
**
2
],
C
)
"""
elif order == 3:
# best-fit cubic curve
A = np.c_[np.ones(datax.shape[0]), np.c_[datax, datay], np.prod(np.c_[datax, datay], axis=1), np.c_[datax, datay]**2, np.c_[datax, datay]**3]
C,_,_,_ = scipy.linalg.lstsq(A, dataz)
pz = np.dot(np.c_[1, px, py, px*py, px**2, py**2, px**3, py**3], C)
"""
return
pz
"""
############################
### not used temporarily ###
############################
def psfSplineMake(px, py, PSFMat, cen_col, cen_row, OnlyNeighbors=False):
minimum_psf_weight = 1e-8
ref_col = px
ref_row = py
cdelt1p = 1
cdelt2p = 1
ngy, ngx = PSFMat[0, :, :].shape
psfx = np.linspace(0, ngx-1, ngx)
psfy = np.linspace(0, ngy-1, ngy)
npsf = PSFMat[:, :, :].shape[0]
psfWeight = np.zeros([npsf])
for ipsf in range(npsf):
psfWeight[ipsf] = np.sqrt((ref_col - cen_col[ipsf])**2 + (ref_row - cen_row[ipsf])**2)
psfWeight[ipsf] = max(psfWeight[ipsf], minimum_psf_weight)
psfWeight[ipsf] = 1./psfWeight[ipsf]
psfWeight /= np.sum(psfWeight)
psf = np.zeros((ngy, ngx), dtype='float64')
for ipsf in range(npsf):
iPSFMat = PSFMat[ipsf, :, :]
ipsfWeight = psfWeight[ipsf]
psf += iPSFMat * ipsfWeight
psf /= (np.nansum(psf) * cdelt1p * cdelt2p)
psfSpline = RectBivariateSpline(psfy, psfx, psf)
return psf, psfSpline
def psfToImage(psfSpline, cutoff_radius=180):
ng = 180
img = np.zeros([ng, ng], dtype='float64')
for i in range(ng):
for j in range(ng):
star_row = 5
star_column = 5
if np.sqrt((j-star_column)**2 + (i-star_row)**2) <= cutoff_radius:
star_flux = 8
column_cen = j #j - star_column
row_cen = i #i - star_row
img[i,j] += star_flux * psfSpline.integral(row_cen-0.5, row_cen+0.5, column_cen-0.5, column_cen+0.5)
return img
"""
##################################################
# C. csstPSF class #
##################################################
class
PSFimg
(
object
):
def
__init__
(
self
,
iccd
,
iwave
,
psfPath
):
self
.
iccd
=
iccd
self
.
iwave
=
iwave
self
.
psfPath
=
psfPath
#loading psfSet >>>
"""
psfSet = []
for ipsf in range(1, 901):
psfInfo = LoadPSF(iccd, iwave, ipsf, psfPath, CalcPSFsize=True, CalcPSFcenter=True, SigRange=False)
psfSet.append(psfInfo)
self.psfSet = psfSet
"""
a
,
b
,
c
=
psfMatLoad
(
iccd
,
iwave
,
psfPath
)
self
.
psfMat
=
a
self
.
cenPosx
=
b
self
.
cenPosy
=
c
def
PSFinplace
(
self
,
px
,
py
,
interpScheme
=
1
):
if
interpScheme
==
1
:
idwIndx
=
2
psf
=
psfMaker_IDW
(
px
,
py
,
self
.
psfMat
,
self
.
cenPosx
,
self
.
cenPosy
,
IDWindex
=
idwIndx
,
OnlyNeighbors
=
True
)
if
interpScheme
==
2
:
libPCA
=
"/Users/chengliangwei/Desktop/csstPSF/libPCA/libPCA.so"
psf
=
psfMaker_PCA
(
px
,
py
,
self
.
psfMat
,
self
.
cenPosx
,
self
.
cenPosy
,
OnlyNeighbors
=
True
,
libPCApath
=
libPCA
)
img
=
galsim
.
ImageF
(
psf
,
scale
=
0.074
/
2
)
xpsf
=
galsim
.
InterpolatedImage
(
img
)
return
xpsf
"""
def gcPlot(self, psf,pscale=0.074,figout="GC.png"):
size = np.size(psf,axis=0)
cxy = 0.5*(size-1)
width = 0.5*size
# log scale
radius = np.arange(np.log10(0.2),np.log10(width),0.01)
radius = 10.0**radius
nr = len(radius)
gc = []
for i in range(nr):
iflux, iferr, xflag = sep.sum_circle(psf,cxy,cxy,radius[i],subpix=0)
gc += [iflux.tolist()]
# Estimate the radius for a given flux ratio
fratio = 0.8
mid = [i for i in range(nr) if gc[i]<=fratio and gc[i+1]>fratio][0]
r0, r1 = radius[mid], radius[mid+1]
gc0, gc1 = gc[mid], gc[mid+1]
r5 = (fratio-gc0)/(gc1-gc0)*(r1-r0) + r0
hlf = r5*pscale
# plot
pfit = interp1d(radius, gc, kind='cubic')
fig = pl.figure(figsize=(5.5,4.0))
ax = fig.add_axes([0.16,0.15,0.80,0.81])
ax.plot(radius*pscale, pfit(radius), "k", linewidth=2.0)
ax.plot(radius*pscale, gc, "*r", markersize=5.0,mec="r",alpha=0.3)
ax.plot([hlf,hlf],[0,fratio],"k",linewidth=2.5)
ax.plot([0,hlf],[fratio,fratio],"k",linewidth=2.5)
ax.text(radius[10]*pscale,0.6,"$r_{%.1f}$=%.2f
\"
"%(fratio,hlf))
ax.set_xlabel("Radius (arcsec)",fontsize=15)
ax.set_ylabel("Growth of Curve",fontsize=15)
ax.set_xscale("log")
ax.set_xlim(radius[0]*pscale,radius[-1]*pscale)
ax.set_ylim(0.0,1.0)
for tick in ax.xaxis.get_major_ticks(): tick.label.set_fontsize(15)
for tick in ax.yaxis.get_major_ticks(): tick.label.set_fontsize(15)
pl.savefig(figout)
pl.clf()
pl.close()
return
"""
def
PSFspin
(
self
,
psf
,
sigSpin
,
sigGauss
,
dx
,
dy
):
"""
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
=
sigGauss
*
0.107
*
(
1000.0
/
10.0
)
# in unit of [pixels]
rc
=
np
.
sqrt
(
dx
*
dx
+
dy
*
dy
)
cpix
=
rc
*
(
sigSpin
*
a2Rad
)
beta
=
(
np
.
arctan2
(
dy
,
dx
)
+
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
psf
.
shear
(
PSFshear
),
PSFshear
(
base
)
##################################################
# D. TEST #
##################################################
def
psfMaker_IDW_test
(
tpsf
,
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
IDWindex
=
2
,
OnlyNeighbors
=
False
):
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
:
neigh
=
findNeighbors
(
px
,
py
,
cen_col
,
cen_row
,
dr
=
0.1
,
dn
=
9
,
OnlyDistance
=
False
)
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
=
'float64'
)
for
ipsf
in
range
(
npsf
):
"""
if OnlyNeighbors == True:
iy, ix = np.unravel_index(ipsf, (10,10))
ty, tx = np.unravel_index(tpsf, (10,10))
if np.abs(iy - ty) > 1 or np.abs(ix - tx) > 1:
continue
"""
if
OnlyNeighbors
==
True
:
if
neighFlag
[
ipsf
]
!=
1
:
continue
if
ipsf
==
tpsf
:
continue
iPSFMat
=
PSFMat
[
ipsf
,
:,
:].
copy
()
iPSFMat
=
psfCentering
(
iPSFMat
,
CenteringMode
=
1
)
ipsfWeight
=
psfWeight
[
ipsf
]
psfMaker
+=
iPSFMat
*
ipsfWeight
psfMaker
/=
np
.
nansum
(
psfMaker
)
return
psfMaker
def
psfMaker_PCA_test
(
tpsf
,
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
OnlyNeighbors
=
False
,
libPCApath
=
'libPCA/libPCA.so'
):
"""
psf interpolation by PCA
Parameters:
Returns:
"""
ref_col
=
px
ref_row
=
py
ngy
,
ngx
=
PSFMat
[
0
,
:,
:].
shape
npsf
=
PSFMat
[:,
:,
:].
shape
[
0
]
neigh
=
findNeighbors
(
px
,
py
,
cen_col
,
cen_row
,
dr
=
0.3
,
dn
=
9
,
OnlyDistance
=
False
)
npsfX
=
len
(
neigh
)
#去掉tpsf,neigh中排在第一个是最近的psf
print
(
"CHECK:::"
,
cen_col
[
neigh
[
0
]],
cen_row
[
neigh
[
0
]],
cen_col
[
tpsf
],
cen_row
[
tpsf
],
cen_col
[
neigh
[
0
]]
-
cen_col
[
tpsf
],
cen_row
[
neigh
[
0
]]
-
cen_row
[
tpsf
])
psfMatX
=
np
.
zeros
([
npsfX
-
1
,
ngy
,
ngx
])
cen_colX
=
np
.
zeros
(
npsfX
-
1
)
cen_rowX
=
np
.
zeros
(
npsfX
-
1
)
for
ipsf
in
range
(
npsfX
):
if
ipsf
==
0
:
continue
psfMatX
[
ipsf
-
1
,
:,
:]
=
PSFMat
[
neigh
[
ipsf
],
:,
:]
cen_colX
[
ipsf
-
1
]
=
cen_col
[
neigh
[
ipsf
]]
cen_rowX
[
ipsf
-
1
]
=
cen_row
[
neigh
[
ipsf
]]
psfMaker
=
np
.
zeros
((
ngy
,
ngx
),
dtype
=
'float64'
)
if
OnlyNeighbors
==
True
:
PCAbasef
,
PCAcoeff
=
psfPCA_generator
(
psfMatX
,
npsfX
-
1
,
ngx
,
libPCApath
)
nPCA
=
npsfX
-
1
for
iPCA
in
range
(
nPCA
):
coeffX
=
fitPoly
(
ref_col
,
ref_row
,
cen_colX
,
cen_rowX
,
PCAcoeff
[:,
iPCA
],
order
=
2
)
psfMaker
+=
coeffX
*
PCAbasef
[
iPCA
,
:,
:]
return
psfMaker
def
test_loadPSF
():
iccd
=
1
#[1, 30]
iwave
=
1
#[1, 4]
ipsf
=
1
#[1, 100]
psfPath
=
'/Users/chengliangwei/csstPSFdata/CSSOS_psf_ciomp'
psfSet
=
[]
for
ipsf
in
range
(
1
,
901
):
psfInfo
=
LoadPSF
(
iccd
,
iwave
,
ipsf
,
psfPath
,
CalcPSFsize
=
True
,
CalcPSFcenter
=
True
,
SigRange
=
False
)
psfSet
.
append
(
psfInfo
)
print
(
'psfSet has been loaded.'
)
print
(
'Usage: psfSet[i][keys]'
)
print
(
'psfSet.keys:'
,
psfSet
[
0
].
keys
())
return
psfSet
def
test_psfPCA
():
#load psf
print
(
'load psf...'
)
psfSet
=
test_loadPSF
()
#set input for psfPCA calc.
print
(
'PCA calc...'
)
npsf
=
5
npix
=
180
psfMat
=
np
.
zeros
([
npsf
,
npix
,
npix
])
libPCApath
=
'./libPCA/libPCA.so'
for
ipsf
in
range
(
5
):
psfMat
[
ipsf
,
:,
:]
=
psfSet
[
ipsf
][
'psfMat'
]
PCAbasef
,
PCAcoeff
=
psfPCA_generator
(
psfMat
,
npsf
,
npix
,
libPCApath
)
#plot check
print
(
'plot...'
)
fig
=
plt
.
figure
(
figsize
=
(
20
,
10
))
cc
=
90
dcc
=
15
ax
=
plt
.
subplot
(
2
,
4
,
1
)
plt
.
imshow
(
PCAbasef
[
0
,
:,
:][
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
ax
=
plt
.
subplot
(
2
,
4
,
2
)
plt
.
imshow
(
PCAbasef
[
1
,
:,
:][
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
ax
=
plt
.
subplot
(
2
,
4
,
3
)
plt
.
imshow
(
PCAbasef
[
2
,
:,
:][
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
ax
=
plt
.
subplot
(
2
,
4
,
4
)
plt
.
imshow
(
PCAbasef
[
3
,
:,
:][
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
ax
=
plt
.
subplot
(
2
,
4
,
5
)
plt
.
imshow
(
PCAbasef
[
4
,
:,
:][
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
ax
=
plt
.
subplot
(
2
,
4
,
6
)
ipsf
=
1
im
=
PCAcoeff
[
ipsf
,
0
]
*
PCAbasef
[
0
,
:,
:]
im
+=
PCAcoeff
[
ipsf
,
1
]
*
PCAbasef
[
1
,
:,
:]
im
+=
PCAcoeff
[
ipsf
,
2
]
*
PCAbasef
[
2
,
:,
:]
im
+=
PCAcoeff
[
ipsf
,
3
]
*
PCAbasef
[
3
,
:,
:]
im
+=
PCAcoeff
[
ipsf
,
4
]
*
PCAbasef
[
4
,
:,
:]
plt
.
imshow
(
im
[
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
plt
.
colorbar
()
ax
=
plt
.
subplot
(
2
,
4
,
8
)
plt
.
imshow
(
psfMat
[
ipsf
,:,:][
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
plt
.
colorbar
()
ax
=
plt
.
subplot
(
2
,
4
,
7
)
plt
.
imshow
((
psfMat
[
ipsf
,:,:]
-
im
)[
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
plt
.
colorbar
()
plt
.
show
()
def
test_fitPoly
():
datax
=
np
.
random
.
random
(
10
)
datay
=
np
.
random
.
random
(
10
)
*
2
dataz
=
datay
**
2
+
datay
*
datax
+
10
*
datay
**
2
px
=
0.28
py
=
10.34
pz
=
fitPoly
(
px
,
py
,
datax
,
datay
,
dataz
,
order
=
2
)
print
(
'check: pz-out:'
,
pz
,
'pz-in'
,
py
**
2
+
px
*
py
+
10
*
py
**
2
)
##################################################
# __main__ #
##################################################
if
__name__
==
'__main__'
:
print
(
'PSF modules for csst-imgsim'
)
#test_loadPSF()
#test_psfPCA()
test_fitPoly
()
ObservationSim/PSF/PSFInterp_deprecated/psfConfigTest.py
deleted
100644 → 0
View file @
e82a5dcc
"""
CSST image simulation module (in python3): Point Spread Function (PSF)
author:: Wei Chengliang <chengliangwei@pmo.ac.cn>
"""
import
sys
from
itertools
import
islice
import
numpy
as
np
import
matplotlib.pyplot
as
plt
import
scipy.io
from
scipy.io
import
loadmat
#import xlrd
from
scipy
import
ndimage
from
scipy.interpolate
import
RectBivariateSpline
#from astropy.modeling.models import Ellipse2D
#from astropy.coordinates import Angle
#import matplotlib.patches as mpatches
import
ctypes
import
galsim
def
setupPSFimg
(
iccd
,
iwave
,
psfPath
=
"/data/simudata/CSSOSDataProductsSims/data/csstPSFdata/CSSOS_psf_ciomp"
):
"""
psf model setup for csst-sim
Parameters:
iccd, iwave (int, int): psf model on iccd & iwave
psfPath (string, optional): path to psf matrix
Returns:
psf_model (psf_class): psf model
Methods:
psf_model.PSFinplace(self, px, py, interpScheme=1): psf interpolation
psf_model.PSFspin(self, psf, sigSpin, sigGauss, dx, dy): psf rotation (from Yudong)
"""
psf_model
=
PSFimg
(
iccd
,
iwave
,
psfPath
)
return
psf_model
##################################################
# A. psf matrix loading & checking #
##################################################
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
return
psfPixelPos
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
imPlotInRange
(
img
):
"""
plot image within a selected range
Parameters:
img (numpy.array-float): image
Returns:
"""
im1
=
img
.
copy
()
im1size
=
im1
.
shape
X
,
Y
=
np
.
meshgrid
(
range
(
im1size
[
1
]),
range
(
im1size
[
0
]))
Z
=
im1
resolution
=
25
f
=
lambda
x
,
y
:
Z
[
int
(
y
),
int
(
x
)
]
g
=
np
.
vectorize
(
f
)
x
=
np
.
linspace
(
0
,
Z
.
shape
[
1
],
Z
.
shape
[
1
]
*
resolution
)
y
=
np
.
linspace
(
0
,
Z
.
shape
[
0
],
Z
.
shape
[
0
]
*
resolution
)
X2
,
Y2
=
np
.
meshgrid
(
x
[:
-
1
],
y
[:
-
1
])
Z2
=
g
(
X2
,
Y2
)
#plt.pcolormesh(X,Y, Z)
#plt.imshow(img, origin='lower')
plt
.
contour
(
X2
-
0.5
,
Y2
-
0.5
,
Z2
,
[
0.
],
colors
=
'w'
,
linestyles
=
'--'
,
linewidths
=
[
1
])
return
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
def
psfTailor
(
img
,
apSizeInArcsec
=
0.5
,
psfSampleSizeInMicrons
=
5
,
focalLengthInMeters
=
28
):
"""
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
)
apSizeInMicrons
=
np
.
deg2rad
(
apSizeInArcsec
/
3600.
)
*
focalLengthInMeters
*
1e6
apSizeInPix
=
apSizeInMicrons
/
psfSampleSizeInMicrons
apSizeInPix
=
np
.
int
(
np
.
ceil
(
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
def
psfEncircle
(
img
,
fraction
=
0.8
,
psfSampleSizeInMicrons
=
5
,
focalLengthInMeters
=
28
):
"""
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
)
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
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
"""
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
w
+=
I
[
jrow
,
icol
]
w11
+=
x
*
x
*
I
[
jrow
,
icol
]
w12
+=
x
*
y
*
I
[
jrow
,
icol
]
w22
+=
y
*
y
*
I
[
jrow
,
icol
]
w11
/=
w
w12
/=
w
w22
/=
w
sz
=
w11
+
w22
e1
=
(
w11
-
w22
)
/
sz
e2
=
2.0
*
w12
/
sz
return
sz
,
e1
,
e2
def
LoadPSF
(
iccd
,
iwave
,
ipsf
,
psfPath
,
psfSampleSize
=
5
,
CalcPSFsize
=
True
,
CalcPSFcenter
=
True
,
SigRange
=
False
,
TailorScheme
=
1
,
InputMaxPixelPos
=
False
):
'''加载psf信息'''
"""
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
psfSampleSize (float-optional): psf size in microns.
CalcPSFsize (bool-optional): whether calculate psf size & ellipticity. Default: True
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:
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矩阵
fpathMat
=
fpath
+
'/'
+
'5_psf_array'
+
'/'
+
'psf_{:}.mat'
.
format
(
ipsf
)
data
=
scipy
.
io
.
loadmat
(
fpathMat
)
psfInfo
[
'psfMat'
]
=
data
[
'psf'
]
#获取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
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
#nrows = 180 #psf采样大小, in pixels
#ncols = 180
nrows
,
ncols
=
psfInfo
[
'psfMat'
].
shape
psfPos
=
psfPixelLayout
(
nrows
,
ncols
,
psfInfo
[
'image_y'
],
psfInfo
[
'image_x'
],
pixSizeInMicrons
=
5.0
)
imgMaxPix_x
,
imgMaxPix_y
=
findMaxPix
(
psfInfo
[
'psfMat'
])
psfInfo
[
'imgMaxPosx_ccd'
]
=
psfPos
[
0
,
imgMaxPix_y
,
imgMaxPix_x
]
#cx, psf最大值位置, in mm
psfInfo
[
'imgMaxPosy_ccd'
]
=
psfPos
[
1
,
imgMaxPix_y
,
imgMaxPix_x
]
#cy
#计算psf size & ellipticity
if
CalcPSFsize
is
True
:
psfMat
=
psfInfo
[
'psfMat'
].
copy
()
cenX
,
cenY
,
sz
,
e1
,
e2
,
REE80
=
psfSizeCalculator
(
psfMat
,
psfSampleSize
=
psfSampleSize
,
CalcPSFcenter
=
CalcPSFcenter
,
SigRange
=
SigRange
,
TailorScheme
=
TailorScheme
)
psfInfo
[
'psfCenX_img'
]
=
cenX
#in local pixels, psf质心位置, in pixels
psfInfo
[
'psfCenY_img'
]
=
cenY
#in local pixels
psfInfo
[
'psfSize'
]
=
sz
psfInfo
[
'psf_e1'
]
=
e1
psfInfo
[
'psf_e2'
]
=
e2
psfInfo
[
'REE80'
]
=
REE80
return
psfInfo
def
psfSizeCalculator
(
psfMat
,
psfSampleSize
=
5
,
CalcPSFcenter
=
True
,
SigRange
=
False
,
TailorScheme
=
1
):
"""
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
)
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
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
##################################################
# B. psf interpolation #
##################################################
def
img2fits
(
img
,
fitsName
=
None
):
"""
saving image to fits file
Parameters:
img (numpy.array): image
fitsName (string): path+filename of fits
Returns:
"""
from
astropy.io
import
fits
grey
=
fits
.
PrimaryHDU
(
img
)
greyHDU
=
fits
.
HDUList
([
grey
])
if
fitsName
!=
None
:
greyHDU
.
writeto
(
fitsName
)
def
psfMatLoad
(
iccd
,
iwave
,
psfPath
,
psfSampleSize
=
5
,
CalcPSFsize
=
False
,
CalcPSFcenter
=
True
):
"""
load psf for interpolation
Parameters:
iccd, iwave, psfPath: # of ccd/wave and path for psfs
CalcPSFsize (bool-optional): whether calculate psf size & ellipticity. Default: False
CalcPSFcenter (bool-optional): whether calculate psf center. Default: True
Returns:
PSFMat (numpy.array): images
cen_col, cen_row (numpy.array, numpy.array): position of psf center in the view field
"""
psfSet
=
[]
for
ipsf
in
range
(
1
,
901
):
psfInfo
=
LoadPSF
(
iccd
,
iwave
,
ipsf
,
psfPath
,
CalcPSFsize
=
CalcPSFsize
,
CalcPSFcenter
=
CalcPSFcenter
,
InputMaxPixelPos
=
True
)
psfSet
.
append
(
psfInfo
)
npsf
=
len
(
psfSet
)
ngy
,
ngx
=
psfSet
[
0
][
'psfMat'
].
shape
PSFMat
=
np
.
zeros
([
npsf
,
ngy
,
ngx
])
cen_col
=
np
.
zeros
(
npsf
)
cen_row
=
np
.
zeros
(
npsf
)
FieldPos
=
False
for
ipsf
in
range
(
npsf
):
PSFMat
[
ipsf
,
:,
:]
=
psfSet
[
ipsf
][
'psfMat'
]
if
FieldPos
==
True
:
cen_col
[
ipsf
]
=
psfSet
[
ipsf
][
'field_x'
]
#cx
cen_row
[
ipsf
]
=
psfSet
[
ipsf
][
'field_y'
]
#cy
if
FieldPos
==
False
:
cen_col
[
ipsf
]
=
psfSet
[
ipsf
][
'imgMaxPosx_ccd'
]
#cx
cen_row
[
ipsf
]
=
psfSet
[
ipsf
][
'imgMaxPosy_ccd'
]
#cy
return
PSFMat
,
cen_col
,
cen_row
def
findNeighbors
(
tx
,
ty
,
px
,
py
,
dr
=
0.1
,
dn
=
1
,
OnlyDistance
=
True
):
"""
find nearest meighbors 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
"""
import
scipy.spatial
as
spatial
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
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
def
psfMaker_IDW
(
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
IDWindex
=
2
,
OnlyNeighbors
=
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
:
neigh
=
findNeighbors
(
px
,
py
,
cen_col
,
cen_row
,
dr
=
5.
,
dn
=
9
,
OnlyDistance
=
False
)
neighFlag
=
np
.
zeros
(
npsf
)
neighFlag
[
neigh
]
=
1
print
(
"neigh:"
,
neigh
)
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
=
'float64'
)
for
ipsf
in
range
(
npsf
):
if
OnlyNeighbors
==
True
:
if
neighFlag
[
ipsf
]
!=
1
:
continue
iPSFMat
=
PSFMat
[
ipsf
,
:,
:].
copy
()
iPSFMat
=
psfCentering
(
iPSFMat
,
CenteringMode
=
1
)
ipsfWeight
=
psfWeight
[
ipsf
]
psfMaker
+=
iPSFMat
*
ipsfWeight
psfMaker
/=
np
.
nansum
(
psfMaker
)
return
psfMaker
def
psfMaker_PCA
(
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
OnlyNeighbors
=
False
,
libPCApath
=
'libPCA/libPCA.so'
):
"""
psf interpolation by PCA
Parameters:
Returns:
"""
ref_col
=
px
ref_row
=
py
ngy
,
ngx
=
PSFMat
[
0
,
:,
:].
shape
npsf
=
PSFMat
[:,
:,
:].
shape
[
0
]
neigh
=
findNeighbors
(
px
,
py
,
cen_col
,
cen_row
,
dr
=
0.3
,
dn
=
5
,
OnlyDistance
=
False
)
npsfX
=
len
(
neigh
)
psfMatX
=
np
.
zeros
([
npsfX
,
ngy
,
ngx
])
cen_colX
=
np
.
zeros
(
npsfX
)
cen_rowX
=
np
.
zeros
(
npsfX
)
for
ipsf
in
range
(
npsfX
):
psfMatX
[
ipsf
,
:,
:]
=
PSFMat
[
neigh
[
ipsf
],
:,
:]
cen_colX
[
ipsf
]
=
cen_col
[
neigh
[
ipsf
]]
cen_rowX
[
ipsf
]
=
cen_row
[
neigh
[
ipsf
]]
psfMaker
=
np
.
zeros
((
ngy
,
ngx
),
dtype
=
'float64'
)
if
OnlyNeighbors
==
True
:
PCAbasef
,
PCAcoeff
=
psfPCA_generator
(
psfMatX
,
npsfX
,
ngx
,
libPCApath
)
nPCA
=
npsfX
for
iPCA
in
range
(
nPCA
):
coeffX
=
fitPoly
(
ref_col
,
ref_row
,
cen_colX
,
cen_rowX
,
PCAcoeff
[:,
iPCA
],
order
=
2
)
psfMaker
+=
coeffX
*
PCAbasef
[
iPCA
,
:,
:]
return
psfMaker
def
psfPCA_generator
(
psfMat
,
npsf
,
npix
,
libPCApath
):
"""
generate PCs from psfMat
Parameters:
Returns:
"""
libPCA
=
ctypes
.
CDLL
(
libPCApath
)
# CDLL加载库
libPCA
.
psfPCA
.
argtypes
=
[
ctypes
.
POINTER
(
ctypes
.
c_float
),
ctypes
.
c_int
,
ctypes
.
c_int
,
ctypes
.
POINTER
(
ctypes
.
c_double
),
ctypes
.
POINTER
(
ctypes
.
c_double
)]
Nstar
=
npsf
Mp
=
npix
*
npix
NM
=
Nstar
*
Mp
NN
=
Nstar
*
Nstar
arr
=
(
ctypes
.
c_float
*
NM
)()
basef
=
(
ctypes
.
c_double
*
NM
)()
coeff
=
(
ctypes
.
c_double
*
NN
)()
psfT
=
np
.
zeros
(
NM
)
for
ipsf
in
range
(
npsf
):
lp
=
0
+
ipsf
*
Mp
up
=
Mp
+
ipsf
*
Mp
ipsfMat
=
psfMat
[
ipsf
,
:,
:]
psfT
[
lp
:
up
]
=
ipsfMat
.
reshape
(
Mp
)
arr
[:]
=
psfT
libPCA
.
psfPCA
(
arr
,
Nstar
,
Mp
,
basef
,
coeff
)
PCAbasef
=
np
.
zeros
([
npsf
,
npix
,
npix
])
PCAcoeff
=
np
.
zeros
([
npsf
,
npsf
])
for
ipsf
in
range
(
npsf
):
lp
=
0
+
ipsf
*
Mp
up
=
Mp
+
ipsf
*
Mp
PCAbasef
[
ipsf
,
:,
:]
=
np
.
array
(
basef
[
lp
:
up
]).
reshape
(
npix
,
npix
)
lp
=
0
+
ipsf
*
npsf
up
=
npsf
+
ipsf
*
npsf
PCAcoeff
[
ipsf
,
:]
=
np
.
array
(
coeff
[
lp
:
up
])
return
PCAbasef
,
PCAcoeff
def
fitPoly
(
px
,
py
,
datax
,
datay
,
dataz
,
order
=
2
):
if
order
==
1
:
# best-fit linear plane
A
=
np
.
c_
[
datax
,
datay
,
np
.
ones
(
datax
.
shape
[
0
])]
C
,
_
,
_
,
_
=
scipy
.
linalg
.
lstsq
(
A
,
dataz
)
# coefficients
pz
=
C
[
0
]
*
px
+
C
[
1
]
*
py
+
C
[
2
]
elif
order
==
2
:
# best-fit quadratic curve
A
=
np
.
c_
[
np
.
ones
(
datax
.
shape
[
0
]),
np
.
c_
[
datax
,
datay
],
np
.
prod
(
np
.
c_
[
datax
,
datay
],
axis
=
1
),
np
.
c_
[
datax
,
datay
]
**
2
]
C
,
_
,
_
,
_
=
scipy
.
linalg
.
lstsq
(
A
,
dataz
)
pz
=
np
.
dot
(
np
.
c_
[
1
,
px
,
py
,
px
*
py
,
px
**
2
,
py
**
2
],
C
)
"""
elif order == 3:
# best-fit cubic curve
A = np.c_[np.ones(datax.shape[0]), np.c_[datax, datay], np.prod(np.c_[datax, datay], axis=1), np.c_[datax, datay]**2, np.c_[datax, datay]**3]
C,_,_,_ = scipy.linalg.lstsq(A, dataz)
pz = np.dot(np.c_[1, px, py, px*py, px**2, py**2, px**3, py**3], C)
"""
return
pz
"""
############################
### not used temporarily ###
############################
def psfSplineMake(px, py, PSFMat, cen_col, cen_row, OnlyNeighbors=False):
minimum_psf_weight = 1e-8
ref_col = px
ref_row = py
cdelt1p = 1
cdelt2p = 1
ngy, ngx = PSFMat[0, :, :].shape
psfx = np.linspace(0, ngx-1, ngx)
psfy = np.linspace(0, ngy-1, ngy)
npsf = PSFMat[:, :, :].shape[0]
psfWeight = np.zeros([npsf])
for ipsf in range(npsf):
psfWeight[ipsf] = np.sqrt((ref_col - cen_col[ipsf])**2 + (ref_row - cen_row[ipsf])**2)
psfWeight[ipsf] = max(psfWeight[ipsf], minimum_psf_weight)
psfWeight[ipsf] = 1./psfWeight[ipsf]
psfWeight /= np.sum(psfWeight)
psf = np.zeros((ngy, ngx), dtype='float64')
for ipsf in range(npsf):
iPSFMat = PSFMat[ipsf, :, :]
ipsfWeight = psfWeight[ipsf]
psf += iPSFMat * ipsfWeight
psf /= (np.nansum(psf) * cdelt1p * cdelt2p)
psfSpline = RectBivariateSpline(psfy, psfx, psf)
return psf, psfSpline
def psfToImage(psfSpline, cutoff_radius=180):
ng = 180
img = np.zeros([ng, ng], dtype='float64')
for i in range(ng):
for j in range(ng):
star_row = 5
star_column = 5
if np.sqrt((j-star_column)**2 + (i-star_row)**2) <= cutoff_radius:
star_flux = 8
column_cen = j #j - star_column
row_cen = i #i - star_row
img[i,j] += star_flux * psfSpline.integral(row_cen-0.5, row_cen+0.5, column_cen-0.5, column_cen+0.5)
return img
"""
##################################################
# C. csstPSF class #
##################################################
class
PSFimg
(
object
):
def
__init__
(
self
,
iccd
,
iwave
,
psfPath
):
self
.
iccd
=
iccd
self
.
iwave
=
iwave
self
.
psfPath
=
psfPath
#loading psfSet >>>
"""
psfSet = []
for ipsf in range(1, 901):
psfInfo = LoadPSF(iccd, iwave, ipsf, psfPath, CalcPSFsize=True, CalcPSFcenter=True, SigRange=False)
psfSet.append(psfInfo)
self.psfSet = psfSet
"""
a
,
b
,
c
=
psfMatLoad
(
iccd
,
iwave
,
psfPath
)
self
.
psfMat
=
a
self
.
cenPosx
=
b
self
.
cenPosy
=
c
def
PSFinplace
(
self
,
px
,
py
,
interpScheme
=
1
):
if
interpScheme
==
1
:
idwIndx
=
2
psf
=
psfMaker_IDW
(
px
,
py
,
self
.
psfMat
,
self
.
cenPosx
,
self
.
cenPosy
,
IDWindex
=
idwIndx
,
OnlyNeighbors
=
True
)
if
interpScheme
==
2
:
libPCA
=
"/Users/chengliangwei/Desktop/csstPSF/libPCA/libPCA.so"
psf
=
psfMaker_PCA
(
px
,
py
,
self
.
psfMat
,
self
.
cenPosx
,
self
.
cenPosy
,
OnlyNeighbors
=
True
,
libPCApath
=
libPCA
)
img
=
galsim
.
ImageF
(
psf
,
scale
=
0.074
/
2
)
xpsf
=
galsim
.
InterpolatedImage
(
img
)
return
xpsf
"""
def gcPlot(self, psf,pscale=0.074,figout="GC.png"):
size = np.size(psf,axis=0)
cxy = 0.5*(size-1)
width = 0.5*size
# log scale
radius = np.arange(np.log10(0.2),np.log10(width),0.01)
radius = 10.0**radius
nr = len(radius)
gc = []
for i in range(nr):
iflux, iferr, xflag = sep.sum_circle(psf,cxy,cxy,radius[i],subpix=0)
gc += [iflux.tolist()]
# Estimate the radius for a given flux ratio
fratio = 0.8
mid = [i for i in range(nr) if gc[i]<=fratio and gc[i+1]>fratio][0]
r0, r1 = radius[mid], radius[mid+1]
gc0, gc1 = gc[mid], gc[mid+1]
r5 = (fratio-gc0)/(gc1-gc0)*(r1-r0) + r0
hlf = r5*pscale
# plot
pfit = interp1d(radius, gc, kind='cubic')
fig = pl.figure(figsize=(5.5,4.0))
ax = fig.add_axes([0.16,0.15,0.80,0.81])
ax.plot(radius*pscale, pfit(radius), "k", linewidth=2.0)
ax.plot(radius*pscale, gc, "*r", markersize=5.0,mec="r",alpha=0.3)
ax.plot([hlf,hlf],[0,fratio],"k",linewidth=2.5)
ax.plot([0,hlf],[fratio,fratio],"k",linewidth=2.5)
ax.text(radius[10]*pscale,0.6,"$r_{%.1f}$=%.2f
\"
"%(fratio,hlf))
ax.set_xlabel("Radius (arcsec)",fontsize=15)
ax.set_ylabel("Growth of Curve",fontsize=15)
ax.set_xscale("log")
ax.set_xlim(radius[0]*pscale,radius[-1]*pscale)
ax.set_ylim(0.0,1.0)
for tick in ax.xaxis.get_major_ticks(): tick.label.set_fontsize(15)
for tick in ax.yaxis.get_major_ticks(): tick.label.set_fontsize(15)
pl.savefig(figout)
pl.clf()
pl.close()
return
"""
def
PSFspin
(
self
,
psf
,
sigSpin
,
sigGauss
,
dx
,
dy
):
"""
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
=
sigGauss
*
0.107
*
(
1000.0
/
10.0
)
# in unit of [pixels]
rc
=
np
.
sqrt
(
dx
*
dx
+
dy
*
dy
)
cpix
=
rc
*
(
sigSpin
*
a2Rad
)
beta
=
(
np
.
arctan2
(
dy
,
dx
)
+
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
psf
.
shear
(
PSFshear
),
PSFshear
(
base
)
##################################################
# D. TEST #
##################################################
def
psfMaker_IDW_test
(
tpsf
,
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
IDWindex
=
2
,
OnlyNeighbors
=
False
):
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
:
neigh
=
findNeighbors
(
px
,
py
,
cen_col
,
cen_row
,
dr
=
0.1
,
dn
=
9
,
OnlyDistance
=
False
)
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
=
'float64'
)
for
ipsf
in
range
(
npsf
):
"""
if OnlyNeighbors == True:
iy, ix = np.unravel_index(ipsf, (10,10))
ty, tx = np.unravel_index(tpsf, (10,10))
if np.abs(iy - ty) > 1 or np.abs(ix - tx) > 1:
continue
"""
if
OnlyNeighbors
==
True
:
if
neighFlag
[
ipsf
]
!=
1
:
continue
if
ipsf
==
tpsf
:
continue
iPSFMat
=
PSFMat
[
ipsf
,
:,
:].
copy
()
iPSFMat
=
psfCentering
(
iPSFMat
,
CenteringMode
=
1
)
ipsfWeight
=
psfWeight
[
ipsf
]
psfMaker
+=
iPSFMat
*
ipsfWeight
psfMaker
/=
np
.
nansum
(
psfMaker
)
return
psfMaker
def
psfMaker_PCA_test
(
tpsf
,
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
OnlyNeighbors
=
False
,
libPCApath
=
'libPCA/libPCA.so'
):
"""
psf interpolation by PCA
Parameters:
Returns:
"""
ref_col
=
px
ref_row
=
py
ngy
,
ngx
=
PSFMat
[
0
,
:,
:].
shape
npsf
=
PSFMat
[:,
:,
:].
shape
[
0
]
neigh
=
findNeighbors
(
px
,
py
,
cen_col
,
cen_row
,
dr
=
0.3
,
dn
=
9
,
OnlyDistance
=
False
)
npsfX
=
len
(
neigh
)
#去掉tpsf,neigh中排在第一个是最近的psf
print
(
"CHECK:::"
,
cen_col
[
neigh
[
0
]],
cen_row
[
neigh
[
0
]],
cen_col
[
tpsf
],
cen_row
[
tpsf
],
cen_col
[
neigh
[
0
]]
-
cen_col
[
tpsf
],
cen_row
[
neigh
[
0
]]
-
cen_row
[
tpsf
])
psfMatX
=
np
.
zeros
([
npsfX
-
1
,
ngy
,
ngx
])
cen_colX
=
np
.
zeros
(
npsfX
-
1
)
cen_rowX
=
np
.
zeros
(
npsfX
-
1
)
for
ipsf
in
range
(
npsfX
):
if
ipsf
==
0
:
continue
psfMatX
[
ipsf
-
1
,
:,
:]
=
PSFMat
[
neigh
[
ipsf
],
:,
:]
cen_colX
[
ipsf
-
1
]
=
cen_col
[
neigh
[
ipsf
]]
cen_rowX
[
ipsf
-
1
]
=
cen_row
[
neigh
[
ipsf
]]
psfMaker
=
np
.
zeros
((
ngy
,
ngx
),
dtype
=
'float64'
)
if
OnlyNeighbors
==
True
:
PCAbasef
,
PCAcoeff
=
psfPCA_generator
(
psfMatX
,
npsfX
-
1
,
ngx
,
libPCApath
)
nPCA
=
npsfX
-
1
for
iPCA
in
range
(
nPCA
):
coeffX
=
fitPoly
(
ref_col
,
ref_row
,
cen_colX
,
cen_rowX
,
PCAcoeff
[:,
iPCA
],
order
=
2
)
psfMaker
+=
coeffX
*
PCAbasef
[
iPCA
,
:,
:]
return
psfMaker
def
test_loadPSF
():
iccd
=
1
#[1, 30]
iwave
=
1
#[1, 4]
ipsf
=
1
#[1, 100]
psfPath
=
'/Users/chengliangwei/csstPSFdata/CSSOS_psf_ciomp'
psfSet
=
[]
for
ipsf
in
range
(
1
,
901
):
psfInfo
=
LoadPSF
(
iccd
,
iwave
,
ipsf
,
psfPath
,
CalcPSFsize
=
True
,
CalcPSFcenter
=
True
,
SigRange
=
False
)
psfSet
.
append
(
psfInfo
)
print
(
'psfSet has been loaded.'
)
print
(
'Usage: psfSet[i][keys]'
)
print
(
'psfSet.keys:'
,
psfSet
[
0
].
keys
())
return
psfSet
def
test_psfPCA
():
#load psf
print
(
'load psf...'
)
psfSet
=
test_loadPSF
()
#set input for psfPCA calc.
print
(
'PCA calc...'
)
npsf
=
5
npix
=
180
psfMat
=
np
.
zeros
([
npsf
,
npix
,
npix
])
libPCApath
=
'./libPCA/libPCA.so'
for
ipsf
in
range
(
5
):
psfMat
[
ipsf
,
:,
:]
=
psfSet
[
ipsf
][
'psfMat'
]
PCAbasef
,
PCAcoeff
=
psfPCA_generator
(
psfMat
,
npsf
,
npix
,
libPCApath
)
#plot check
print
(
'plot...'
)
fig
=
plt
.
figure
(
figsize
=
(
20
,
10
))
cc
=
90
dcc
=
15
ax
=
plt
.
subplot
(
2
,
4
,
1
)
plt
.
imshow
(
PCAbasef
[
0
,
:,
:][
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
ax
=
plt
.
subplot
(
2
,
4
,
2
)
plt
.
imshow
(
PCAbasef
[
1
,
:,
:][
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
ax
=
plt
.
subplot
(
2
,
4
,
3
)
plt
.
imshow
(
PCAbasef
[
2
,
:,
:][
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
ax
=
plt
.
subplot
(
2
,
4
,
4
)
plt
.
imshow
(
PCAbasef
[
3
,
:,
:][
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
ax
=
plt
.
subplot
(
2
,
4
,
5
)
plt
.
imshow
(
PCAbasef
[
4
,
:,
:][
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
ax
=
plt
.
subplot
(
2
,
4
,
6
)
ipsf
=
1
im
=
PCAcoeff
[
ipsf
,
0
]
*
PCAbasef
[
0
,
:,
:]
im
+=
PCAcoeff
[
ipsf
,
1
]
*
PCAbasef
[
1
,
:,
:]
im
+=
PCAcoeff
[
ipsf
,
2
]
*
PCAbasef
[
2
,
:,
:]
im
+=
PCAcoeff
[
ipsf
,
3
]
*
PCAbasef
[
3
,
:,
:]
im
+=
PCAcoeff
[
ipsf
,
4
]
*
PCAbasef
[
4
,
:,
:]
plt
.
imshow
(
im
[
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
plt
.
colorbar
()
ax
=
plt
.
subplot
(
2
,
4
,
8
)
plt
.
imshow
(
psfMat
[
ipsf
,:,:][
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
plt
.
colorbar
()
ax
=
plt
.
subplot
(
2
,
4
,
7
)
plt
.
imshow
((
psfMat
[
ipsf
,:,:]
-
im
)[
cc
-
dcc
:
cc
+
dcc
,
cc
-
dcc
:
cc
+
dcc
],
origin
=
'lower'
)
plt
.
colorbar
()
plt
.
show
()
def
test_fitPoly
():
datax
=
np
.
random
.
random
(
10
)
datay
=
np
.
random
.
random
(
10
)
*
2
dataz
=
datay
**
2
+
datay
*
datax
+
10
*
datay
**
2
px
=
0.28
py
=
10.34
pz
=
fitPoly
(
px
,
py
,
datax
,
datay
,
dataz
,
order
=
2
)
print
(
'check: pz-out:'
,
pz
,
'pz-in'
,
py
**
2
+
px
*
py
+
10
*
py
**
2
)
##################################################
# __main__ #
##################################################
if
__name__
==
'__main__'
:
print
(
'PSF modules for csst-imgsim'
)
#test_loadPSF()
#test_psfPCA()
test_fitPoly
()
ObservationSim/PSF/PSFInterp_deprecated/testPlot.pdf
deleted
100644 → 0
View file @
e82a5dcc
File deleted
ObservationSim/PSF/PSFInterp_deprecated/test_PSFConvolve.py
deleted
100644 → 0
View file @
e82a5dcc
import
numpy
as
np
import
matplotlib.pyplot
as
plt
import
scipy.io
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
photonEnergy
(
lambd
):
nu
=
vc_A
/
lambd
eph
=
h_Plank
*
nu
return
eph
pixSize
=
0.037
mag_star
=
15.
Nx
=
256
Ny
=
256
###加载PSF信息###
def
LoadPSF
(
iccd
,
iwave
,
ipsf
,
psfPath
,
psfSampleSize
=
5
,
PSFCentroidWgt
=
False
):
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'
]
return
psfInfo
def
psfCentering
(
img
,
apSizeInArcsec
=
0.5
,
psfSampleSizeInMicrons
=
5
,
focalLengthInMeters
=
28
,
CenteringMode
=
1
):
imgMaxPix_x
,
imgMaxPix_y
=
findMaxPix
(
img
)
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
def
findMaxPix
(
img
):
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
def
magToFlux
(
mag
):
flux
=
10
**
(
-
0.4
*
(
mag
+
48.6
))
return
flux
def
getElectronFluxFilt
(
mag
,
exptime
=
150.
):
pE
=
photonEnergy
(
lambd
=
6199.8
)
flux
=
magToFlux
(
mag
)
factor
=
1.0e4
*
flux
/
pE
*
vc_A
*
(
1.0
/
5370.0
-
1.0
/
7030.0
)
return
factor
*
0.5040
*
np
.
pi
*
(
0.5
*
2.0
)
**
2
*
exptime
def
radial_profile
(
img
,
cx
,
cy
,
nbins
=
100
,
Rmin
=
16
,
Rmax
=
128
):
nx
=
img
.
shape
[
0
]
ny
=
img
.
shape
[
1
]
x
=
np
.
arange
(
0
,
img
.
shape
[
0
],
1
)
y
=
np
.
arange
(
0
,
img
.
shape
[
1
],
1
)
xx
,
yy
=
np
.
meshgrid
(
x
,
y
)
dist
=
np
.
sqrt
((
xx
-
cx
)
**
2
+
(
yy
-
cy
)
**
2
)
img_flat
=
img
.
flatten
()
dist_flat
=
dist
.
flatten
()
a
,
bins
=
np
.
histogram
(
dist_flat
,
range
=
(
Rmin
,
Rmax
),
bins
=
nbins
,
weights
=
img_flat
)
b
,
bins
=
np
.
histogram
(
dist_flat
,
range
=
(
Rmin
,
Rmax
),
bins
=
nbins
)
b
[
b
==
0
]
=
1.
mid
=
(
bins
[
0
:
-
1
]
+
bins
[
1
:])
/
2.
return
a
/
b
,
mid
if
__name__
==
'__main__'
:
iccd
=
1
iwave
=
1
ipsf
=
1
psfPath
=
'/data/simudata/CSSOSDataProductsSims/data/csstPSFdata/CSSOS_psf_ciomp_30X30'
psfInfo
=
LoadPSF
(
iccd
,
iwave
,
ipsf
,
psfPath
,
psfSampleSize
=
5
,
PSFCentroidWgt
=
False
)
ipsfMat
=
psfInfo
[
'psfMat'
]
print
(
ipsfMat
[
0
:
100
,
0
:
100
])
cgrid
=
128
dgrid
=
15
cx
=
int
(
Nx
/
2
)
cy
=
int
(
Ny
/
2
)
with
np
.
printoptions
(
precision
=
5
,
suppress
=
True
):
fig
=
plt
.
figure
(
figsize
=
(
18
,
12
))
ax
=
plt
.
subplot
(
2
,
2
,
1
)
plt
.
imshow
(
ipsfMat
[
cgrid
-
dgrid
:
cgrid
+
dgrid
,
cgrid
-
dgrid
:
cgrid
+
dgrid
],
origin
=
'lower'
)
plt
.
annotate
(
'originalPSF'
,
[
0.1
,
0.85
],
xycoords
=
'axes fraction'
,
color
=
'w'
)
ax
=
plt
.
subplot
(
2
,
2
,
2
)
img
=
galsim
.
ImageF
(
ncol
=
Nx
,
nrow
=
Ny
,
scale
=
pixSize
)
psf_img
=
galsim
.
ImageF
(
ipsfMat
,
scale
=
pixSize
)
psf
=
galsim
.
InterpolatedImage
(
psf_img
)
psf_list
=
[
psf
]
*
4
mag_star
=
15
nphotons_tot
=
getElectronFluxFilt
(
mag
=
mag_star
)
print
(
nphotons_tot
)
for
i
in
range
(
4
):
nphotons
=
nphotons_tot
/
4.
# star = galsim.Gaussian(sigma=1.e-8, flux=1.)
star
=
galsim
.
DeltaFunction
()
star
=
star
.
withFlux
(
nphotons
)
star
=
galsim
.
Convolve
(
psf_list
[
i
],
star
)
img
=
star
.
drawImage
(
image
=
img
,
method
=
'phot'
,
center
=
galsim
.
PositionD
(
cx
,
cy
),
add_to_image
=
True
)
print
(
img
.
array
.
shape
)
plt
.
imshow
(
img
.
array
[
cx
-
dgrid
:
cx
+
dgrid
,
cy
-
dgrid
:
cy
+
dgrid
],
origin
=
'lower'
)
plt
.
annotate
(
'photon shooting 4 times'
,
[
0.1
,
0.85
],
xycoords
=
'axes fraction'
,
color
=
'w'
)
plt
.
colorbar
()
ax
=
plt
.
subplot
(
2
,
2
,
3
)
val
,
bins
=
radial_profile
(
img
=
img
.
array
,
cx
=
cx
,
cy
=
cy
,
nbins
=
100
,
Rmax
=
cx
)
# plt.hist(val, bins=bins)
plt
.
plot
(
bins
,
val
,
label
=
'mag=%d'
%
(
mag_star
))
img
=
galsim
.
ImageF
(
ncol
=
Nx
,
nrow
=
Ny
,
scale
=
pixSize
)
psf_img
=
galsim
.
ImageF
(
ipsfMat
,
scale
=
pixSize
)
psf
=
galsim
.
InterpolatedImage
(
psf_img
)
psf_list
=
[
psf
]
*
4
mag_star
=
13
nphotons_tot
=
getElectronFluxFilt
(
mag
=
mag_star
)
print
(
nphotons_tot
)
for
i
in
range
(
4
):
nphotons
=
nphotons_tot
/
4.
# star = galsim.Gaussian(sigma=1.e-8, flux=1.)
star
=
galsim
.
DeltaFunction
()
star
=
star
.
withFlux
(
nphotons
)
star
=
galsim
.
Convolve
(
psf_list
[
i
],
star
)
img
=
star
.
drawImage
(
image
=
img
,
method
=
'phot'
,
center
=
galsim
.
PositionD
(
cx
,
cy
),
add_to_image
=
True
)
print
(
img
.
array
.
shape
)
val
,
bins
=
radial_profile
(
img
=
img
.
array
,
cx
=
cx
,
cy
=
cy
,
nbins
=
100
,
Rmax
=
cx
)
# plt.hist(val, bins=bins)
plt
.
plot
(
bins
,
val
,
label
=
'mag=%d'
%
(
mag_star
))
plt
.
legend
(
loc
=
'upper right'
,
fancybox
=
True
)
plt
.
xlabel
(
"R [pix]"
,
size
=
'x-large'
)
plt
.
ylabel
(
"photon count"
,
size
=
'x-large'
)
plt
.
ylim
([
0
,
500
])
# print(img.array[0:100,0:100])
#psf Convolve galsim.DeltaFunction
#photon shooting ?
#plot image?
# ax = plt.subplot(2,2,2)
# plt.imshow(ipsfMat[cgrid-dgrid:cgrid+dgrid, cgrid-dgrid:cgrid+dgrid], origin='lower')
# plt.annotate('originalPSF', [0.1, 0.85], xycoords='axes fraction', color='w')
# ax = plt.subplot(2,2,4)
# img = galsim.ImageF(ncol=Nx, nrow=Ny, scale=pixSize)
# psf_img = galsim.ImageF(ipsfMat, scale=pixSize)
# psf = galsim.InterpolatedImage(psf_img)
# psf_list = [psf] * 4
# nphotons_tot = getElectronFluxFilt(mag=mag_star)
# print(nphotons_tot)
# obj_list = []
# for i in range(4):
# nphotons = nphotons_tot / 4.
# # star = galsim.Gaussian(sigma=1.e-8, flux=1.)
# star = galsim.DeltaFunction()
# star = star.withFlux(nphotons)
# star = galsim.Convolve(psf_list[i], star)
# obj_list.append(star)
# star = galsim.Sum(obj_list)
# img = star.drawImage(image=img, method='phot', center=galsim.PositionD(cx, cy), add_to_image=True)
# plt.annotate('photon shooting once', [0.1, 0.85], xycoords='axes fraction', color='w')
# print(img.array.shape)
# plt.imshow(img.array[cx-dgrid:cx+dgrid, cy-dgrid:cy+dgrid], origin='lower')
# plt.colorbar()
# print(img.array[0:100,0:100])
# ax = plt.subplot(2,3,2)
# imy = psfCentering(ipsfMat, apSizeInArcsec=2.0)
# plt.imshow(imy[cgrid-dgrid:cgrid+dgrid, cgrid-dgrid:cgrid+dgrid], origin='lower')
# plt.annotate('PSFCentroidOld', [0.1, 0.85], xycoords='axes fraction', color='w')
# ax = plt.subplot(2,3,5)
# #psf Convolve galsim.DeltaFunction
# #photon shooting ?
# #plot image?
# ax = plt.subplot(2,3,3)
# psfInfo= LoadPSF(iccd, iwave, ipsf, psfPath, psfSampleSize=5, PSFCentroidWgt=True)
# ipsfMat = psfInfo['psfMat']
# # print(ipsfMat[0:100,0:100])
# plt.imshow(ipsfMat[cgrid-dgrid:cgrid+dgrid, cgrid-dgrid:cgrid+dgrid], origin='lower')
# plt.annotate('PSFCentroidNew', [0.1, 0.85], xycoords='axes fraction', color='w')
# ax = plt.subplot(2,3,6)
# #psf Convolve galsim.DeltaFunction
# #photon shooting ?
# #plot image?
plt
.
savefig
(
'testPlot.pdf'
)
ObservationSim/run.pbs
View file @
883b7a77
...
...
@@ -16,8 +16,4 @@ NP=40
date
echo
$NP
# mpirun -np $NP --oversubscribe -H comput101 python /public/home/fangyuedong/CSST/ObservationSim/runExposure.py
# python /public/home/fangyuedong/sim_code_release/CSSTSim/ObservationSim/preprocess.py
# mpirun -np $NP python /public/home/fangyuedong/sim_code_release/CSSTSim/ObservationSim/runExposure.py
mpirun
-np
$NP
python /public/home/fangyuedong/sim_code_release/CSSTSim/ObservationSim/runExposure.py config_sim.yaml
-c
/public/home/fangyuedong/sim_code_release/CSSTSim/config
mpirun
-np
$NP
python /public/home/fangyuedong/test_release/CSST/ObservationSim/runExposure.py config_sim.yaml
-c
/public/home/fangyuedong/test_release/CSST/config
config/config_sim.yaml
View file @
883b7a77
...
...
@@ -10,7 +10,7 @@
# Can add some of the command-line arguments here as well;
# OK to pass either way or both, as long as they are consistent
# work_dir: "/public/home/fangyuedong/sim_code_release/CSST/test/"
work_dir
:
"
/public/home/fangyuedong/
sim_code
_release/CSST
Sim
/workplace/"
work_dir
:
"
/public/home/fangyuedong/
test
_release/CSST/workplace/"
data_dir
:
"
/data/simudata/CSSOSDataProductsSims/data/"
run_name
:
"
TEST"
...
...
@@ -39,9 +39,9 @@ obs_setting:
# Options for survey types:
# "Photometric": simulate photometric chips only
# "Spectroscop
l
ic": simulate slitless spectroscopic chips only
# "Spectroscopic": simulate slitless spectroscopic chips only
# "All": simulate full focal plane
survey_type
:
"
Photometric
"
survey_type
:
"
All
"
# Exposure time [seconds]
exp_time
:
150.
...
...
@@ -61,15 +61,15 @@ obs_setting:
# Number of calibration pointings
# Note: only valid when a pointing list is specified
np_cal
:
1
np_cal
:
0
# (Optional) only run specific pointing(s).
# Note: only valid when a pointing list is specified
run_pointings
:
[
0
,
1
,
2
,
3
,
4
]
run_pointings
:
[
5
,
6
]
# (Optional) only run specific chip(s)
# Note: for all pointings
run_chips
:
[
6
,
25
]
#
run_chips: [6, 25]
###############################################
# Input path setting
...
...
@@ -116,7 +116,11 @@ psf_setting:
# path to PSF data
# NOTE: only valid for "Interp" PSF
psf_dir
:
"
csstPSFdata/CSSOS_psf_20210108/CSST_psf_ciomp_2p5um_cycle3_ccr90_proc"
psf_dir
:
"
csstPSFdata/CSSOS_psf_20210108/CSST_psf_ciomp_2p5um_cycle3_ccr90"
# path to field-distortion model
# Note: only valid when ins_effects: field_dist is "ON"
fd_path
:
"
FieldDistModelv2.0.pickle"
# sigma_spin: 0.0 # psf spin?
...
...
Prev
1
…
16
17
18
19
20
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