Commit 1b4f4012 authored by Fang Yuedong's avatar Fang Yuedong
Browse files

Merge branch 'master' into 'release_v3.0'

version v3.1.0

See merge request !31
parents d8118d46 5544935f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
# CSST主巡天仿真软件

## 重要更新或问题修复:
* 2024.08.03: 更新至v3.1版本,内容包括:
    * 加入对导星稳像过程的仿真
    * 加入银河系消光的仿真
    * Bug修复:修复因滤光片漏光导致的仿真星等不吻合等bug
* 2024.05.15: 更新至v3.0版本,新功能具体内容见[软件说明文档](https://kdocs.cn/l/cjyiU0SXGyn2)
* 2023.07.29: 更新至v2.1版本,内容包括:
    * 加入杂散光模块,config文件中添加开关:enable_straylight_model: True/False
+41 −3
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@ from astropy.table import Table
from scipy import interpolate
from datetime import datetime

from observation_sim.mock_objects import CatalogBase, Star, Galaxy, Quasar
from observation_sim.mock_objects import CatalogBase, Star, Galaxy, Quasar, ExtinctionMW
from observation_sim.mock_objects._util import tag_sed, getObservedSED, getABMAG, integrate_sed_bandpass, comoving_dist
from observation_sim.astrometry.Astrometry_util import on_orbit_obs_position

@@ -110,6 +110,16 @@ class Catalog(CatalogBase):

        self.max_size = 0.

        # [TODO] Milky Way extinction
        if "enable_mw_ext_gal" in config["catalog_options"] and config["catalog_options"]["enable_mw_ext_gal"]:
            if "planck_ebv_map" not in config["catalog_options"]:
                raise ValueError(
                    "Planck dust map must be given to enable Milky Way extinction calculation for galaxies.")
            self.mw_ext = ExtinctionMW()
            self.mw_ext.init_ext_model(model_name="odonnell")
            self.mw_ext.load_Planck_ext(
                file_path=config["catalog_options"]["planck_ebv_map"])

        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(
@@ -248,6 +258,12 @@ class Catalog(CatalogBase):
                input_time_str=time_str
            )

        # [TODO] get Milky Way extinction AVs
        if "enable_mw_ext_gal" in self.config["catalog_options"] and self.config["catalog_options"]["enable_mw_ext_gal"]:
            MW_Av_arr = self.mw_ext.Av_from_Planck(ra=ra_arr, dec=dec_arr)
        else:
            MW_Av_arr = np.zeros(len(ra_arr))

        for igals in range(ngals):
            # # (TEST)
            # if igals > 100:
@@ -259,6 +275,9 @@ class Catalog(CatalogBase):
            param['ra_orig'] = gals['ra'][igals]
            param['dec_orig'] = gals['dec'][igals]

            # [TODO] get Milky Way extinction AVs
            param['mw_Av'] = MW_Av_arr[igals]

            if not self.chip.isContainObj(ra_obj=param['ra'], dec_obj=param['dec'], margin=200):
                continue

@@ -530,11 +549,30 @@ class Catalog(CatalogBase):
        speci = interpolate.interp1d(wave, flux)
        lamb = np.arange(2000, 11001+0.5, 0.5)
        y = speci(lamb)

        # [TODO] Apply Milky Way extinction
        if obj.type != 'star' and ("enable_mw_ext_gal" in self.config["catalog_options"] and self.config["catalog_options"]["enable_mw_ext_gal"]):
            y = self.mw_ext.apply_extinction(y, Av=obj.mw_Av)

        # 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'))
        if obj.type == 'quasar':
        # 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)
        #     # mag = getABMAG(interFlux, self.filt.bandpass_full)
        #     # print("mag diff = %.3f"%(mag - obj.param['mag_use_normal']))

        # integrate to get the magnitudes
        if obj.type == 'quasar' or obj.type == 'galaxy':
            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')
+7 −3
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@
# can add some of the command-line arguments here as well;
# ok to pass either way or both, as long as they are consistent
work_dir: "/public/home/fangyuedong/project/workplace/"
run_name: "no_nonlinearity_test"
run_name: "ext_on"

# Project cycle and run counter are used to name the outputs
project_cycle: 9
@@ -49,6 +49,10 @@ catalog_options:
  # rotate galaxy ellipticity
  rotateEll: 0. # [degree]

  # Whether to apply milky way extinction to galaxies
  enable_mw_ext_gal: YES
  planck_ebv_map: "/public/home/fangyuedong/project/ext_maps/planck/HFI_CompMap_ThermalDustModel_2048_R1.20.fits"

###############################################
# Observation setting
###############################################
@@ -65,10 +69,10 @@ obs_setting:
  # - 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: [1]
  run_pointings: [0, 1, 2, 3, 4]

  # Whether to enable astrometric modeling
  enable_astrometric_model: True
  enable_astrometric_model: YES

  # Cut by saturation magnitude in which band?
  cut_in_band: "z"
+1 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ obs_id: "00000001" # this setting will only be used if pointing list file is not
# Define list of chips
# run_chips: [6,7,8,9,11,12,13,14,15,16,17,18,19,20,22,23,24,25] # Photometric chips
#run_chips: [1,2,3,4,5,10,21,26,27,28,29,30] # Spectroscopic chips
run_chips: [1]
run_chips: [17, 22]

# Define observation sequence
call_sequence:
+38 −7
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ class Observation(object):
        self.filter_param = FilterParam()
        self.Catalog = Catalog

    def prepare_chip_for_exposure(self, chip, ra_cen, dec_cen, pointing, wcs_fp=None):
    def prepare_chip_for_exposure(self, chip, ra_cen, dec_cen, pointing, wcs_fp=None, slsPSFOptim=False):
        # Get WCS for the focal plane
        if wcs_fp == None:
            wcs_fp = self.focal_plane.getTanWCS(
@@ -34,6 +34,27 @@ class Observation(object):
        chip.img.setOrigin(chip.bound.xmin, chip.bound.ymin)
        chip.img.wcs = wcs_fp

        chip.slsPSFOptim = slsPSFOptim
        if chip.chipID in [1, 2, 3, 4, 5, 10, 21, 26, 27, 28, 29, 30] and slsPSFOptim:
            chip.img_stack = {}
            for id1 in np.arange(2):
                gn = chip_utils.getChipSLSGratingID(chip.chipID)[id1]
                orders = {}
                # for id2 in ['-2','-1','0','1','2']:
                for id2 in ['0', '1']:
                    o_n = "order"+id2
                    allbands = {}
                    for id3 in ['1', '2', '3', '4']:
                        w_n = "w"+id3
                        allbands[w_n] = galsim.ImageF(chip.npix_x, chip.npix_y)
                        allbands[w_n].setOrigin(
                            chip.bound.xmin, chip.bound.ymin)
                        allbands[w_n].wcs = wcs_fp
                    orders[o_n] = allbands
                chip.img_stack[gn] = orders
        else:
            chip.img_stack = {}

        # 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.)
@@ -45,7 +66,7 @@ class Observation(object):
            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.img, t_exp=pointing.exp_time, 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))

@@ -91,17 +112,24 @@ class Observation(object):
                input_date_str=date_str,
                input_time_str=time_str
            )
            ra_cen, dec_cen = ra_cen[0], dec_cen[0]
            ra_offset, dec_offset = pointing.ra - \
                ra_cen[0], pointing.dec - dec_cen[0]
        else:
            ra_offset, dec_offset = 0., 0.
        ra_cen = pointing.ra
        dec_cen = pointing.dec

        slsPSFOpt = False
        # Prepare necessary chip properties for simulation
        chip = self.prepare_chip_for_exposure(chip, ra_cen, dec_cen, pointing)
        chip = self.prepare_chip_for_exposure(
            chip, ra_cen, dec_cen, pointing, slsPSFOptim=slsPSFOpt)

        # Initialize SimSteps
        sim_steps = SimSteps(overall_config=self.config,
                             chip_output=chip_output, all_filters=self.all_filters)
                             chip_output=chip_output,
                             all_filters=self.all_filters,
                             ra_offset=ra_offset,
                             dec_offset=dec_offset)

        for step in pointing.obs_param["call_sequence"]:
            if self.config["run_option"]["out_cat_only"]:
@@ -130,6 +158,9 @@ class Observation(object):
        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
        del chip.flat_img
        del chip.prnu_img
        del chip.shutter_img

    def runExposure_MPI_PointingList(self, pointing_list, chips=None):
        comm = MPI.COMM_WORLD
Loading