Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
csst-sims
csst_cpic_sim
Commits
849db78f
Commit
849db78f
authored
Apr 15, 2024
by
Chen Yili
Browse files
Upload New File
parent
9422bbd2
Changes
1
Hide whitespace changes
Inline
Side-by-side
CpicImgSim/optics.py
0 → 100644
View file @
849db78f
import
os
import
yaml
import
numpy
as
np
from
.config
import
cpism_refdata
,
which_focalplane
,
S
# S is synphot
from
.config
import
optics_config
from
.utils
import
region_replace
from
.io
import
log
FILTERS
=
{
"f565"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f565_total.fits"
),
"f661"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f661_total.fits"
),
"f743"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f743_total.fits"
),
"f883"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f883_total.fits"
),
"f940"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f940_total.fits"
),
"f1265"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f1265_total.fits"
),
"f1425"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f1425_total.fits"
),
"f1542"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f1542_total.fits"
),
"f860"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f860.fits"
),
"f850"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f850.fits"
),
"f725"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f725.fits"
),
"f720"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f725.fits"
),
"f520"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f520.fits"
),
"f662"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f662.fits"
),
"f729"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f729.fits"
),
"f825"
:
S
.
FileBandpass
(
f
"
{
cpism_refdata
}
/throughtput/f825.fits"
),
}
def
filter_throughput
(
filter_name
):
"""
Totally throughput of each CPIC band.
Including the throughput of the filter, telescope, cpic, and camera QE.
If the filter_name is not supported, return the throughput of the default filter(f661).
Parameters
-----------
filter_name: str
The name of the filter.
One of ['f565', 'f661'(default), 'f743', 'f883', 'f940', 'f1265', 'f1425', 'f1542']
Returns
--------
synphot.Bandpass
The throughput of the filter.
"""
filter_name
=
filter_name
.
lower
()
filter_name
=
"f661"
if
filter_name
==
"default"
else
filter_name
if
filter_name
not
in
FILTERS
.
keys
():
log
.
warning
(
f
"滤光片名称错误(
{
filter_name
}
),返回默认滤光片(f661)透过率"
)
filter_name
=
"f661"
return
FILTERS
[
filter_name
]
def
example_psf_func
(
band
,
spectrum
,
frame_size
,
error
=
0.1
):
"""
Example psf generating function.
Parameters
-------------
band: str
The name of the band.
spectrum: synphot.Spectrum or synphot.SourceSpectrum
The spectrum of the target.
frame_size: int
The size of the frame.
error: float
Phase RMS error.
Returns
---------------
2D array
psf image with shape of `frame_size`
"""
pass
def
make_focus_image
(
band
:
str
,
targets
:
list
,
psf_function
:
callable
,
init_shifts
:
list
=
[
0
,
0
],
rotation
:
float
=
0
,
platesize
:
list
=
[
1024
,
1024
],
)
->
np
.
ndarray
:
"""
Make the focus image of the targets.
Parameters
-----------
band: str
The name of the band.
targets: list
The list of the targets.
Each element of the list is a tuple of (x, y, spectrum).
- x, y: float
- The position of the target in the focal plane.
- spectrum: synphot.Spectrum or synphot.SourceSpectrum
- The spectrum of the target.
psf_function: callable
The function to generate the PSF, with same parameters and return as `example_psf_func`.
init_shifts: list
The initial shifts of the center targets. Unit: arcsec.
The default is [0, 0].
rotation: float
The rotation of the focal plane. Unit: degree.
The default is 0 degree.
platesize: list
The size of the focal plane. Unit: pixel.
The default is [1024, 1024].
Returns
--------
np.ndarray
The focus image of the targets.
2D array with the shape of platesize.
"""
config
=
optics_config
[
which_focalplane
(
band
)]
platescale
=
config
[
"platescale"
]
focal_image
=
np
.
zeros
(
platesize
)
if
not
targets
:
return
focal_image
def
rotate_and_shift
(
shift
):
rotation_rad
=
rotation
/
180
*
np
.
pi
return
np
.
array
(
[
shift
[
0
]
*
np
.
cos
(
rotation_rad
)
+
shift
[
1
]
*
np
.
sin
(
rotation_rad
),
-
shift
[
0
]
*
np
.
sin
(
rotation_rad
)
+
shift
[
1
]
*
np
.
cos
(
rotation_rad
),
]
)
+
np
.
array
(
init_shifts
)
cstar_x
,
cstar_y
,
cstar_spectrum
=
targets
[
0
]
cstar_shift
=
rotate_and_shift
([
cstar_x
,
cstar_y
])
/
platescale
error_value
=
0
# nm
cstar_psf
=
psf_function
(
band
,
cstar_spectrum
,
config
[
"cstar_frame_size"
],
error
=
error_value
)
platesize
=
np
.
array
(
platesize
)[::
-
1
]
psf_shape
=
np
.
array
(
cstar_psf
.
shape
)[::
-
1
]
cstar_shift
+=
(
platesize
-
1
)
/
2
-
(
psf_shape
-
1
)
/
2
focal_image
=
region_replace
(
focal_image
,
cstar_psf
,
cstar_shift
,
padded_in
=
False
,
padded_out
=
False
,
subpix
=
True
,
)
for
i_target
in
range
(
1
,
len
(
targets
)):
sub_x
,
sub_y
,
sub_spectrum
=
targets
[
i_target
]
pdout
=
False
if
i_target
==
len
(
targets
)
-
1
else
True
pdin
=
False
if
i_target
==
1
else
True
log
.
debug
(
f
"input target
{
sub_x
=
:}
,
{
sub_y
=
:}
"
)
sub_shift
=
rotate_and_shift
([
sub_x
,
sub_y
])
/
platescale
log
.
debug
(
f
"after rotate and shift
{
sub_shift
=
:}
"
)
sub_psf
=
psf_function
(
band
,
sub_spectrum
,
config
[
"substellar_frame_size"
],
error
=
error_value
)
psf_shape
=
np
.
array
(
sub_psf
.
shape
)[::
-
1
]
sub_shift
+=
(
platesize
-
1
)
/
2
-
(
psf_shape
-
1
)
/
2
log
.
debug
(
f
"input shift of region_replace:
{
sub_shift
=
:}
"
)
focal_image
=
region_replace
(
focal_image
,
sub_psf
,
sub_shift
,
padded_in
=
pdin
,
padded_out
=
pdout
,
subpix
=
True
,
)
return
focal_image
def
focal_mask
(
image
,
iwa
,
platescale
,
throughtput
=
1e-6
):
"""
Mask the image outside the inner working angle.
Parameters
-----------
image: np.ndarray
The image to be masked.
iwa: float
The inner working angle. Unit: arcsec.
platescale: float
The platescale of the image. Unit: arcsec/pixel.
throughtput: float
The throughtput of the mask. The default is 1e-6.
Returns
--------
np.ndarray
The masked image.
"""
xx
,
yy
=
np
.
mgrid
[
0
:
image
.
shape
[
0
],
0
:
image
.
shape
[
1
]]
center
=
np
.
array
([(
image
.
shape
[
0
]
-
1
)
/
2
,
(
image
.
shape
[
1
]
-
1
)
/
2
])
mask
=
(
abs
(
xx
-
center
[
0
])
<
iwa
/
platescale
)
|
(
abs
(
yy
-
center
[
1
])
<
iwa
/
platescale
)
image_out
=
image
.
copy
()
image_out
[
mask
]
*=
throughtput
return
image_out
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