ObservationSim.py 8.73 KB
Newer Older
1
import os
Fang Yuedong's avatar
Fang Yuedong committed
2
3
4
5
import numpy as np
import mpi4py.MPI as MPI
import galsim
import psutil
Fang Yuedong's avatar
Fang Yuedong committed
6
import gc
7
8
from datetime import datetime

Fang Yuedong's avatar
Fang Yuedong committed
9
10
import traceback

11
from ObservationSim.Config import ChipOutput
12
from ObservationSim.Instrument import Telescope, Filter, FilterParam, FocalPlane, Chip
13
from ObservationSim.Instrument.Chip import Effects
Fang Yuedong's avatar
Fang Yuedong committed
14
from ObservationSim.Instrument.Chip import ChipUtils as chip_utils
15
from ObservationSim.Astrometry.Astrometry_util import on_orbit_obs_position
16
from ObservationSim.sim_steps import SimSteps, SIM_STEP_TYPES
Fang Yuedong's avatar
Fang Yuedong committed
17

Fang Yuedong's avatar
Fang Yuedong committed
18
class Observation(object):
19
    def __init__(self, config, Catalog, work_dir=None, data_dir=None):
Fang Yuedong's avatar
Fang Yuedong committed
20
        self.config = config
Fang Yuedong's avatar
Fang Yuedong committed
21
22
        self.tel = Telescope()
        self.filter_param = FilterParam() 
23
        self.Catalog = Catalog
Fang Yuedong's avatar
Fang Yuedong committed
24

25
    def prepare_chip_for_exposure(self, chip, ra_cen, dec_cen, pointing, wcs_fp=None):
Fang Yuedong's avatar
Fang Yuedong committed
26
27
28
        # 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)
Fang Yuedong's avatar
Fang Yuedong committed
29

Fang Yuedong's avatar
Fang Yuedong committed
30
31
32
33
34
35
36
37
38
39
        # Create chip Image
        chip.img = galsim.ImageF(chip.npix_x, chip.npix_y)
        chip.img.setOrigin(chip.bound.xmin, chip.bound.ymin)
        chip.img.wcs = wcs_fp

        # 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
40
        chip.flat_img, _ = chip_utils.get_flat(img=chip.img, seed=int(self.config["random_seeds"]["seed_flat"]))
41
42
43
44
        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)
Fang Yuedong's avatar
Fang Yuedong committed
45
46
47
48
        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
Fang Yuedong's avatar
Fang Yuedong committed
49

50
    def run_one_chip(self, chip, filt, pointing, chip_output, wcs_fp=None, psf_model=None, cat_dir=None, sed_dir=None):
Fang Yuedong's avatar
Fang Yuedong committed
51

Fang Yuedong's avatar
Fang Yuedong committed
52
53
54
55
56
57
58
59
60
        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("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("Position Angle: %f" % pointing.img_pa.deg)
        chip_output.Log_info('Chip : %d' % chip.chipID)
        chip_output.Log_info(':::::::::::::::::::::::::::END:::::::::::::::::::::::::::::::::::')
Fang Yuedong's avatar
Fang Yuedong committed
61

62
63
        # Apply astrometric simulation for pointing
        if self.config["obs_setting"]["enable_astrometric_model"]:
Fang Yuedong's avatar
Fang Yuedong committed
64
            dt = datetime.utcfromtimestamp(pointing.timestamp)
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
            date_str = dt.date().isoformat()
            time_str = dt.time().isoformat()
            ra_cen, dec_cen = on_orbit_obs_position(
                input_ra_list=[pointing.ra],
                input_dec_list=[pointing.dec],
                input_pmra_list=[0.],
                input_pmdec_list=[0.],
                input_rv_list=[0.],
                input_parallax_list=[1e-9],
                input_nstars=1,
                input_x=pointing.sat_x,
                input_y=pointing.sat_y,
                input_z=pointing.sat_z,
                input_vx=pointing.sat_vx,
                input_vy=pointing.sat_vy,
                input_vz=pointing.sat_vz,
Fang Yuedong's avatar
Fang Yuedong committed
81
                input_epoch="J2000",
82
83
84
85
86
87
88
89
                input_date_str=date_str,
                input_time_str=time_str
            )
            ra_cen, dec_cen = ra_cen[0], dec_cen[0]
        else:
            ra_cen = pointing.ra
            dec_cen = pointing.dec

90
        # Prepare necessary chip properties for simulation
Fang Yuedong's avatar
Fang Yuedong committed
91
        chip = self.prepare_chip_for_exposure(chip, ra_cen, dec_cen, pointing)
92

Fang Yuedong's avatar
Fang Yuedong committed
93
94
        # Initialize SimSteps
        sim_steps = SimSteps(overall_config=self.config, chip_output=chip_output, all_filters=self.all_filters)
95

Fang Yuedong's avatar
Fang Yuedong committed
96
        for step in pointing.obs_param["call_sequence"]:
97
98
99
            if self.config["run_option"]["out_cat_only"]:
                if step != "scie_obs":
                    continue
100
            chip_output.Log_info("Starting simulation step: %s, calling function: %s"%(step, SIM_STEP_TYPES[step]))
Fang Yuedong's avatar
Fang Yuedong committed
101
102
103
104
105
106
107
            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, 
108
                    tel=self.tel,
Fang Yuedong's avatar
Fang Yuedong committed
109
                    pointing=pointing, 
110
                    catalog=self.Catalog, 
Fang Yuedong's avatar
Fang Yuedong committed
111
                    obs_param=obs_param)
112
                chip_output.Log_info("Finished simulation step: %s"%(step))
Fang Yuedong's avatar
Fang Yuedong committed
113
114
115
            except Exception as e:
                traceback.print_exc()
                chip_output.Log_error(e)
116
117
                chip_output.Log_error("Failed simulation on step: %s"%(step))
                break
Fang Yuedong's avatar
Fang Yuedong committed
118

Fang Yuedong's avatar
Fang Yuedong committed
119
        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) ))
Zhang Xin's avatar
Zhang Xin committed
120
121
        del chip.img

Fang Yuedong's avatar
Fang Yuedong committed
122
    def runExposure_MPI_PointingList(self, pointing_list, chips=None, use_mpi=False):
Fang Yuedong's avatar
Fang Yuedong committed
123
124
125
126
        if use_mpi:
            comm = MPI.COMM_WORLD
            ind_thread = comm.Get_rank()
            num_thread = comm.Get_size()
Fang Yuedong's avatar
Fang Yuedong committed
127

Fang Yuedong's avatar
Fang Yuedong committed
128
        process_counter = 0
129
        for ipoint in range(len(pointing_list)):
Fang Yuedong's avatar
Fang Yuedong committed
130
131
            # Construct chips & filters:
            pointing = pointing_list[ipoint]
132
133
            # pointing_ID = pointing.id
            pointing_ID = pointing.obs_id
134

135
            pointing.make_output_pointing_dir(overall_config=self.config, copy_obs_config=True)
136

Fang Yuedong's avatar
Fang Yuedong committed
137
138
            self.focal_plane = FocalPlane(chip_list=pointing.obs_param["run_chips"])
            # Make Chip & Filter lists
139
140
141
            self.chip_list = []
            self.filter_list = []
            self.all_filters = []
Fang Yuedong's avatar
Fang Yuedong committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
            for i in range(self.focal_plane.nchips):
                chipID = i + 1
                chip = Chip(chipID=chipID, config=self.config)
                filter_id, filter_type = chip.getChipFilter()
                filt = Filter(
                    filter_id=filter_id,
                    filter_type=filter_type,
                    filter_param=self.filter_param)
                if not self.focal_plane.isIgnored(chipID=chipID):
                    self.chip_list.append(chip)
                    self.filter_list.append(filt)
                self.all_filters.append(filt)

            if chips is None:
                # Run all chips defined in configuration of this pointing
                run_chips = self.chip_list
                run_filts = self.filter_list
                nchips_per_fp = len(self.chip_list)
            else:
                # Only run a particular set of chips (defined in the overall config file)
                run_chips = []
                run_filts = []
                for ichip in range(len(self.chip_list)):
                    chip = self.chip_list[ichip]
                    filt = self.filter_list[ichip]
                    if chip.chipID in chips:
                        run_chips.append(chip)
                        run_filts.append(filt)
                nchips_per_fp = len(chips)
            
Fang Yuedong's avatar
Fang Yuedong committed
172
            for ichip in range(nchips_per_fp):
Fang Yuedong's avatar
Fang Yuedong committed
173
                i_process = process_counter + ichip
Fang Yuedong's avatar
Fang Yuedong committed
174
                if use_mpi:
Fang Yuedong's avatar
Fang Yuedong committed
175
                    if i_process % num_thread != ind_thread:
Fang Yuedong's avatar
Fang Yuedong committed
176
                        continue
Fang Yuedong's avatar
Fang Yuedong committed
177
178
                pid = os.getpid()

Fang Yuedong's avatar
Fang Yuedong committed
179
180
                chip = run_chips[ichip]
                filt = run_filts[ichip]
181
                
Fang Yuedong's avatar
Fang Yuedong committed
182
                chip_output = ChipOutput(
183
184
185
186
187
188
                    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))
Fang Yuedong's avatar
Fang Yuedong committed
189
190
191
192
193
                self.run_one_chip(
                    chip=chip,
                    filt=filt,
                    chip_output=chip_output,
                    pointing=pointing)
Fang Yuedong's avatar
Fang Yuedong committed
194
                chip_output.Log_info("finished running chip#%d..."%(chip.chipID))
195
196
                for handler in chip_output.logger.handlers[:]:
                    chip_output.logger.removeHandler(handler)
Fang Yuedong's avatar
Fang Yuedong committed
197
                gc.collect()
Fang Yuedong's avatar
Fang Yuedong committed
198
            process_counter += nchips_per_fp