Commit a3e660e379beb56421bf301edac7dd7a937f22ee
1 parent
256eb549
Improve code quality of example scripts (#1828)
Showing
5 changed files
with
128 additions
and
128 deletions
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__ == '__main__': | @@ -82,36 +70,6 @@ if __name__ == '__main__': | ||
| 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__ == '__main__': | @@ -122,15 +80,15 @@ if __name__ == '__main__': | ||
| 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. |