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
f1dab347
Commit
f1dab347
authored
Oct 28, 2023
by
Fang Yuedong
Browse files
Merge branch 'new_sim' of
https://csst-tb.bao.ac.cn/code/csst_sim/csst-simulation
into new_sim
parents
3321919c
20067476
Changes
10
Expand all
Show whitespace changes
Inline
Side-by-side
ObservationSim/Config/Config.py
View file @
f1dab347
...
@@ -20,6 +20,7 @@ def config_dir(config, work_dir=None, data_dir=None):
...
@@ -20,6 +20,7 @@ def config_dir(config, work_dir=None, data_dir=None):
# PSF data directory
# PSF data directory
if
config
[
"psf_setting"
][
"psf_model"
]
==
"Interp"
:
if
config
[
"psf_setting"
][
"psf_model"
]
==
"Interp"
:
path_dict
[
"psf_dir"
]
=
os
.
path
.
join
(
path_dict
[
"data_dir"
],
config
[
"psf_setting"
][
"psf_dir"
])
path_dict
[
"psf_dir"
]
=
os
.
path
.
join
(
path_dict
[
"data_dir"
],
config
[
"psf_setting"
][
"psf_dir"
])
path_dict
[
"psf_sls_dir"
]
=
os
.
path
.
join
(
path_dict
[
"data_dir"
],
config
[
"psf_setting"
][
"psf_sls_dir"
])
return
path_dict
return
path_dict
...
...
ObservationSim/Instrument/Chip/ChipUtils.py
View file @
f1dab347
...
@@ -21,6 +21,22 @@ def log_info(msg, logger=None):
...
@@ -21,6 +21,22 @@ def log_info(msg, logger=None):
else
:
else
:
print
(
msg
,
flush
=
True
)
print
(
msg
,
flush
=
True
)
def
getChipSLSGratingID
(
chipID
):
gratingID
=
[
''
,
''
]
if
chipID
==
1
:
gratingID
=
[
'GI2'
,
'GI1'
]
if
chipID
==
2
:
gratingID
=
[
'GV4'
,
'GV3'
]
if
chipID
==
3
:
gratingID
=
[
'GU2'
,
'GU1'
]
if
chipID
==
4
:
gratingID
=
[
'GU4'
,
'GU3'
]
if
chipID
==
5
:
gratingID
=
[
'GV2'
,
'GV1'
]
if
chipID
==
10
:
gratingID
=
[
'GI4'
,
'GI3'
]
if
chipID
==
21
:
gratingID
=
[
'GI6'
,
'GI5'
]
if
chipID
==
26
:
gratingID
=
[
'GV8'
,
'GV7'
]
if
chipID
==
27
:
gratingID
=
[
'GU6'
,
'GU5'
]
if
chipID
==
28
:
gratingID
=
[
'GU8'
,
'GU7'
]
if
chipID
==
29
:
gratingID
=
[
'GV6'
,
'GV5'
]
if
chipID
==
30
:
gratingID
=
[
'GI8'
,
'GI7'
]
return
gratingID
def
getChipSLSConf
(
chipID
):
def
getChipSLSConf
(
chipID
):
confFile
=
''
confFile
=
''
if
chipID
==
1
:
confFile
=
[
'CSST_GI2.conf'
,
'CSST_GI1.conf'
]
if
chipID
==
1
:
confFile
=
[
'CSST_GI2.conf'
,
'CSST_GI1.conf'
]
...
...
ObservationSim/MockObject/Galaxy.py
View file @
f1dab347
...
@@ -248,10 +248,27 @@ class Galaxy(MockObject):
...
@@ -248,10 +248,27 @@ class Galaxy(MockObject):
xOrderSigPlus
=
{
'A'
:
1.3909419820029296
,
'B'
:
1.4760376591236062
,
'C'
:
4.035447379743442
,
'D'
:
5.5684364343742825
,
'E'
:
16.260021029735388
}
xOrderSigPlus
=
{
'A'
:
1.3909419820029296
,
'B'
:
1.4760376591236062
,
'C'
:
4.035447379743442
,
'D'
:
5.5684364343742825
,
'E'
:
16.260021029735388
}
grating_split_pos_chip
=
0
+
grating_split_pos
grating_split_pos_chip
=
0
+
grating_split_pos
branges
=
np
.
zeros
([
len
(
bandpass_list
),
2
])
# print(hasattr(psf_model, 'bandranges'))
if
hasattr
(
psf_model
,
'bandranges'
):
if
psf_model
.
bandranges
is
None
:
return
2
,
None
if
len
(
psf_model
.
bandranges
)
!=
len
(
bandpass_list
):
return
2
,
None
branges
=
psf_model
.
bandranges
else
:
for
i
in
range
(
len
(
bandpass_list
)):
for
i
in
range
(
len
(
bandpass_list
)):
bandpass
=
bandpass_list
[
i
]
branges
[
i
,
0
]
=
bandpass_list
[
i
].
blue_limit
*
10
branges
[
i
,
1
]
=
bandpass_list
[
i
].
red_limit
*
10
psf
,
pos_shear
=
psf_model
.
get_PSF
(
chip
=
chip
,
pos_img
=
pos_img
,
bandpass
=
bandpass
,
folding_threshold
=
folding_threshold
)
for
i
in
range
(
len
(
bandpass_list
)):
# bandpass = bandpass_list[i]
brange
=
branges
[
i
]
# psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img, bandpass=bandpass, folding_threshold=folding_threshold)
disk
=
galsim
.
Sersic
(
n
=
self
.
disk_sersic_idx
,
half_light_radius
=
self
.
hlr_disk
,
flux
=
1.0
,
gsparams
=
gsp
)
disk
=
galsim
.
Sersic
(
n
=
self
.
disk_sersic_idx
,
half_light_radius
=
self
.
hlr_disk
,
flux
=
1.0
,
gsparams
=
gsp
)
disk_shape
=
galsim
.
Shear
(
g1
=
self
.
e1_disk
,
g2
=
self
.
e2_disk
)
disk_shape
=
galsim
.
Shear
(
g1
=
self
.
e1_disk
,
g2
=
self
.
e2_disk
)
disk
=
disk
.
shear
(
disk_shape
)
disk
=
disk
.
shear
(
disk_shape
)
...
@@ -272,14 +289,14 @@ class Galaxy(MockObject):
...
@@ -272,14 +289,14 @@ class Galaxy(MockObject):
g2
+=
fd_shear
.
g2
g2
+=
fd_shear
.
g2
gal_shear
=
galsim
.
Shear
(
g1
=
g1
,
g2
=
g2
)
gal_shear
=
galsim
.
Shear
(
g1
=
g1
,
g2
=
g2
)
gal
=
gal
.
shear
(
gal_shear
)
gal
=
gal
.
shear
(
gal_shear
)
gal
=
galsim
.
Convolve
(
psf
,
gal
)
#
gal = galsim.Convolve(psf, gal)
if
not
big_galaxy
:
# Not apply PSF for very big galaxy
#
if not big_galaxy: # Not apply PSF for very big galaxy
gal
=
galsim
.
Convolve
(
psf
,
gal
)
#
gal = galsim.Convolve(psf, gal)
# if fd_shear is not None:
#
# if fd_shear is not None:
# gal = gal.shear(fd_shear)
#
# gal = gal.shear(fd_shear)
starImg
=
gal
.
drawImage
(
wcs
=
chip_wcs_local
,
offset
=
offset
)
starImg
=
gal
.
drawImage
(
wcs
=
chip_wcs_local
,
offset
=
offset
,
method
=
'real_space'
)
origin_star
=
[
y_nominal
-
(
starImg
.
center
.
y
-
starImg
.
ymin
),
origin_star
=
[
y_nominal
-
(
starImg
.
center
.
y
-
starImg
.
ymin
),
x_nominal
-
(
starImg
.
center
.
x
-
starImg
.
xmin
)]
x_nominal
-
(
starImg
.
center
.
x
-
starImg
.
xmin
)]
...
@@ -301,12 +318,16 @@ class Galaxy(MockObject):
...
@@ -301,12 +318,16 @@ class Galaxy(MockObject):
sdp_p1
=
SpecDisperser
(
orig_img
=
star_p1
,
xcenter
=
xcenter_p1
,
sdp_p1
=
SpecDisperser
(
orig_img
=
star_p1
,
xcenter
=
xcenter_p1
,
ycenter
=
ycenter_p1
,
origin
=
origin_p1
,
ycenter
=
ycenter_p1
,
origin
=
origin_p1
,
tar_spec
=
normalSED
,
tar_spec
=
normalSED
,
band_start
=
ban
dpass
.
blue_limit
*
10
,
band_end
=
ban
dpass
.
red_limit
*
10
,
band_start
=
b
r
an
ge
[
0
]
,
band_end
=
b
r
an
ge
[
1
]
,
conf
=
chip
.
sls_conf
[
0
],
conf
=
chip
.
sls_conf
[
0
],
isAlongY
=
0
,
isAlongY
=
0
,
flat_cube
=
flat_cube
)
flat_cube
=
flat_cube
)
self
.
addSLStoChipImage
(
sdp
=
sdp_p1
,
chip
=
chip
,
xOrderSigPlus
=
xOrderSigPlus
,
local_wcs
=
chip_wcs_local
)
# self.addSLStoChipImage(sdp=sdp_p1, chip=chip, xOrderSigPlus = xOrderSigPlus, local_wcs=chip_wcs_local)
pos_shear
=
self
.
addSLStoChipImageWithPSF
(
sdp
=
sdp_p1
,
chip
=
chip
,
pos_img_local
=
[
xcenter_p1
,
ycenter_p1
],
psf_model
=
psf_model
,
bandNo
=
i
+
1
,
grating_split_pos
=
grating_split_pos
,
local_wcs
=
chip_wcs_local
,
pos_img
=
pos_img
)
subImg_p2
=
starImg
.
array
[:,
subSlitPos
+
1
:
starImg
.
array
.
shape
[
1
]]
subImg_p2
=
starImg
.
array
[:,
subSlitPos
+
1
:
starImg
.
array
.
shape
[
1
]]
star_p2
=
galsim
.
Image
(
subImg_p2
)
star_p2
=
galsim
.
Image
(
subImg_p2
)
...
@@ -318,12 +339,16 @@ class Galaxy(MockObject):
...
@@ -318,12 +339,16 @@ class Galaxy(MockObject):
sdp_p2
=
SpecDisperser
(
orig_img
=
star_p2
,
xcenter
=
xcenter_p2
,
sdp_p2
=
SpecDisperser
(
orig_img
=
star_p2
,
xcenter
=
xcenter_p2
,
ycenter
=
ycenter_p2
,
origin
=
origin_p2
,
ycenter
=
ycenter_p2
,
origin
=
origin_p2
,
tar_spec
=
normalSED
,
tar_spec
=
normalSED
,
band_start
=
ban
dpass
.
blue_limit
*
10
,
band_end
=
ban
dpass
.
red_limit
*
10
,
band_start
=
b
r
an
ge
[
0
]
,
band_end
=
b
r
an
ge
[
1
]
,
conf
=
chip
.
sls_conf
[
1
],
conf
=
chip
.
sls_conf
[
1
],
isAlongY
=
0
,
isAlongY
=
0
,
flat_cube
=
flat_cube
)
flat_cube
=
flat_cube
)
self
.
addSLStoChipImage
(
sdp
=
sdp_p2
,
chip
=
chip
,
xOrderSigPlus
=
xOrderSigPlus
,
local_wcs
=
chip_wcs_local
)
# self.addSLStoChipImage(sdp=sdp_p2, chip=chip, xOrderSigPlus = xOrderSigPlus, local_wcs=chip_wcs_local)
pos_shear
=
self
.
addSLStoChipImageWithPSF
(
sdp
=
sdp_p2
,
chip
=
chip
,
pos_img_local
=
[
xcenter_p2
,
ycenter_p2
],
psf_model
=
psf_model
,
bandNo
=
i
+
1
,
grating_split_pos
=
grating_split_pos
,
local_wcs
=
chip_wcs_local
,
pos_img
=
pos_img
)
del
sdp_p1
del
sdp_p1
del
sdp_p2
del
sdp_p2
...
@@ -331,25 +356,33 @@ class Galaxy(MockObject):
...
@@ -331,25 +356,33 @@ class Galaxy(MockObject):
sdp
=
SpecDisperser
(
orig_img
=
starImg
,
xcenter
=
x_nominal
-
0
,
sdp
=
SpecDisperser
(
orig_img
=
starImg
,
xcenter
=
x_nominal
-
0
,
ycenter
=
y_nominal
-
0
,
origin
=
origin_star
,
ycenter
=
y_nominal
-
0
,
origin
=
origin_star
,
tar_spec
=
normalSED
,
tar_spec
=
normalSED
,
band_start
=
ban
dpass
.
blue_limit
*
10
,
band_end
=
ban
dpass
.
red_limit
*
10
,
band_start
=
b
r
an
ge
[
0
]
,
band_end
=
b
r
an
ge
[
1
]
,
conf
=
chip
.
sls_conf
[
1
],
conf
=
chip
.
sls_conf
[
1
],
isAlongY
=
0
,
isAlongY
=
0
,
flat_cube
=
flat_cube
)
flat_cube
=
flat_cube
)
self
.
addSLStoChipImage
(
sdp
=
sdp
,
chip
=
chip
,
xOrderSigPlus
=
xOrderSigPlus
,
local_wcs
=
chip_wcs_local
)
# self.addSLStoChipImage(sdp=sdp, chip=chip, xOrderSigPlus = xOrderSigPlus, local_wcs=chip_wcs_local)
pos_shear
=
self
.
addSLStoChipImageWithPSF
(
sdp
=
sdp
,
chip
=
chip
,
pos_img_local
=
[
x_nominal
,
y_nominal
],
psf_model
=
psf_model
,
bandNo
=
i
+
1
,
grating_split_pos
=
grating_split_pos
,
local_wcs
=
chip_wcs_local
,
pos_img
=
pos_img
)
del
sdp
del
sdp
elif
grating_split_pos_chip
>=
gal_end
[
1
]:
elif
grating_split_pos_chip
>=
gal_end
[
1
]:
sdp
=
SpecDisperser
(
orig_img
=
starImg
,
xcenter
=
x_nominal
-
0
,
sdp
=
SpecDisperser
(
orig_img
=
starImg
,
xcenter
=
x_nominal
-
0
,
ycenter
=
y_nominal
-
0
,
origin
=
origin_star
,
ycenter
=
y_nominal
-
0
,
origin
=
origin_star
,
tar_spec
=
normalSED
,
tar_spec
=
normalSED
,
band_start
=
ban
dpass
.
blue_limit
*
10
,
band_end
=
ban
dpass
.
red_limit
*
10
,
band_start
=
b
r
an
ge
[
0
]
,
band_end
=
b
r
an
ge
[
1
]
,
conf
=
chip
.
sls_conf
[
0
],
conf
=
chip
.
sls_conf
[
0
],
isAlongY
=
0
,
isAlongY
=
0
,
flat_cube
=
flat_cube
)
flat_cube
=
flat_cube
)
self
.
addSLStoChipImage
(
sdp
=
sdp
,
chip
=
chip
,
xOrderSigPlus
=
xOrderSigPlus
,
local_wcs
=
chip_wcs_local
)
# self.addSLStoChipImage(sdp=sdp, chip=chip, xOrderSigPlus = xOrderSigPlus, local_wcs=chip_wcs_local)
pos_shear
=
self
.
addSLStoChipImageWithPSF
(
sdp
=
sdp
,
chip
=
chip
,
pos_img_local
=
[
x_nominal
,
y_nominal
],
psf_model
=
psf_model
,
bandNo
=
i
+
1
,
grating_split_pos
=
grating_split_pos
,
local_wcs
=
chip_wcs_local
,
pos_img
=
pos_img
)
del
sdp
del
sdp
# print(self.y_nominal, starImg.center.y, starImg.ymin)
# print(self.y_nominal, starImg.center.y, starImg.ymin)
del
psf
#
del psf
return
1
,
pos_shear
return
1
,
pos_shear
def
getGSObj
(
self
,
psf
,
g1
=
0
,
g2
=
0
,
flux
=
None
,
filt
=
None
,
tel
=
None
,
exptime
=
150.
):
def
getGSObj
(
self
,
psf
,
g1
=
0
,
g2
=
0
,
flux
=
None
,
filt
=
None
,
tel
=
None
,
exptime
=
150.
):
...
...
ObservationSim/MockObject/MockObject.py
View file @
f1dab347
...
@@ -4,7 +4,7 @@ import astropy.constants as cons
...
@@ -4,7 +4,7 @@ import astropy.constants as cons
from
astropy
import
wcs
from
astropy
import
wcs
from
astropy.table
import
Table
from
astropy.table
import
Table
from
ObservationSim.MockObject._util
import
magToFlux
,
VC_A
,
convolveGaussXorders
from
ObservationSim.MockObject._util
import
magToFlux
,
VC_A
,
convolveGaussXorders
,
convolveImg
from
ObservationSim.MockObject._util
import
integrate_sed_bandpass
,
getNormFactorForSpecWithABMAG
,
getObservedSED
,
\
from
ObservationSim.MockObject._util
import
integrate_sed_bandpass
,
getNormFactorForSpecWithABMAG
,
getObservedSED
,
\
getABMAG
getABMAG
from
ObservationSim.MockObject.SpecDisperser
import
SpecDisperser
from
ObservationSim.MockObject.SpecDisperser
import
SpecDisperser
...
@@ -223,9 +223,69 @@ class MockObject(object):
...
@@ -223,9 +223,69 @@ class MockObject(object):
del
stamp
del
stamp
del
spec_orders
del
spec_orders
def
addSLStoChipImageWithPSF
(
self
,
sdp
=
None
,
chip
=
None
,
pos_img_local
=
[
1
,
1
],
psf_model
=
None
,
bandNo
=
1
,
grating_split_pos
=
3685
,
local_wcs
=
None
,
pos_img
=
None
):
spec_orders
=
sdp
.
compute_spec_orders
()
for
k
,
v
in
spec_orders
.
items
():
img_s
=
v
[
0
]
# print(bandNo,k)
try
:
psf
,
pos_shear
=
psf_model
.
get_PSF
(
chip
,
pos_img_local
=
pos_img_local
,
bandNo
=
bandNo
,
galsimGSObject
=
True
,
g_order
=
k
,
grating_split_pos
=
grating_split_pos
)
except
:
psf
,
pos_shear
=
psf_model
.
get_PSF
(
chip
=
chip
,
pos_img
=
pos_img
)
psf_img
=
psf
.
drawImage
(
nx
=
100
,
ny
=
100
,
wcs
=
local_wcs
)
psf_img_m
=
psf_img
.
array
#########################################################
# DEBUG
#########################################################
# ids_p = psf_img_m < 0
# psf_img_m[ids_p] = 0
# from astropy.io import fits
# fits.writeto(str(bandNo) + '_' + str(k) + '_psf.fits', psf_img_m)
# print("DEBUG: orig_off is", orig_off)
nan_ids
=
np
.
isnan
(
img_s
)
if
img_s
[
nan_ids
].
shape
[
0
]
>
0
:
img_s
[
nan_ids
]
=
0
print
(
"DEBUG: specImg nan num is"
,
img_s
[
nan_ids
].
shape
[
0
])
#########################################################
img_s
,
orig_off
=
convolveImg
(
img_s
,
psf_img_m
)
origin_order_x
=
v
[
1
]
-
orig_off
[
0
]
origin_order_y
=
v
[
2
]
-
orig_off
[
1
]
specImg
=
galsim
.
ImageF
(
img_s
)
# photons = galsim.PhotonArray.makeFromImage(specImg)
# photons.x += origin_order_x
# photons.y += origin_order_y
# xlen_imf = int(specImg.xmax - specImg.xmin + 1)
# ylen_imf = int(specImg.ymax - specImg.ymin + 1)
# stamp = galsim.ImageF(xlen_imf, ylen_imf)
# stamp.wcs = local_wcs
# stamp.setOrigin(origin_order_x, origin_order_y)
specImg
.
wcs
=
local_wcs
specImg
.
setOrigin
(
origin_order_x
,
origin_order_y
)
bounds
=
specImg
.
bounds
&
galsim
.
BoundsI
(
0
,
chip
.
npix_x
-
1
,
0
,
chip
.
npix_y
-
1
)
if
bounds
.
area
()
==
0
:
continue
chip
.
img
.
setOrigin
(
0
,
0
)
chip
.
img
[
bounds
]
=
chip
.
img
[
bounds
]
+
specImg
[
bounds
]
# stamp[bounds] = chip.img[bounds]
# # chip.sensor.accumulate(photons, stamp)
# chip.img[bounds] = stamp[bounds]
chip
.
img
.
setOrigin
(
chip
.
bound
.
xmin
,
chip
.
bound
.
ymin
)
# del stamp
del
spec_orders
return
pos_shear
def
drawObj_slitless
(
self
,
tel
,
pos_img
,
psf_model
,
bandpass_list
,
filt
,
chip
,
nphotons_tot
=
None
,
g1
=
0
,
g2
=
0
,
def
drawObj_slitless
(
self
,
tel
,
pos_img
,
psf_model
,
bandpass_list
,
filt
,
chip
,
nphotons_tot
=
None
,
g1
=
0
,
g2
=
0
,
exptime
=
150.
,
normFilter
=
None
,
grating_split_pos
=
3685
,
fd_shear
=
None
):
exptime
=
150.
,
normFilter
=
None
,
grating_split_pos
=
3685
,
fd_shear
=
None
):
if
normFilter
is
not
None
:
if
normFilter
is
not
None
:
norm_thr_rang_ids
=
normFilter
[
'SENSITIVITY'
]
>
0.001
norm_thr_rang_ids
=
normFilter
[
'SENSITIVITY'
]
>
0.001
sedNormFactor
=
getNormFactorForSpecWithABMAG
(
ABMag
=
self
.
param
[
'mag_use_normal'
],
spectrum
=
self
.
sed
,
sedNormFactor
=
getNormFactorForSpecWithABMAG
(
ABMag
=
self
.
param
[
'mag_use_normal'
],
spectrum
=
self
.
sed
,
...
@@ -263,22 +323,38 @@ class MockObject(object):
...
@@ -263,22 +323,38 @@ class MockObject(object):
xOrderSigPlus
=
{
'A'
:
1.3909419820029296
,
'B'
:
1.4760376591236062
,
'C'
:
4.035447379743442
,
xOrderSigPlus
=
{
'A'
:
1.3909419820029296
,
'B'
:
1.4760376591236062
,
'C'
:
4.035447379743442
,
'D'
:
5.5684364343742825
,
'E'
:
16.260021029735388
}
'D'
:
5.5684364343742825
,
'E'
:
16.260021029735388
}
grating_split_pos_chip
=
0
+
grating_split_pos
grating_split_pos_chip
=
0
+
grating_split_pos
branges
=
np
.
zeros
([
len
(
bandpass_list
),
2
])
if
hasattr
(
psf_model
,
'bandranges'
):
if
psf_model
.
bandranges
is
None
:
return
2
,
None
if
len
(
psf_model
.
bandranges
)
!=
len
(
bandpass_list
):
return
2
,
None
branges
=
psf_model
.
bandranges
else
:
for
i
in
range
(
len
(
bandpass_list
)):
for
i
in
range
(
len
(
bandpass_list
)):
bandpass
=
bandpass_list
[
i
]
branges
[
i
,
0
]
=
bandpass_list
[
i
].
blue_limit
*
10
psf
,
pos_shear
=
psf_model
.
get_PSF
(
chip
=
chip
,
pos_img
=
pos_img
,
bandpass
=
bandpass
,
branges
[
i
,
1
]
=
bandpass_list
[
i
].
red_limit
*
10
folding_threshold
=
folding_threshold
)
for
i
in
range
(
len
(
bandpass_list
)):
# bandpass = bandpass_list[i]
brange
=
branges
[
i
]
# psf, pos_shear = psf_model.get_PSF(chip=chip, pos_img=pos_img, bandpass=bandpass,
# folding_threshold=folding_threshold)
star
=
galsim
.
DeltaFunction
(
gsparams
=
gsp
)
star
=
galsim
.
DeltaFunction
(
gsparams
=
gsp
)
star
=
star
.
withFlux
(
tel
.
pupil_area
*
exptime
)
star
=
star
.
withFlux
(
tel
.
pupil_area
*
exptime
)
star
=
galsim
.
Convolve
(
psf
,
star
)
psf_tmp
=
galsim
.
Gaussian
(
sigma
=
0.002
)
star
=
galsim
.
Convolve
(
psf_tmp
,
star
)
starImg
=
star
.
drawImage
(
nx
=
10
0
,
ny
=
10
0
,
wcs
=
chip_wcs_local
,
offset
=
offset
)
starImg
=
star
.
drawImage
(
nx
=
6
0
,
ny
=
6
0
,
wcs
=
chip_wcs_local
,
offset
=
offset
)
origin_star
=
[
y_nominal
-
(
starImg
.
center
.
y
-
starImg
.
ymin
),
origin_star
=
[
y_nominal
-
(
starImg
.
center
.
y
-
starImg
.
ymin
),
x_nominal
-
(
starImg
.
center
.
x
-
starImg
.
xmin
)]
x_nominal
-
(
starImg
.
center
.
x
-
starImg
.
xmin
)]
starImg
.
setOrigin
(
0
,
0
)
starImg
.
setOrigin
(
0
,
0
)
gal_origin
=
[
origin_star
[
0
],
origin_star
[
1
]]
gal_origin
=
[
origin_star
[
0
],
origin_star
[
1
]]
gal_end
=
[
origin_star
[
0
]
+
starImg
.
array
.
shape
[
0
]
-
1
,
origin_star
[
1
]
+
starImg
.
array
.
shape
[
1
]
-
1
]
gal_end
=
[
origin_star
[
0
]
+
starImg
.
array
.
shape
[
0
]
-
1
,
origin_star
[
1
]
+
starImg
.
array
.
shape
[
1
]
-
1
]
if
gal_origin
[
1
]
<
grating_split_pos_chip
<
gal_end
[
1
]:
if
gal_origin
[
1
]
<
grating_split_pos_chip
<
gal_end
[
1
]:
subSlitPos
=
int
(
grating_split_pos_chip
-
gal_origin
[
1
]
+
1
)
subSlitPos
=
int
(
grating_split_pos_chip
-
gal_origin
[
1
]
+
1
)
## part img disperse
## part img disperse
...
@@ -293,12 +369,15 @@ class MockObject(object):
...
@@ -293,12 +369,15 @@ class MockObject(object):
sdp_p1
=
SpecDisperser
(
orig_img
=
star_p1
,
xcenter
=
xcenter_p1
,
sdp_p1
=
SpecDisperser
(
orig_img
=
star_p1
,
xcenter
=
xcenter_p1
,
ycenter
=
ycenter_p1
,
origin
=
origin_p1
,
ycenter
=
ycenter_p1
,
origin
=
origin_p1
,
tar_spec
=
normalSED
,
tar_spec
=
normalSED
,
band_start
=
ban
dpass
.
blue_limit
*
10
,
band_end
=
ban
dpass
.
red_limit
*
10
,
band_start
=
b
r
an
ge
[
0
]
,
band_end
=
b
r
an
ge
[
1
]
,
conf
=
chip
.
sls_conf
[
0
],
conf
=
chip
.
sls_conf
[
0
],
isAlongY
=
0
,
isAlongY
=
0
,
flat_cube
=
flat_cube
)
flat_cube
=
flat_cube
)
self
.
addSLStoChipImage
(
sdp
=
sdp_p1
,
chip
=
chip
,
xOrderSigPlus
=
xOrderSigPlus
,
local_wcs
=
chip_wcs_local
)
# self.addSLStoChipImage(sdp=sdp_p1, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local)
pos_shear
=
self
.
addSLStoChipImageWithPSF
(
sdp
=
sdp_p1
,
chip
=
chip
,
pos_img_local
=
[
xcenter_p1
,
ycenter_p1
],
psf_model
=
psf_model
,
bandNo
=
i
+
1
,
grating_split_pos
=
grating_split_pos
,
local_wcs
=
chip_wcs_local
,
pos_img
=
pos_img
)
subImg_p2
=
starImg
.
array
[:,
subSlitPos
+
1
:
starImg
.
array
.
shape
[
1
]]
subImg_p2
=
starImg
.
array
[:,
subSlitPos
+
1
:
starImg
.
array
.
shape
[
1
]]
star_p2
=
galsim
.
Image
(
subImg_p2
)
star_p2
=
galsim
.
Image
(
subImg_p2
)
...
@@ -310,12 +389,15 @@ class MockObject(object):
...
@@ -310,12 +389,15 @@ class MockObject(object):
sdp_p2
=
SpecDisperser
(
orig_img
=
star_p2
,
xcenter
=
xcenter_p2
,
sdp_p2
=
SpecDisperser
(
orig_img
=
star_p2
,
xcenter
=
xcenter_p2
,
ycenter
=
ycenter_p2
,
origin
=
origin_p2
,
ycenter
=
ycenter_p2
,
origin
=
origin_p2
,
tar_spec
=
normalSED
,
tar_spec
=
normalSED
,
band_start
=
ban
dpass
.
blue_limit
*
10
,
band_end
=
ban
dpass
.
red_limit
*
10
,
band_start
=
b
r
an
ge
[
0
]
,
band_end
=
b
r
an
ge
[
1
]
,
conf
=
chip
.
sls_conf
[
1
],
conf
=
chip
.
sls_conf
[
1
],
isAlongY
=
0
,
isAlongY
=
0
,
flat_cube
=
flat_cube
)
flat_cube
=
flat_cube
)
self
.
addSLStoChipImage
(
sdp
=
sdp_p2
,
chip
=
chip
,
xOrderSigPlus
=
xOrderSigPlus
,
local_wcs
=
chip_wcs_local
)
# self.addSLStoChipImage(sdp=sdp_p2, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local)
pos_shear
=
self
.
addSLStoChipImageWithPSF
(
sdp
=
sdp_p2
,
chip
=
chip
,
pos_img_local
=
[
xcenter_p2
,
ycenter_p2
],
psf_model
=
psf_model
,
bandNo
=
i
+
1
,
grating_split_pos
=
grating_split_pos
,
local_wcs
=
chip_wcs_local
,
pos_img
=
pos_img
)
del
sdp_p1
del
sdp_p1
del
sdp_p2
del
sdp_p2
...
@@ -323,23 +405,29 @@ class MockObject(object):
...
@@ -323,23 +405,29 @@ class MockObject(object):
sdp
=
SpecDisperser
(
orig_img
=
starImg
,
xcenter
=
x_nominal
-
0
,
sdp
=
SpecDisperser
(
orig_img
=
starImg
,
xcenter
=
x_nominal
-
0
,
ycenter
=
y_nominal
-
0
,
origin
=
origin_star
,
ycenter
=
y_nominal
-
0
,
origin
=
origin_star
,
tar_spec
=
normalSED
,
tar_spec
=
normalSED
,
band_start
=
ban
dpass
.
blue_limit
*
10
,
band_end
=
ban
dpass
.
red_limit
*
10
,
band_start
=
b
r
an
ge
[
0
]
,
band_end
=
b
r
an
ge
[
1
]
,
conf
=
chip
.
sls_conf
[
1
],
conf
=
chip
.
sls_conf
[
1
],
isAlongY
=
0
,
isAlongY
=
0
,
flat_cube
=
flat_cube
)
flat_cube
=
flat_cube
)
self
.
addSLStoChipImage
(
sdp
=
sdp
,
chip
=
chip
,
xOrderSigPlus
=
xOrderSigPlus
,
local_wcs
=
chip_wcs_local
)
# self.addSLStoChipImage(sdp=sdp, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local)
pos_shear
=
self
.
addSLStoChipImageWithPSF
(
sdp
=
sdp
,
chip
=
chip
,
pos_img_local
=
[
x_nominal
,
y_nominal
],
psf_model
=
psf_model
,
bandNo
=
i
+
1
,
grating_split_pos
=
grating_split_pos
,
local_wcs
=
chip_wcs_local
,
pos_img
=
pos_img
)
del
sdp
del
sdp
elif
grating_split_pos_chip
>=
gal_end
[
1
]:
elif
grating_split_pos_chip
>=
gal_end
[
1
]:
sdp
=
SpecDisperser
(
orig_img
=
starImg
,
xcenter
=
x_nominal
-
0
,
sdp
=
SpecDisperser
(
orig_img
=
starImg
,
xcenter
=
x_nominal
-
0
,
ycenter
=
y_nominal
-
0
,
origin
=
origin_star
,
ycenter
=
y_nominal
-
0
,
origin
=
origin_star
,
tar_spec
=
normalSED
,
tar_spec
=
normalSED
,
band_start
=
ban
dpass
.
blue_limit
*
10
,
band_end
=
ban
dpass
.
red_limit
*
10
,
band_start
=
b
r
an
ge
[
0
]
,
band_end
=
b
r
an
ge
[
1
]
,
conf
=
chip
.
sls_conf
[
0
],
conf
=
chip
.
sls_conf
[
0
],
isAlongY
=
0
,
isAlongY
=
0
,
flat_cube
=
flat_cube
)
flat_cube
=
flat_cube
)
self
.
addSLStoChipImage
(
sdp
=
sdp
,
chip
=
chip
,
xOrderSigPlus
=
xOrderSigPlus
,
local_wcs
=
chip_wcs_local
)
# self.addSLStoChipImage(sdp=sdp, chip=chip, xOrderSigPlus=xOrderSigPlus, local_wcs=chip_wcs_local)
pos_shear
=
self
.
addSLStoChipImageWithPSF
(
sdp
=
sdp
,
chip
=
chip
,
pos_img_local
=
[
x_nominal
,
y_nominal
],
psf_model
=
psf_model
,
bandNo
=
i
+
1
,
grating_split_pos
=
grating_split_pos
,
local_wcs
=
chip_wcs_local
,
pos_img
=
pos_img
)
del
sdp
del
sdp
del
psf
#
del psf
return
1
,
pos_shear
return
1
,
pos_shear
def
SNRestimate
(
self
,
img_obj
,
flux
,
noise_level
=
0.0
,
seed
=
31415
):
def
SNRestimate
(
self
,
img_obj
,
flux
,
noise_level
=
0.0
,
seed
=
31415
):
...
...
ObservationSim/MockObject/SpecDisperser/SpecDisperser.py
View file @
f1dab347
...
@@ -155,7 +155,7 @@ class SpecDisperser(object):
...
@@ -155,7 +155,7 @@ class SpecDisperser(object):
sensitivity_beam
=
ysens
sensitivity_beam
=
ysens
len_spec_x
=
len
(
dx
)
len_spec_x
=
len
(
dx
)
len_spec_y
=
int
(
ceil
(
ytrace_beam
[
-
1
])
-
floor
(
ytrace_beam
[
0
])
+
1
)
len_spec_y
=
int
(
abs
(
ceil
(
ytrace_beam
[
-
1
])
-
floor
(
ytrace_beam
[
0
])
)
+
1
)
beam_sh
=
(
self
.
img_sh
[
0
]
+
len_spec_y
,
self
.
img_sh
[
1
]
+
len_spec_x
)
beam_sh
=
(
self
.
img_sh
[
0
]
+
len_spec_y
,
self
.
img_sh
[
1
]
+
len_spec_x
)
modelf
=
zeros
(
product
(
beam_sh
),
dtype
=
float
)
modelf
=
zeros
(
product
(
beam_sh
),
dtype
=
float
)
...
...
ObservationSim/MockObject/_util.py
View file @
f1dab347
...
@@ -571,4 +571,14 @@ def convolveGaussXorders(img=None, sigma = 1):
...
@@ -571,4 +571,14 @@ def convolveGaussXorders(img=None, sigma = 1):
convImg
=
signal
.
fftconvolve
(
img
,
psf
,
mode
=
'full'
,
axes
=
None
)
convImg
=
signal
.
fftconvolve
(
img
,
psf
,
mode
=
'full'
,
axes
=
None
)
return
convImg
,
offset
return
convImg
,
offset
def
convolveImg
(
img
=
None
,
psf
=
None
):
from
astropy.modeling.models
import
Gaussian2D
from
scipy
import
signal
convImg
=
signal
.
fftconvolve
(
img
,
psf
,
mode
=
'full'
,
axes
=
None
)
offset_x
=
int
(
psf
.
shape
[
1
]
/
2.
+
0.5
)
-
1
offset_y
=
int
(
psf
.
shape
[
0
]
/
2.
+
0.5
)
-
1
offset
=
[
offset_x
,
offset_y
]
return
convImg
,
offset
ObservationSim/ObservationSim.py
View file @
f1dab347
...
@@ -15,7 +15,7 @@ from ObservationSim.Config.Header import generatePrimaryHeader, generateExtensio
...
@@ -15,7 +15,7 @@ from ObservationSim.Config.Header import generatePrimaryHeader, generateExtensio
from
ObservationSim.Instrument
import
Telescope
,
Filter
,
FilterParam
,
FocalPlane
,
Chip
from
ObservationSim.Instrument
import
Telescope
,
Filter
,
FilterParam
,
FocalPlane
,
Chip
from
ObservationSim.Instrument.Chip
import
Effects
from
ObservationSim.Instrument.Chip
import
Effects
from
ObservationSim.Straylight
import
calculateSkyMap_split_g
from
ObservationSim.Straylight
import
calculateSkyMap_split_g
from
ObservationSim.PSF
import
PSFGauss
,
FieldDistortion
,
PSFInterp
from
ObservationSim.PSF
import
PSFGauss
,
FieldDistortion
,
PSFInterp
,
PSFInterpSLS
from
ObservationSim._util
import
get_shear_field
,
makeSubDir_PointingList
from
ObservationSim._util
import
get_shear_field
,
makeSubDir_PointingList
from
ObservationSim.Astrometry.Astrometry_util
import
on_orbit_obs_position
from
ObservationSim.Astrometry.Astrometry_util
import
on_orbit_obs_position
...
@@ -63,6 +63,9 @@ class Observation(object):
...
@@ -63,6 +63,9 @@ class Observation(object):
if
self
.
config
[
"psf_setting"
][
"psf_model"
]
==
"Gauss"
:
if
self
.
config
[
"psf_setting"
][
"psf_model"
]
==
"Gauss"
:
psf_model
=
PSFGauss
(
chip
=
chip
,
psfRa
=
self
.
config
[
"psf_setting"
][
"psf_rcont"
])
psf_model
=
PSFGauss
(
chip
=
chip
,
psfRa
=
self
.
config
[
"psf_setting"
][
"psf_rcont"
])
elif
self
.
config
[
"psf_setting"
][
"psf_model"
]
==
"Interp"
:
elif
self
.
config
[
"psf_setting"
][
"psf_model"
]
==
"Interp"
:
if
chip
.
survey_type
==
"spectroscopic"
:
psf_model
=
PSFInterpSLS
(
chip
,
filt
,
PSF_data_prefix
=
self
.
path_dict
[
"psf_sls_dir"
])
else
:
psf_model
=
PSFInterp
(
chip
=
chip
,
npsf
=
chip
.
n_psf_samples
,
PSF_data_file
=
self
.
path_dict
[
"psf_dir"
])
psf_model
=
PSFInterp
(
chip
=
chip
,
npsf
=
chip
.
n_psf_samples
,
PSF_data_file
=
self
.
path_dict
[
"psf_dir"
])
else
:
else
:
chip_output
.
Log_error
(
"unrecognized PSF model type!!"
,
flush
=
True
)
chip_output
.
Log_error
(
"unrecognized PSF model type!!"
,
flush
=
True
)
...
@@ -198,6 +201,10 @@ class Observation(object):
...
@@ -198,6 +201,10 @@ class Observation(object):
obj
=
self
.
cat
.
objs
[
j
]
obj
=
self
.
cat
.
objs
[
j
]
# (DEBUG)
# if obj.getMagFilter(filt)>20:
# continue
# load and convert SED; also caculate object's magnitude in all CSST bands
# load and convert SED; also caculate object's magnitude in all CSST bands
try
:
try
:
sed_data
=
self
.
cat
.
load_sed
(
obj
)
sed_data
=
self
.
cat
.
load_sed
(
obj
)
...
...
ObservationSim/PSF/PSFInterpSLS.py
0 → 100644
View file @
f1dab347
This diff is collapsed.
Click to expand it.
ObservationSim/PSF/__init__.py
View file @
f1dab347
...
@@ -2,4 +2,5 @@ from .PSFModel import PSFModel
...
@@ -2,4 +2,5 @@ from .PSFModel import PSFModel
from
.PSFGauss
import
PSFGauss
from
.PSFGauss
import
PSFGauss
# from .PSFInterp.PSFInterp import PSFInterp
# from .PSFInterp.PSFInterp import PSFInterp
from
.PSFInterp
import
PSFInterp
from
.PSFInterp
import
PSFInterp
from
.PSFInterpSLS
import
PSFInterpSLS
from
.FieldDistortion
import
FieldDistortion
from
.FieldDistortion
import
FieldDistortion
\ No newline at end of file
config/config_C6_dev.yaml
0 → 100644
View file @
f1dab347
---
###############################################
#
# Configuration file for CSST simulation
# CSST-Sim Group, 2023/04/25
#
###############################################
# Base diretories and naming setup
# Can add some of the command-line arguments here as well;
# OK to pass either way or both, as long as they are consistent
<<<<<<< HEAD
work_dir
:
"
/share/home/zhangxin/CSST_SIM/CSST_new_sim/csst-simulation/"
=======
work_dir
:
"
/share/home/fangyuedong/new_sim/workplace/"
# work_dir: "/share/C6_new_sim_2sq"
>
>>>>>>
new_sim
d
ata_dir: "/share/simudata/CSSOSDataProductsSims/data/"
r
un_name: "C6_new_sim_2sq_run1"
p
roject_cycle: 6
r
un_counter: 1
#
Whether to use MPI
r
un_option:
use_mpi: NO
# NOTE: "n_threads" paramters is currently not used in the backend
# simulation codes. It should be implemented later in the web frontend
# in order to config the number of threads to request from NAOC cluster
n_threads: 80
# Output catalog only?
# If yes, no imaging simulation will run
out_cat_only: NO
#
##############################################
#
Catalog setting
#
##############################################
#
Configure your catalog: options to be implemented
#
in the corresponding (user defined) 'Catalog' class
c
atalog_options:
input_path:
cat_dir: "Catalog_C6_20221212"
star_cat: "C6_MMW_GGC_Astrometry_healpix.hdf5"
galaxy_cat: "cat2CSSTSim_bundle/"
AGN_cat: "AGN_C6_ross13_rand_pos_rmax-1.3.fits"
SED_templates_path:
star_SED: "Catalog_20210126/SpecLib.hdf5"
galaxy_SED: "Catalog_C6_20221212/sedlibs/"
AGN_SED: "quickspeclib_ross13.fits"
AGN_SED_WAVE: "wave_ross13.npy"
# Only simulate stars?
star_only: YES
# Only simulate galaxies?
galaxy_only: NO
# rotate galaxy ellipticity
rotateEll: 0. # [degree]
seed_Av: 121212 # Seed for generating random intrinsic extinction
#
##############################################
#
Observation setting
#
##############################################
o
bs_setting:
# Options for survey types:
# "Photometric": simulate photometric chips only
# "Spectroscopic": simulate slitless spectroscopic chips only
# "FGS": simulate FGS chips only (31-42)
# "All": simulate full focal plane
survey_type: "Spectroscopic"
# Exposure time [seconds]
exp_time: 150.
# Observation starting date & time
date_obs: "210525" # [yymmdd]
time_obs: "120000" # [hhmmss]
# Default Pointing [degrees]
# Note: NOT valid when a pointing list file is specified
ra_center: 192.8595
dec_center: 27.1283
# Image rotation [degree]
image_rot: -113.4333
# (Optional) a file of point list
# if you just want to run default pointing:
# - pointing_dir: null
# - pointing_file: null
pointing_dir: "/share/simudata/CSSOSDataProductsSims/data/"
pointing_file: "pointing_radec_246.5_40.dat"
# Number of calibration pointings
np_cal: 0
# Run specific pointing(s):
# - give a list of indexes of pointings: [ip_1, ip_2...]
# - run all pointings: null
# Note: only valid when a pointing list is specified
run_pointings: [0]
# Run specific chip(s):
# - give a list of indexes of chips: [ip_1, ip_2...]
# - run all chips: null
# Note: for all pointings
run_chips: [10]
# Whether to enable astrometric modeling
enable_astrometric_model: True
# Whether to enable straylight model
enable_straylight_model: True
# Cut by saturation magnitude in which band?
cut_in_band: "z"
# saturation magnitude margin
# mag_sat_margin: -2.5
mag_sat_margin: -15.
# limiting magnitude margin
mag_lim_margin: +1.0
#
##############################################
#
PSF setting
#
##############################################
p
sf_setting:
# Which PSF model to use:
# "Gauss": simple gaussian profile
# "Interp": Interpolated PSF from sampled ray-tracing data
psf_model: "Interp"
# PSF size [arcseconds]
# radius of 80% energy encircled
# NOTE: only valid for "Gauss" PSF
psf_rcont: 0.15
# path to PSF data
# NOTE: only valid for "Interp" PSF
psf_dir: "/share/simudata/CSSOSDataProductsSims/data/psfCube1"
psf_sls_dir: "/share/simudata/CSSOSDataProductsSims/data/SLS_PSF_PCA_fp/"
#
##############################################
#
Shear setting
#
##############################################
s
hear_setting:
# Options to generate mock shear field:
# "constant": all galaxies are assigned a constant reduced shear
# "catalog": from catalog
shear_type: "catalog"
# For constant shear filed
reduced_g1: 0.
reduced_g2: 0.
#
##############################################
#
Instrumental effects setting
#
##############################################
i
ns_effects:
# switches
# Note: bias_16channel, gain_16channel, and shutter_effect
# is currently not applicable to "FGS" observations
field_dist: YES # Whether to add field distortions
add_back: YES # Whether to add sky background
add_dark: YES # Whether to add dark noise
add_readout: YES # Whether to add read-out (Gaussian) noise
add_bias: YES # Whether to add bias-level to images
bias_16channel: YES # Whether to add different biases for 16 channels
gain_16channel: YES # Whether to make different gains for 16 channels
shutter_effect: YES # Whether to add shutter effect
flat_fielding: YES # Whether to add flat-fielding effect
prnu_effect: YES # Whether to add PRNU effect
non_linear: YES # Whether to add non-linearity
cosmic_ray: YES # Whether to add cosmic-ray
cray_differ: YES # Whether to generate different cosmic ray maps CAL and MS output
cte_trail: YES # Whether to simulate CTE trails
saturbloom: YES # Whether to simulate Saturation & Blooming
add_badcolumns: YES # Whether to add bad columns
add_hotpixels: YES # Whether to add hot pixels
add_deadpixels: YES # Whether to add dead(dark) pixels
bright_fatter: YES # Whether to simulate Brighter-Fatter (also diffusion) effect
# Values:
# default values have been defined individually for each chip in:
# ObservationSim/Instrument/data/ccd/chip_definition.json
# Set them here will override the default values
# dark_exptime: 300 # Exposure time for dark current frames [seconds]
# flat_exptime: 150 # Exposure time for flat-fielding frames [seconds]
# readout_time: 40 # The read-out time for each channel [seconds]
# df_strength: 2.3 # Sillicon sensor diffusion strength
# bias_level: 500 # bias level [e-/pixel]
# gain: 1.1 # Gain
# full_well: 90000 # Full well depth [e-]
#
##############################################
#
Output options (for calibration pointings only)
#
##############################################
o
utput_setting:
readout16: OFF # Whether to export as 16 channels (subimages) with pre- and over-scan
shutter_output: OFF # Whether to export shutter effect 16-bit image
bias_output: ON # Whether to export bias frames
dark_output: ON # Whether to export the combined dark current files
flat_output: ON # Whether to export the combined flat-fielding files
prnu_output: OFF # Whether to export the PRNU (pixel-to-pixel flat-fielding) files
NBias: 1 # Number of bias frames to be exported for each exposure
NDark: 1 # Number of dark frames to be exported for each exposure
NFlat: 1 # Number of flat frames to be exported for each exposure
#
##############################################
#
Random seeds
#
##############################################
r
andom_seeds:
seed_poisson: 20210601 # Seed for Poisson noise
seed_CR: 20210317 # Seed for generating random cosmic ray maps
seed_flat: 20210101 # Seed for generating random flat fields
seed_prnu: 20210102 # Seed for photo-response non-uniformity
seed_gainNonUniform: 20210202 # Seed for gain nonuniformity
seed_biasNonUniform: 20210203 # Seed for bias nonuniformity
seed_rnNonUniform: 20210204 # Seed for readout-noise nonuniformity
seed_badcolumns: 20240309 # Seed for bad columns
seed_defective: 20210304 # Seed for defective (bad) pixels
seed_readout: 20210601 # Seed for read-out gaussian noise
.
..
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