Commit a3e660e379beb56421bf301edac7dd7a937f22ee

Authored by Jürgen Knödlseder
1 parent 256eb549

Improve code quality of example scripts (#1828)

cscripts/ioutils.py
@@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
18 # 18 #
19 # ========================================================================== 19 # ==========================================================================
20 import csv 20 import csv
  21 +import sys
21 import gammalib 22 import gammalib
22 import ctools 23 import ctools
23 24
@@ -62,3 +63,59 @@ def write_csv_row(outfile, row, colnames, colvalues): @@ -62,3 +63,59 @@ def write_csv_row(outfile, row, colnames, colvalues):
62 63
63 # Return 64 # Return
64 return 65 return
  66 +
  67 +
  68 +# ============================== #
  69 +# Get options from argument list #
  70 +# ============================== #
  71 +def get_arg_options(options, usage):
  72 + """
  73 + Get options from argument list
  74 +
  75 + Parameters
  76 + ----------
  77 + options : list of dict
  78 + List of possible options and default values
  79 + usage : str
  80 + Usage string to be shown in case of a problem
  81 +
  82 + Returns
  83 + -------
  84 + options : list of dict
  85 + Update list of options
  86 + """
  87 + # If there are no command line arguments then show usage string and
  88 + # exit
  89 + if len(sys.argv) < 1:
  90 + print(usage)
  91 + sys.exit()
  92 +
  93 + # First possible option is element 1
  94 + i = 1
  95 +
  96 + # Loop over all arguments
  97 + while i < len(sys.argv):
  98 +
  99 + # Search for options
  100 + for option in options:
  101 + if sys.argv[i] == option['option']:
  102 +
  103 + # If an option has been found then check if there is a
  104 + # following parameter and extract that parameter as a
  105 + # string
  106 + if len(sys.argv) > i+1:
  107 + i += 1
  108 + try:
  109 + option['value'] = str(sys.argv[i])
  110 + except:
  111 + print(usage)
  112 + sys.exit()
  113 + else:
  114 + print(usage)
  115 + sys.exit()
  116 +
  117 + # Next item
  118 + i += 1
  119 +
  120 + # Return options
  121 + return options
cscripts/obsutils.py
@@ -31,9 +31,9 @@ def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, @@ -31,9 +31,9 @@ def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0,
31 Simulate events for all observations in the container 31 Simulate events for all observations in the container
32 32
33 Simulate events for all observations using ctobssim. If the number of 33 Simulate events for all observations using ctobssim. If the number of
34 - energy bins is positive, the events are then binned in a counts cube  
35 - using ctbin. If multiple observations are simulated, the counts cube is  
36 - a stacked cube and the corresponding response cubes are computed using 34 + energy bins is positive, the events are binned into a counts cube using
  35 + ctbin. If multiple observations are simulated, the counts cube is a
  36 + stacked cube and the corresponding response cubes are computed using
37 ctexpcube, ctpsfcube, ctbkgcube and optionally ctedispcube. The response 37 ctexpcube, ctpsfcube, ctbkgcube and optionally ctedispcube. The response
38 cubes are attached to the first observation in the container, which 38 cubes are attached to the first observation in the container, which
39 normally is the observation with the counts cube. 39 normally is the observation with the counts cube.
@@ -203,8 +203,8 @@ def set_obs(pntdir, tstart=0.0, duration=1800.0, deadc=0.95, \ @@ -203,8 +203,8 @@ def set_obs(pntdir, tstart=0.0, duration=1800.0, deadc=0.95, \
203 Set a single CTA observation 203 Set a single CTA observation
204 204
205 The function sets a single CTA observation containing an empty CTA 205 The function sets a single CTA observation containing an empty CTA
206 - event list. By looping over this function you can add CTA observations  
207 - to the observation container. 206 + event list. By looping over this function CTA observations can be
  207 + added to the observation container.
208 208
209 Parameters 209 Parameters
210 ---------- 210 ----------
@@ -235,19 +235,19 @@ def set_obs(pntdir, tstart=0.0, duration=1800.0, deadc=0.95, \ @@ -235,19 +235,19 @@ def set_obs(pntdir, tstart=0.0, duration=1800.0, deadc=0.95, \
235 CTA observation 235 CTA observation
236 """ 236 """
237 # Allocate CTA observation 237 # Allocate CTA observation
238 - obs_cta = gammalib.GCTAObservation() 238 + obs = gammalib.GCTAObservation()
239 239
240 - # Set calibration database 240 + # Set CTA calibration database
241 db = gammalib.GCaldb() 241 db = gammalib.GCaldb()
242 if (gammalib.dir_exists(caldb)): 242 if (gammalib.dir_exists(caldb)):
243 db.rootdir(caldb) 243 db.rootdir(caldb)
244 else: 244 else:
245 db.open('cta', caldb) 245 db.open('cta', caldb)
246 246
247 - # Set pointing direction 247 + # Set pointing direction for CTA observation
248 pnt = gammalib.GCTAPointing() 248 pnt = gammalib.GCTAPointing()
249 pnt.dir(pntdir) 249 pnt.dir(pntdir)
250 - obs_cta.pointing(pnt) 250 + obs.pointing(pnt)
251 251
252 # Set ROI 252 # Set ROI
253 roi = gammalib.GCTARoi() 253 roi = gammalib.GCTARoi()
@@ -266,22 +266,26 @@ def set_obs(pntdir, tstart=0.0, duration=1800.0, deadc=0.95, \ @@ -266,22 +266,26 @@ def set_obs(pntdir, tstart=0.0, duration=1800.0, deadc=0.95, \
266 266
267 # Allocate event list 267 # Allocate event list
268 events = gammalib.GCTAEventList() 268 events = gammalib.GCTAEventList()
  269 +
  270 + # Set ROI, GTI and energy boundaries for event list
269 events.roi(roi) 271 events.roi(roi)
270 events.gti(gti) 272 events.gti(gti)
271 events.ebounds(ebounds) 273 events.ebounds(ebounds)
272 - obs_cta.events(events)  
273 274
274 - # Set instrument response  
275 - obs_cta.response(irf, db) 275 + # Set the event list as the events for CTA observation
  276 + obs.events(events)
  277 +
  278 + # Set instrument response for CTA observation
  279 + obs.response(irf, db)
276 280
277 - # Set ontime, livetime, and deadtime correction factor  
278 - obs_cta.ontime(duration)  
279 - obs_cta.livetime(duration*deadc)  
280 - obs_cta.deadc(deadc)  
281 - obs_cta.id(obsid) 281 + # Set ontime, livetime, and deadtime correction factor for CTA observation
  282 + obs.ontime(duration)
  283 + obs.livetime(duration*deadc)
  284 + obs.deadc(deadc)
  285 + obs.id(obsid)
282 286
283 # Return CTA observation 287 # Return CTA observation
284 - return obs_cta 288 + return obs
285 289
286 290
287 # ============================ # 291 # ============================ #
examples/generate_prod3_irfs.py
1 #! /usr/bin/env python 1 #! /usr/bin/env python
2 # ========================================================================== 2 # ==========================================================================
3 -# Generates Prod3 IRFs from ROOT performance files. 3 +# Generates Prod3 IRFs from ROOT performance files
4 # 4 #
5 # Copyright (C) 2016 Juergen Knoedlseder 5 # Copyright (C) 2016 Juergen Knoedlseder
6 # 6 #
@@ -30,7 +30,7 @@ def set_prod3_desy(datadir): @@ -30,7 +30,7 @@ def set_prod3_desy(datadir):
30 Set Prod3 DESY database 30 Set Prod3 DESY database
31 31
32 This function sets the calibration database. By adding dictionaries to 32 This function sets the calibration database. By adding dictionaries to
33 - the db list a number of calibrations can be defined for which IRFs 33 + the "db" list a number of calibrations can be defined for which IRFs
34 should be generated. All calibrations will be added to the calibration 34 should be generated. All calibrations will be added to the calibration
35 database. 35 database.
36 36
@@ -44,22 +44,10 @@ def set_prod3_desy(datadir): @@ -44,22 +44,10 @@ def set_prod3_desy(datadir):
44 db : list of dict 44 db : list of dict
45 Database 45 Database
46 """ 46 """
47 - # Set database attributes  
48 - path = datadir  
49 - file = 'irf.root'  
50 - psftype = 'Gauss'  
51 - oversample = 3  
52 - #norm1d = True # Will normalise the on-axis 2D IRFs on the 1D IRFs  
53 - norm1d = False  
54 - bgdinfill = False  
55 - bgdethres = 10.0  
56 -  
57 # Set database content 47 # Set database content
58 - db = [{'inst': 'prod3', 'id': 'South_50h', 'psftype': psftype,  
59 - 'oversample': oversample, 'norm1d': norm1d,  
60 - 'bgdinfill': bgdinfill, 'bgdethres': bgdethres,  
61 - 'path': path, 'file': file}  
62 - ] 48 + db = [{'inst': 'prod3', 'id': 'South_50h', 'analysis': 'DESY',
  49 + 'oversample': 3, 'norm1d': False, 'bgdinfill': False,
  50 + 'bgdethres': 10.0, 'path': datadir, 'file': 'irf.root'}]
63 51
64 # Return database 52 # Return database
65 return db 53 return db
@@ -82,36 +70,6 @@ if __name__ == &#39;__main__&#39;: @@ -82,36 +70,6 @@ if __name__ == &#39;__main__&#39;:
82 # Loop over entries 70 # Loop over entries
83 for entry in entries: 71 for entry in entries:
84 72
85 - # Set optional attributes  
86 - if 'rebin' in entry:  
87 - rebin = entry['rebin']  
88 - else:  
89 - rebin = False  
90 - if 'eascale' in entry:  
91 - eascale = entry['eascale']  
92 - else:  
93 - eascale = 1.0  
94 - if 'bgdscale' in entry:  
95 - bgdscale = entry['bgdscale']  
96 - else:  
97 - bgdscale = 1.0  
98 - if 'bgdethres' in entry:  
99 - bgdethres = entry['bgdethres']  
100 - else:  
101 - bgdethres = 1000.0  
102 - if 'bgdinfill' in entry:  
103 - bgdinfill = entry['bgdinfill']  
104 - else:  
105 - bgdinfill = False  
106 - if 'oversample' in entry:  
107 - oversample = entry['oversample']  
108 - else:  
109 - oversample = 1  
110 - if 'norm1d' in entry:  
111 - norm1d = entry['norm1d']  
112 - else:  
113 - norm1d = False  
114 -  
115 # Set filename 73 # Set filename
116 filename = entry['path']+'/'+entry['file'] 74 filename = entry['path']+'/'+entry['file']
117 75
@@ -122,15 +80,15 @@ if __name__ == &#39;__main__&#39;: @@ -122,15 +80,15 @@ if __name__ == &#39;__main__&#39;:
122 caldb['inst'] = entry['inst'] 80 caldb['inst'] = entry['inst']
123 caldb['id'] = entry['id'] 81 caldb['id'] = entry['id']
124 caldb['version'] = entry['inst'] 82 caldb['version'] = entry['inst']
125 - caldb['analysis'] = 'DESY'  
126 - caldb['psftype'] = entry['psftype']  
127 - caldb['norm1d'] = norm1d  
128 - caldb['rebin'] = rebin  
129 - caldb['eascale'] = eascale  
130 - caldb['bgdscale'] = bgdscale  
131 - caldb['bgdoversample'] = oversample  
132 - caldb['bgdethres'] = bgdethres  
133 - caldb['bgdinfill'] = bgdinfill 83 + caldb['analysis'] = entry.setdefault('analysis', 'DESY')
  84 + caldb['psftype'] = entry.setdefault('psftype', 'Gauss')
  85 + caldb['norm1d'] = entry.setdefault('norm1d', False)
  86 + caldb['rebin'] = entry.setdefault('rebin', False)
  87 + caldb['eascale'] = entry.setdefault('eascale', 1.0)
  88 + caldb['bgdscale'] = entry.setdefault('bgdscale', 1.0)
  89 + caldb['bgdoversample'] = entry.setdefault('oversample', 1)
  90 + caldb['bgdethres'] = entry.setdefault('bgdethres', 1000.0)
  91 + caldb['bgdinfill'] = entry.setdefault('bgdinfill', False)
134 caldb['logfile'] = 'generate_prod3_irfs.log' 92 caldb['logfile'] = 'generate_prod3_irfs.log'
135 93
136 # Add CALDB entry 94 # Add CALDB entry
examples/make_pointings.py
@@ -56,7 +56,7 @@ def get_positions(xmin, xmax, ymin, ymax, step): @@ -56,7 +56,7 @@ def get_positions(xmin, xmax, ymin, ymax, step):
56 # Initialise positions 56 # Initialise positions
57 positions = [] 57 positions = []
58 58
59 - # Determine ystep and number of rows 59 + # Determine ystep and number of pointing rows
60 ystep = step * math.sqrt(0.75) 60 ystep = step * math.sqrt(0.75)
61 ny = int((ymax-ymin)/ystep+1.5) 61 ny = int((ymax-ymin)/ystep+1.5)
62 rescale = (ymax-ymin)/(ystep*(ny-1)) 62 rescale = (ymax-ymin)/(ystep*(ny-1))
@@ -67,13 +67,16 @@ def get_positions(xmin, xmax, ymin, ymax, step): @@ -67,13 +67,16 @@ def get_positions(xmin, xmax, ymin, ymax, step):
67 y = ymin 67 y = ymin
68 for row in range(ny): 68 for row in range(ny):
69 69
70 - # Determine xstep and number of pointings in row  
71 - xstep = step / math.cos(gammalib.deg2rad * y)  
72 - nx = int((xmax-xmin)/xstep+1.5) 70 + # Determine xstep and number of pointings in row. The xstep increases
  71 + # with the cosine of the latitude so that the distance of the step
  72 + # is invariant of latitude.
  73 + xstep = step / math.cos(gammalib.deg2rad * y)
  74 + nx = int((xmax-xmin)/xstep+1.5)
73 rescale = (xmax-xmin)/(xstep*(nx-1)) 75 rescale = (xmax-xmin)/(xstep*(nx-1))
74 xstep *= rescale 76 xstep *= rescale
75 77
76 - # Set x offset 78 + # Set x offset. For every second row the x position is displace by
  79 + # half a step size.
77 if row % 2 == 0: 80 if row % 2 == 0:
78 x = xmin 81 x = xmin
79 else: 82 else:
@@ -151,7 +154,9 @@ def set_patch(lmin=-30.0, lmax=30.0, bmin=-1.5, bmax=+1.5, @@ -151,7 +154,9 @@ def set_patch(lmin=-30.0, lmax=30.0, bmin=-1.5, bmax=+1.5,
151 # Optionally add-in site dependent IRF 154 # Optionally add-in site dependent IRF
152 if site != None: 155 if site != None:
153 156
154 - # Handle automatic site switching 157 + # If automatic site switching is requested then set the North
  158 + # IRF for declinations greater or equal than "autodec" and the
  159 + # South IRF for declination smaller than "autodec".
155 if site == 'Automatic': 160 if site == 'Automatic':
156 pos = gammalib.GSkyDir() 161 pos = gammalib.GSkyDir()
157 pos.lb_deg(pnt['x'], pnt['y']) 162 pos.lb_deg(pnt['x'], pnt['y'])
@@ -160,10 +165,13 @@ def set_patch(lmin=-30.0, lmax=30.0, bmin=-1.5, bmax=+1.5, @@ -160,10 +165,13 @@ def set_patch(lmin=-30.0, lmax=30.0, bmin=-1.5, bmax=+1.5,
160 obs_site = 'North' 165 obs_site = 'North'
161 else: 166 else:
162 obs_site = 'South' 167 obs_site = 'South'
  168 +
  169 + # ... otherwise use the specified site, North or South
163 else: 170 else:
164 obs_site = site 171 obs_site = site
165 172
166 - # Set site IRF 173 + # Set site dependent Prod2 50 hour IRF and add up exposure for
  174 + # a given site
167 caldb = 'prod2' 175 caldb = 'prod2'
168 if obs_site == 'North': 176 if obs_site == 'North':
169 if lst: 177 if lst:
examples/make_ts_distributions.py
@@ -87,53 +87,26 @@ def create_ts(datadir, loge, emin, emax, ntrials=100, duration=180000.0, @@ -87,53 +87,26 @@ def create_ts(datadir, loge, emin, emax, ntrials=100, duration=180000.0,
87 # ======================== # 87 # ======================== #
88 if __name__ == '__main__': 88 if __name__ == '__main__':
89 89
90 - # Get input arguments  
91 - usage = 'make_ts_distributions.py [-n ntrials] [-e enumbins] [-m max_threads]'  
92 - if len(sys.argv) < 1:  
93 - print(usage)  
94 - sys.exit()  
95 -  
96 - # Set default parameters  
97 - ntrials = 100  
98 - enumbins = 0  
99 - duration = 180000.0  
100 - max_threads = 1  
101 - datadir = 'data'  
102 -  
103 - # Parameter dictionnary  
104 - pars = [{'option': '-n', 'value': ntrials},  
105 - {'option': '-e', 'value': enumbins},  
106 - {'option': '-d', 'value': duration},  
107 - {'option': '-m', 'value': max_threads},  
108 - {'option': '-p', 'value': datadir}]  
109 -  
110 - # Gather parameters from command line  
111 - i = 1  
112 - while i < len(sys.argv):  
113 -  
114 - # Search for options  
115 - for par in pars:  
116 - if sys.argv[i] == par['option']:  
117 - if len(sys.argv) > i+1:  
118 - i += 1  
119 - try:  
120 - par['value'] = int(sys.argv[i])  
121 - except:  
122 - print(usage)  
123 - sys.exit()  
124 - else:  
125 - print(usage)  
126 - sys.exit()  
127 -  
128 - # Next item  
129 - i += 1  
130 -  
131 - # Recover parameters  
132 - ntrials = pars[0]['value']  
133 - enumbins = pars[1]['value']  
134 - duration = pars[2]['value']  
135 - max_threads = pars[3]['value']  
136 - datadir = pars[4]['value'] 90 + # Set usage string
  91 + usage = 'make_ts_distributions.py [-n ntrials] [-e enumbins]'\
  92 + ' [-d duration] [-m max_threads] [-p datadir]'
  93 +
  94 + # Set default options
  95 + options = [{'option': '-n', 'value': '100'},
  96 + {'option': '-e', 'value': '0'},
  97 + {'option': '-d', 'value': '180000.0'},
  98 + {'option': '-m', 'value': '1'},
  99 + {'option': '-p', 'value': 'data'}]
  100 +
  101 + # Get options from command line arguments
  102 + options = cscripts.ioutils.get_arg_options(options, usage)
  103 +
  104 + # Extract script parameters from options
  105 + ntrials = int(options[0]['value'])
  106 + enumbins = int(options[1]['value'])
  107 + duration = float(options[2]['value'])
  108 + max_threads = int(options[3]['value'])
  109 + datadir = options[4]['value']
137 110
138 # Loop over energy bands. The energy bands are those that are also 111 # Loop over energy bands. The energy bands are those that are also
139 # used for sensitivity computation. 112 # used for sensitivity computation.