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 | 18 | # |
| 19 | 19 | # ========================================================================== |
| 20 | 20 | import csv |
| 21 | +import sys | |
| 21 | 22 | import gammalib |
| 22 | 23 | import ctools |
| 23 | 24 | |
| ... | ... | @@ -62,3 +63,59 @@ def write_csv_row(outfile, row, colnames, colvalues): |
| 62 | 63 | |
| 63 | 64 | # Return |
| 64 | 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 | 31 | Simulate events for all observations in the container |
| 32 | 32 | |
| 33 | 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 | 37 | ctexpcube, ctpsfcube, ctbkgcube and optionally ctedispcube. The response |
| 38 | 38 | cubes are attached to the first observation in the container, which |
| 39 | 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 | 203 | Set a single CTA observation |
| 204 | 204 | |
| 205 | 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 | 209 | Parameters |
| 210 | 210 | ---------- |
| ... | ... | @@ -235,19 +235,19 @@ def set_obs(pntdir, tstart=0.0, duration=1800.0, deadc=0.95, \ |
| 235 | 235 | CTA observation |
| 236 | 236 | """ |
| 237 | 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 | 241 | db = gammalib.GCaldb() |
| 242 | 242 | if (gammalib.dir_exists(caldb)): |
| 243 | 243 | db.rootdir(caldb) |
| 244 | 244 | else: |
| 245 | 245 | db.open('cta', caldb) |
| 246 | 246 | |
| 247 | - # Set pointing direction | |
| 247 | + # Set pointing direction for CTA observation | |
| 248 | 248 | pnt = gammalib.GCTAPointing() |
| 249 | 249 | pnt.dir(pntdir) |
| 250 | - obs_cta.pointing(pnt) | |
| 250 | + obs.pointing(pnt) | |
| 251 | 251 | |
| 252 | 252 | # Set ROI |
| 253 | 253 | roi = gammalib.GCTARoi() |
| ... | ... | @@ -266,22 +266,26 @@ def set_obs(pntdir, tstart=0.0, duration=1800.0, deadc=0.95, \ |
| 266 | 266 | |
| 267 | 267 | # Allocate event list |
| 268 | 268 | events = gammalib.GCTAEventList() |
| 269 | + | |
| 270 | + # Set ROI, GTI and energy boundaries for event list | |
| 269 | 271 | events.roi(roi) |
| 270 | 272 | events.gti(gti) |
| 271 | 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 | 287 | # Return CTA observation |
| 284 | - return obs_cta | |
| 288 | + return obs | |
| 285 | 289 | |
| 286 | 290 | |
| 287 | 291 | # ============================ # | ... | ... |
examples/generate_prod3_irfs.py
| 1 | 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 | 5 | # Copyright (C) 2016 Juergen Knoedlseder |
| 6 | 6 | # |
| ... | ... | @@ -30,7 +30,7 @@ def set_prod3_desy(datadir): |
| 30 | 30 | Set Prod3 DESY database |
| 31 | 31 | |
| 32 | 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 | 34 | should be generated. All calibrations will be added to the calibration |
| 35 | 35 | database. |
| 36 | 36 | |
| ... | ... | @@ -44,22 +44,10 @@ def set_prod3_desy(datadir): |
| 44 | 44 | db : list of dict |
| 45 | 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 | 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 | 52 | # Return database |
| 65 | 53 | return db |
| ... | ... | @@ -82,36 +70,6 @@ if __name__ == '__main__': |
| 82 | 70 | # Loop over entries |
| 83 | 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 | 73 | # Set filename |
| 116 | 74 | filename = entry['path']+'/'+entry['file'] |
| 117 | 75 | |
| ... | ... | @@ -122,15 +80,15 @@ if __name__ == '__main__': |
| 122 | 80 | caldb['inst'] = entry['inst'] |
| 123 | 81 | caldb['id'] = entry['id'] |
| 124 | 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 | 92 | caldb['logfile'] = 'generate_prod3_irfs.log' |
| 135 | 93 | |
| 136 | 94 | # Add CALDB entry | ... | ... |
examples/make_pointings.py
| ... | ... | @@ -56,7 +56,7 @@ def get_positions(xmin, xmax, ymin, ymax, step): |
| 56 | 56 | # Initialise positions |
| 57 | 57 | positions = [] |
| 58 | 58 | |
| 59 | - # Determine ystep and number of rows | |
| 59 | + # Determine ystep and number of pointing rows | |
| 60 | 60 | ystep = step * math.sqrt(0.75) |
| 61 | 61 | ny = int((ymax-ymin)/ystep+1.5) |
| 62 | 62 | rescale = (ymax-ymin)/(ystep*(ny-1)) |
| ... | ... | @@ -67,13 +67,16 @@ def get_positions(xmin, xmax, ymin, ymax, step): |
| 67 | 67 | y = ymin |
| 68 | 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 | 75 | rescale = (xmax-xmin)/(xstep*(nx-1)) |
| 74 | 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 | 80 | if row % 2 == 0: |
| 78 | 81 | x = xmin |
| 79 | 82 | else: |
| ... | ... | @@ -151,7 +154,9 @@ def set_patch(lmin=-30.0, lmax=30.0, bmin=-1.5, bmax=+1.5, |
| 151 | 154 | # Optionally add-in site dependent IRF |
| 152 | 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 | 160 | if site == 'Automatic': |
| 156 | 161 | pos = gammalib.GSkyDir() |
| 157 | 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 | 165 | obs_site = 'North' |
| 161 | 166 | else: |
| 162 | 167 | obs_site = 'South' |
| 168 | + | |
| 169 | + # ... otherwise use the specified site, North or South | |
| 163 | 170 | else: |
| 164 | 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 | 175 | caldb = 'prod2' |
| 168 | 176 | if obs_site == 'North': |
| 169 | 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 | 87 | # ======================== # |
| 88 | 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 | 111 | # Loop over energy bands. The energy bands are those that are also |
| 139 | 112 | # used for sensitivity computation. | ... | ... |