ObservationSim.py 8.62 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

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

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

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

Fang Yuedong's avatar
Fang Yuedong committed
136
137
            self.focal_plane = FocalPlane(chip_list=pointing.obs_param["run_chips"])
            # Make Chip & Filter lists
138
139
140
            self.chip_list = []
            self.filter_list = []
            self.all_filters = []
Fang Yuedong's avatar
Fang Yuedong committed
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
            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:
160
                # Only run a particular set of chips
Fang Yuedong's avatar
Fang Yuedong committed
161
162
163
164
165
166
167
168
169
170
                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
171
            for ichip in range(nchips_per_fp):
Fang Yuedong's avatar
Fang Yuedong committed
172
                i_process = process_counter + ichip
173
174
                if i_process % num_thread != ind_thread:
                    continue
Fang Yuedong's avatar
Fang Yuedong committed
175
176
                pid = os.getpid()

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