Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
csst-sims
csst_msc_sim
Commits
36189a3e
Commit
36189a3e
authored
May 12, 2024
by
JX
😵
Browse files
Merge remote-tracking branch 'origin/develop'
parents
dd26d370
27646bc4
Pipeline
#4509
passed with stage
in 0 seconds
Changes
229
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
ObservationSim/Config/Header/ImageHeader_1.py
deleted
100644 → 0
View file @
dd26d370
"""
generate image header
"""
import
numpy
as
np
from
astropy.io
import
fits
import
astropy.wcs
as
pywcs
from
scipy
import
math
import
random
import
os
import
sys
def
chara2digit
(
char
):
""" Function to judge and convert characters to digitals
Parameters
----------
"""
try
:
float
(
char
)
# for int, long and float
except
ValueError
:
pass
return
char
else
:
data
=
float
(
char
)
return
data
def
read_header_parameter
(
filename
=
'global_header.param'
):
""" Function to read the header parameters
Parameters
----------
"""
name
=
[]
value
=
[]
description
=
[]
for
line
in
open
(
filename
):
line
=
line
.
strip
(
"
\n
"
)
arr
=
line
.
split
(
'|'
)
# csvReader = csv.reader(csvDataFile)
# for arr in csvReader:
name
.
append
(
arr
[
0
])
value
.
append
(
chara2digit
(
arr
[
1
]))
description
.
append
(
arr
[
2
])
# print(value)
return
name
,
value
,
description
def
rotate_CD_matrix
(
cd
,
pa_aper
):
"""Rotate CD matrix
Parameters
----------
cd: (2,2) array
CD matrix
pa_aper: float
Position angle, in degrees E from N, of y axis of the detector
Returns
-------
cd_rot: (2,2) array
Rotated CD matrix
Comments
--------
`astropy.wcs.WCS.rotateCD` doesn't work for non-square pixels in that it
doesn't preserve the pixel scale! The bug seems to come from the fact
that `rotateCD` assumes a transposed version of its own CD matrix.
"""
rad
=
np
.
deg2rad
(
-
pa_aper
)
mat
=
np
.
zeros
((
2
,
2
))
mat
[
0
,:]
=
np
.
array
([
np
.
cos
(
rad
),
-
np
.
sin
(
rad
)])
mat
[
1
,:]
=
np
.
array
([
np
.
sin
(
rad
),
np
.
cos
(
rad
)])
cd_rot
=
np
.
dot
(
mat
,
cd
)
return
cd_rot
def
Header_extention
(
xlen
=
9232
,
ylen
=
9216
,
gain
=
1.0
,
readout
=
5.0
,
dark
=
0.02
,
saturation
=
90000
,
row_num
=
1
,
col_num
=
1
):
""" Creat an image frame for CCST with multiple extensions
Parameters
----------
"""
flag_ltm_x
=
[
0
,
1
,
-
1
,
1
,
-
1
]
flag_ltm_y
=
[
0
,
1
,
1
,
-
1
,
-
1
]
flag_ltv_x
=
[
0
,
0
,
1
,
0
,
1
]
flag_ltv_y
=
[
0
,
0
,
0
,
1
,
1
]
detector_size_x
=
int
(
xlen
)
detector_size_y
=
int
(
ylen
)
data_x
=
str
(
int
(
detector_size_x
))
data_y
=
str
(
int
(
detector_size_y
))
data_sec
=
'[1:'
+
data_x
+
',1:'
+
data_y
+
']'
name
=
[]
value
=
[]
description
=
[]
for
k
in
range
(
1
,
2
):
# f = open("extension"+str(k)+"_image.param","w")
j
=
row_num
i
=
col_num
ccdnum
=
str
((
j
-
1
)
*
5
+
i
)
name
=
[
'EXTNAME'
,
'BSCALE'
,
'BZERO'
,
'OBSID'
,
'CCDNAME'
,
'AMPNAME'
,
'GAIN'
,
'RDNOISE'
,
'DARK'
,
'SATURATE'
,
'RSPEED'
,
'CHIPTEMP'
,
'CCDCHIP'
,
'DATASEC'
,
'CCDSUM'
,
'NSUM'
,
'LTM1_1'
,
'LTM2_2'
,
'LTV1'
,
'LTV2'
,
'ATM1_1'
,
'ATM2_2'
,
'ATV1'
,
'ATV2'
,
'DTV1'
,
'DTV2'
,
'DTM1_1'
,
'DTM2_2'
]
value
=
[
'IM'
+
str
(
k
),
1.0
,
0.0
,
'CSST.20200101T000000'
,
'ccd'
+
ccdnum
.
rjust
(
2
,
'0'
),
'ccd'
+
ccdnum
.
rjust
(
2
,
'0'
)
+
':'
+
str
(
k
),
gain
,
readout
,
dark
,
saturation
,
10.0
,
-
100.0
,
'ccd'
+
ccdnum
.
rjust
(
2
,
'0'
),
data_sec
,
'1 1'
,
'1 1'
,
flag_ltm_x
[
k
],
flag_ltm_y
[
k
],
flag_ltv_x
[
k
]
*
(
detector_size_x
-
20
*
2
+
1
),
flag_ltv_y
[
k
]
*
(
detector_size_y
+
1
),
flag_ltm_x
[
k
],
flag_ltm_y
[
k
],
flag_ltv_x
[
k
]
*
(
detector_size_x
-
20
*
2
+
1
),
flag_ltv_y
[
k
]
*
(
detector_size_y
+
1
),
0
,
0
,
1
,
1
]
description
=
[
'Extension name'
,
' '
,
' '
,
'Observation ID'
,
'CCD name'
,
'Amplifier name'
,
'Gain (e-/ADU)'
,
'Readout noise (e-/pixel)'
,
'Dark noise (e-/pixel/s)'
,
'Saturation (e-)'
,
'Read speed'
,
'Chip temperature'
,
'CCD chip ID'
,
'Data section'
,
'CCD pixel summing'
,
'CCD pixel summing'
,
'CCD to image transformation'
,
'CCD to image transformation'
,
'CCD to image transformation'
,
'CCD to image transformation'
,
'CCD to amplifier transformation'
,
'CCD to amplifier transformation'
,
'CCD to amplifier transformation'
,
'CCD to amplifier transformation'
,
'CCD to detector transformatio'
,
'CCD to detector transformatio'
,
'CCD to detector transformatio'
,
'CCD to detector transformatio'
]
return
name
,
value
,
description
##9232 9216 898 534 1309 60 -40 -23.4333
def
WCS_def
(
xlen
=
9232
,
ylen
=
9216
,
gapx
=
898.0
,
gapy1
=
534
,
gapy2
=
1309
,
ra
=
60
,
dec
=
-
40
,
pa
=
-
23.433
,
psize
=
0.074
,
row_num
=
1
,
col_num
=
1
):
""" Creat a wcs frame for CCST with multiple extensions
Parameters
----------
"""
flag_x
=
[
0
,
1
,
-
1
,
1
,
-
1
]
flag_y
=
[
0
,
1
,
1
,
-
1
,
-
1
]
flag_ext_x
=
[
0
,
-
1
,
1
,
-
1
,
1
]
flag_ext_y
=
[
0
,
-
1
,
-
1
,
1
,
1
]
x_num
=
5
y_num
=
6
detector_num
=
x_num
*
y_num
detector_size_x
=
xlen
detector_size_y
=
ylen
gap_x
=
gapx
gap_y
=
[
gapy1
,
gapy2
]
ra_ref
=
ra
dec_ref
=
dec
pa_aper
=
pa
pixel_size
=
psize
gap_y1_num
=
3
gap_y2_num
=
2
x_center
=
(
detector_size_x
*
x_num
+
gap_x
*
(
x_num
-
1
))
/
2
y_center
=
(
detector_size_y
*
y_num
+
gap_y
[
0
]
*
gap_y1_num
+
gap_y
[
1
]
*
gap_y2_num
)
/
2
gap_y_map
=
np
.
array
([[
0
,
0
,
0
,
0
,
0
],[
gap_y
[
0
],
gap_y
[
1
],
gap_y
[
1
],
gap_y
[
1
],
gap_y
[
1
]],[
gap_y
[
1
],
gap_y
[
0
],
gap_y
[
0
],
gap_y
[
0
],
gap_y
[
0
]],[
gap_y
[
0
],
gap_y
[
0
],
gap_y
[
0
],
gap_y
[
0
],
gap_y
[
0
]],[
gap_y
[
0
],
gap_y
[
0
],
gap_y
[
0
],
gap_y
[
0
],
gap_y
[
1
]],[
gap_y
[
1
],
gap_y
[
1
],
gap_y
[
1
],
gap_y
[
1
],
gap_y
[
0
]]])
frame_array
=
np
.
empty
((
5
,
6
),
dtype
=
np
.
float64
)
# print(x_center,y_center)
j
=
row_num
i
=
col_num
ccdnum
=
str
((
j
-
1
)
*
5
+
i
)
x_ref
,
y_ref
=
(
detector_size_x
+
gap_x
)
*
i
-
gap_x
-
detector_size_x
/
2
,
detector_size_y
*
j
+
sum
(
gap_y_map
[
0
:
j
,
i
-
1
])
-
detector_size_y
/
2
# print(i,j,x_ref,y_ref,ra_ref,dec_ref)
name
=
[]
value
=
[]
description
=
[]
for
k
in
range
(
1
,
2
):
cd
=
np
.
array
([[
pixel_size
,
0
],
[
0
,
pixel_size
]])
/
3600.
*
flag_x
[
k
]
cd_rot
=
rotate_CD_matrix
(
cd
,
pa_aper
)
# f = open("CCD"+ccdnum.rjust(2,'0')+"_extension"+str(k)+"_wcs.param","w")
name
=
[
'EQUINOX'
,
'WCSDIM'
,
'CTYPE1'
,
'CTYPE2'
,
'CRVAL1'
,
'CRVAL2'
,
'CRPIX1'
,
'CRPIX2'
,
'CD1_1'
,
'CD1_2'
,
'CD2_1'
,
'CD2_2'
]
value
=
[
2000.0
,
2.0
,
'RA---TAN'
,
'DEC--TAN'
,
ra_ref
,
dec_ref
,
flag_ext_x
[
k
]
*
((
x_ref
+
flag_ext_x
[
k
]
*
detector_size_x
/
2
)
-
x_center
),
flag_ext_y
[
k
]
*
((
y_ref
+
flag_ext_y
[
k
]
*
detector_size_y
/
2
)
-
y_center
),
cd_rot
[
0
,
0
],
cd_rot
[
0
,
1
],
cd_rot
[
1
,
0
],
cd_rot
[
1
,
1
]]
description
=
[
'Equinox of WCS'
,
'WCS Dimensionality'
,
'Coordinate type'
,
'Coordinate typ'
,
'Coordinate reference value'
,
'Coordinate reference value'
,
'Coordinate reference pixel'
,
'Coordinate reference pixel'
,
'Coordinate matrix'
,
'Coordinate matrix'
,
'Coordinate matrix'
,
'Coordinate matrix'
]
return
name
,
value
,
description
def
generatePrimaryHeader
(
xlen
=
9232
,
ylen
=
9216
,
pointNum
=
'1'
,
ra
=
60
,
dec
=
-
40
,
psize
=
0.074
,
row_num
=
1
,
col_num
=
1
):
# array_size1, array_size2, flux, sigma = int(argv[1]), int(argv[2]), 1000.0, 5.0
filerParm_fn
=
os
.
path
.
split
(
os
.
path
.
realpath
(
__file__
))[
0
]
+
'/filter.lst'
f
=
open
(
filerParm_fn
)
s
=
f
.
readline
()
s
=
s
.
strip
(
"
\n
"
)
filter
=
s
.
split
(
' '
)
k
=
(
row_num
-
1
)
*
5
+
col_num
ccdnum
=
str
(
k
)
g_header_fn
=
os
.
path
.
split
(
os
.
path
.
realpath
(
__file__
))[
0
]
+
'/global_header.param'
name
,
value
,
description
=
read_header_parameter
(
g_header_fn
)
h_prim
=
fits
.
Header
()
date
=
'200930'
time_obs
=
'120000'
for
i
in
range
(
len
(
name
)):
if
(
name
[
i
]
==
'FILTER'
):
value
[
i
]
=
filter
[
k
-
1
]
if
(
name
[
i
]
==
'FILENAME'
):
value
[
i
]
=
'CSST_'
+
date
+
'_'
+
time_obs
+
'_'
+
pointNum
.
rjust
(
6
,
'0'
)
+
'_'
+
ccdnum
.
rjust
(
2
,
'0'
)
+
'_raw'
if
(
name
[
i
]
==
'DETSIZE'
):
value
[
i
]
=
'[1:'
+
str
(
int
(
xlen
))
+
',1:'
+
str
(
int
(
ylen
))
+
']'
if
(
name
[
i
]
==
'PIXSCAL1'
):
value
[
i
]
=
str
(
psize
)
if
(
name
[
i
]
==
'PIXSCAL2'
):
value
[
i
]
=
str
(
psize
)
h_prim
[
name
[
i
]]
=
(
value
[
i
],
description
[
i
])
h_prim
.
add_comment
(
'=================================================================='
,
after
=
'FILETYPE'
)
h_prim
.
add_comment
(
'Target information'
)
h_prim
.
add_comment
(
'=================================================================='
)
h_prim
.
add_comment
(
'=================================================================='
,
after
=
'EQUINOX'
)
h_prim
.
add_comment
(
'Exposure information'
)
h_prim
.
add_comment
(
'=================================================================='
)
h_prim
.
add_comment
(
'=================================================================='
,
after
=
'MJDEND'
)
h_prim
.
add_comment
(
'Telescope information'
)
h_prim
.
add_comment
(
'=================================================================='
)
h_prim
.
add_comment
(
'=================================================================='
,
after
=
'REFFRAME'
)
h_prim
.
add_comment
(
'Detector information'
)
h_prim
.
add_comment
(
'=================================================================='
)
h_prim
.
add_comment
(
'=================================================================='
,
after
=
'FILTER'
)
h_prim
.
add_comment
(
'Other information'
)
h_prim
.
add_comment
(
'=================================================================='
)
return
h_prim
def
generateExtensionHeader
(
xlen
=
9232
,
ylen
=
9216
,
ra
=
60
,
dec
=
-
40
,
pa
=
-
23.433
,
gain
=
1.0
,
readout
=
5.0
,
dark
=
0.02
,
saturation
=
90000
,
psize
=
0.074
,
row_num
=
1
,
col_num
=
1
):
h_ext
=
fits
.
Header
()
for
i
in
range
(
1
,
2
):
# NAXIS1:Number of pixels per row; NAXIS2:Number of rows
h_ext
[
'NAXIS1'
]
=
xlen
h_ext
[
'NAXIS2'
]
=
ylen
name
,
value
,
description
=
Header_extention
(
xlen
=
xlen
,
ylen
=
ylen
,
gain
=
gain
,
readout
=
readout
,
dark
=
dark
,
saturation
=
saturation
,
row_num
=
row_num
,
col_num
=
col_num
)
for
j
in
range
(
len
(
name
)):
h_ext
[
name
[
j
]]
=
(
value
[
j
],
description
[
j
])
name
,
value
,
description
=
WCS_def
(
xlen
=
xlen
,
ylen
=
ylen
,
gapx
=
898.0
,
gapy1
=
534
,
gapy2
=
1309
,
ra
=
ra
,
dec
=
dec
,
pa
=
pa
,
psize
=
psize
,
row_num
=
row_num
,
col_num
=
col_num
)
for
j
in
range
(
len
(
name
)):
h_ext
[
name
[
j
]]
=
(
value
[
j
],
description
[
j
])
h_ext
.
add_comment
(
'=================================================================='
,
after
=
'OBSID'
)
h_ext
.
add_comment
(
'Readout information'
)
h_ext
.
add_comment
(
'=================================================================='
)
h_ext
.
add_comment
(
'=================================================================='
,
after
=
'CHIPTEMP'
)
h_ext
.
add_comment
(
'Chip information'
)
h_ext
.
add_comment
(
'=================================================================='
)
h_ext
.
add_comment
(
'=================================================================='
,
after
=
'DTM2_2'
)
h_ext
.
add_comment
(
'WCS information'
)
h_ext
.
add_comment
(
'=================================================================='
)
return
h_ext
def
main
(
argv
):
xlen
=
int
(
argv
[
1
])
ylen
=
int
(
argv
[
2
])
pointingNum
=
argv
[
3
]
ra
=
float
(
argv
[
4
])
dec
=
float
(
argv
[
5
])
pSize
=
float
(
argv
[
6
])
ccd_row_num
=
int
(
argv
[
7
])
ccd_col_num
=
int
(
argv
[
8
])
pa_aper
=
float
(
argv
[
9
])
gain
=
float
(
argv
[
10
])
readout
=
float
(
argv
[
11
])
dark
=
float
(
argv
[
12
])
fw
=
float
(
argv
[
13
])
h_prim
=
generatePrimaryHeader
(
xlen
=
xlen
,
ylen
=
ylen
,
ra
=
ra
,
dec
=
dec
,
psize
=
pSize
,
row_num
=
ccd_row_num
,
col_num
=
ccd_col_num
,
pointNum
=
pointingNum
)
h_ext
=
generateExtensionHeader
(
xlen
=
xlen
,
ylen
=
ylen
,
ra
=
ra
,
dec
=
dec
,
pa
=
pa_aper
,
gain
=
gain
,
readout
=
readout
,
dark
=
dark
,
saturation
=
fw
,
psize
=
pSize
,
row_num
=
ccd_row_num
,
col_num
=
ccd_col_num
)
hdu1
=
fits
.
PrimaryHDU
(
header
=
h_prim
)
hdu2
=
fits
.
ImageHDU
(
np
.
zeros
([
ylen
,
xlen
]),
header
=
h_ext
)
hdul
=
fits
.
HDUList
([
hdu1
,
hdu2
])
hdul
.
writeto
(
h_prim
[
'FILENAME'
]
+
'.fits'
,
output_verify
=
'ignore'
)
# if __name__ == "__main__":
# main(sys.argv)
ObservationSim/Instrument/Chip/Chip.py
deleted
100755 → 0
View file @
dd26d370
import
galsim
import
os
import
numpy
as
np
import
pickle
import
json
import
ObservationSim.Instrument._util
as
_util
from
astropy.table
import
Table
from
numpy.random
import
Generator
,
PCG64
from
astropy.io
import
fits
from
datetime
import
datetime
from
ObservationSim.Instrument.Chip
import
Effects
as
effects
from
ObservationSim.Instrument.FocalPlane
import
FocalPlane
from
ObservationSim.Config.Header
import
generatePrimaryHeader
,
generateExtensionHeader
from
ObservationSim.Instrument._util
import
rotate_conterclockwise
from
ObservationSim.Instrument.Chip
import
ChipUtils
as
chip_utils
from
ObservationSim.Instrument.Chip.libCTI.CTI_modeling
import
CTI_sim
try
:
import
importlib.resources
as
pkg_resources
except
ImportError
:
# Try backported to PY<37 'importlib_resources'
import
importlib_resources
as
pkg_resources
class
Chip
(
FocalPlane
):
def
__init__
(
self
,
chipID
,
ccdEffCurve_dir
=
None
,
CRdata_dir
=
None
,
sls_dir
=
None
,
config
=
None
,
treering_func
=
None
,
logger
=
None
):
# Get focal plane (instance of paraent class) info
super
().
__init__
()
self
.
nsecy
=
2
self
.
nsecx
=
8
self
.
gain_channel
=
np
.
ones
(
self
.
nsecy
*
self
.
nsecx
)
self
.
_set_attributes_from_config
(
config
)
self
.
logger
=
logger
# A chip ID must be assigned
self
.
chipID
=
int
(
chipID
)
self
.
chip_name
=
str
(
chipID
).
rjust
(
2
,
'0'
)
# Get corresponding filter info
self
.
filter_id
,
self
.
filter_type
=
self
.
getChipFilter
()
self
.
survey_type
=
self
.
_getSurveyType
()
if
self
.
filter_type
!=
"FGS"
:
self
.
_getChipRowCol
()
# Set the relavent specs for detectors
try
:
with
pkg_resources
.
files
(
'ObservationSim.Instrument.data.ccd'
).
joinpath
(
"chip_definition.json"
)
as
chip_definition
:
with
open
(
chip_definition
,
"r"
)
as
f
:
chip_dict
=
json
.
load
(
f
)[
str
(
self
.
chipID
)]
except
AttributeError
:
with
pkg_resources
.
path
(
'ObservationSim.Instrument.data.ccd'
,
"chip_definition.json"
)
as
chip_definition
:
with
open
(
chip_definition
,
"r"
)
as
f
:
chip_dict
=
json
.
load
(
f
)[
str
(
self
.
chipID
)]
for
key
in
chip_dict
:
setattr
(
self
,
key
,
chip_dict
[
key
])
self
.
fdModel
=
None
if
self
.
filter_type
==
"FGS"
:
fgs_name
=
self
.
chip_name
[
0
:
4
]
try
:
with
pkg_resources
.
files
(
'ObservationSim.Instrument.data.field_distortion'
).
joinpath
(
"FieldDistModelGlobal_pr4_%s.pickle"
%
(
fgs_name
.
lower
()))
as
field_distortion
:
with
open
(
field_distortion
,
"rb"
)
as
f
:
self
.
fdModel
=
pickle
.
load
(
f
)
except
AttributeError
:
with
pkg_resources
.
path
(
'ObservationSim.Instrument.data.field_distortion'
,
"FieldDistModelGlobal_pr4_%s.pickle"
%
(
fgs_name
.
lower
()))
as
field_distortion
:
with
open
(
field_distortion
,
"rb"
)
as
f
:
self
.
fdModel
=
pickle
.
load
(
f
)
else
:
# Get the corresponding field distortion model
try
:
with
pkg_resources
.
files
(
'ObservationSim.Instrument.data.field_distortion'
).
joinpath
(
"FieldDistModel_v2.0.pickle"
)
as
field_distortion
:
with
open
(
field_distortion
,
"rb"
)
as
f
:
self
.
fdModel
=
pickle
.
load
(
f
)
except
AttributeError
:
with
pkg_resources
.
path
(
'ObservationSim.Instrument.data.field_distortion'
,
"FieldDistModelGlobal_mainFP_v1.0.pickle"
)
as
field_distortion
:
with
open
(
field_distortion
,
"rb"
)
as
f
:
self
.
fdModel
=
pickle
.
load
(
f
)
# Get boundary (in pix)
self
.
bound
=
self
.
getChipLim
()
self
.
ccdEffCurve_dir
=
ccdEffCurve_dir
self
.
CRdata_dir
=
CRdata_dir
slsconfs
=
chip_utils
.
getChipSLSConf
(
chipID
=
self
.
chipID
)
if
np
.
size
(
slsconfs
)
==
1
:
try
:
with
pkg_resources
.
files
(
'ObservationSim.Instrument.data.sls_conf'
).
joinpath
(
slsconfs
)
as
conf_path
:
self
.
sls_conf
=
str
(
conf_path
)
except
AttributeError
:
with
pkg_resources
.
path
(
'ObservationSim.Instrument.data.sls_conf'
,
slsconfs
)
as
conf_path
:
self
.
sls_conf
=
str
(
conf_path
)
else
:
# self.sls_conf = [os.path.join(self.sls_dir, slsconfs[0]), os.path.join(self.sls_dir, slsconfs[1])]
self
.
sls_conf
=
[]
try
:
with
pkg_resources
.
files
(
'ObservationSim.Instrument.data.sls_conf'
).
joinpath
(
slsconfs
[
0
])
as
conf_path
:
self
.
sls_conf
.
append
(
str
(
conf_path
))
except
AttributeError
:
with
pkg_resources
.
path
(
'ObservationSim.Instrument.data.sls_conf'
,
slsconfs
[
0
])
as
conf_path
:
self
.
sls_conf
.
append
(
str
(
conf_path
))
try
:
with
pkg_resources
.
files
(
'ObservationSim.Instrument.data.sls_conf'
).
joinpath
(
slsconfs
[
1
])
as
conf_path
:
self
.
sls_conf
.
append
(
str
(
conf_path
))
except
AttributeError
:
with
pkg_resources
.
path
(
'ObservationSim.Instrument.data.sls_conf'
,
slsconfs
[
1
])
as
conf_path
:
self
.
sls_conf
.
append
(
str
(
conf_path
))
self
.
effCurve
=
self
.
_getChipEffCurve
(
self
.
filter_type
)
self
.
_getCRdata
()
# # Define the sensor model
self
.
sensor
=
galsim
.
Sensor
()
self
.
flat_cube
=
None
# for spectroscopic flat field cube simulation
def
_set_attributes_from_config
(
self
,
config
):
# Default setting
self
.
read_noise
=
5.0
# e/pix
self
.
dark_noise
=
0.02
# e/pix/s
self
.
rotate_angle
=
0.
self
.
overscan
=
1000
# Override default values
# for key in ["gain", "bias_level, dark_exptime", "flat_exptime", "readout_time", "full_well", "read_noise", "dark_noise", "overscan"]:
# if key in config["ins_effects"]:
# setattr(self, key, config["ins_effects"][key])
def
_getChipRowCol
(
self
):
self
.
rowID
,
self
.
colID
=
self
.
getChipRowCol
(
self
.
chipID
)
def
getChipRowCol
(
self
,
chipID
):
rowID
=
((
chipID
-
1
)
%
5
)
+
1
colID
=
6
-
((
chipID
-
1
)
//
5
)
return
rowID
,
colID
def
_getSurveyType
(
self
):
if
self
.
filter_type
in
_util
.
SPEC_FILTERS
:
return
"spectroscopic"
elif
self
.
filter_type
in
_util
.
PHOT_FILTERS
:
return
"photometric"
# elif self.filter_type in ["FGS"]:
# return "FGS"
def
_getChipEffCurve
(
self
,
filter_type
):
# CCD efficiency curves
if
filter_type
in
[
'NUV'
,
'u'
,
'GU'
]:
filename
=
'UV0.txt'
if
filter_type
in
[
'g'
,
'r'
,
'GV'
,
'FGS'
]:
# TODO, need to switch to the right efficiency curvey for FGS CMOS
filename
=
'Astro_MB.txt'
if
filter_type
in
[
'i'
,
'z'
,
'y'
,
'GI'
]:
filename
=
'Basic_NIR.txt'
try
:
with
pkg_resources
.
files
(
'ObservationSim.Instrument.data.ccd'
).
joinpath
(
filename
)
as
ccd_path
:
table
=
Table
.
read
(
ccd_path
,
format
=
'ascii'
)
except
AttributeError
:
with
pkg_resources
.
path
(
'ObservationSim.Instrument.data.ccd'
,
filename
)
as
ccd_path
:
table
=
Table
.
read
(
ccd_path
,
format
=
'ascii'
)
throughput
=
galsim
.
LookupTable
(
x
=
table
[
'col1'
],
f
=
table
[
'col2'
],
interpolant
=
'linear'
)
bandpass
=
galsim
.
Bandpass
(
throughput
,
wave_type
=
'nm'
)
return
bandpass
def
_getCRdata
(
self
):
try
:
with
pkg_resources
.
files
(
'ObservationSim.Instrument.data'
).
joinpath
(
"wfc-cr-attachpixel.dat"
)
as
cr_path
:
self
.
attachedSizes
=
np
.
loadtxt
(
cr_path
)
except
AttributeError
:
with
pkg_resources
.
path
(
'ObservationSim.Instrument.data'
,
"wfc-cr-attachpixel.dat"
)
as
cr_path
:
self
.
attachedSizes
=
np
.
loadtxt
(
cr_path
)
# def loadSLSFLATCUBE(self, flat_fn='flat_cube.fits'):
# try:
# with pkg_resources.files('ObservationSim.Instrument.data').joinpath(flat_fn) as data_path:
# flat_fits = fits.open(data_path, ignore_missing_simple=True)
# except AttributeError:
# with pkg_resources.path('ObservationSim.Instrument.data', flat_fn) as data_path:
# flat_fits = fits.open(data_path, ignore_missing_simple=True)
# fl = len(flat_fits)
# fl_sh = flat_fits[0].data.shape
# assert fl == 4, 'FLAT Field Cube is Not 4 layess!!!!!!!'
# self.flat_cube = np.zeros([fl, fl_sh[0], fl_sh[1]])
# for i in np.arange(0, fl, 1):
# self.flat_cube[i] = flat_fits[i].data
def
getChipFilter
(
self
,
chipID
=
None
):
"""Return the filter index and type for a given chip #(chipID)
"""
filter_type_list
=
_util
.
ALL_FILTERS
if
chipID
==
None
:
chipID
=
self
.
chipID
# updated configurations
if
chipID
>
42
or
chipID
<
1
:
raise
ValueError
(
"!!! Chip ID: [1,42]"
)
if
chipID
in
[
6
,
15
,
16
,
25
]:
filter_type
=
"y"
if
chipID
in
[
11
,
20
]:
filter_type
=
"z"
if
chipID
in
[
7
,
24
]:
filter_type
=
"i"
if
chipID
in
[
14
,
17
]:
filter_type
=
"u"
if
chipID
in
[
9
,
22
]:
filter_type
=
"r"
if
chipID
in
[
12
,
13
,
18
,
19
]:
filter_type
=
"NUV"
if
chipID
in
[
8
,
23
]:
filter_type
=
"g"
if
chipID
in
[
1
,
10
,
21
,
30
]:
filter_type
=
"GI"
if
chipID
in
[
2
,
5
,
26
,
29
]:
filter_type
=
"GV"
if
chipID
in
[
3
,
4
,
27
,
28
]:
filter_type
=
"GU"
if
chipID
in
range
(
31
,
43
):
filter_type
=
'FGS'
filter_id
=
filter_type_list
.
index
(
filter_type
)
return
filter_id
,
filter_type
def
getChipLim
(
self
,
chipID
=
None
):
"""Calculate the edges in pixel for a given CCD chip on the focal plane
NOTE: There are 5*4 CCD chips in the focus plane for photometric / spectroscopic observation.
Parameters:
chipID: int
the index of the chip
Returns:
A galsim BoundsD object
"""
xmin
,
xmax
,
ymin
,
ymax
=
1e10
,
-
1e10
,
1e10
,
-
1e10
xcen
=
self
.
x_cen
/
self
.
pix_size
ycen
=
self
.
y_cen
/
self
.
pix_size
sign_x
=
[
-
1.
,
1.
,
-
1.
,
1.
]
sign_y
=
[
-
1.
,
-
1.
,
1.
,
1.
]
for
i
in
range
(
4
):
x
=
xcen
+
sign_x
[
i
]
*
self
.
npix_x
/
2.
y
=
ycen
+
sign_y
[
i
]
*
self
.
npix_y
/
2.
x
,
y
=
_util
.
rotate_conterclockwise
(
x0
=
xcen
,
y0
=
ycen
,
x
=
x
,
y
=
y
,
angle
=
self
.
rotate_angle
)
xmin
,
xmax
=
min
(
xmin
,
x
),
max
(
xmax
,
x
)
ymin
,
ymax
=
min
(
ymin
,
y
),
max
(
ymax
,
y
)
return
galsim
.
BoundsD
(
xmin
,
xmax
,
ymin
,
ymax
)
def
getSkyCoverage
(
self
,
wcs
):
# print("In getSkyCoverage: xmin = %.3f, xmax = %.3f, ymin = %.3f, ymax = %.3f"%(self.bound.xmin, self.bound.xmax, self.bound.ymin, self.bound.ymax))
return
super
().
getSkyCoverage
(
wcs
,
self
.
bound
.
xmin
,
self
.
bound
.
xmax
,
self
.
bound
.
ymin
,
self
.
bound
.
ymax
)
def
getSkyCoverageEnlarged
(
self
,
wcs
,
margin
=
0.5
):
"""The enlarged sky coverage of the chip
"""
margin
/=
60.0
bound
=
self
.
getSkyCoverage
(
wcs
)
return
galsim
.
BoundsD
(
bound
.
xmin
-
margin
,
bound
.
xmax
+
margin
,
bound
.
ymin
-
margin
,
bound
.
ymax
+
margin
)
def
isContainObj
(
self
,
ra_obj
=
None
,
dec_obj
=
None
,
x_image
=
None
,
y_image
=
None
,
wcs
=
None
,
margin
=
1
):
# magin in number of pix
if
(
ra_obj
is
not
None
)
and
(
dec_obj
is
not
None
):
if
wcs
is
None
:
wcs
=
self
.
img
.
wcs
pos_obj
=
wcs
.
toImage
(
galsim
.
CelestialCoord
(
ra
=
ra_obj
*
galsim
.
degrees
,
dec
=
dec_obj
*
galsim
.
degrees
))
x_image
,
y_image
=
pos_obj
.
x
,
pos_obj
.
y
elif
(
x_image
is
None
)
or
(
y_image
is
None
):
raise
ValueError
(
"Either (ra_obj, dec_obj) or (x_image, y_image) should be given"
)
xmin
,
xmax
=
self
.
bound
.
xmin
-
margin
,
self
.
bound
.
xmax
+
margin
ymin
,
ymax
=
self
.
bound
.
ymin
-
margin
,
self
.
bound
.
ymax
+
margin
if
(
x_image
-
xmin
)
*
(
x_image
-
xmax
)
>
0.0
or
(
y_image
-
ymin
)
*
(
y_image
-
ymax
)
>
0.0
:
return
False
return
True
def
getChipNoise
(
self
,
exptime
=
150.0
):
noise
=
self
.
dark_noise
*
exptime
+
self
.
read_noise
**
2
return
noise
# def addEffects(self, config, img, chip_output, filt, ra_cen, dec_cen, img_rot, exptime=150., pointing_ID=0, timestamp_obs=1621915200, pointing_type='SCI', sky_map=None, post_flash_map=None, tel=None, logger=None):
# # Set random seeds
# SeedGainNonuni = int(config["random_seeds"]["seed_gainNonUniform"])
# SeedBiasNonuni = int(config["random_seeds"]["seed_biasNonUniform"])
# SeedRnNonuni = int(config["random_seeds"]["seed_rnNonUniform"])
# SeedBadColumns = int(config["random_seeds"]["seed_badcolumns"])
# SeedDefective = int(config["random_seeds"]["seed_defective"])
# SeedCosmicRay = int(config["random_seeds"]["seed_CR"])
# fullwell = int(self.full_well)
# if config["ins_effects"]["add_hotpixels"] == True:
# BoolHotPix = True
# else:
# BoolHotPix = False
# if config["ins_effects"]["add_deadpixels"] == True:
# BoolDeadPix = True
# else:
# BoolDeadPix = False
# self.logger = logger
# # Get Poisson noise generator
# rng_poisson, poisson_noise = chip_utils.get_poisson(
# seed=int(config["random_seeds"]["seed_poisson"]) + pointing_ID*30 + self.chipID, sky_level=0.)
# # Add sky background
# if config["ins_effects"]["add_back"] == True:
# img, sky_map = chip_utils.add_sky_background(
# img=img, filt=filt, exptime=exptime, sky_map=sky_map, tel=tel)
# del sky_map
# # Apply flat-field large scale structure for one chip
# if config["ins_effects"]["flat_fielding"] == True:
# chip_utils.log_info(
# msg=" Creating and applying Flat-Fielding", logger=self.logger)
# chip_utils.log_info(msg=str(img.bounds), logger=self.logger)
# flat_img, flat_normal = chip_utils.get_flat(
# img=img, seed=int(config["random_seeds"]["seed_flat"]))
# if self.survey_type == "photometric":
# img *= flat_normal
# del flat_normal
# if config["output_setting"]["flat_output"] == False:
# del flat_img
# if post_flash_map is not None:
# img = img + post_flash_map
# # Apply Shutter-effect for one chip
# if config["ins_effects"]["shutter_effect"] == True:
# chip_utils.log_info(
# msg=" Apply shutter effect", logger=self.logger)
# # shutter effect normalized image for this chip
# shuttimg = effects.ShutterEffectArr(
# img, t_shutter=1.3, dist_bearing=735, dt=1E-3)
# if self.survey_type == "photometric":
# img *= shuttimg
# # output 16-bit shutter effect image with pixel value <=65535
# if config["output_setting"]["shutter_output"] == True:
# shutt_gsimg = galsim.ImageUS(shuttimg*6E4)
# shutt_gsimg.write("%s/ShutterEffect_%s_1.fits" %
# (chip_output.subdir, self.chipID))
# del shutt_gsimg
# del shuttimg
# # # Add Poisson noise to the resulting images
# # # (NOTE): this can only applied to the slitless image
# # # since it dose not use photon shooting to draw stamps
# # if self.survey_type == "spectroscopic":
# # img.addNoise(poisson_noise)
# # Add cosmic-rays
# if config["ins_effects"]["cosmic_ray"] == True and pointing_type == 'SCI':
# chip_utils.log_info(msg=" Adding Cosmic-Ray", logger=self.logger)
# img, crmap_gsimg, cr_event_num = chip_utils.add_cosmic_rays(img=img, chip=self, exptime=exptime,
# seed=SeedCosmicRay+pointing_ID*30+self.chipID)
# chip_utils.outputCal(
# chip=self,
# img=crmap_gsimg,
# ra_cen=ra_cen,
# dec_cen=dec_cen,
# img_rot=img_rot,
# im_type='CRS',
# pointing_ID=pointing_ID,
# output_dir=chip_output.subdir,
# exptime=exptime,
# project_cycle=config["project_cycle"],
# run_counter=config["run_counter"],
# timestamp=timestamp_obs)
# del crmap_gsimg
# # Apply PRNU effect and output PRNU flat file:
# if config["ins_effects"]["prnu_effect"] == True:
# chip_utils.log_info(
# msg=" Applying PRNU effect", logger=self.logger)
# img, prnu_img = chip_utils.add_PRNU(img=img, chip=self,
# seed=int(config["random_seeds"]["seed_prnu"]+self.chipID))
# if config["output_setting"]["prnu_output"] == True:
# prnu_img.write("%s/FlatImg_PRNU_%s.fits" %
# (chip_output.subdir, self.chipID))
# if config["output_setting"]["flat_output"] == False:
# del prnu_img
# # # Add dark current
# # if config["ins_effects"]["add_dark"] == True:
# # dark_noise = galsim.DeviateNoise(galsim.PoissonDeviate(rng_poisson, self.dark_noise*(exptime+0.5*self.readout_time)))
# # img.addNoise(dark_noise)
# # Add dark current & Poisson noise
# InputDark = False
# if config["ins_effects"]["add_dark"] == True:
# if InputDark:
# img = chip_utils.add_inputdark(
# img=img, chip=self, exptime=exptime)
# else:
# img, _ = chip_utils.add_poisson(
# img=img, chip=self, exptime=exptime, poisson_noise=poisson_noise)
# else:
# img, _ = chip_utils.add_poisson(
# img=img, chip=self, exptime=exptime, poisson_noise=poisson_noise, dark_noise=0.)
# # Add diffusion & brighter-fatter effects
# if config["ins_effects"]["bright_fatter"] == True:
# img = chip_utils.add_brighter_fatter(img=img)
# # Add Hot Pixels or/and Dead Pixels
# rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID)))
# badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
# img = effects.DefectivePixels(img, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix,
# fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=0)
# # Apply Bad lines
# if config["ins_effects"]["add_badcolumns"] == True:
# img = effects.BadColumns(
# img, seed=SeedBadColumns, chipid=self.chipID, logger=self.logger)
# # Apply Nonlinearity on the chip image
# if config["ins_effects"]["non_linear"] == True:
# chip_utils.log_info(
# msg=" Applying Non-Linearity on the chip image", logger=self.logger)
# img = effects.NonLinearity(GSImage=img, beta1=5.e-7, beta2=0)
# # Apply CCD Saturation & Blooming
# if config["ins_effects"]["saturbloom"] == True:
# chip_utils.log_info(
# msg=" Applying CCD Saturation & Blooming", logger=self.logger)
# img = effects.SaturBloom(
# GSImage=img, nsect_x=1, nsect_y=1, fullwell=fullwell)
# # Apply CTE Effect
# # if config["ins_effects"]["cte_trail"] == True:
# # chip_utils.log_info(msg=" Apply CTE Effect", logger=self.logger)
# # img = effects.CTE_Effect(GSImage=img, threshold=27)
# pre1 = self.prescan_x # 27
# over1 = self.overscan_x # 71
# pre2 = self.prescan_y # 0 #4
# over2 = self.overscan_y # 84 #80
# if config["ins_effects"]["cte_trail"] == True:
# chip_utils.log_info(msg=" Apply CTE Effect", logger=self.logger)
# # img = effects.CTE_Effect(GSImage=img, threshold=27)
# # CTI_modeling
# # 2*8 -> 1*16 img-layout
# img = chip_utils.formatOutput(GSImage=img)
# self.nsecy = 1
# self.nsecx = 16
# img_arr = img.array
# ny, nx = img_arr.shape
# dx = int(nx/self.nsecx)
# dy = int(ny/self.nsecy)
# newimg = galsim.Image(nx, int(ny+over2), init_value=0)
# for ichannel in range(16):
# print('\n***add CTI effects: pointing-{:} chip-{:} channel-{:}***'.format(
# pointing_ID, self.chipID, ichannel+1))
# # nx,ny,noverscan,nsp,nmax = 4608,4616,84,3,10
# noverscan, nsp, nmax = over2, 3, 10
# beta, w, c = 0.478, 84700, 0
# t = np.array([0.74, 7.7, 37], dtype=np.float32)
# rho_trap = np.array([0.6, 1.6, 1.4], dtype=np.float32)
# trap_seeds = np.array(
# [0, 1000, 10000], dtype=np.int32) + ichannel + self.chipID*16
# release_seed = 50 + ichannel + pointing_ID*30 + self.chipID*16
# newimg.array[:, 0+ichannel*dx:dx+ichannel*dx] = CTI_sim(
# img_arr[:, 0+ichannel*dx:dx+ichannel*dx], dx, dy, noverscan, nsp, nmax, beta, w, c, t, rho_trap, trap_seeds, release_seed)
# newimg.wcs = img.wcs
# del img
# img = newimg
# # 1*16 -> 2*8 img-layout
# img = chip_utils.formatRevert(GSImage=img)
# self.nsecy = 2
# self.nsecx = 8
# # prescan & overscan
# if config["ins_effects"]["add_prescan"] == True:
# chip_utils.log_info(
# msg=" Apply pre/over-scan", logger=self.logger)
# if config["ins_effects"]["cte_trail"] == False:
# img = chip_utils.AddPreScan(
# GSImage=img, pre1=pre1, pre2=pre2, over1=over1, over2=over2)
# if config["ins_effects"]["cte_trail"] == True:
# img = chip_utils.AddPreScan(
# GSImage=img, pre1=pre1, pre2=pre2, over1=over1, over2=0)
# # 1*16 output
# if config["ins_effects"]["format_output"] == True:
# chip_utils.log_info(msg=" Apply 1*16 format", logger=self.logger)
# img = chip_utils.formatOutput(GSImage=img)
# self.nsecy = 1
# self.nsecx = 16
# # Add Bias level
# if config["ins_effects"]["add_bias"] == True:
# chip_utils.log_info(
# msg=" Adding Bias level and 16-channel non-uniformity", logger=self.logger)
# if config["ins_effects"]["bias_16channel"] == True:
# img = effects.AddBiasNonUniform16(img,
# bias_level=float(
# self.bias_level),
# nsecy=self.nsecy, nsecx=self.nsecx,
# seed=SeedBiasNonuni+self.chipID,
# logger=self.logger)
# elif config["ins_effects"]["bias_16channel"] == False:
# img += self.bias_level
# # Add Read-out Noise
# if config["ins_effects"]["add_readout"] == True:
# seed = int(config["random_seeds"]["seed_readout"]
# ) + pointing_ID*30 + self.chipID
# rng_readout = galsim.BaseDeviate(seed)
# readout_noise = galsim.GaussianNoise(
# rng=rng_readout, sigma=self.read_noise)
# img.addNoise(readout_noise)
# # Apply Gain & Quantization
# chip_utils.log_info(
# msg=" Applying Gain (and 16 channel non-uniformity) & Quantization", logger=self.logger)
# if config["ins_effects"]["gain_16channel"] == True:
# img, self.gain_channel = effects.ApplyGainNonUniform16(
# img, gain=self.gain,
# nsecy=self.nsecy, nsecx=self.nsecx,
# seed=SeedGainNonuni+self.chipID,
# logger=self.logger)
# elif config["ins_effects"]["gain_16channel"] == False:
# img /= self.gain
# img.array[img.array > 65535] = 65535
# img.replaceNegative(replace_value=0)
# img.quantize()
# ######################################################################################
# # Output images for calibration pointing
# ######################################################################################
# # Bias output
# if config["ins_effects"]["add_bias"] == True and config["output_setting"]["bias_output"] == True and pointing_type == 'CAL':
# if self.logger is not None:
# self.logger.info(" Output N frame Bias files")
# else:
# print(" Output N frame Bias files", flush=True)
# NBias = int(config["output_setting"]["NBias"])
# for i in range(NBias):
# # BiasCombImg, BiasTag = effects.MakeBiasNcomb(
# # self.npix_x, self.npix_y,
# # bias_level=float(self.bias_level),
# # ncombine=1, read_noise=self.read_noise, gain=1,
# # seed=SeedBiasNonuni+self.chipID,
# # logger=self.logger)
# BiasCombImg = galsim.Image(
# self.npix_x, self.npix_y, init_value=0)
# if config["ins_effects"]["add_bias"] == True:
# biaslevel = self.bias_level
# overscan = biaslevel-2
# elif config["ins_effects"]["add_bias"] == False:
# biaslevel = 0
# overscan = 0
# # Readout noise for Biases is not generated with random seeds. So readout noise for bias images can't be reproduced.
# if config["ins_effects"]["cosmic_ray"] == True:
# if config["ins_effects"]["cray_differ"] == True:
# cr_map, cr_event_num = effects.produceCR_Map(
# xLen=self.npix_x, yLen=self.npix_y,
# exTime=0.01,
# cr_pixelRatio=0.003 *
# (0.01+0.5*self.readout_time)/150.,
# gain=self.gain,
# attachedSizes=self.attachedSizes,
# seed=SeedCosmicRay+pointing_ID*30+self.chipID+1)
# # seed: obj-imaging:+0; bias:+1; dark:+2; flat:+3;
# BiasCombImg += cr_map
# del cr_map
# # Apply Bad lines
# if config["ins_effects"]["add_badcolumns"] == True:
# BiasCombImg = effects.BadColumns(
# BiasCombImg-float(self.bias_level)+5, seed=SeedBadColumns, chipid=self.chipID, logger=self.logger) + float(self.bias_level)-5
# # Non-Linearity for Bias
# if config["ins_effects"]["non_linear"] == True:
# if self.logger is not None:
# self.logger.info(
# " Applying Non-Linearity on the Bias image")
# else:
# print(
# " Applying Non-Linearity on the Bias image", flush=True)
# BiasCombImg = effects.NonLinearity(
# GSImage=BiasCombImg, beta1=5.e-7, beta2=0)
# # START
# pre1 = self.prescan_x # 27
# over1 = self.overscan_x # 71
# pre2 = self.prescan_y # 0 #4
# over2 = self.overscan_y # 84 #80
# # prescan & overscan
# if config["ins_effects"]["add_prescan"] == True:
# chip_utils.log_info(
# msg=" Apply pre/over-scan", logger=self.logger)
# BiasCombImg = chip_utils.AddPreScan(
# GSImage=BiasCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=over2)
# # 1*16 output
# if config["ins_effects"]["format_output"] == True:
# chip_utils.log_info(
# msg=" Apply 1*16 format", logger=self.logger)
# BiasCombImg = chip_utils.formatOutput(GSImage=BiasCombImg)
# self.nsecy = 1
# self.nsecx = 16
# # END
# # Add Bias level
# if config["ins_effects"]["add_bias"] == True:
# if self.logger is not None:
# self.logger.info(
# " Adding Bias level and 16-channel non-uniformity")
# else:
# print(" Adding Bias level and 16-channel non-uniformity")
# BiasCombImg = effects.AddBiasNonUniform16(BiasCombImg,
# bias_level=biaslevel,
# nsecy=self.nsecy, nsecx=self.nsecx,
# seed=SeedBiasNonuni+self.chipID,
# logger=self.logger)
# rng = galsim.UniformDeviate()
# ncombine = 1
# NoiseBias = galsim.GaussianNoise(
# rng=rng, sigma=self.read_noise*ncombine**0.5)
# BiasCombImg.addNoise(NoiseBias)
# BiasCombImg, self.gain_channel = effects.ApplyGainNonUniform16(BiasCombImg, gain=self.gain,
# nsecy=self.nsecy, nsecx=self.nsecx,
# seed=SeedGainNonuni+self.chipID,
# logger=self.logger)
# # BiasCombImg = effects.AddOverscan(
# # BiasCombImg,
# # overscan=float(config["ins_effects"]["bias_level"])-2, gain=self.gain,
# # widthl=27, widthr=27, widtht=8, widthb=8)
# BiasCombImg.replaceNegative(replace_value=0)
# BiasCombImg.quantize()
# BiasCombImg = galsim.ImageUS(BiasCombImg)
# timestamp_obs += 10 * 60
# chip_utils.outputCal(
# chip=self,
# img=BiasCombImg,
# ra_cen=ra_cen,
# dec_cen=dec_cen,
# img_rot=img_rot,
# im_type='BIAS',
# pointing_ID=pointing_ID,
# output_dir=chip_output.subdir,
# exptime=0.0,
# project_cycle=config["project_cycle"],
# run_counter=config["run_counter"],
# timestamp=timestamp_obs)
# del BiasCombImg
# # Export combined (ncombine, Vignetting + PRNU) & single vignetting flat-field file
# if config["ins_effects"]["flat_fielding"] == True and config["output_setting"]["flat_output"] == True and pointing_type == 'CAL':
# if self.logger is not None:
# self.logger.info(" Output N frame Flat-Field files")
# else:
# print(" Output N frame Flat-Field files", flush=True)
# NFlat = int(config["output_setting"]["NFlat"])
# if config["ins_effects"]["add_bias"] == True:
# biaslevel = self.bias_level
# overscan = biaslevel-2
# elif config["ins_effects"]["add_bias"] == False:
# biaslevel = 0
# overscan = 0
# darklevel = self.dark_noise * \
# (self.flat_exptime+0.5*self.readout_time)
# for i in range(NFlat):
# FlatSingle = flat_img * prnu_img + darklevel
# FlatCombImg, FlatTag = effects.MakeFlatNcomb(
# flat_single_image=FlatSingle,
# ncombine=1,
# read_noise=self.read_noise,
# gain=1,
# overscan=overscan,
# biaslevel=0,
# seed_bias=SeedDefective+self.chipID,
# logger=self.logger
# )
# if config["ins_effects"]["cosmic_ray"] == True:
# if config["ins_effects"]["cray_differ"] == True:
# cr_map, cr_event_num = effects.produceCR_Map(
# xLen=self.npix_x, yLen=self.npix_y,
# exTime=self.flat_exptime+0.5*self.readout_time,
# cr_pixelRatio=0.003 *
# (self.flat_exptime+0.5*self.readout_time)/150.,
# gain=self.gain,
# attachedSizes=self.attachedSizes,
# seed=SeedCosmicRay+pointing_ID*30+self.chipID+3)
# # seed: obj-imaging:+0; bias:+1; dark:+2; flat:+3;
# FlatCombImg += cr_map
# del cr_map
# # Add Hot Pixels or/and Dead Pixels
# rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID)))
# badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
# FlatCombImg = effects.DefectivePixels(
# FlatCombImg, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=0)
# # Apply Bad lines
# if config["ins_effects"]["add_badcolumns"] == True:
# FlatCombImg = effects.BadColumns(
# FlatCombImg, seed=SeedBadColumns, chipid=self.chipID, logger=self.logger)
# if config["ins_effects"]["non_linear"] == True:
# if self.logger is not None:
# self.logger.info(
# " Applying Non-Linearity on the Flat image")
# else:
# print(
# " Applying Non-Linearity on the Flat image", flush=True)
# FlatCombImg = effects.NonLinearity(
# GSImage=FlatCombImg, beta1=5.e-7, beta2=0)
# # if config["ins_effects"]["cte_trail"] == True:
# # FlatCombImg = effects.CTE_Effect(GSImage=FlatCombImg, threshold=3)
# # START
# pre1 = self.prescan_x # 27
# over1 = self.overscan_x # 71
# pre2 = self.prescan_y # 0 #4
# over2 = self.overscan_y # 84 #80
# if config["ins_effects"]["cte_trail"] == True:
# chip_utils.log_info(
# msg=" Apply CTE Effect", logger=self.logger)
# # img = effects.CTE_Effect(GSImage=img, threshold=27)
# # CTI_modeling
# # 2*8 -> 1*16 img-layout
# FlatCombImg = chip_utils.formatOutput(GSImage=FlatCombImg)
# self.nsecy = 1
# self.nsecx = 16
# img_arr = FlatCombImg.array
# ny, nx = img_arr.shape
# dx = int(nx/self.nsecx)
# dy = int(ny/self.nsecy)
# newimg = galsim.Image(nx, int(ny+over2), init_value=0)
# for ichannel in range(16):
# print('\n***add CTI effects: pointing-{:} chip-{:} channel-{:}***'.format(
# pointing_ID, self.chipID, ichannel+1))
# # nx,ny,noverscan,nsp,nmax = 4608,4616,84,3,10
# noverscan, nsp, nmax = over2, 3, 10
# beta, w, c = 0.478, 84700, 0
# t = np.array([0.74, 7.7, 37], dtype=np.float32)
# rho_trap = np.array([0.6, 1.6, 1.4], dtype=np.float32)
# trap_seeds = np.array(
# [0, 1000, 10000], dtype=np.int32) + ichannel + self.chipID*16
# release_seed = 50 + ichannel + pointing_ID*30 + self.chipID*16
# newimg.array[:, 0+ichannel*dx:dx+ichannel*dx] = CTI_sim(
# img_arr[:, 0+ichannel*dx:dx+ichannel*dx], dx, dy, noverscan, nsp, nmax, beta, w, c, t, rho_trap, trap_seeds, release_seed)
# newimg.wcs = FlatCombImg.wcs
# del FlatCombImg
# FlatCombImg = newimg
# # 1*16 -> 2*8 img-layout
# FlatCombImg = chip_utils.formatRevert(GSImage=FlatCombImg)
# self.nsecy = 2
# self.nsecx = 8
# # prescan & overscan
# if config["ins_effects"]["add_prescan"] == True:
# chip_utils.log_info(
# msg=" Apply pre/over-scan", logger=self.logger)
# if config["ins_effects"]["cte_trail"] == False:
# FlatCombImg = chip_utils.AddPreScan(
# GSImage=FlatCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=over2)
# if config["ins_effects"]["cte_trail"] == True:
# FlatCombImg = chip_utils.AddPreScan(
# GSImage=FlatCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=0)
# # 1*16 output
# if config["ins_effects"]["format_output"] == True:
# chip_utils.log_info(
# msg=" Apply 1*16 format", logger=self.logger)
# FlatCombImg = chip_utils.formatOutput(GSImage=FlatCombImg)
# self.nsecy = 1
# self.nsecx = 16
# # END
# # Add Bias level
# if config["ins_effects"]["add_bias"] == True:
# if self.logger is not None:
# self.logger.info(
# " Adding Bias level and 16-channel non-uniformity")
# else:
# print(" Adding Bias level and 16-channel non-uniformity")
# # img += float(config["ins_effects"]["bias_level"])
# FlatCombImg = effects.AddBiasNonUniform16(FlatCombImg,
# bias_level=biaslevel,
# nsecy=self.nsecy, nsecx=self.nsecx,
# seed=SeedBiasNonuni+self.chipID,
# logger=self.logger)
# # Add Read-out Noise
# if config["ins_effects"]["add_readout"] == True:
# seed = int(config["random_seeds"]["seed_readout"]
# ) + pointing_ID*30 + self.chipID + 3
# rng_readout = galsim.BaseDeviate(seed)
# readout_noise = galsim.GaussianNoise(
# rng=rng_readout, sigma=self.read_noise)
# FlatCombImg.addNoise(readout_noise)
# FlatCombImg, self.gain_channel = effects.ApplyGainNonUniform16(FlatCombImg, gain=self.gain,
# nsecy=self.nsecy, nsecx=self.nsecx,
# seed=SeedGainNonuni+self.chipID,
# logger=self.logger)
# # FlatCombImg = effects.AddOverscan(FlatCombImg, overscan=overscan, gain=self.gain, widthl=27, widthr=27, widtht=8, widthb=8)
# FlatCombImg.replaceNegative(replace_value=0)
# FlatCombImg.quantize()
# FlatCombImg = galsim.ImageUS(FlatCombImg)
# timestamp_obs += 10 * 60
# chip_utils.outputCal(
# chip=self,
# img=FlatCombImg,
# ra_cen=ra_cen,
# dec_cen=dec_cen,
# img_rot=img_rot,
# im_type='FLAT',
# pointing_ID=pointing_ID,
# output_dir=chip_output.subdir,
# exptime=self.flat_exptime,
# project_cycle=config["project_cycle"],
# run_counter=config["run_counter"],
# timestamp=timestamp_obs)
# del FlatCombImg, FlatSingle, prnu_img
# # flat_img.replaceNegative(replace_value=0)
# # flat_img.quantize()
# # galsim.ImageUS(flat_img).write("%s/FlatImg_Vignette_%s.fits" % (chip_output.subdir, self.chipID))
# del flat_img
# # Export Dark current images
# if config["ins_effects"]["add_dark"] == True and config["output_setting"]["dark_output"] == True and pointing_type == 'CAL':
# if self.logger is not None:
# self.logger.info(" Output N frame Dark Current files")
# else:
# print(" Output N frame Dark Current files", flush=True)
# NDark = int(config["output_setting"]["NDark"])
# if config["ins_effects"]["add_bias"] == True:
# biaslevel = self.bias_level
# overscan = biaslevel-2
# elif config["ins_effects"]["add_bias"] == False:
# biaslevel = 0
# overscan = 0
# for i in range(NDark):
# DarkCombImg, DarkTag = effects.MakeDarkNcomb(
# self.npix_x, self.npix_y,
# overscan=overscan, bias_level=0, darkpsec=0.02, exptime=self.dark_exptime+0.5*self.readout_time,
# ncombine=1, read_noise=self.read_noise,
# gain=1, seed_bias=SeedBiasNonuni+self.chipID,
# logger=self.logger)
# if config["ins_effects"]["cosmic_ray"] == True:
# if config["ins_effects"]["cray_differ"] == True:
# cr_map, cr_event_num = effects.produceCR_Map(
# xLen=self.npix_x, yLen=self.npix_y,
# exTime=self.dark_exptime+0.5*self.readout_time,
# cr_pixelRatio=0.003 *
# (self.dark_exptime+0.5*self.readout_time)/150.,
# gain=self.gain,
# attachedSizes=self.attachedSizes,
# seed=SeedCosmicRay+pointing_ID*30+self.chipID+2)
# # seed: obj-imaging:+0; bias:+1; dark:+2; flat:+3;
# DarkCombImg += cr_map
# cr_map[cr_map > 65535] = 65535
# cr_map[cr_map < 0] = 0
# crmap_gsimg = galsim.Image(cr_map, dtype=np.uint16)
# del cr_map
# # START
# # prescan & overscan
# if config["ins_effects"]["add_prescan"] == True:
# chip_utils.log_info(
# msg=" Apply pre/over-scan", logger=self.logger)
# crmap_gsimg = chip_utils.AddPreScan(
# GSImage=crmap_gsimg, pre1=pre1, pre2=pre2, over1=over1, over2=over2)
# # 1*16 output
# if config["ins_effects"]["format_output"] == True:
# chip_utils.log_info(
# msg=" Apply 1*16 format", logger=self.logger)
# crmap_gsimg = chip_utils.formatOutput(
# GSImage=crmap_gsimg)
# self.nsecy = 1
# self.nsecx = 16
# # END
# chip_utils.outputCal(
# chip=self,
# img=crmap_gsimg,
# ra_cen=ra_cen,
# dec_cen=dec_cen,
# img_rot=img_rot,
# im_type='CRD',
# pointing_ID=pointing_ID,
# output_dir=chip_output.subdir,
# exptime=self.dark_exptime,
# project_cycle=config["project_cycle"],
# run_counter=config["run_counter"],
# timestamp=timestamp_obs)
# del crmap_gsimg
# # Add Hot Pixels or/and Dead Pixels
# rgbadpix = Generator(PCG64(int(SeedDefective+self.chipID)))
# badfraction = 5E-5*(rgbadpix.random()*0.5+0.7)
# DarkCombImg = effects.DefectivePixels(
# DarkCombImg, IfHotPix=BoolHotPix, IfDeadPix=BoolDeadPix, fraction=badfraction, seed=SeedDefective+self.chipID, biaslevel=0)
# # Apply Bad lines
# if config["ins_effects"]["add_badcolumns"] == True:
# DarkCombImg = effects.BadColumns(
# DarkCombImg, seed=SeedBadColumns, chipid=self.chipID, logger=self.logger)
# # Non-Linearity for Dark
# if config["ins_effects"]["non_linear"] == True:
# if self.logger is not None:
# self.logger.info(
# " Applying Non-Linearity on the Dark image")
# else:
# print(
# " Applying Non-Linearity on the Dark image", flush=True)
# DarkCombImg = effects.NonLinearity(
# GSImage=DarkCombImg, beta1=5.e-7, beta2=0)
# # if config["ins_effects"]["cte_trail"] == True:
# # DarkCombImg = effects.CTE_Effect(GSImage=DarkCombImg, threshold=3)
# # START
# pre1 = self.prescan_x # 27
# over1 = self.overscan_x # 71
# pre2 = self.prescan_y # 0 #4
# over2 = self.overscan_y # 84 #80
# if config["ins_effects"]["cte_trail"] == True:
# chip_utils.log_info(
# msg=" Apply CTE Effect", logger=self.logger)
# # img = effects.CTE_Effect(GSImage=img, threshold=27)
# # CTI_modeling
# # 2*8 -> 1*16 img-layout
# DarkCombImg = chip_utils.formatOutput(GSImage=DarkCombImg)
# self.nsecy = 1
# self.nsecx = 16
# img_arr = DarkCombImg.array
# ny, nx = img_arr.shape
# dx = int(nx/self.nsecx)
# dy = int(ny/self.nsecy)
# newimg = galsim.Image(nx, int(ny+over2), init_value=0)
# for ichannel in range(16):
# print('\n***add CTI effects: pointing-{:} chip-{:} channel-{:}***'.format(
# pointing_ID, self.chipID, ichannel+1))
# # nx,ny,noverscan,nsp,nmax = 4608,4616,84,3,10
# noverscan, nsp, nmax = over2, 3, 10
# beta, w, c = 0.478, 84700, 0
# t = np.array([0.74, 7.7, 37], dtype=np.float32)
# rho_trap = np.array([0.6, 1.6, 1.4], dtype=np.float32)
# trap_seeds = np.array(
# [0, 1000, 10000], dtype=np.int32) + ichannel + self.chipID*16
# release_seed = 50 + ichannel + pointing_ID*30 + self.chipID*16
# newimg.array[:, 0+ichannel*dx:dx+ichannel*dx] = CTI_sim(
# img_arr[:, 0+ichannel*dx:dx+ichannel*dx], dx, dy, noverscan, nsp, nmax, beta, w, c, t, rho_trap, trap_seeds, release_seed)
# newimg.wcs = DarkCombImg.wcs
# del DarkCombImg
# DarkCombImg = newimg
# # 1*16 -> 2*8 img-layout
# DarkCombImg = chip_utils.formatRevert(GSImage=DarkCombImg)
# self.nsecy = 2
# self.nsecx = 8
# # prescan & overscan
# if config["ins_effects"]["add_prescan"] == True:
# chip_utils.log_info(
# msg=" Apply pre/over-scan", logger=self.logger)
# if config["ins_effects"]["cte_trail"] == False:
# DarkCombImg = chip_utils.AddPreScan(
# GSImage=DarkCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=over2)
# if config["ins_effects"]["cte_trail"] == True:
# DarkCombImg = chip_utils.AddPreScan(
# GSImage=DarkCombImg, pre1=pre1, pre2=pre2, over1=over1, over2=0)
# # 1*16 output
# if config["ins_effects"]["format_output"] == True:
# chip_utils.log_info(
# msg=" Apply 1*16 format", logger=self.logger)
# DarkCombImg = chip_utils.formatOutput(GSImage=DarkCombImg)
# self.nsecy = 1
# self.nsecx = 16
# # END
# # Add Bias level
# if config["ins_effects"]["add_bias"] == True:
# if self.logger is not None:
# self.logger.info(
# " Adding Bias level and 16-channel non-uniformity")
# else:
# print(" Adding Bias level and 16-channel non-uniformity")
# # img += float(config["ins_effects"]["bias_level"])
# DarkCombImg = effects.AddBiasNonUniform16(DarkCombImg,
# bias_level=biaslevel,
# nsecy=self.nsecy, nsecx=self.nsecx,
# seed=SeedBiasNonuni+self.chipID,
# logger=self.logger)
# # Add Read-out Noise
# if config["ins_effects"]["add_readout"] == True:
# seed = int(config["random_seeds"]["seed_readout"]
# ) + pointing_ID*30 + self.chipID + 2
# rng_readout = galsim.BaseDeviate(seed)
# readout_noise = galsim.GaussianNoise(
# rng=rng_readout, sigma=self.read_noise)
# DarkCombImg.addNoise(readout_noise)
# DarkCombImg, self.gain_channel = effects.ApplyGainNonUniform16(
# DarkCombImg, gain=self.gain,
# nsecy=self.nsecy, nsecx=self.nsecx,
# seed=SeedGainNonuni+self.chipID,
# logger=self.logger)
# # DarkCombImg = effects.AddOverscan(
# # DarkCombImg,
# # overscan=overscan, gain=self.gain,
# # widthl=27, widthr=27, widtht=8, widthb=8)
# DarkCombImg.replaceNegative(replace_value=0)
# DarkCombImg.quantize()
# DarkCombImg = galsim.ImageUS(DarkCombImg)
# timestamp_obs += 10 * 60
# chip_utils.outputCal(
# chip=self,
# img=DarkCombImg,
# ra_cen=ra_cen,
# dec_cen=dec_cen,
# img_rot=img_rot,
# im_type='DARK',
# pointing_ID=pointing_ID,
# output_dir=chip_output.subdir,
# exptime=self.dark_exptime,
# project_cycle=config["project_cycle"],
# run_counter=config["run_counter"],
# timestamp=timestamp_obs)
# del DarkCombImg
# # img = galsim.ImageUS(img)
# # # 16 output channel, with each a single image file
# # if config["ins_effects"]["readout16"] == True:
# # print(" 16 Output Channel simulation")
# # for coli in [0, 1]:
# # for rowi in range(8):
# # sub_img = effects.readout16(
# # GSImage=img,
# # rowi=rowi,
# # coli=coli,
# # overscan_value=self.overscan)
# # rowcoltag = str(rowi) + str(coli)
# # img_name_root = chip_output.img_name.split(".")[0]
# # sub_img.write("%s/%s_%s.fits" % (chip_output.subdir, img_name_root, rowcoltag))
# # del sub_img
# return img
ObservationSim/Instrument/Telescope.py
deleted
100755 → 0
View file @
dd26d370
import
numpy
as
np
try
:
import
importlib.resources
as
pkg_resources
except
ImportError
:
# Try backported to PY<37 'importlib_resources'
import
importlib_resources
as
pkg_resources
class
Telescope
(
object
):
def
__init__
(
self
,
param
=
None
,
optEffCurve_path
=
None
):
self
.
diameter
=
2.0
# in unit of meter
if
param
is
not
None
:
self
.
diameter
=
param
[
"diameter"
]
self
.
pupil_area
=
np
.
pi
*
(
0.5
*
self
.
diameter
)
**
2
if
optEffCurve_path
is
not
None
:
self
.
efficiency
=
self
.
_get_efficiency
(
optEffCurve_path
)
else
:
try
:
with
pkg_resources
.
files
(
'ObservationSim.Instrument.data'
).
joinpath
(
'mirror_ccdnote.txt'
)
as
optEffCurve_path
:
self
.
efficiency
=
self
.
_get_efficiency
(
optEffCurve_path
)
except
AttributeError
:
with
pkg_resources
.
path
(
'ObservationSim.Instrument.data'
,
'mirror_ccdnote.txt'
)
as
optEffCurve_path
:
self
.
efficiency
=
self
.
_get_efficiency
(
optEffCurve_path
)
def
_get_efficiency
(
self
,
effCurve_path
):
""" Read in the efficiency of optics
for each band
Parameters:
effCurve_path: the path for efficiency file
Returns:
opticsEff: a dictionary of efficiency (a scalar) for each band
"""
f
=
open
(
effCurve_path
,
'r'
)
for
_
in
range
(
2
):
header
=
f
.
readline
()
iline
=
0
opticsEff
=
{}
for
line
in
f
:
line
=
line
.
strip
()
columns
=
line
.
split
()
opticsEff
[
str
(
columns
[
0
])]
=
float
(
columns
[
2
])
f
.
close
()
return
opticsEff
\ No newline at end of file
ObservationSim/Instrument/_util.py
deleted
100755 → 0
View file @
dd26d370
import
numpy
as
np
import
os
import
math
from
pylab
import
*
from
scipy
import
interpolate
try
:
import
importlib.resources
as
pkg_resources
except
ImportError
:
# Try backported to PY<37 'importlib_resources'
import
importlib_resources
as
pkg_resources
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
ALL_FILTERS
=
[
"NUV"
,
"u"
,
"g"
,
"r"
,
"i"
,
"z"
,
"y"
,
"GU"
,
"GV"
,
"GI"
,
"FGS"
]
PHOT_FILTERS
=
[
"NUV"
,
"u"
,
"g"
,
'r'
,
'i'
,
'z'
,
'y'
,
'FGS'
]
SPEC_FILTERS
=
[
"GI"
,
"GV"
,
"GU"
]
def
rotate_conterclockwise
(
x0
,
y0
,
x
,
y
,
angle
):
"""
Rotate a point counterclockwise by a given angle around a given origin.
The angle should be given in radians.
"""
angle
=
np
.
deg2rad
(
angle
)
qx
=
x0
+
np
.
cos
(
angle
)
*
(
x
-
x0
)
-
np
.
sin
(
angle
)
*
(
y
-
y0
)
qy
=
y0
+
np
.
sin
(
angle
)
*
(
x
-
x0
)
+
np
.
cos
(
angle
)
*
(
y
-
y0
)
return
qx
,
qy
def
photonEnergy
(
lambd
):
""" The energy of photon at a given wavelength
Parameter:
lambd: the wavelength in unit of Angstrom
Return:
eph: energy of photon in unit of erg
"""
nu
=
VC_A
/
lambd
eph
=
H_PLANK
*
nu
return
eph
def
calculateLimitMag
(
aperture
=
2.0
,
psf_fwhm
=
0.1969
,
pixelSize
=
0.074
,
pmRation
=
0.8
,
throughputFn
=
'i_throughput.txt'
,
readout
=
5.0
,
skyFn
=
'sky_emiss_hubble_50_50_A.dat'
,
darknoise
=
0.02
,
exTime
=
150
,
exNum
=
1
,
fw
=
90000
):
'''
description:
param {*} aperture: unit m, default 2 m
param {*} psf_fwhm: psf fwhm, default 0.1969"
param {*} pixelSize: pixel size, default 0.074"
param {*} pmRation: the ratio of souce flux in the limit mag calculation
param {*} throughputFn: throuput file name
param {*} readout: unit, e-/pixel
param {*} skyFn: sky sed file name, average of hst, 'sky_emiss_hubble_50_50_A.dat'
param {*} darknoise: unit, e-/pixel/s
param {*} exTime: exposure time one time, default 150s
param {*} exNum: exposure number, defautl 1
param {*} fw, full well value( or saturation value),default 90000e-/pixel
return {*} limit mag and saturation mag
'''
try
:
with
pkg_resources
.
files
(
'ObservationSim.Instrument.data.throughputs'
).
joinpath
(
throughputFn
)
as
data_file
:
throughput_f
=
np
.
loadtxt
(
data_file
)
except
AttributeError
:
with
pkg_resources
.
path
(
'ObservationSim.Instrument.data.throughputs'
,
throughputFn
)
as
data_file
:
throughput_f
=
np
.
loadtxt
(
data_file
)
thr_i
=
interpolate
.
interp1d
(
throughput_f
[:,
0
]
/
10
,
throughput_f
[:,
1
]);
# wavelength in anstrom
f_s
=
200
f_e
=
1100
delt_f
=
0.5
data_num
=
int
((
f_e
-
f_s
)
/
delt_f
+
1
)
eff
=
np
.
zeros
([
data_num
,
2
])
eff
[:,
0
]
=
np
.
arange
(
f_s
,
f_e
+
delt_f
,
delt_f
)
eff
[:,
1
]
=
thr_i
(
eff
[:,
0
])
wave
=
np
.
arange
(
f_s
,
f_e
+
delt_f
,
delt_f
)
wavey
=
np
.
ones
(
wave
.
shape
[
0
])
try
:
with
pkg_resources
.
files
(
'ObservationSim.Instrument.data.throughputs'
).
joinpath
(
skyFn
)
as
data_file
:
skydata
=
np
.
loadtxt
(
data_file
)
except
AttributeError
:
with
pkg_resources
.
path
(
'ObservationSim.Instrument.data.throughputs'
,
skyFn
)
as
data_file
:
skydata
=
np
.
loadtxt
(
data_file
)
skydatai
=
interpolate
.
interp1d
(
skydata
[:,
0
]
/
10
,
skydata
[:,
1
]
*
10
)
sky_data
=
np
.
zeros
([
data_num
,
2
])
sky_data
[:,
0
]
=
np
.
arange
(
f_s
,
f_e
+
delt_f
,
delt_f
)
sky_data
[:,
1
]
=
skydatai
(
sky_data
[:,
0
])
flux_sky
=
trapz
((
sky_data
[:,
1
])
*
eff
[:,
1
],
sky_data
[:,
0
])
skyPix
=
flux_sky
*
pixelSize
*
pixelSize
*
pi
*
(
aperture
*
aperture
/
4
)
###limit mag
r_pix
=
psf_fwhm
*
0.7618080243778568
/
pixelSize
# radius RE80, pixel
cnum
=
math
.
pi
*
r_pix
*
r_pix
sn
=
5
d
=
skyPix
*
exTime
*
exNum
*
cnum
+
darknoise
*
exTime
*
exNum
*
cnum
+
readout
*
readout
*
cnum
*
exNum
a
=
1
b
=-
sn
*
sn
c
=-
sn
*
sn
*
d
flux
=
(
-
b
+
sqrt
(
b
*
b
-
4
*
a
*
c
))
/
(
2
*
a
)
/
pmRation
limitMag
=
-
2.5
*
log10
(
flux
/
(
54799275581.04437
*
trapz
(
wavey
*
eff
[:,
1
]
/
wave
,
wave
,
0.1
)
*
exTime
*
exNum
*
pi
*
(
aperture
/
2
)
*
(
aperture
/
2
)))
### saturation mag
from
astropy.modeling.models
import
Gaussian2D
m_size
=
int
(
20
*
psf_fwhm
/
pixelSize
)
if
m_size
%
2
==
0
:
m_size
+
1
m_cen
=
m_size
//
2
psf_sigma
=
psf_fwhm
/
2.355
/
pixelSize
gaussShape
=
Gaussian2D
(
1
,
m_cen
,
m_cen
,
psf_sigma
,
psf_sigma
)
yp
,
xp
=
np
.
mgrid
[
0
:
m_size
,
0
:
m_size
]
psfMap
=
gaussShape
(
xp
,
yp
)
maxRatio
=
np
.
amax
(
psfMap
)
/
np
.
sum
(
psfMap
)
# print(maxRatio)
flux_sat
=
fw
/
maxRatio
*
exNum
satMag
=
-
2.5
*
log10
(
flux_sat
/
(
54799275581.04437
*
trapz
(
wavey
*
eff
[:,
1
]
/
wave
,
wave
,
0.1
)
*
exTime
*
exNum
*
pi
*
(
aperture
/
2
)
*
(
aperture
/
2
)));
return
limitMag
,
satMag
\ No newline at end of file
ObservationSim/MockObject/CosmicRay.py
deleted
100755 → 0
View file @
dd26d370
from
ObservationSim.MockObject.MockObject
import
MockObject
class
CosmicRay
(
MockObject
):
pass
\ No newline at end of file
ObservationSim/PSF/PSFGauss.py
deleted
100644 → 0
View file @
dd26d370
import
galsim
import
sep
import
numpy
as
np
from
scipy.interpolate
import
interp1d
from
ObservationSim.PSF.PSFModel
import
PSFModel
class
PSFGauss
(
PSFModel
):
def
__init__
(
self
,
chip
,
fwhm
=
0.187
,
sigSpin
=
0.
,
psfRa
=
None
):
self
.
pix_size
=
chip
.
pix_scale
self
.
chip
=
chip
if
psfRa
is
None
:
self
.
fwhm
=
fwhm
self
.
sigGauss
=
0.15
else
:
self
.
fwhm
=
self
.
fwhmGauss
(
r
=
psfRa
)
self
.
sigGauss
=
psfRa
# 80% light radius
self
.
sigSpin
=
sigSpin
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
)
return
flux
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/PSFModel.py
deleted
100755 → 0
View file @
dd26d370
import
galsim
import
sep
import
numpy
as
np
from
scipy.interpolate
import
interp1d
import
pylab
as
pl
import
os
,
sys
class
PSFModel
(
object
):
def
__init__
(
self
,
sigSpin
=
0.
,
psfRa
=
0.15
):
# TODO: what are the nesseary fields in PSFModel class?
pass
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
\ No newline at end of file
C
atalog/C9_Catalog.py
→
c
atalog/C9_Catalog.py
View file @
36189a3e
...
...
@@ -12,9 +12,9 @@ from astropy.table import Table
from
scipy
import
interpolate
from
datetime
import
datetime
from
O
bservation
S
im.
M
ock
O
bject
import
CatalogBase
,
Star
,
Galaxy
,
Quasar
from
O
bservation
S
im.
M
ock
O
bject._util
import
tag_sed
,
getObservedSED
,
getABMAG
,
integrate_sed_bandpass
,
comoving_dist
from
O
bservation
S
im.
A
strometry.Astrometry_util
import
on_orbit_obs_position
from
o
bservation
_s
im.
m
ock
_o
bject
s
import
CatalogBase
,
Star
,
Galaxy
,
Quasar
from
o
bservation
_s
im.
m
ock
_o
bject
s
._util
import
tag_sed
,
getObservedSED
,
getABMAG
,
integrate_sed_bandpass
,
comoving_dist
from
o
bservation
_s
im.
a
strometry.Astrometry_util
import
on_orbit_obs_position
# (TEST)
from
astropy.cosmology
import
FlatLambdaCDM
...
...
@@ -34,23 +34,29 @@ except ImportError:
NSIDE
=
128
bundle_file_list
=
[
'galaxies_C6_bundle000199.h5'
,
'galaxies_C6_bundle000200.h5'
,
'galaxies_C6_bundle000241.h5'
,
'galaxies_C6_bundle000242.h5'
,
'galaxies_C6_bundle000287.h5'
,
'galaxies_C6_bundle000288.h5'
,
'galaxies_C6_bundle000714.h5'
,
'galaxies_C6_bundle000715.h5'
,
'galaxies_C6_bundle000778.h5'
,
'galaxies_C6_bundle000779.h5'
,
'galaxies_C6_bundle000842.h5'
,
'galaxies_C6_bundle000843.h5'
,
'galaxies_C6_bundle002046.h5'
,
'galaxies_C6_bundle002110.h5'
,
'galaxies_C6_bundle002111.h5'
,
'galaxies_C6_bundle002173.h5'
,
'galaxies_C6_bundle002174.h5'
,
'galaxies_C6_bundle002238.h5'
,
'galaxies_C6_bundle002596.h5'
,
'galaxies_C6_bundle002597.h5'
,
'galaxies_C6_bundle002656.h5'
,
'galaxies_C6_bundle002657.h5'
,
'galaxies_C6_bundle002711.h5'
,
'galaxies_C6_bundle002712.h5'
,
'galaxies_C6_bundle002844.h5'
,
'galaxies_C6_bundle002845.h5'
,
'galaxies_C6_bundle002884.h5'
,
'galaxies_C6_bundle002885.h5'
,
'galaxies_C6_bundle002921.h5'
,
'galaxies_C6_bundle002922.h5'
]
bundle_file_list
=
[
'galaxies_C6_bundle000199.h5'
,
'galaxies_C6_bundle000200.h5'
,
'galaxies_C6_bundle000241.h5'
,
'galaxies_C6_bundle000242.h5'
,
'galaxies_C6_bundle000287.h5'
,
'galaxies_C6_bundle000288.h5'
,
'galaxies_C6_bundle000714.h5'
,
'galaxies_C6_bundle000715.h5'
,
'galaxies_C6_bundle000778.h5'
,
'galaxies_C6_bundle000779.h5'
,
'galaxies_C6_bundle000842.h5'
,
'galaxies_C6_bundle000843.h5'
,
'galaxies_C6_bundle002046.h5'
,
'galaxies_C6_bundle002110.h5'
,
'galaxies_C6_bundle002111.h5'
,
'galaxies_C6_bundle002173.h5'
,
'galaxies_C6_bundle002174.h5'
,
'galaxies_C6_bundle002238.h5'
,
'galaxies_C6_bundle002596.h5'
,
'galaxies_C6_bundle002597.h5'
,
'galaxies_C6_bundle002656.h5'
,
'galaxies_C6_bundle002657.h5'
,
'galaxies_C6_bundle002711.h5'
,
'galaxies_C6_bundle002712.h5'
,
'galaxies_C6_bundle002844.h5'
,
'galaxies_C6_bundle002845.h5'
,
'galaxies_C6_bundle002884.h5'
,
'galaxies_C6_bundle002885.h5'
,
'galaxies_C6_bundle002921.h5'
,
'galaxies_C6_bundle002922.h5'
]
qsosed_file_list
=
[
'quickspeclib_interp1d_run1.fits'
,
'quickspeclib_interp1d_run2.fits'
,
'quickspeclib_interp1d_run3.fits'
,
'quickspeclib_interp1d_run4.fits'
,
'quickspeclib_interp1d_run5.fits'
,
'quickspeclib_interp1d_run6.fits'
,
'quickspeclib_interp1d_run7.fits'
,
'quickspeclib_interp1d_run8.fits'
,
'quickspeclib_interp1d_run9.fits'
,
'quickspeclib_interp1d_run10.fits'
,
'quickspeclib_interp1d_run11.fits'
,
'quickspeclib_interp1d_run12.fits'
,
'quickspeclib_interp1d_run13.fits'
,
'quickspeclib_interp1d_run14.fits'
,
'quickspeclib_interp1d_run15.fits'
,
'quickspeclib_interp1d_run16.fits'
,
'quickspeclib_interp1d_run17.fits'
,
'quickspeclib_interp1d_run18.fits'
,
'quickspeclib_interp1d_run19.fits'
,
'quickspeclib_interp1d_run20.fits'
,
'quickspeclib_interp1d_run21.fits'
,
'quickspeclib_interp1d_run22.fits'
,
'quickspeclib_interp1d_run23.fits'
,
'quickspeclib_interp1d_run24.fits'
,
'quickspeclib_interp1d_run25.fits'
,
'quickspeclib_interp1d_run26.fits'
,
'quickspeclib_interp1d_run27.fits'
,
'quickspeclib_interp1d_run28.fits'
,
'quickspeclib_interp1d_run29.fits'
,
'quickspeclib_interp1d_run30.fits'
]
qsosed_file_list
=
[
'quickspeclib_interp1d_run1.fits'
,
'quickspeclib_interp1d_run2.fits'
,
'quickspeclib_interp1d_run3.fits'
,
'quickspeclib_interp1d_run4.fits'
,
'quickspeclib_interp1d_run5.fits'
,
'quickspeclib_interp1d_run6.fits'
,
'quickspeclib_interp1d_run7.fits'
,
'quickspeclib_interp1d_run8.fits'
,
'quickspeclib_interp1d_run9.fits'
,
'quickspeclib_interp1d_run10.fits'
,
'quickspeclib_interp1d_run11.fits'
,
'quickspeclib_interp1d_run12.fits'
,
'quickspeclib_interp1d_run13.fits'
,
'quickspeclib_interp1d_run14.fits'
,
'quickspeclib_interp1d_run15.fits'
,
'quickspeclib_interp1d_run16.fits'
,
'quickspeclib_interp1d_run17.fits'
,
'quickspeclib_interp1d_run18.fits'
,
'quickspeclib_interp1d_run19.fits'
,
'quickspeclib_interp1d_run20.fits'
,
'quickspeclib_interp1d_run21.fits'
,
'quickspeclib_interp1d_run22.fits'
,
'quickspeclib_interp1d_run23.fits'
,
'quickspeclib_interp1d_run24.fits'
,
'quickspeclib_interp1d_run25.fits'
,
'quickspeclib_interp1d_run26.fits'
,
'quickspeclib_interp1d_run27.fits'
,
'quickspeclib_interp1d_run28.fits'
,
'quickspeclib_interp1d_run29.fits'
,
'quickspeclib_interp1d_run30.fits'
]
# star_file_list = ['C7_Gaia_Galaxia_RA170DECm23_healpix.hdf5', 'C7_Gaia_Galaxia_RA180DECp60_healpix.hdf5', 'C7_Gaia_Galaxia_RA240DECp30_healpix.hdf5', 'C7_Gaia_Galaxia_RA300DECm60_healpix.hdf5', 'C7_Gaia_Galaxia_RA30DECm48_healpix.hdf5']
star_center_list
=
[(
170.
,
-
23.
),
(
180.
,
60.
),
(
240.
,
30.
),
(
300.
,
-
60.
),
(
30.
,
-
48.
),[
246.5
,
40
]]
star_center_list
=
[(
170.
,
-
23.
),
(
180.
,
60.
),
(
240.
,
30.
),
(
300.
,
-
60.
),
(
30.
,
-
48.
),
[
246.5
,
40
]]
star_file_list
=
[
'C9_RA170_DECm23_calmag_Nside_128_healpix.hdf5'
,
'C9_RA180_DECp60_calmag_Nside_128_healpix.hdf5'
,
'C9_RA240_DECp30_calmag_Nside_128_healpix.hdf5'
,
'C9_RA300_DECm60_calmag_Nside_128_healpix.hdf5'
,
'C9_RA30_DECm48_calmag_Nside_128_healpix.hdf5'
,
'trilegal_calMag_mpi_Nside_128_healpix.hdf5'
]
star_file_list
=
[
'C9_RA170_DECm23_calmag_Nside_128_healpix.hdf5'
,
'C9_RA180_DECp60_calmag_Nside_128_healpix.hdf5'
,
'C9_RA240_DECp30_calmag_Nside_128_healpix.hdf5'
,
'C9_RA300_DECm60_calmag_Nside_128_healpix.hdf5'
,
'C9_RA30_DECm48_calmag_Nside_128_healpix.hdf5'
,
'trilegal_calMag_mpi_Nside_128_healpix.hdf5'
]
class
StarParm
(
ctypes
.
Structure
):
_fields_
=
[
(
'logte'
,
ctypes
.
c_float
),
(
'logg'
,
ctypes
.
c_float
),
(
'Mass'
,
ctypes
.
c_float
),
(
'Av'
,
ctypes
.
c_float
),
(
'mu0'
,
ctypes
.
c_float
),
(
'Z'
,
ctypes
.
c_float
)]
(
'logte'
,
ctypes
.
c_float
),
(
'logg'
,
ctypes
.
c_float
),
(
'Mass'
,
ctypes
.
c_float
),
(
'Av'
,
ctypes
.
c_float
),
(
'mu0'
,
ctypes
.
c_float
),
(
'Z'
,
ctypes
.
c_float
)]
def
get_bundleIndex
(
healpixID_ring
,
bundleOrder
=
4
,
healpixOrder
=
7
):
assert
NSIDE
==
2
**
healpixOrder
...
...
@@ -58,17 +64,19 @@ def get_bundleIndex(healpixID_ring, bundleOrder=4, healpixOrder=7):
shift
=
2
*
shift
nside_bundle
=
2
**
bundleOrder
nside_healpix
=
2
**
healpixOrder
nside_healpix
=
2
**
healpixOrder
healpixID_nest
=
hp
.
ring2nest
(
nside_healpix
,
healpixID_ring
)
healpixID_nest
=
hp
.
ring2nest
(
nside_healpix
,
healpixID_ring
)
bundleID_nest
=
(
healpixID_nest
>>
shift
)
bundleID_ring
=
hp
.
nest2ring
(
nside_bundle
,
bundleID_nest
)
return
bundleID_ring
def
get_agnsed_file
(
bundle_file_name
):
return
qsosed_file_list
[
bundle_file_list
.
index
(
bundle_file_name
)]
def
get_star_cat
(
ra_pointing
,
dec_pointing
):
pointing_c
=
SkyCoord
(
ra
=
ra_pointing
*
U
.
deg
,
dec
=
dec_pointing
*
U
.
deg
)
max_dist
=
10
...
...
@@ -81,6 +89,7 @@ def get_star_cat(ra_pointing, dec_pointing):
max_dist
=
dist
return
return_star_path
class
Catalog
(
CatalogBase
):
def
__init__
(
self
,
config
,
chip
,
pointing
,
chip_output
,
filt
,
**
kwargs
):
super
().
__init__
()
...
...
@@ -92,9 +101,9 @@ class Catalog(CatalogBase):
self
.
filt
=
filt
self
.
logger
=
chip_output
.
logger
with
pkg_resources
.
path
(
'
C
atalog.data'
,
'SLOAN_SDSS.g.fits'
)
as
filter_path
:
with
pkg_resources
.
path
(
'
c
atalog.data'
,
'SLOAN_SDSS.g.fits'
)
as
filter_path
:
self
.
normF_star
=
Table
.
read
(
str
(
filter_path
))
self
.
config
=
config
self
.
chip
=
chip
self
.
pointing
=
pointing
...
...
@@ -103,12 +112,14 @@ class Catalog(CatalogBase):
if
"star_cat"
in
config
[
"catalog_options"
][
"input_path"
]
and
config
[
"catalog_options"
][
"input_path"
][
"star_cat"
]
and
not
config
[
"catalog_options"
][
"galaxy_only"
]:
# Get the cloest star catalog file
star_file_name
=
get_star_cat
(
ra_pointing
=
self
.
pointing
.
ra
,
dec_pointing
=
self
.
pointing
.
dec
)
star_path
=
os
.
path
.
join
(
config
[
"catalog_options"
][
"input_path"
][
"star_cat"
],
star_file_name
)
star_file_name
=
get_star_cat
(
ra_pointing
=
self
.
pointing
.
ra
,
dec_pointing
=
self
.
pointing
.
dec
)
star_path
=
os
.
path
.
join
(
config
[
"catalog_options"
][
"input_path"
][
"star_cat"
],
star_file_name
)
self
.
star_path
=
os
.
path
.
join
(
self
.
cat_dir
,
star_path
)
self
.
star_SED_path
=
config
[
"catalog_options"
][
"SED_templates_path"
][
"star_SED"
]
self
.
_load_SED_lib_star
()
if
"galaxy_cat"
in
config
[
"catalog_options"
][
"input_path"
]
and
config
[
"catalog_options"
][
"input_path"
][
"galaxy_cat"
]
and
not
config
[
"catalog_options"
][
"star_only"
]:
galaxy_dir
=
config
[
"catalog_options"
][
"input_path"
][
"galaxy_cat"
]
self
.
galaxy_path
=
os
.
path
.
join
(
self
.
cat_dir
,
galaxy_dir
)
...
...
@@ -120,7 +131,8 @@ class Catalog(CatalogBase):
self
.
AGN_SED_path
=
config
[
"catalog_options"
][
"SED_templates_path"
][
"AGN_SED"
]
if
"rotateEll"
in
config
[
"catalog_options"
]:
self
.
rotation
=
np
.
radians
(
float
(
config
[
"catalog_options"
][
"rotateEll"
]))
self
.
rotation
=
np
.
radians
(
float
(
config
[
"catalog_options"
][
"rotateEll"
]))
else
:
self
.
rotation
=
0.
...
...
@@ -129,17 +141,19 @@ class Catalog(CatalogBase):
self
.
_get_healpix_list
()
self
.
_load
()
def
_add_output_columns_header
(
self
):
self
.
add_hdr
=
" av stellarmass dm teff logg feh"
self
.
add_hdr
+=
" bulgemass diskmass detA e1 e2 kappa g1 g2 size galType veldisp "
self
.
add_fmt
=
"%8.4f %8.4f %8.4f %8.4f %8.4f %8.4f"
self
.
add_fmt
+=
" %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %4d %8.4f "
self
.
chip_output
.
update_output_header
(
additional_column_names
=
self
.
add_hdr
)
self
.
chip_output
.
update_output_header
(
additional_column_names
=
self
.
add_hdr
)
def
_get_healpix_list
(
self
):
self
.
sky_coverage
=
self
.
chip
.
getSkyCoverageEnlarged
(
self
.
chip
.
img
.
wcs
,
margin
=
0.2
)
self
.
sky_coverage
=
self
.
chip
.
getSkyCoverageEnlarged
(
self
.
chip
.
img
.
wcs
,
margin
=
0.2
)
ra_min
,
ra_max
,
dec_min
,
dec_max
=
self
.
sky_coverage
.
xmin
,
self
.
sky_coverage
.
xmax
,
self
.
sky_coverage
.
ymin
,
self
.
sky_coverage
.
ymax
ra
=
np
.
deg2rad
(
np
.
array
([
ra_min
,
ra_max
,
ra_max
,
ra_min
]))
dec
=
np
.
deg2rad
(
np
.
array
([
dec_max
,
dec_max
,
dec_min
,
dec_min
]))
...
...
@@ -167,27 +181,31 @@ class Catalog(CatalogBase):
# self.tempSED_star = h5.File(self.star_SED_path,'r')
def
_load_SED_lib_star
(
self
):
# self.tempSED_star = h5.File(self.star_SED_path,'r')
with
pkg_resources
.
path
(
'
C
atalog.data'
,
'starSpecInterp.so'
)
as
ddl_path
:
with
pkg_resources
.
path
(
'
c
atalog.data'
,
'starSpecInterp.so'
)
as
ddl_path
:
self
.
starDDL
=
ctypes
.
CDLL
(
str
(
ddl_path
))
self
.
starDDL
.
loadSpecLibs
.
argtypes
=
[
ctypes
.
c_char_p
,
ctypes
.
c_char_p
]
self
.
starDDL
.
loadExts
.
argtypes
=
[
ctypes
.
c_char_p
]
nwv
=
self
.
starDDL
.
loadSpecLibs
(
str
.
encode
(
os
.
path
.
join
(
self
.
star_SED_path
,
'file_BT-Settl_CSST_wl1000-24000_R1000.par'
)),
str
.
encode
(
self
.
star_SED_path
))
self
.
starDDL
.
loadExts
(
str
.
encode
(
os
.
path
.
join
(
self
.
star_SED_path
,
"Ext_odonnell94_R3.1_CSST_wl1000-24000_R1000.fits"
)))
self
.
starDDL
.
loadSpecLibs
.
argtypes
=
[
ctypes
.
c_char_p
,
ctypes
.
c_char_p
]
self
.
starDDL
.
loadExts
.
argtypes
=
[
ctypes
.
c_char_p
]
nwv
=
self
.
starDDL
.
loadSpecLibs
(
str
.
encode
(
os
.
path
.
join
(
self
.
star_SED_path
,
'file_BT-Settl_CSST_wl1000-24000_R1000.par'
)),
str
.
encode
(
self
.
star_SED_path
))
self
.
starDDL
.
loadExts
(
str
.
encode
(
os
.
path
.
join
(
self
.
star_SED_path
,
"Ext_odonnell94_R3.1_CSST_wl1000-24000_R1000.fits"
)))
self
.
star_spec_len
=
nwv
def
_interp_star_sed
(
self
,
obj
):
spec
=
(
ctypes
.
c_float
*
self
.
star_spec_len
)()
wave
=
(
ctypes
.
c_float
*
self
.
star_spec_len
)()
self
.
starDDL
.
interpSingleStar
.
argtypes
=
[
ctypes
.
Structure
,
ctypes
.
POINTER
(
ctypes
.
c_float
)]
self
.
starDDL
.
interpSingleStar
.
argtypes
=
[
ctypes
.
Structure
,
ctypes
.
POINTER
(
ctypes
.
c_float
)]
# s=Star(obj.param['teff'], obj.param['grav''], obj.paramstar['mwmsc_mass'], obj.param['AV'], obj.param['DM'], obj.param['z_met'])
s
=
StarParm
(
obj
.
param
[
'teff'
],
obj
.
param
[
'logg'
],
obj
.
param
[
'stellarMass'
],
obj
.
param
[
'av'
],
obj
.
param
[
'DM'
],
obj
.
param
[
'feh'
])
s
=
StarParm
(
obj
.
param
[
'teff'
],
obj
.
param
[
'logg'
],
obj
.
param
[
'stellarMass'
],
obj
.
param
[
'av'
],
obj
.
param
[
'DM'
],
obj
.
param
[
'feh'
])
self
.
starDDL
.
interpSingleStar
(
s
,
spec
,
wave
)
rv_c
=
obj
.
param
[
'rv'
]
/
(
atcons
.
c
.
value
/
1000.
)
Doppler_factor
=
np
.
sqrt
((
1
+
rv_c
)
/
(
1
-
rv_c
))
wave_RV
=
wave
*
Doppler_factor
return
wave_RV
,
np
.
power
(
10
,
spec
[:])
return
wave_RV
,
np
.
power
(
10
,
spec
[:])
def
_load_SED_lib_gals
(
self
):
pcs
=
h5
.
File
(
os
.
path
.
join
(
self
.
galaxy_SED_path
,
"pcs.h5"
),
"r"
)
...
...
@@ -231,10 +249,10 @@ class Catalog(CatalogBase):
)
for
igals
in
range
(
ngals
):
#
#
(TEST)
#
if igals > 100:
#
break
# (TEST)
if
igals
>
100
:
break
param
=
self
.
initialize_param
()
param
[
'ra'
]
=
ra_arr
[
igals
]
param
[
'dec'
]
=
dec_arr
[
igals
]
...
...
@@ -243,12 +261,13 @@ class Catalog(CatalogBase):
if
not
self
.
chip
.
isContainObj
(
ra_obj
=
param
[
'ra'
],
dec_obj
=
param
[
'dec'
],
margin
=
200
):
continue
# param['mag_use_normal'] = gals['mag_csst_%s'%(self.filt.filter_type)][igals]
if
self
.
filt
.
filter_type
==
'NUV'
:
param
[
'mag_use_normal'
]
=
gals
[
'mag_csst_nuv'
][
igals
]
else
:
param
[
'mag_use_normal'
]
=
gals
[
'mag_csst_%s'
%
(
self
.
filt
.
filter_type
)][
igals
]
param
[
'mag_use_normal'
]
=
gals
[
'mag_csst_%s'
%
(
self
.
filt
.
filter_type
)][
igals
]
if
self
.
filt
.
is_too_dim
(
mag
=
param
[
'mag_use_normal'
],
margin
=
self
.
config
[
"obs_setting"
][
"mag_lim_margin"
]):
continue
...
...
@@ -259,26 +278,25 @@ class Catalog(CatalogBase):
param
[
'kappa'
]
=
gals
[
'kappa'
][
igals
]
param
[
'e1'
]
=
gals
[
'ellipticity_true'
][
igals
][
0
]
param
[
'e2'
]
=
gals
[
'ellipticity_true'
][
igals
][
1
]
# For shape calculation
param
[
'e1'
],
param
[
'e2'
],
param
[
'ell_total'
]
=
self
.
rotate_ellipticity
(
e1
=
gals
[
'ellipticity_true'
][
igals
][
0
],
e2
=
gals
[
'ellipticity_true'
][
igals
][
1
],
rotation
=
self
.
rotation
,
unit
=
'radians'
)
e1
=
gals
[
'ellipticity_true'
][
igals
][
0
],
e2
=
gals
[
'ellipticity_true'
][
igals
][
1
],
rotation
=
self
.
rotation
,
unit
=
'radians'
)
# param['ell_total'] = np.sqrt(param['e1']**2 + param['e2']**2)
if
param
[
'ell_total'
]
>
0.9
:
continue
# phi_e = cmath.phase(complex(param['e1'], param['e2']))
# param['e1'] = param['ell_total'] * np.cos(phi_e + 2*self.rotation)
# param['e2'] = param['ell_total'] * np.sin(phi_e + 2*self.rotation)
param
[
'e1_disk'
]
=
param
[
'e1'
]
param
[
'e2_disk'
]
=
param
[
'e2'
]
param
[
'e1_bulge'
]
=
param
[
'e1'
]
param
[
'e2_bulge'
]
=
param
[
'e2'
]
param
[
'delta_ra'
]
=
0
param
[
'delta_dec'
]
=
0
...
...
@@ -295,7 +313,8 @@ class Catalog(CatalogBase):
param
[
'bulge_sersic_idx'
]
=
4.
# Sizes
param
[
'bfrac'
]
=
param
[
'bulgemass'
]
/
(
param
[
'bulgemass'
]
+
param
[
'diskmass'
])
param
[
'bfrac'
]
=
param
[
'bulgemass'
]
/
\
(
param
[
'bulgemass'
]
+
param
[
'diskmass'
])
if
param
[
'bfrac'
]
>=
0.6
:
param
[
'hlr_bulge'
]
=
param
[
'size'
]
param
[
'hlr_disk'
]
=
param
[
'size'
]
*
(
1.
-
param
[
'bfrac'
])
...
...
@@ -310,14 +329,15 @@ class Catalog(CatalogBase):
# Others
param
[
'galType'
]
=
gals
[
'type'
][
igals
]
param
[
'veldisp'
]
=
gals
[
'veldisp'
][
igals
]
# TEST no redening and no extinction
param
[
'av'
]
=
0.0
param
[
'redden'
]
=
0
# TEMP
self
.
ids
+=
1
param
[
'id'
]
=
'%06d'
%
(
int
(
pix_id
))
+
'%06d'
%
(
cat_id
)
+
'%08d'
%
(
igals
)
param
[
'id'
]
=
'%06d'
%
(
int
(
pix_id
))
+
\
'%06d'
%
(
cat_id
)
+
'%08d'
%
(
igals
)
# Is this an Quasar?
param
[
'qsoindex'
]
=
gals
[
'qsoindex'
][
igals
]
...
...
@@ -332,20 +352,20 @@ class Catalog(CatalogBase):
# First add QSO model
obj
=
Quasar
(
param_qso
,
logger
=
self
.
logger
)
# Need to deal with additional output columns
obj
.
additional_output_str
=
self
.
add_fmt
%
(
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0
,
0.
)
obj
.
additional_output_str
=
self
.
add_fmt
%
(
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0
,
0.
)
self
.
objs
.
append
(
obj
)
# Then add host galaxy model
param
[
'star'
]
=
0
# Galaxy
param
[
'agnsed_file'
]
=
""
obj
=
Galaxy
(
param
,
logger
=
self
.
logger
)
# Need to deal with additional output columns for (host) galaxy
obj
.
additional_output_str
=
self
.
add_fmt
%
(
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
param
[
'bulgemass'
],
param
[
'diskmass'
],
param
[
'detA'
],
param
[
'e1'
],
param
[
'e2'
],
param
[
'kappa'
],
param
[
'g1'
],
param
[
'g2'
],
param
[
'size'
],
param
[
'galType'
],
param
[
'veldisp'
])
obj
.
additional_output_str
=
self
.
add_fmt
%
(
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
param
[
'bulgemass'
],
param
[
'diskmass'
],
param
[
'detA'
],
param
[
'e1'
],
param
[
'e2'
],
param
[
'kappa'
],
param
[
'g1'
],
param
[
'g2'
],
param
[
'size'
],
param
[
'galType'
],
param
[
'veldisp'
])
self
.
objs
.
append
(
obj
)
def
_load_stars
(
self
,
stars
,
pix_id
=
None
):
...
...
@@ -387,8 +407,8 @@ class Catalog(CatalogBase):
)
for
istars
in
range
(
nstars
):
# (TEST)
#
if istars > 100:
#
break
if
istars
>
100
:
break
param
=
self
.
initialize_param
()
param
[
'ra'
]
=
ra_arr
[
istars
]
...
...
@@ -404,7 +424,7 @@ class Catalog(CatalogBase):
param
[
'mag_use_normal'
]
=
stars
[
'app_sdss_g'
][
istars
]
self
.
ids
+=
1
param
[
'id'
]
=
'%06d'
%
(
int
(
pix_id
))
+
'%08d'
%
(
istars
)
param
[
'id'
]
=
'%06d'
%
(
int
(
pix_id
))
+
'%08d'
%
(
istars
)
# param['sed_type'] = istars
# param['model_tag'] = ''
param
[
'teff'
]
=
stars
[
'teff'
][
istars
]
...
...
@@ -412,29 +432,28 @@ class Catalog(CatalogBase):
param
[
'feh'
]
=
stars
[
'z_met'
][
istars
]
param
[
'stellarMass'
]
=
stars
[
'mass'
][
istars
]
param
[
'av'
]
=
stars
[
'AV'
][
istars
]
param
[
'DM'
]
=
stars
[
'DM'
][
istars
]
# param['z_met'] = stars['z_met'][istars]
param
[
'z'
]
=
0.0
param
[
'star'
]
=
1
# Star
try
:
obj
=
Star
(
param
,
logger
=
self
.
logger
)
except
Exception
as
e
:
print
(
e
)
# Append additional output columns to the .cat file
obj
.
additional_output_str
=
self
.
add_fmt
%
(
param
[
"av"
],
param
[
'stellarMass'
],
param
[
'DM'
],
param
[
'teff'
],
param
[
'logg'
],
param
[
'feh'
],
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
-
1
,
0.
)
obj
.
additional_output_str
=
self
.
add_fmt
%
(
param
[
"av"
],
param
[
'stellarMass'
],
param
[
'DM'
],
param
[
'teff'
],
param
[
'logg'
],
param
[
'feh'
],
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
0.
,
-
1
,
0.
)
self
.
objs
.
append
(
obj
)
def
_load
(
self
,
**
kwargs
):
self
.
objs
=
[]
self
.
ids
=
0
if
"star_cat"
in
self
.
config
[
"catalog_options"
][
"input_path"
]
and
self
.
config
[
"catalog_options"
][
"input_path"
][
"star_cat"
]
and
not
self
.
config
[
"catalog_options"
][
"galaxy_only"
]:
star_cat
=
h5
.
File
(
self
.
star_path
,
'r'
)[
'star_catalog'
]
for
pix
in
self
.
pix_list
:
...
...
@@ -445,11 +464,11 @@ class Catalog(CatalogBase):
except
Exception
as
e
:
self
.
logger
.
error
(
str
(
e
))
# print(e)
if
"galaxy_cat"
in
self
.
config
[
"catalog_options"
][
"input_path"
]
and
self
.
config
[
"catalog_options"
][
"input_path"
][
"galaxy_cat"
]
and
not
self
.
config
[
"catalog_options"
][
"star_only"
]:
for
pix
in
self
.
pix_list
:
try
:
bundleID
=
get_bundleIndex
(
pix
)
bundleID
=
get_bundleIndex
(
pix
)
bundle_file
=
"galaxies_C6_bundle{:06}.h5"
.
format
(
bundleID
)
file_path
=
os
.
path
.
join
(
self
.
galaxy_path
,
bundle_file
)
gals_cat
=
h5
.
File
(
file_path
,
'r'
)[
'galaxies'
]
...
...
@@ -460,7 +479,8 @@ class Catalog(CatalogBase):
agnsed_path
=
os
.
path
.
join
(
self
.
AGN_SED_path
,
agnsed_file
)
self
.
agn_seds
[
agnsed_file
]
=
fits
.
open
(
agnsed_path
)[
0
].
data
self
.
_load_gals
(
gals
,
pix_id
=
pix
,
cat_id
=
bundleID
,
agnsed_file
=
agnsed_file
)
self
.
_load_gals
(
gals
,
pix_id
=
pix
,
cat_id
=
bundleID
,
agnsed_file
=
agnsed_file
)
del
gals
except
Exception
as
e
:
...
...
@@ -469,8 +489,9 @@ class Catalog(CatalogBase):
print
(
e
)
if
self
.
logger
is
not
None
:
self
.
logger
.
info
(
"maximum galaxy size: %.4f"
%
(
self
.
max_size
))
self
.
logger
.
info
(
"number of objects in catalog: %d"
%
(
len
(
self
.
objs
)))
self
.
logger
.
info
(
"maximum galaxy size: %.4f"
%
(
self
.
max_size
))
self
.
logger
.
info
(
"number of objects in catalog: %d"
%
(
len
(
self
.
objs
)))
else
:
print
(
"number of objects in catalog: "
,
len
(
self
.
objs
))
...
...
@@ -500,7 +521,8 @@ class Catalog(CatalogBase):
)
wave
,
flux
=
sed_data
[
0
],
sed_data
[
1
]
elif
obj
.
type
==
'quasar'
:
flux
=
self
.
agn_seds
[
obj
.
agnsed_file
][
int
(
obj
.
qsoindex
)]
*
1e-17
flux
=
self
.
agn_seds
[
obj
.
agnsed_file
][
int
(
obj
.
qsoindex
)]
*
1e-17
flux
[
flux
<
0
]
=
0.
wave
=
self
.
lamb_gal
*
(
1.0
+
obj
.
z
)
else
:
...
...
@@ -514,10 +536,14 @@ class Catalog(CatalogBase):
if
obj
.
type
==
'quasar'
:
# integrate to get the magnitudes
sed_photon
=
np
.
array
([
sed
[
'WAVELENGTH'
],
sed
[
'FLUX'
]]).
T
sed_photon
=
galsim
.
LookupTable
(
x
=
np
.
array
(
sed_photon
[:,
0
]),
f
=
np
.
array
(
sed_photon
[:,
1
]),
interpolant
=
'nearest'
)
sed_photon
=
galsim
.
SED
(
sed_photon
,
wave_type
=
'A'
,
flux_type
=
'1'
,
fast
=
False
)
interFlux
=
integrate_sed_bandpass
(
sed
=
sed_photon
,
bandpass
=
self
.
filt
.
bandpass_full
)
obj
.
param
[
'mag_use_normal'
]
=
getABMAG
(
interFlux
,
self
.
filt
.
bandpass_full
)
sed_photon
=
galsim
.
LookupTable
(
x
=
np
.
array
(
sed_photon
[:,
0
]),
f
=
np
.
array
(
sed_photon
[:,
1
]),
interpolant
=
'nearest'
)
sed_photon
=
galsim
.
SED
(
sed_photon
,
wave_type
=
'A'
,
flux_type
=
'1'
,
fast
=
False
)
interFlux
=
integrate_sed_bandpass
(
sed
=
sed_photon
,
bandpass
=
self
.
filt
.
bandpass_full
)
obj
.
param
[
'mag_use_normal'
]
=
getABMAG
(
interFlux
,
self
.
filt
.
bandpass_full
)
# mag = getABMAG(interFlux, self.filt.bandpass_full)
# print("mag diff = %.3f"%(mag - obj.param['mag_use_normal']))
del
wave
...
...
C
atalog/Catalog_example.py
→
c
atalog/Catalog_example.py
View file @
36189a3e
...
...
@@ -4,15 +4,16 @@ import astropy.constants as cons
from
astropy.table
import
Table
from
scipy
import
interpolate
from
ObservationSim.MockObject
import
CatalogBase
,
Star
,
Galaxy
,
Quasar
from
observation_sim.mock_objects
import
CatalogBase
,
Star
,
Galaxy
,
Quasar
class
Catalog
(
CatalogBase
):
"""An user customizable class for reading in catalog(s) of objects and SEDs.
NOTE: must inherit the "CatalogBase" abstract class
...
Attributes
----------
cat_dir : str
...
...
@@ -24,7 +25,7 @@ class Catalog(CatalogBase):
objs : list
a list of ObservationSim.MockObject (Star, Galaxy, or Quasar)
NOTE: must have "obj" list when implement your own Catalog
Methods
----------
load_sed(obj, **kwargs):
...
...
@@ -32,9 +33,10 @@ class Catalog(CatalogBase):
load_norm_filt(obj):
load the filter throughput for the input catalog's photometric system.
"""
def
__init__
(
self
,
config
,
chip
,
**
kwargs
):
"""Constructor method.
Parameters
----------
config : dict
...
...
@@ -44,20 +46,22 @@ class Catalog(CatalogBase):
**kwargs : dict
other needed input parameters (in key-value pairs), please modify corresponding
initialization call in "ObservationSim.py" as you need.
Returns
----------
None
"""
super
().
__init__
()
self
.
cat_dir
=
os
.
path
.
join
(
config
[
"data_dir"
],
config
[
"catalog_options"
][
"input_path"
][
"cat_dir"
])
self
.
cat_dir
=
os
.
path
.
join
(
config
[
"data_dir"
],
config
[
"catalog_options"
][
"input_path"
][
"cat_dir"
])
self
.
chip
=
chip
if
"star_cat"
in
config
[
"catalog_options"
][
"input_path"
]
and
config
[
"catalog_options"
][
"input_path"
][
"star_cat"
]:
star_file
=
config
[
"catalog_options"
][
"input_path"
][
"star_cat"
]
star_SED_file
=
config
[
"catalog_options"
][
"SED_templates_path"
][
"star_SED"
]
self
.
star_path
=
os
.
path
.
join
(
self
.
cat_dir
,
star_file
)
self
.
star_SED_path
=
os
.
path
.
join
(
config
[
"data_dir"
],
star_SED_file
)
self
.
star_SED_path
=
os
.
path
.
join
(
config
[
"data_dir"
],
star_SED_file
)
# NOTE: must call _load() method here to read in all objects
self
.
objs
=
[]
self
.
_load
()
...
...
@@ -67,7 +71,7 @@ class Catalog(CatalogBase):
This is a must implemented method which is used to read in all objects, and
then convert them to ObservationSim.MockObject (Star, Galaxy, or Quasar).
Currently,
the model of ObservationSim.MockObject.Star class requires:
param["star"] : int
...
...
@@ -83,7 +87,7 @@ class Catalog(CatalogBase):
NOTE: if that filter is not the corresponding CSST filter, the
load_norm_filt(obj) function must be implemented to load the filter
throughput of that particular photometric system
the model of ObservationSim.MockObject.Galaxy class requires:
param["star"] : int
specify the object type: 0: galaxy, 1: star, 2: quasar
...
...
@@ -173,7 +177,8 @@ class Catalog(CatalogBase):
"""
if
obj
.
type
==
'star'
:
wave
=
Table
.
read
(
self
.
star_SED_path
,
path
=
f
"/SED/wave_
{
obj
.
model_tag
}
"
)
wave
=
Table
.
read
(
self
.
star_SED_path
,
path
=
f
"/SED/wave_
{
obj
.
model_tag
}
"
)
flux
=
Table
.
read
(
self
.
star_SED_path
,
path
=
f
"/SED/
{
obj
.
sed_type
}
"
)
wave
,
flux
=
wave
[
'col0'
].
data
,
flux
[
'col0'
].
data
else
:
...
...
@@ -203,4 +208,4 @@ class Catalog(CatalogBase):
norm_filt["WAVELENGTH"] : wavelengthes in Angstroms
norm_filt["SENSITIVITY"] : efficiencies
"""
return
None
\ No newline at end of file
return
None
C
atalog/data/SLOAN_SDSS.g.fits
→
c
atalog/data/SLOAN_SDSS.g.fits
View file @
36189a3e
File moved
C
atalog/data/__init__.py
→
c
atalog/data/__init__.py
View file @
36189a3e
File moved
C
atalog/data/lsst_throuput_g.fits
→
c
atalog/data/lsst_throuput_g.fits
View file @
36189a3e
File moved
C
atalog/data/starSpecInterp.so
→
c
atalog/data/starSpecInterp.so
View file @
36189a3e
File moved
C
atalog/testCat_fits.py
→
c
atalog/testCat_fits.py
View file @
36189a3e
...
...
@@ -11,12 +11,12 @@ from astropy.table import Table
from
scipy
import
interpolate
from
datetime
import
datetime
from
O
bservation
S
im.
M
ock
O
bject
import
CatalogBase
,
Star
,
Galaxy
,
Quasar
,
Stamp
from
O
bservation
S
im.
M
ock
O
bject._util
import
tag_sed
,
getObservedSED
,
getABMAG
,
integrate_sed_bandpass
,
comoving_dist
from
O
bservation
S
im.
A
strometry.Astrometry_util
import
on_orbit_obs_position
from
o
bservation
_s
im.
m
ock
_o
bject
s
import
CatalogBase
,
Star
,
Galaxy
,
Quasar
,
Stamp
from
o
bservation
_s
im.
m
ock
_o
bject
s
._util
import
tag_sed
,
getObservedSED
,
getABMAG
,
integrate_sed_bandpass
,
comoving_dist
from
o
bservation
_s
im.
a
strometry.Astrometry_util
import
on_orbit_obs_position
import
astropy.io.fits
as
fitsio
from
O
bservation
S
im.
M
ock
O
bject._util
import
seds
,
sed_assign
,
extAv
from
o
bservation
_s
im.
m
ock
_o
bject
s
._util
import
seds
,
sed_assign
,
extAv
# (TEST)
from
astropy.cosmology
import
FlatLambdaCDM
...
...
@@ -31,11 +31,12 @@ except ImportError:
NSIDE
=
128
class
Catalog
(
CatalogBase
):
def
__init__
(
self
,
config
,
chip
,
pointing
,
chip_output
,
filt
,
**
kwargs
):
super
().
__init__
()
self
.
cat_dir
=
config
[
"catalog_options"
][
"input_path"
][
"cat_dir"
]
self
.
seed_Av
=
121212
#
config["catalog_options"]["seed_Av"]
self
.
seed_Av
=
121212
#
config["catalog_options"]["seed_Av"]
# (TEST)
self
.
cosmo
=
FlatLambdaCDM
(
H0
=
67.66
,
Om0
=
0.3111
)
...
...
@@ -44,11 +45,11 @@ class Catalog(CatalogBase):
self
.
filt
=
filt
self
.
logger
=
chip_output
.
logger
with
pkg_resources
.
path
(
'
C
atalog.data'
,
'SLOAN_SDSS.g.fits'
)
as
filter_path
:
with
pkg_resources
.
path
(
'
c
atalog.data'
,
'SLOAN_SDSS.g.fits'
)
as
filter_path
:
self
.
normF_star
=
Table
.
read
(
str
(
filter_path
))
with
pkg_resources
.
path
(
'
C
atalog.data'
,
'lsst_throuput_g.fits'
)
as
filter_path
:
with
pkg_resources
.
path
(
'
c
atalog.data'
,
'lsst_throuput_g.fits'
)
as
filter_path
:
self
.
normF_galaxy
=
Table
.
read
(
str
(
filter_path
))
self
.
config
=
config
self
.
chip
=
chip
self
.
pointing
=
pointing
...
...
@@ -58,24 +59,27 @@ class Catalog(CatalogBase):
if
"stamp_cat"
in
config
[
"catalog_options"
][
"input_path"
]
and
config
[
"catalog_options"
][
"input_path"
][
"stamp_cat"
]
and
config
[
"catalog_options"
][
"stamp_yes"
]:
stamp_file
=
config
[
"catalog_options"
][
"input_path"
][
"stamp_cat"
]
self
.
stamp_path
=
os
.
path
.
join
(
self
.
cat_dir
,
stamp_file
)
#self.stamp_SED_path = os.path.join(config["data_dir"], config["SED_templates_path"]["stamp_SED"]) ###shoule be stamp-SED
#self._load_SED_lib_stamps() ###shoule be stamp-SED
self
.
tempSed_gal
,
self
.
tempRed_gal
=
seds
(
"galaxy.list"
,
seddir
=
"/public/home/chengliang/CSSOSDataProductsSims/testCats/Templates/Galaxy/"
)
#only for test
# self.stamp_SED_path = os.path.join(config["data_dir"], config["SED_templates_path"]["stamp_SED"]) ###shoule be stamp-SED
# self._load_SED_lib_stamps() ###shoule be stamp-SED
self
.
tempSed_gal
,
self
.
tempRed_gal
=
seds
(
"galaxy.list"
,
seddir
=
"/public/home/chengliang/CSSOSDataProductsSims/testCats/Templates/Galaxy/"
)
# only for test
self
.
_add_output_columns_header
()
self
.
_get_healpix_list
()
self
.
_load
()
def
_add_output_columns_header
(
self
):
self
.
add_hdr
=
" model_tag teff logg feh"
self
.
add_hdr
+=
" bulgemass diskmass detA e1 e2 kappa g1 g2 size galType veldisp "
self
.
add_fmt
=
" %10s %8.4f %8.4f %8.4f"
self
.
add_fmt
+=
" %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f %4d %8.4f "
self
.
chip_output
.
update_output_header
(
additional_column_names
=
self
.
add_hdr
)
self
.
chip_output
.
update_output_header
(
additional_column_names
=
self
.
add_hdr
)
def
_get_healpix_list
(
self
):
self
.
sky_coverage
=
self
.
chip
.
getSkyCoverageEnlarged
(
self
.
chip
.
img
.
wcs
,
margin
=
0.2
)
self
.
sky_coverage
=
self
.
chip
.
getSkyCoverageEnlarged
(
self
.
chip
.
img
.
wcs
,
margin
=
0.2
)
ra_min
,
ra_max
,
dec_min
,
dec_max
=
self
.
sky_coverage
.
xmin
,
self
.
sky_coverage
.
xmax
,
self
.
sky_coverage
.
ymin
,
self
.
sky_coverage
.
ymax
ra
=
np
.
deg2rad
(
np
.
array
([
ra_min
,
ra_max
,
ra_max
,
ra_min
]))
dec
=
np
.
deg2rad
(
np
.
array
([
dec_max
,
dec_max
,
dec_min
,
dec_min
]))
...
...
@@ -94,7 +98,7 @@ class Catalog(CatalogBase):
def
load_norm_filt
(
self
,
obj
):
if
obj
.
type
==
"stamp"
:
return
self
.
normF_galaxy
#
##
normalize_filter for stamp
return
self
.
normF_galaxy
#
normalize_filter for stamp
else
:
return
None
...
...
@@ -102,35 +106,38 @@ class Catalog(CatalogBase):
print
(
"debug:: load_stamps"
)
nstamps
=
len
(
stamps
[
'filename'
])
self
.
rng_sedGal
=
random
.
Random
()
self
.
rng_sedGal
.
seed
(
float
(
pix_id
))
# Use healpix index as the random seed
# Use healpix index as the random seed
self
.
rng_sedGal
.
seed
(
float
(
pix_id
))
self
.
ud
=
galsim
.
UniformDeviate
(
pix_id
)
for
istamp
in
range
(
nstamps
):
print
(
"debug::"
,
istamp
)
fitsfile
=
os
.
path
.
join
(
self
.
cat_dir
,
"stampCats/"
+
stamps
[
'filename'
][
istamp
].
decode
(
'utf-8'
))
fitsfile
=
os
.
path
.
join
(
self
.
cat_dir
,
"stampCats/"
+
stamps
[
'filename'
][
istamp
].
decode
(
'utf-8'
))
print
(
"debug::"
,
istamp
,
fitsfile
)
hdu
=
fitsio
.
open
(
fitsfile
)
hdu
=
fitsio
.
open
(
fitsfile
)
param
=
self
.
initialize_param
()
param
[
'id'
]
=
hdu
[
0
].
header
[
'index'
]
#
istamp
param
[
'id'
]
=
hdu
[
0
].
header
[
'index'
]
#
istamp
param
[
'star'
]
=
3
# Stamp type in .cat file
param
[
'ra'
]
=
hdu
[
0
].
header
[
'ra'
]
param
[
'dec'
]
=
hdu
[
0
].
header
[
'dec'
]
param
[
'pixScale'
]
=
hdu
[
0
].
header
[
'pixScale'
]
#param['srcGalaxyID'] = hdu[0].header['srcGID']
#param['mu']= hdu[0].header['mu']
#param['PA']= hdu[0].header['PA']
#param['bfrac']= hdu[0].header['bfrac']
#param['z']= hdu[0].header['z']
param
[
'mag_use_normal'
]
=
hdu
[
0
].
header
[
'mag_g'
]
#gals['mag_true_g_lsst']
param
[
'dec'
]
=
hdu
[
0
].
header
[
'dec'
]
param
[
'pixScale'
]
=
hdu
[
0
].
header
[
'pixScale'
]
# param['srcGalaxyID'] = hdu[0].header['srcGID']
# param['mu']= hdu[0].header['mu']
# param['PA']= hdu[0].header['PA']
# param['bfrac']= hdu[0].header['bfrac']
# param['z']= hdu[0].header['z']
# gals['mag_true_g_lsst']
param
[
'mag_use_normal'
]
=
hdu
[
0
].
header
[
'mag_g'
]
# Apply astrometric modeling
# in C3 case only aberration
param
[
'ra_orig'
]
=
param
[
'ra'
]
param
[
'dec_orig'
]
=
param
[
'dec'
]
param
[
'dec_orig'
]
=
param
[
'dec'
]
if
self
.
config
[
"obs_setting"
][
"enable_astrometric_model"
]:
ra_list
=
[
param
[
'ra'
]]
#
ra_arr.tolist()
dec_list
=
[
param
[
'dec'
]]
#
dec_arr.tolist()
ra_list
=
[
param
[
'ra'
]]
#
ra_arr.tolist()
dec_list
=
[
param
[
'dec'
]]
#
dec_arr.tolist()
pmra_list
=
np
.
zeros
(
1
).
tolist
()
pmdec_list
=
np
.
zeros
(
1
).
tolist
()
rv_list
=
np
.
zeros
(
1
).
tolist
()
...
...
@@ -157,19 +164,20 @@ class Catalog(CatalogBase):
input_time_str
=
time_str
)
param
[
'ra'
]
=
ra_arr
[
0
]
param
[
'dec'
]
=
dec_arr
[
0
]
param
[
'dec'
]
=
dec_arr
[
0
]
# Assign each galaxy a template SED
param
[
'sed_type'
]
=
sed_assign
(
phz
=
param
[
'z'
],
btt
=
param
[
'bfrac'
],
rng
=
self
.
rng_sedGal
)
param
[
'sed_type'
]
=
sed_assign
(
phz
=
param
[
'z'
],
btt
=
param
[
'bfrac'
],
rng
=
self
.
rng_sedGal
)
param
[
'redden'
]
=
self
.
tempRed_gal
[
param
[
'sed_type'
]]
param
[
'av'
]
=
0.0
param
[
'redden'
]
=
0
param
[
'mu'
]
=
1
#param["CSSTmag"]= True
#param["mag_r"] = 20.
#param['']
###more keywords for stamp###
#
param["CSSTmag"]= True
#
param["mag_r"] = 20.
#
param['']
###
more keywords for stamp###
param
[
'image'
]
=
hdu
[
0
].
data
param
[
'image'
]
=
param
[
'image'
]
/
(
np
.
sum
(
param
[
'image'
]))
obj
=
Stamp
(
param
)
...
...
@@ -181,12 +189,12 @@ class Catalog(CatalogBase):
if
"stamp_cat"
in
self
.
config
[
"catalog_options"
][
"input_path"
]
and
self
.
config
[
"catalog_options"
][
"input_path"
][
"stamp_cat"
]
and
self
.
config
[
"catalog_options"
][
"stamp_yes"
]:
stamps_cat
=
h5
.
File
(
self
.
stamp_path
,
'r'
)[
'Stamps'
]
print
(
"debug::"
,
stamps_cat
.
keys
())
print
(
"debug::"
,
stamps_cat
.
keys
())
for
pix
in
self
.
pix_list
:
try
:
stamps
=
stamps_cat
[
str
(
pix
)]
print
(
"debug::"
,
stamps
.
keys
())
print
(
"debug::"
,
stamps
.
keys
())
self
.
_load_stamps
(
stamps
,
pix_id
=
pix
)
del
stamps
except
Exception
as
e
:
...
...
@@ -194,12 +202,12 @@ class Catalog(CatalogBase):
print
(
e
)
if
self
.
logger
is
not
None
:
self
.
logger
.
info
(
"maximum galaxy size: %.4f"
%
(
self
.
max_size
))
self
.
logger
.
info
(
"number of objects in catalog: %d"
%
(
len
(
self
.
objs
)))
self
.
logger
.
info
(
"maximum galaxy size: %.4f"
%
(
self
.
max_size
))
self
.
logger
.
info
(
"number of objects in catalog: %d"
%
(
len
(
self
.
objs
)))
else
:
print
(
"number of objects in catalog: "
,
len
(
self
.
objs
))
def
load_sed
(
self
,
obj
,
**
kwargs
):
if
obj
.
type
==
'stamp'
:
sed_data
=
getObservedSED
(
...
...
@@ -217,7 +225,7 @@ class Catalog(CatalogBase):
# erg/s/cm2/A --> photon/s/m2/A
all_sed
=
y
*
lamb
/
(
cons
.
h
.
value
*
cons
.
c
.
value
)
*
1e-13
sed
=
Table
(
np
.
array
([
lamb
,
all_sed
]).
T
,
names
=
(
'WAVELENGTH'
,
'FLUX'
))
del
wave
del
flux
return
sed
O
bservation
S
im/ObservationSim.py
→
o
bservation
_s
im/ObservationSim.py
View file @
36189a3e
...
...
@@ -8,24 +8,26 @@ from datetime import datetime
import
traceback
from
ObservationSim.Config
import
ChipOutput
from
ObservationSim.Instrument
import
Telescope
,
Filter
,
FilterParam
,
FocalPlane
,
Chip
from
ObservationSim.Instrument.Chip
import
Effects
from
ObservationSim.Instrument.Chip
import
ChipUtils
as
chip_utils
from
ObservationSim.Astrometry.Astrometry_util
import
on_orbit_obs_position
from
ObservationSim.sim_steps
import
SimSteps
,
SIM_STEP_TYPES
from
observation_sim.config
import
ChipOutput
from
observation_sim.instruments
import
Telescope
,
Filter
,
FilterParam
,
FocalPlane
,
Chip
from
observation_sim.instruments.chip
import
effects
from
observation_sim.instruments.chip
import
chip_utils
as
chip_utils
from
observation_sim.astrometry.Astrometry_util
import
on_orbit_obs_position
from
observation_sim.sim_steps
import
SimSteps
,
SIM_STEP_TYPES
class
Observation
(
object
):
def
__init__
(
self
,
config
,
Catalog
,
work_dir
=
None
,
data_dir
=
None
):
self
.
config
=
config
self
.
tel
=
Telescope
()
self
.
filter_param
=
FilterParam
()
self
.
filter_param
=
FilterParam
()
self
.
Catalog
=
Catalog
def
prepare_chip_for_exposure
(
self
,
chip
,
ra_cen
,
dec_cen
,
pointing
,
wcs_fp
=
None
):
# Get WCS for the focal plane
if
wcs_fp
==
None
:
wcs_fp
=
self
.
focal_plane
.
getTanWCS
(
ra_cen
,
dec_cen
,
pointing
.
img_pa
,
chip
.
pix_scale
)
wcs_fp
=
self
.
focal_plane
.
getTanWCS
(
ra_cen
,
dec_cen
,
pointing
.
img_pa
,
chip
.
pix_scale
)
# Create chip Image
chip
.
img
=
galsim
.
ImageF
(
chip
.
npix_x
,
chip
.
npix_y
)
...
...
@@ -35,29 +37,36 @@ class Observation(object):
# Get random generators for this chip
chip
.
rng_poisson
,
chip
.
poisson_noise
=
chip_utils
.
get_poisson
(
seed
=
int
(
self
.
config
[
"random_seeds"
][
"seed_poisson"
])
+
pointing
.
id
*
30
+
chip
.
chipID
,
sky_level
=
0.
)
# Get flat, shutter, and PRNU images
chip
.
flat_img
,
_
=
chip_utils
.
get_flat
(
img
=
chip
.
img
,
seed
=
int
(
self
.
config
[
"random_seeds"
][
"seed_flat"
]))
chip
.
flat_img
,
_
=
chip_utils
.
get_flat
(
img
=
chip
.
img
,
seed
=
int
(
self
.
config
[
"random_seeds"
][
"seed_flat"
]))
if
chip
.
chipID
>
30
:
chip
.
shutter_img
=
np
.
ones_like
(
chip
.
img
.
array
)
else
:
chip
.
shutter_img
=
Effects
.
ShutterEffectArr
(
chip
.
img
,
t_shutter
=
1.3
,
dist_bearing
=
735
,
dt
=
1E-3
)
chip
.
prnu_img
=
Effects
.
PRNU_Img
(
xsize
=
chip
.
npix_x
,
ysize
=
chip
.
npix_y
,
sigma
=
0.01
,
chip
.
shutter_img
=
effects
.
ShutterEffectArr
(
chip
.
img
,
t_shutter
=
1.3
,
dist_bearing
=
735
,
dt
=
1E-3
)
chip
.
prnu_img
=
effects
.
PRNU_Img
(
xsize
=
chip
.
npix_x
,
ysize
=
chip
.
npix_y
,
sigma
=
0.01
,
seed
=
int
(
self
.
config
[
"random_seeds"
][
"seed_prnu"
]
+
chip
.
chipID
))
return
chip
def
run_one_chip
(
self
,
chip
,
filt
,
pointing
,
chip_output
,
wcs_fp
=
None
,
psf_model
=
None
,
cat_dir
=
None
,
sed_dir
=
None
):
chip_output
.
Log_info
(
':::::::::::::::::::Current Pointing Information::::::::::::::::::'
)
chip_output
.
Log_info
(
':::::::::::::::::::Current Pointing Information::::::::::::::::::'
)
chip_output
.
Log_info
(
"RA: %f, DEC; %f"
%
(
pointing
.
ra
,
pointing
.
dec
))
chip_output
.
Log_info
(
"Time: %s"
%
datetime
.
utcfromtimestamp
(
pointing
.
timestamp
).
isoformat
())
chip_output
.
Log_info
(
"Time: %s"
%
datetime
.
utcfromtimestamp
(
pointing
.
timestamp
).
isoformat
())
chip_output
.
Log_info
(
"Exposure time: %f"
%
pointing
.
exp_time
)
chip_output
.
Log_info
(
"Satellite Position (x, y, z): (%f, %f, %f)"
%
(
pointing
.
sat_x
,
pointing
.
sat_y
,
pointing
.
sat_z
))
chip_output
.
Log_info
(
"Satellite Velocity (x, y, z): (%f, %f, %f)"
%
(
pointing
.
sat_vx
,
pointing
.
sat_vy
,
pointing
.
sat_vz
))
chip_output
.
Log_info
(
"Satellite Position (x, y, z): (%f, %f, %f)"
%
(
pointing
.
sat_x
,
pointing
.
sat_y
,
pointing
.
sat_z
))
chip_output
.
Log_info
(
"Satellite Velocity (x, y, z): (%f, %f, %f)"
%
(
pointing
.
sat_vx
,
pointing
.
sat_vy
,
pointing
.
sat_vz
))
chip_output
.
Log_info
(
"Position Angle: %f"
%
pointing
.
img_pa
.
deg
)
chip_output
.
Log_info
(
'Chip : %d'
%
chip
.
chipID
)
chip_output
.
Log_info
(
':::::::::::::::::::::::::::END:::::::::::::::::::::::::::::::::::'
)
chip_output
.
Log_info
(
':::::::::::::::::::::::::::END:::::::::::::::::::::::::::::::::::'
)
# Apply astrometric simulation for pointing
if
self
.
config
[
"obs_setting"
][
"enable_astrometric_model"
]:
...
...
@@ -91,32 +100,35 @@ class Observation(object):
chip
=
self
.
prepare_chip_for_exposure
(
chip
,
ra_cen
,
dec_cen
,
pointing
)
# Initialize SimSteps
sim_steps
=
SimSteps
(
overall_config
=
self
.
config
,
chip_output
=
chip_output
,
all_filters
=
self
.
all_filters
)
sim_steps
=
SimSteps
(
overall_config
=
self
.
config
,
chip_output
=
chip_output
,
all_filters
=
self
.
all_filters
)
for
step
in
pointing
.
obs_param
[
"call_sequence"
]:
if
self
.
config
[
"run_option"
][
"out_cat_only"
]:
if
step
!=
"scie_obs"
:
continue
chip_output
.
Log_info
(
"Starting simulation step: %s, calling function: %s"
%
(
step
,
SIM_STEP_TYPES
[
step
]))
chip_output
.
Log_info
(
"Starting simulation step: %s, calling function: %s"
%
(
step
,
SIM_STEP_TYPES
[
step
]))
obs_param
=
pointing
.
obs_param
[
"call_sequence"
][
step
]
step_name
=
SIM_STEP_TYPES
[
step
]
try
:
step_func
=
getattr
(
sim_steps
,
step_name
)
chip
,
filt
,
tel
,
pointing
=
step_func
(
chip
=
chip
,
filt
=
filt
,
chip
=
chip
,
filt
=
filt
,
tel
=
self
.
tel
,
pointing
=
pointing
,
catalog
=
self
.
Catalog
,
pointing
=
pointing
,
catalog
=
self
.
Catalog
,
obs_param
=
obs_param
)
chip_output
.
Log_info
(
"Finished simulation step: %s"
%
(
step
))
chip_output
.
Log_info
(
"Finished simulation step: %s"
%
(
step
))
except
Exception
as
e
:
traceback
.
print_exc
()
chip_output
.
Log_error
(
e
)
chip_output
.
Log_error
(
"Failed simulation on step: %s"
%
(
step
))
chip_output
.
Log_error
(
"Failed simulation on step: %s"
%
(
step
))
break
chip_output
.
Log_info
(
"check running:1: pointing-%d chip-%d pid-%d memory-%6.2fGB"
%
(
pointing
.
id
,
chip
.
chipID
,
os
.
getpid
(),
(
psutil
.
Process
(
os
.
getpid
()).
memory_info
().
rss
/
1024
/
1024
/
1024
)
))
chip_output
.
Log_info
(
"check running:1: pointing-%d chip-%d pid-%d memory-%6.2fGB"
%
(
pointing
.
id
,
chip
.
chipID
,
os
.
getpid
(),
(
psutil
.
Process
(
os
.
getpid
()).
memory_info
().
rss
/
1024
/
1024
/
1024
)))
del
chip
.
img
def
runExposure_MPI_PointingList
(
self
,
pointing_list
,
chips
=
None
):
...
...
@@ -131,9 +143,11 @@ class Observation(object):
# pointing_ID = pointing.id
pointing_ID
=
pointing
.
obs_id
pointing
.
make_output_pointing_dir
(
overall_config
=
self
.
config
,
copy_obs_config
=
True
)
pointing
.
make_output_pointing_dir
(
overall_config
=
self
.
config
,
copy_obs_config
=
True
)
self
.
focal_plane
=
FocalPlane
(
chip_list
=
pointing
.
obs_param
[
"run_chips"
])
self
.
focal_plane
=
FocalPlane
(
chip_list
=
pointing
.
obs_param
[
"run_chips"
])
# Make Chip & Filter lists
self
.
chip_list
=
[]
self
.
filter_list
=
[]
...
...
@@ -167,7 +181,7 @@ class Observation(object):
run_chips
.
append
(
chip
)
run_filts
.
append
(
filt
)
nchips_per_fp
=
len
(
chips
)
for
ichip
in
range
(
nchips_per_fp
):
i_process
=
process_counter
+
ichip
if
i_process
%
num_thread
!=
ind_thread
:
...
...
@@ -176,20 +190,22 @@ class Observation(object):
chip
=
run_chips
[
ichip
]
filt
=
run_filts
[
ichip
]
chip_output
=
ChipOutput
(
config
=
self
.
config
,
chip
=
chip
,
filt
=
filt
,
pointing
=
pointing
config
=
self
.
config
,
chip
=
chip
,
filt
=
filt
,
pointing
=
pointing
)
chip_output
.
Log_info
(
"running pointing#%d, chip#%d, at PID#%d..."
%
(
int
(
pointing_ID
),
chip
.
chipID
,
pid
))
chip_output
.
Log_info
(
"running pointing#%d, chip#%d, at PID#%d..."
%
(
int
(
pointing_ID
),
chip
.
chipID
,
pid
))
self
.
run_one_chip
(
chip
=
chip
,
filt
=
filt
,
chip_output
=
chip_output
,
pointing
=
pointing
)
chip_output
.
Log_info
(
"finished running chip#%d..."
%
(
chip
.
chipID
))
chip_output
.
Log_info
(
"finished running chip#%d..."
%
(
chip
.
chipID
))
for
handler
in
chip_output
.
logger
.
handlers
[:]:
chip_output
.
logger
.
removeHandler
(
handler
)
gc
.
collect
()
...
...
O
bservation
S
im/PSF/FieldDistortion.py
→
o
bservation
_s
im/PSF/FieldDistortion.py
View file @
36189a3e
...
...
@@ -2,6 +2,7 @@ import galsim
import
numpy
as
np
import
cmath
class
FieldDistortion
(
object
):
def
__init__
(
self
,
chip
,
fdModel
=
None
,
fdModel_path
=
None
,
img_rot
=
0.
):
...
...
@@ -13,7 +14,8 @@ class FieldDistortion(object):
with
open
(
fdModel_path
,
"rb"
)
as
f
:
self
.
fdModel
=
pickle
.
load
(
f
)
else
:
raise
ValueError
(
"Error: no field distortion model has been specified!"
)
raise
ValueError
(
"Error: no field distortion model has been specified!"
)
else
:
self
.
fdModel
=
fdModel
self
.
img_rot
=
img_rot
...
...
@@ -21,19 +23,20 @@ class FieldDistortion(object):
self
.
ixfdModel
=
self
.
ifdModel
[
"xImagePos"
]
self
.
iyfdModel
=
self
.
ifdModel
[
"yImagePos"
]
# first-order derivatives of the global field distortion model
self
.
ifx_dx
=
self
.
ixfdModel
.
partial_derivative
(
1
,
0
)
self
.
ifx_dy
=
self
.
ixfdModel
.
partial_derivative
(
0
,
1
)
self
.
ify_dx
=
self
.
iyfdModel
.
partial_derivative
(
1
,
0
)
self
.
ify_dy
=
self
.
iyfdModel
.
partial_derivative
(
0
,
1
)
self
.
ifx_dx
=
self
.
ixfdModel
.
partial_derivative
(
1
,
0
)
self
.
ifx_dy
=
self
.
ixfdModel
.
partial_derivative
(
0
,
1
)
self
.
ify_dx
=
self
.
iyfdModel
.
partial_derivative
(
1
,
0
)
self
.
ify_dy
=
self
.
iyfdModel
.
partial_derivative
(
0
,
1
)
if
"residual"
in
self
.
fdModel
[
"wave1"
]:
self
.
irsModel
=
self
.
fdModel
[
"wave1"
][
"residual"
][
"ccd"
+
chip
.
getChipLabel
(
chipID
=
chip
.
chipID
)]
self
.
irsModel
=
self
.
fdModel
[
"wave1"
][
"residual"
][
"ccd"
+
chip
.
getChipLabel
(
chipID
=
chip
.
chipID
)]
self
.
ixrsModel
=
self
.
irsModel
[
"xResidual"
]
self
.
iyrsModel
=
self
.
irsModel
[
"yResidual"
]
# first-order derivatives of the residual field distortion model
self
.
irx_dx
=
self
.
ixrsModel
.
partial_derivative
(
1
,
0
)
self
.
irx_dy
=
self
.
ixrsModel
.
partial_derivative
(
0
,
1
)
self
.
iry_dx
=
self
.
iyrsModel
.
partial_derivative
(
1
,
0
)
self
.
iry_dy
=
self
.
iyrsModel
.
partial_derivative
(
0
,
1
)
self
.
irx_dx
=
self
.
ixrsModel
.
partial_derivative
(
1
,
0
)
self
.
irx_dy
=
self
.
ixrsModel
.
partial_derivative
(
0
,
1
)
self
.
iry_dx
=
self
.
iyrsModel
.
partial_derivative
(
1
,
0
)
self
.
iry_dy
=
self
.
iyrsModel
.
partial_derivative
(
0
,
1
)
else
:
self
.
irsModel
=
None
...
...
@@ -95,8 +98,8 @@ class FieldDistortion(object):
ix_dy
=
self
.
ifx_dy
(
x
,
y
)
iy_dx
=
self
.
ify_dx
(
x
,
y
)
iy_dy
=
self
.
ify_dy
(
x
,
y
)
g1k_fd
=
0.0
+
(
iy_dy
-
ix_dx
)
/
(
iy_dy
+
ix_dx
)
g2k_fd
=
0.0
-
(
iy_dx
+
ix_dy
)
/
(
iy_dy
+
ix_dx
)
g1k_fd
=
0.0
+
(
iy_dy
-
ix_dx
)
/
(
iy_dy
+
ix_dx
)
g2k_fd
=
0.0
-
(
iy_dx
+
ix_dy
)
/
(
iy_dy
+
ix_dx
)
# [TODO] [TESTING] Rotate the shear:
g_abs
=
np
.
sqrt
(
g1k_fd
**
2
+
g2k_fd
**
2
)
...
...
@@ -107,4 +110,3 @@ class FieldDistortion(object):
fd_shear
=
galsim
.
Shear
(
g1
=
g1k_fd
,
g2
=
g2k_fd
)
return
galsim
.
PositionD
(
x
,
y
),
fd_shear
observation_sim/PSF/PSFGauss.py
0 → 100644
View file @
36189a3e
import
galsim
import
sep
import
numpy
as
np
from
scipy.interpolate
import
interp1d
from
observation_sim.PSF.PSFModel
import
PSFModel
class
PSFGauss
(
PSFModel
):
def
__init__
(
self
,
chip
,
fwhm
=
0.187
,
sigSpin
=
0.
,
psfRa
=
None
):
self
.
pix_size
=
chip
.
pix_scale
self
.
chip
=
chip
if
psfRa
is
None
:
self
.
fwhm
=
fwhm
self
.
sigGauss
=
0.15
else
:
self
.
fwhm
=
self
.
fwhmGauss
(
r
=
psfRa
)
self
.
sigGauss
=
psfRa
# 80% light radius
self
.
sigSpin
=
sigSpin
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
"""
def
gaussFun
(
sigma
,
r
):
return
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
)
return
flux
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
O
bservation
S
im/PSF/PSFInterp.py
→
o
bservation
_s
im/PSF/PSFInterp.py
View file @
36189a3e
...
...
@@ -12,14 +12,14 @@ import scipy.spatial as spatial
import
galsim
import
h5py
from
O
bservation
S
im.PSF.PSFModel
import
PSFModel
from
o
bservation
_s
im.PSF.PSFModel
import
PSFModel
NPSF
=
900
#***# 30*30
PixSizeInMicrons
=
5.
#***# in microns
NPSF
=
900
#
***# 30*30
PixSizeInMicrons
=
5.
#
***# in microns
###find neighbors-KDtree###
###
find neighbors-KDtree###
def
findNeighbors
(
tx
,
ty
,
px
,
py
,
dr
=
0.1
,
dn
=
1
,
OnlyDistance
=
True
):
"""
find nearest neighbors by 2D-KDTree
...
...
@@ -38,7 +38,7 @@ def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True):
datay
=
py
tree
=
spatial
.
KDTree
(
list
(
zip
(
datax
.
ravel
(),
datay
.
ravel
())))
dataq
=
[]
dataq
=
[]
rr
=
dr
if
OnlyDistance
==
True
:
dataq
=
tree
.
query_ball_point
([
tx
,
ty
],
rr
)
...
...
@@ -51,7 +51,9 @@ def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True):
dataq
=
np
.
array
(
dataq
)[
ddSortindx
[
0
:
dn
]]
return
dataq
###find neighbors-hoclist###
### find neighbors-hoclist###
def
hocBuild
(
partx
,
party
,
nhocx
,
nhocy
,
dhocx
,
dhocy
):
if
np
.
max
(
partx
)
>
nhocx
*
dhocx
:
print
(
'ERROR'
)
...
...
@@ -60,8 +62,8 @@ def hocBuild(partx, party, nhocx, nhocy, dhocx, dhocy):
print
(
'ERROR'
)
sys
.
exit
()
npart
=
partx
.
size
hoclist
=
np
.
zeros
(
npart
,
dtype
=
np
.
int32
)
-
1
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
)
...
...
@@ -70,18 +72,20 @@ def hocBuild(partx, party, nhocx, nhocy, dhocx, dhocy):
hoc
[
iy
,
ix
]
=
ipart
return
hoc
,
hoclist
def
hocFind
(
px
,
py
,
dhocx
,
dhocy
,
hoc
,
hoclist
):
ix
=
int
(
px
/
dhocx
)
iy
=
int
(
py
/
dhocy
)
neigh
=
[]
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
):
def
findNeighbors_hoclist
(
px
,
py
,
tx
=
None
,
ty
=
None
,
dn
=
4
,
hoc
=
None
,
hoclist
=
None
):
nhocy
=
nhocx
=
20
pxMin
=
np
.
min
(
px
)
...
...
@@ -91,21 +95,21 @@ def findNeighbors_hoclist(px, py, tx=None,ty=None, dn=4, hoc=None, hoclist=None)
dhocx
=
(
pxMax
-
pxMin
)
/
(
nhocx
-
1
)
dhocy
=
(
pyMax
-
pyMin
)
/
(
nhocy
-
1
)
partx
=
px
-
pxMin
+
dhocx
/
2
party
=
py
-
pyMin
+
dhocy
/
2
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
tx
=
tx
-
pxMin
+
dhocx
/
2
ty
=
ty
-
pyMin
+
dhocy
/
2
itx
=
int
(
tx
/
dhocx
)
ity
=
int
(
ty
/
dhocy
)
ps
=
[
-
1
,
0
,
1
]
neigh
=
[]
neigh
=
[]
for
ii
in
range
(
3
):
for
jj
in
range
(
3
):
ix
=
itx
+
ps
[
ii
]
...
...
@@ -119,23 +123,23 @@ def findNeighbors_hoclist(px, py, tx=None,ty=None, dn=4, hoc=None, hoclist=None)
if
iy
>
nhocy
-
1
:
continue
#neightt = myUtil.hocFind(ppx, ppy, dhocx, dhocy, hoc, hoclist)
#
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]
#
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
)
dd
=
np
.
hypot
(
ptx
-
tx
,
pty
-
ty
)
idx
=
np
.
argsort
(
dd
)
neigh
=
np
.
array
(
neigh
)[
idx
[
0
:
dn
]]
neigh
=
np
.
array
(
neigh
)[
idx
[
0
:
dn
]]
return
neigh
###PSF-IDW###
###
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
...
...
@@ -161,9 +165,11 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru
if
OnlyNeighbors
==
True
:
if
hoc
is
None
:
neigh
=
findNeighbors
(
px
,
py
,
cen_col
,
cen_row
,
dr
=
5.
,
dn
=
4
,
OnlyDistance
=
False
)
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
)
neigh
=
findNeighbors_hoclist
(
cen_col
,
cen_row
,
tx
=
px
,
ty
=
py
,
dn
=
4
,
hoc
=
hoc
,
hoclist
=
hoclist
)
neighFlag
=
np
.
zeros
(
npsf
)
neighFlag
[
neigh
]
=
1
...
...
@@ -173,7 +179,8 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru
if
neighFlag
[
ipsf
]
!=
1
:
continue
dist
=
np
.
sqrt
((
ref_col
-
cen_col
[
ipsf
])
**
2
+
(
ref_row
-
cen_row
[
ipsf
])
**
2
)
dist
=
np
.
sqrt
((
ref_col
-
cen_col
[
ipsf
])
**
2
+
(
ref_row
-
cen_row
[
ipsf
])
**
2
)
if
IDWindex
==
1
:
psfWeight
[
ipsf
]
=
dist
if
IDWindex
==
2
:
...
...
@@ -186,7 +193,7 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru
psfWeight
[
ipsf
]
=
1.
/
psfWeight
[
ipsf
]
psfWeight
/=
np
.
sum
(
psfWeight
)
psfMaker
=
np
.
zeros
([
ngy
,
ngx
],
dtype
=
np
.
float32
)
psfMaker
=
np
.
zeros
([
ngy
,
ngx
],
dtype
=
np
.
float32
)
for
ipsf
in
range
(
npsf
):
if
OnlyNeighbors
==
True
:
if
neighFlag
[
ipsf
]
!=
1
:
...
...
@@ -201,15 +208,14 @@ def psfMaker_IDW(px, py, PSFMat, cen_col, cen_row, IDWindex=2, OnlyNeighbors=Tru
return
psfMaker
###define PSFInterp###
### define PSFInterp###
class
PSFInterp
(
PSFModel
):
def
__init__
(
self
,
chip
,
npsf
=
NPSF
,
PSF_data
=
None
,
PSF_data_file
=
None
,
PSF_data_prefix
=
""
,
sigSpin
=
0
,
psfRa
=
0.15
,
HocBuild
=
False
,
LOG_DEBUG
=
False
):
self
.
LOG_DEBUG
=
LOG_DEBUG
if
self
.
LOG_DEBUG
:
print
(
'==================================================='
)
print
(
'DEBUG: psf module for csstSim '
\
+
time
.
strftime
(
"(%Y-%m-%d %H:%M:%S)"
,
time
.
localtime
()),
flush
=
True
)
print
(
'DEBUG: psf module for csstSim '
+
time
.
strftime
(
"(%Y-%m-%d %H:%M:%S)"
,
time
.
localtime
()),
flush
=
True
)
print
(
'==================================================='
)
self
.
sigSpin
=
sigSpin
...
...
@@ -221,53 +227,62 @@ class PSFInterp(PSFModel):
print
(
'Error - PSF_data_file is None'
)
sys
.
exit
()
self
.
nwave
=
self
.
_getPSFwave
(
self
.
iccd
,
PSF_data_file
,
PSF_data_prefix
)
self
.
nwave
=
self
.
_getPSFwave
(
self
.
iccd
,
PSF_data_file
,
PSF_data_prefix
)
self
.
npsf
=
npsf
self
.
PSF_data
=
self
.
_loadPSF
(
self
.
iccd
,
PSF_data_file
,
PSF_data_prefix
)
self
.
PSF_data
=
self
.
_loadPSF
(
self
.
iccd
,
PSF_data_file
,
PSF_data_prefix
)
if
self
.
LOG_DEBUG
:
print
(
'nwave-{:} on ccd-{:}::'
.
format
(
self
.
nwave
,
self
.
iccd
),
flush
=
True
)
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
,
self
.
npsf
,
ngy
,
ngx
],
dtype
=
np
.
float32
)
self
.
cen_col
=
np
.
zeros
([
self
.
nwave
,
self
.
npsf
],
dtype
=
np
.
float32
)
self
.
cen_row
=
np
.
zeros
([
self
.
nwave
,
self
.
npsf
],
dtype
=
np
.
float32
)
self
.
hoc
=
[]
self
.
hoclist
=
[]
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
,
self
.
npsf
,
ngy
,
ngx
],
dtype
=
np
.
float32
)
self
.
cen_col
=
np
.
zeros
([
self
.
nwave
,
self
.
npsf
],
dtype
=
np
.
float32
)
self
.
cen_row
=
np
.
zeros
([
self
.
nwave
,
self
.
npsf
],
dtype
=
np
.
float32
)
self
.
hoc
=
[]
self
.
hoclist
=
[]
for
twave
in
range
(
self
.
nwave
):
for
tpsf
in
range
(
self
.
npsf
):
self
.
psfMat
[
twave
,
tpsf
,
:,
:]
=
self
.
PSF_data
[
twave
][
tpsf
][
'psfMat'
]
self
.
PSF_data
[
twave
][
tpsf
][
'psfMat'
]
=
0
###free psfMat
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'
]
+
self
.
PSF_data
[
twave
][
tpsf
][
'centroid_x'
]
self
.
cen_row
[
twave
,
tpsf
]
=
self
.
PSF_data
[
twave
][
tpsf
][
'image_y'
]
+
self
.
PSF_data
[
twave
][
tpsf
][
'centroid_y'
]
self
.
pixsize
=
self
.
PSF_data
[
twave
][
tpsf
][
'pixsize'
]
*
1e-3
# mm
self
.
cen_col
[
twave
,
tpsf
]
=
self
.
PSF_data
[
twave
][
tpsf
][
'image_x'
]
+
\
self
.
PSF_data
[
twave
][
tpsf
][
'centroid_x'
]
self
.
cen_row
[
twave
,
tpsf
]
=
self
.
PSF_data
[
twave
][
tpsf
][
'image_y'
]
+
\
self
.
PSF_data
[
twave
][
tpsf
][
'centroid_y'
]
if
HocBuild
:
#hoclist on twave for neighborsFinding
hoc
,
hoclist
=
findNeighbors_hoclist
(
self
.
cen_col
[
twave
],
self
.
cen_row
[
twave
])
# hoclist on twave for neighborsFinding
hoc
,
hoclist
=
findNeighbors_hoclist
(
self
.
cen_col
[
twave
],
self
.
cen_row
[
twave
])
self
.
hoc
.
append
(
hoc
)
self
.
hoclist
.
append
(
hoclist
)
if
self
.
LOG_DEBUG
:
print
(
'ok'
,
flush
=
True
)
def
_getPSFwave
(
self
,
iccd
,
PSF_data_file
,
PSF_data_prefix
):
# fq = h5py.File(PSF_data_file+'/' +PSF_data_prefix +'psfCube_ccd{:}.h5'.format(iccd), 'r')
fq
=
h5py
.
File
(
PSF_data_file
+
'/'
+
PSF_data_prefix
+
'psfCube_{:}.h5'
.
format
(
iccd
),
'r'
)
fq
=
h5py
.
File
(
PSF_data_file
+
'/'
+
PSF_data_prefix
+
'psfCube_{:}.h5'
.
format
(
iccd
),
'r'
)
nwave
=
len
(
fq
.
keys
())
fq
.
close
()
return
nwave
def
_loadPSF
(
self
,
iccd
,
PSF_data_file
,
PSF_data_prefix
):
psfSet
=
[]
# fq = h5py.File(PSF_data_file+'/' +PSF_data_prefix +'psfCube_ccd{:}.h5'.format(iccd), 'r')
fq
=
h5py
.
File
(
PSF_data_file
+
'/'
+
PSF_data_prefix
+
'psfCube_{:}.h5'
.
format
(
iccd
),
'r'
)
fq
=
h5py
.
File
(
PSF_data_file
+
'/'
+
PSF_data_prefix
+
'psfCube_{:}.h5'
.
format
(
iccd
),
'r'
)
for
ii
in
range
(
self
.
nwave
):
iwave
=
ii
+
1
psfWave
=
[]
...
...
@@ -276,30 +291,30 @@ class PSFInterp(PSFModel):
for
jj
in
range
(
self
.
npsf
):
ipsf
=
jj
+
1
psfInfo
=
{}
psfInfo
[
'wavelength'
]
=
fq_iwave
[
'wavelength'
][()]
psfInfo
[
'wavelength'
]
=
fq_iwave
[
'wavelength'
][()]
fq_iwave_ipsf
=
fq_iwave
[
'psf_{:}'
.
format
(
ipsf
)]
psfInfo
[
'pixsize'
]
=
PixSizeInMicrons
psfInfo
[
'field_x'
]
=
fq_iwave_ipsf
[
'field_x'
][()]
psfInfo
[
'field_y'
]
=
fq_iwave_ipsf
[
'field_y'
][()]
psfInfo
[
'image_x'
]
=
fq_iwave_ipsf
[
'image_x'
][()]
psfInfo
[
'image_y'
]
=
fq_iwave_ipsf
[
'image_y'
][()]
psfInfo
[
'centroid_x'
]
=
fq_iwave_ipsf
[
'cx'
][()]
psfInfo
[
'centroid_y'
]
=
fq_iwave_ipsf
[
'cy'
][()]
psfInfo
[
'psfMat'
]
=
fq_iwave_ipsf
[
'psfMat'
][()]
psfInfo
[
'pixsize'
]
=
PixSizeInMicrons
psfInfo
[
'field_x'
]
=
fq_iwave_ipsf
[
'field_x'
][()]
psfInfo
[
'field_y'
]
=
fq_iwave_ipsf
[
'field_y'
][()]
psfInfo
[
'image_x'
]
=
fq_iwave_ipsf
[
'image_x'
][()]
psfInfo
[
'image_y'
]
=
fq_iwave_ipsf
[
'image_y'
][()]
psfInfo
[
'centroid_x'
]
=
fq_iwave_ipsf
[
'cx'
][()]
psfInfo
[
'centroid_y'
]
=
fq_iwave_ipsf
[
'cy'
][()]
psfInfo
[
'psfMat'
]
=
fq_iwave_ipsf
[
'psfMat'
][()]
psfWave
.
append
(
psfInfo
)
psfSet
.
append
(
psfWave
)
fq
.
close
()
if
self
.
LOG_DEBUG
:
print
(
'psfSet has been loaded:'
,
flush
=
True
)
print
(
'psfSet[iwave][ipsf][keys]:'
,
psfSet
[
0
][
0
].
keys
(),
flush
=
True
)
print
(
'psfSet[iwave][ipsf][keys]:'
,
psfSet
[
0
][
0
].
keys
(),
flush
=
True
)
return
psfSet
def
_findWave
(
self
,
bandpass
):
if
isinstance
(
bandpass
,
int
):
if
isinstance
(
bandpass
,
int
):
twave
=
bandpass
return
twave
...
...
@@ -308,7 +323,6 @@ class PSFInterp(PSFModel):
if
bandpass
.
blue_limit
<
bandwave
and
bandwave
<
bandpass
.
red_limit
:
return
twave
return
-
1
def
get_PSF
(
self
,
chip
,
pos_img
,
bandpass
,
galsimGSObject
=
True
,
findNeighMode
=
'treeFind'
,
folding_threshold
=
5.e-3
,
pointing_pa
=
0.0
):
"""
...
...
@@ -323,7 +337,7 @@ class PSFInterp(PSFModel):
Returns:
PSF: A 'galsim.GSObject'.
"""
pixSize
=
np
.
rad2deg
(
self
.
pixsize
*
1e-3
/
28
)
*
3600
#set psf pixsize
pixSize
=
np
.
rad2deg
(
self
.
pixsize
*
1e-3
/
28
)
*
3600
#
set psf pixsize
# assert self.iccd == int(chip.getChipLabel(chipID=chip.chipID)), 'ERROR: self.iccd != chip.chipID'
twave
=
self
.
_findWave
(
bandpass
)
...
...
@@ -331,16 +345,18 @@ class PSFInterp(PSFModel):
print
(
"!!!PSF bandpass does not match."
)
exit
()
PSFMat
=
self
.
psfMat
[
twave
]
cen_col
=
self
.
cen_col
[
twave
]
cen_row
=
self
.
cen_row
[
twave
]
cen_col
=
self
.
cen_col
[
twave
]
cen_row
=
self
.
cen_row
[
twave
]
px
=
(
pos_img
.
x
-
chip
.
cen_pix_x
)
*
0.01
py
=
(
pos_img
.
y
-
chip
.
cen_pix_y
)
*
0.01
if
findNeighMode
==
'treeFind'
:
imPSF
=
psfMaker_IDW
(
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
IDWindex
=
2
,
OnlyNeighbors
=
True
,
PSFCentroidWgt
=
True
)
imPSF
=
psfMaker_IDW
(
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
IDWindex
=
2
,
OnlyNeighbors
=
True
,
PSFCentroidWgt
=
True
)
if
findNeighMode
==
'hoclistFind'
:
assert
(
self
.
hoc
!=
0
),
'hoclist should be built correctly!'
imPSF
=
psfMaker_IDW
(
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
IDWindex
=
2
,
OnlyNeighbors
=
True
,
hoc
=
self
.
hoc
[
twave
],
hoclist
=
self
.
hoclist
[
twave
],
PSFCentroidWgt
=
True
)
assert
(
self
.
hoc
!=
0
),
'hoclist should be built correctly!'
imPSF
=
psfMaker_IDW
(
px
,
py
,
PSFMat
,
cen_col
,
cen_row
,
IDWindex
=
2
,
OnlyNeighbors
=
True
,
hoc
=
self
.
hoc
[
twave
],
hoclist
=
self
.
hoclist
[
twave
],
PSFCentroidWgt
=
True
)
'''
############TEST: START
...
...
@@ -353,20 +369,21 @@ class PSFInterp(PSFModel):
'''
if
galsimGSObject
:
imPSFt
=
np
.
zeros
([
257
,
257
])
imPSFt
=
np
.
zeros
([
257
,
257
])
imPSFt
[
0
:
256
,
0
:
256
]
=
imPSF
# imPSFt[120:130, 0:256] = 1.
img
=
galsim
.
ImageF
(
imPSFt
,
scale
=
pixSize
)
gsp
=
galsim
.
GSParams
(
folding_threshold
=
folding_threshold
)
#
###########
TEST: START
#
TEST: START
# Use sheared PSF to test the PSF orientation
# self.psf = galsim.InterpolatedImage(img, gsparams=gsp).shear(g1=0.8, g2=0.)
#
###########
TEST: END
#
TEST: END
self
.
psf
=
galsim
.
InterpolatedImage
(
img
,
gsparams
=
gsp
)
wcs
=
chip
.
img
.
wcs
.
local
(
pos_img
)
scale
=
galsim
.
PixelScale
(
0.074
)
self
.
psf
=
wcs
.
toWorld
(
scale
.
toImage
(
self
.
psf
),
image_pos
=
(
pos_img
))
self
.
psf
=
wcs
.
toWorld
(
scale
.
toImage
(
self
.
psf
),
image_pos
=
(
pos_img
))
# return self.PSFspin(x=px/0.01, y=py/0.01)
return
self
.
psf
,
galsim
.
Shear
(
e
=
0.
,
beta
=
(
np
.
pi
/
2
)
*
galsim
.
radians
)
...
...
O
bservation
S
im/PSF/PSFInterpSLS.py
→
o
bservation
_s
im/PSF/PSFInterpSLS.py
View file @
36189a3e
...
...
@@ -4,6 +4,7 @@ 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
yaml
import
sys
import
time
import
copy
...
...
@@ -12,8 +13,9 @@ import scipy.spatial as spatial
import
galsim
import
h5py
from
ObservationSim.PSF.PSFModel
import
PSFModel
from
ObservationSim.Instrument.Chip
import
ChipUtils
as
chip_utils
from
observation_sim.instruments
import
Filter
,
FilterParam
,
Chip
from
observation_sim.PSF.PSFModel
import
PSFModel
from
observation_sim.instruments.chip
import
chip_utils
import
os
from
astropy.io
import
fits
...
...
@@ -21,12 +23,12 @@ from astropy.modeling.models import Gaussian2D
from
scipy
import
signal
LOG_DEBUG
=
False
#***#
NPSF
=
900
#***# 30*30
P
ixSizeInMicrons
=
5.
#***# in microns
LOG_DEBUG
=
False
#
***#
NPSF
=
900
#
***# 30*30
P
IX_SIZE_MICRON
=
5.
#
***# in microns
###find neighbors-KDtree###
###
find neighbors-KDtree###
# def findNeighbors(tx, ty, px, py, dr=0.1, dn=1, OnlyDistance=True):
# """
# find nearest neighbors by 2D-KDTree
...
...
@@ -208,36 +210,35 @@ PixSizeInMicrons = 5. #***# in microns
# return psfMaker
###define PSFInterp###
### define PSFInterp###
class
PSFInterpSLS
(
PSFModel
):
def
__init__
(
self
,
chip
,
filt
,
PSF_data_prefix
=
""
,
sigSpin
=
0
,
psfRa
=
0.15
,
pix_size
=
0.005
):
def
__init__
(
self
,
chip
,
filt
,
PSF_data_prefix
=
""
,
sigSpin
=
0
,
psfRa
=
0.15
,
pix_size
=
0.005
):
if
LOG_DEBUG
:
print
(
'==================================================='
)
print
(
'DEBUG: psf module for csstSim '
\
+
time
.
strftime
(
"(%Y-%m-%d %H:%M:%S)"
,
time
.
localtime
()),
flush
=
True
)
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
.
grating_ids
=
chip_utils
.
getChipSLSGratingID
(
chip
.
chipID
)
_
,
self
.
grating_type
=
chip
.
getChipFilter
(
chipID
=
chip
.
chipID
)
_
,
self
.
grating_type
=
chip
.
getChipFilter
(
chipID
=
chip
.
chipID
)
self
.
data_folder
=
PSF_data_prefix
self
.
getPSFDataFromFile
(
filt
)
self
.
pixsize
=
pix_size
# um
self
.
pixsize
=
pix_size
# um
def
getPSFDataFromFile
(
self
,
filt
):
gratingInwavelist
=
{
'GU'
:
0
,
'GV'
:
1
,
'GI'
:
2
}
grating_orders
=
[
'0'
,
'1'
]
gratingInwavelist
=
{
'GU'
:
0
,
'GV'
:
1
,
'GI'
:
2
}
grating_orders
=
[
'0'
,
'1'
]
waveListFn
=
self
.
data_folder
+
'/wavelist.dat'
wavelists
=
np
.
loadtxt
(
waveListFn
)
self
.
waveList
=
wavelists
[:,
gratingInwavelist
[
self
.
grating_type
]]
bandranges
=
np
.
zeros
([
4
,
2
])
self
.
waveList
=
wavelists
[:,
gratingInwavelist
[
self
.
grating_type
]]
bandranges
=
np
.
zeros
([
4
,
2
])
midBand
=
(
self
.
waveList
[
0
:
3
]
+
self
.
waveList
[
1
:
4
])
/
2.
*
10000.
bandranges
[
0
,
0
]
=
filt
.
blue_limit
bandranges
[
1
:
4
,
0
]
=
midBand
bandranges
[
0
,
0
]
=
filt
.
blue_limit
bandranges
[
1
:
4
,
0
]
=
midBand
bandranges
[
0
:
3
,
1
]
=
midBand
bandranges
[
3
,
1
]
=
filt
.
red_limit
bandranges
[
3
,
1
]
=
filt
.
red_limit
self
.
bandranges
=
bandranges
...
...
@@ -246,7 +247,7 @@ class PSFInterpSLS(PSFModel):
for
g_order
in
grating_orders
:
g_folder_order
=
g_folder
+
'PSF_Order_'
+
g_order
+
'/'
grating_order_data
=
{}
for
bandi
in
[
1
,
2
,
3
,
4
]:
for
bandi
in
[
1
,
2
,
3
,
4
]:
subBand_data
=
{}
subBand_data
[
'bandrange'
]
=
bandranges
[
bandi
-
1
]
final_folder
=
g_folder_order
+
str
(
bandi
)
+
'/'
...
...
@@ -305,7 +306,7 @@ class PSFInterpSLS(PSFModel):
# psfInfo['wavelength']= fq_iwave['wavelength'][()]
#
# fq_iwave_ipsf = fq_iwave['psf_{:}'.format(ipsf)]
# psfInfo['pixsize'] = P
ixSizeInMicrons
# psfInfo['pixsize'] = P
IX_SIZE_MICRON
# psfInfo['field_x'] = fq_iwave_ipsf['field_x'][()]
# psfInfo['field_y'] = fq_iwave_ipsf['field_y'][()]
# psfInfo['image_x'] = fq_iwave_ipsf['image_x'][()]
...
...
@@ -342,7 +343,7 @@ class PSFInterpSLS(PSFModel):
offset
=
int
(
np
.
ceil
(
sigma
*
3
))
g_size
=
2
*
offset
+
1
m_cen
=
int
(
g_size
/
2
)
print
(
'-----'
,
g_size
)
print
(
'-----'
,
g_size
)
g_PSF_
=
Gaussian2D
(
1
,
m_cen
,
m_cen
,
sigma
,
sigma
)
yp
,
xp
=
np
.
mgrid
[
0
:
g_size
,
0
:
g_size
]
g_PSF
=
g_PSF_
(
xp
,
yp
)
...
...
@@ -351,8 +352,7 @@ class PSFInterpSLS(PSFModel):
convImg
=
convImg
/
np
.
sum
(
convImg
)
return
convImg
def
get_PSF
(
self
,
chip
,
pos_img_local
=
[
1000
,
1000
],
bandNo
=
1
,
galsimGSObject
=
True
,
folding_threshold
=
5.e-3
,
g_order
=
'A'
,
grating_split_pos
=
3685
):
def
get_PSF
(
self
,
chip
,
pos_img_local
=
[
1000
,
1000
],
bandNo
=
1
,
galsimGSObject
=
True
,
folding_threshold
=
5.e-3
,
g_order
=
'A'
,
grating_split_pos
=
3685
):
"""
Get the PSF at a given image position
...
...
@@ -365,8 +365,9 @@ class PSFInterpSLS(PSFModel):
Returns:
PSF: A 'galsim.GSObject'.
"""
order_IDs
=
{
'A'
:
'1'
,
'B'
:
'0'
,
'C'
:
'0'
,
'D'
:
'0'
,
'E'
:
'0'
}
contam_order_sigma
=
{
'C'
:
0.28032344707964174
,
'D'
:
0.39900182912061344
,
'E'
:
1.1988309797685412
}
#arcsec
order_IDs
=
{
'A'
:
'1'
,
'B'
:
'0'
,
'C'
:
'0'
,
'D'
:
'0'
,
'E'
:
'0'
}
contam_order_sigma
=
{
'C'
:
0.28032344707964174
,
'D'
:
0.39900182912061344
,
'E'
:
1.1988309797685412
}
# arcsec
x_start
=
chip
.
x_cen
/
chip
.
pix_size
-
chip
.
npix_x
/
2.
y_start
=
chip
.
y_cen
/
chip
.
pix_size
-
chip
.
npix_y
/
2.
# print(pos_img.x - x_start)
...
...
@@ -382,7 +383,6 @@ class PSFInterpSLS(PSFModel):
# if grating_order in ['-2','-1','2']:
# grating_order = '1'
# if grating_order in ['0', '1']:
psf_order
=
psf_data
[
'order'
+
grating_order
]
psf_order_b
=
psf_order
[
'band'
+
str
(
bandNo
)]
...
...
@@ -396,31 +396,34 @@ class PSFInterpSLS(PSFModel):
px
=
pos_img
.
x
*
chip
.
pix_size
py
=
pos_img
.
y
*
chip
.
pix_size
dist2
=
(
pos_p
[:,
1
]
-
px
)
*
(
pos_p
[:,
1
]
-
px
)
+
(
pos_p
[:,
0
]
-
py
)
*
(
pos_p
[:,
0
]
-
py
)
temp_sort_dist
=
np
.
zeros
([
dist2
.
shape
[
0
],
2
])
temp_sort_dist
[:,
0
]
=
np
.
arange
(
0
,
dist2
.
shape
[
0
],
1
)
dist2
=
(
pos_p
[:,
1
]
-
px
)
*
(
pos_p
[:,
1
]
-
px
)
+
\
(
pos_p
[:,
0
]
-
py
)
*
(
pos_p
[:,
0
]
-
py
)
temp_sort_dist
=
np
.
zeros
([
dist2
.
shape
[
0
],
2
])
temp_sort_dist
[:,
0
]
=
np
.
arange
(
0
,
dist2
.
shape
[
0
],
1
)
temp_sort_dist
[:,
1
]
=
dist2
# print(temp_sort_dist)
dits2_sortlist
=
sorted
(
temp_sort_dist
,
key
=
lambda
x
:
x
[
1
])
dits2_sortlist
=
sorted
(
temp_sort_dist
,
key
=
lambda
x
:
x
[
1
])
# print(dits2_sortlist)
nearest4p
=
np
.
zeros
([
4
,
2
])
pc_coeff_4p
=
np
.
zeros
([
pc_coeff
.
data
.
shape
[
0
],
4
])
nearest4p
=
np
.
zeros
([
4
,
2
])
pc_coeff_4p
=
np
.
zeros
([
pc_coeff
.
data
.
shape
[
0
],
4
])
for
i
in
np
.
arange
(
4
):
smaller_ids
=
int
(
dits2_sortlist
[
i
][
0
])
nearest4p
[
i
,
0
]
=
pos_p
[
smaller_ids
,
1
]
nearest4p
[
i
,
1
]
=
pos_p
[
smaller_ids
,
0
]
pc_coeff_4p
[:,
i
]
=
pc_coeff
[:,
smaller_ids
]
idw_dist
=
1
/
(
np
.
sqrt
((
px
-
nearest4p
[:,
0
])
*
(
px
-
nearest4p
[:,
0
])
+
(
py
-
nearest4p
[:,
1
])
*
(
py
-
nearest4p
[:,
1
])))
pc_coeff_4p
[:,
i
]
=
pc_coeff
[:,
smaller_ids
]
idw_dist
=
1
/
(
np
.
sqrt
((
px
-
nearest4p
[:,
0
])
*
(
px
-
nearest4p
[:,
0
])
+
(
py
-
nearest4p
[:,
1
])
*
(
py
-
nearest4p
[:,
1
])))
coeff_int
=
np
.
zeros
(
pc_coeff
.
data
.
shape
[
0
])
for
i
in
np
.
arange
(
4
):
coeff_int
=
coeff_int
+
pc_coeff_4p
[:,
i
]
*
idw_dist
[
i
]
coeff_int
=
coeff_int
+
pc_coeff_4p
[:,
i
]
*
idw_dist
[
i
]
coeff_int
=
coeff_int
/
np
.
sum
(
coeff_int
)
npc
=
10
m_size
=
int
(
pcs
.
shape
[
0
]
**
0.5
)
PSF_int
=
np
.
dot
(
pcs
[:,
0
:
npc
],
coeff_int
[
0
:
npc
]).
reshape
(
m_size
,
m_size
)
PSF_int
=
np
.
dot
(
pcs
[:,
0
:
npc
],
coeff_int
[
0
:
npc
]
).
reshape
(
m_size
,
m_size
)
# PSF_int = PSF_int/np.sum(PSF_int)
PSF_int_trans
=
np
.
flipud
(
np
.
fliplr
(
PSF_int
))
...
...
@@ -434,7 +437,6 @@ class PSFInterpSLS(PSFModel):
# from astropy.io import fits
# fits.writeto(str(bandNo) + '_' + g_order+ '_psf_o.fits', PSF_int_trans)
# if g_order in ['C','D','E']:
# g_simgma = contam_order_sigma[g_order]/pixel_size_arc
# PSF_int_trans = self.convolveWithGauss(PSF_int_trans,g_simgma)
...
...
@@ -459,24 +461,24 @@ class PSFInterpSLS(PSFModel):
pixel_size_arc
=
np
.
rad2deg
(
self
.
pixsize
*
1e-3
/
28
)
*
3600
img
=
galsim
.
ImageF
(
PSF_int_trans
,
scale
=
pixel_size_arc
)
gsp
=
galsim
.
GSParams
(
folding_threshold
=
folding_threshold
)
#
###########
TEST: START
#
TEST: START
# Use sheared PSF to test the PSF orientation
# self.psf = galsim.InterpolatedImage(img, gsparams=gsp).shear(g1=0.8, g2=0.)
#
###########
TEST: END
#
TEST: END
self
.
psf
=
galsim
.
InterpolatedImage
(
img
,
gsparams
=
gsp
)
# if g_order in ['C','D','E']:
# add_psf = galsim.Gaussian(sigma=contam_order_sigma[g_order], flux=1.0)
# self.psf = galsim.Convolve(self.psf, add_psf)
wcs
=
chip
.
img
.
wcs
.
local
(
pos_img
)
scale
=
galsim
.
PixelScale
(
0.074
)
self
.
psf
=
wcs
.
toWorld
(
scale
.
toImage
(
self
.
psf
),
image_pos
=
(
pos_img
))
self
.
psf
=
wcs
.
toWorld
(
scale
.
toImage
(
self
.
psf
),
image_pos
=
(
pos_img
))
# return self.PSFspin(x=px/0.01, y=py/0.01)
return
self
.
psf
,
galsim
.
Shear
(
e
=
0.
,
beta
=
(
np
.
pi
/
2
)
*
galsim
.
radians
)
return
PSF_int_trans
,
PSF_int
# pixSize = np.rad2deg(self.pixsize*1e-3/28)*3600 #set psf pixsize
#
# # assert self.iccd == int(chip.getChipLabel(chipID=chip.chipID)), 'ERROR: self.iccd != chip.chipID'
...
...
@@ -547,24 +549,23 @@ class PSFInterpSLS(PSFModel):
# PSFshear = galsim.Shear(e=ell, beta=beta*galsim.radians)
# return self.psf.shear(PSFshear), PSFshear
from
ObservationSim.Instrument
import
Filter
,
FilterParam
,
Chip
import
yaml
if
__name__
==
'__main__'
:
configfn
=
'/Users/zhangxin/Work/SlitlessSim/CSST_SIM/CSST_new_sim/csst-simulation/config/config_C6_dev.yaml'
with
open
(
configfn
,
"r"
)
as
stream
:
try
:
config
=
yaml
.
safe_load
(
stream
)
for
key
,
value
in
config
.
items
():
print
(
key
+
" : "
+
str
(
value
))
print
(
key
+
" : "
+
str
(
value
))
except
yaml
.
YAMLError
as
exc
:
print
(
exc
)
chip
=
Chip
(
chipID
=
1
,
config
=
config
)
chip
=
Chip
(
chipID
=
1
,
config
=
config
)
filter_id
,
filter_type
=
chip
.
getChipFilter
()
filt
=
Filter
(
filter_id
=
filter_id
,
filter_type
=
filter_type
,
filter_param
=
FilterParam
())
psf_i
=
PSFInterpSLS
(
chip
,
filt
,
PSF_data_prefix
=
"/Volumes/EAGET/CSST_PSF_data/SLS_PSF_PCA_fp/"
)
psf_i
=
PSFInterpSLS
(
chip
,
filt
,
PSF_data_prefix
=
"/Volumes/EAGET/CSST_PSF_data/SLS_PSF_PCA_fp/"
)
pos_img
=
galsim
.
PositionD
(
x
=
25155
,
y
=-
22060
)
psf_im
=
psf_i
.
get_PSF
(
chip
,
pos_img
=
pos_img
,
g_order
=
'1'
)
psf_im
=
psf_i
.
get_PSF
(
chip
,
pos_img
=
pos_img
,
g_order
=
'1'
)
observation_sim/PSF/PSFModel.py
0 → 100755
View file @
36189a3e
import
galsim
import
sep
import
numpy
as
np
from
scipy.interpolate
import
interp1d
import
pylab
as
pl
import
os
import
sys
class
PSFModel
(
object
):
def
__init__
(
self
,
sigSpin
=
0.
,
psfRa
=
0.15
):
# TODO: what are the nesseary fields in PSFModel class?
pass
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
Prev
1
2
3
4
5
…
12
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