Commit 241f817426796d1f3641e019d8b8ff1bc2ec867d

Authored by Jürgen Knödlseder
1 parent c60f05be

Integrate cscript improvements

cscripts/csfindobs.py
... ... @@ -18,11 +18,11 @@
18 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19 #
20 20 # ==========================================================================
21   -import gammalib
22   -import ctools
23 21 import sys
24 22 import os
25 23 import json
  24 +import gammalib
  25 +import ctools
26 26  
27 27  
28 28 # =============== #
... ... @@ -145,7 +145,7 @@ class csfindobs(ctools.cscript):
145 145 if not filename.is_fits():
146 146 raise RuntimeError('Observation index file "'+
147 147 self._obs_index+
148   - '"[OBS_INDEX]" for FITS data store "'+
  148 + '[OBS_INDEX]" for FITS data store "'+
149 149 self._prodname+
150 150 '" not available. Check your master index '+
151 151 'file or run csiactdata to get a list of '+
... ...
cscripts/csiactcopy.py
... ... @@ -18,19 +18,19 @@
18 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19 #
20 20 # ==========================================================================
21   -import gammalib
22   -import ctools
23 21 import sys
24 22 import os
25 23 import json
26 24 import shutil
  25 +import gammalib
  26 +import ctools
27 27  
28 28 # ================ #
29 29 # csiactdata class #
30 30 # ================ #
31 31 class csiactcopy(ctools.cscript):
32 32 """
33   - Copies IACT data from remote machine.
  33 + Copies IACT data from remote machine
34 34  
35 35 This script copies IACT data from one location to another. It can
36 36 take a list of observation IDs to allow the download specific
... ... @@ -64,7 +64,7 @@ class csiactcopy(ctools.cscript):
64 64 # Private methods
65 65 def _get_parameters(self):
66 66 """
67   - Get parameters from parfile and setup the observation.
  67 + Get parameters from parfile and setup the observation
68 68 """
69 69  
70 70 # Get Parameters
... ... @@ -134,7 +134,7 @@ class csiactcopy(ctools.cscript):
134 134  
135 135 else:
136 136 # Create directory if not existent
137   - dest_dir = os.path.dirname(destination)
  137 + dest_dir = os.path.dirname(destination)
138 138 if not os.path.isdir(dest_dir):
139 139 os.makedirs(dest_dir)
140 140  
... ... @@ -154,8 +154,9 @@ class csiactcopy(ctools.cscript):
154 154  
155 155 def _merge(self, localfits, remotefits, hduname, clobber):
156 156 """
157   - merge remote and local fits file
158   - If local fits file not present, a new one is created
  157 + Merge remote and local fits files
  158 +
  159 + If the local fits file is not present, a new one is created.
159 160 """
160 161  
161 162 if self._logTerse():
... ... @@ -216,8 +217,8 @@ class csiactcopy(ctools.cscript):
216 217 # Create file name
217 218 remotefile = remotefits + selection
218 219  
219   - # open remote fits file
220   - remote = gammalib.GFits(str(remotefile))
  220 + # Open remote fits file
  221 + remote = gammalib.GFits(str(remotefile))
221 222  
222 223 # If first iteration, create clone of FITS column for later use
223 224 if i == 0:
... ... @@ -236,7 +237,7 @@ class csiactcopy(ctools.cscript):
236 237 # Loop over rows and columns to copy over values exteding remote HDU
237 238 for col in tmp_hdu:
238 239 for row in range(col.length()):
239   - remote_hdu[col.name()][size + row] = col[row]
  240 + remote_hdu[col.name()][size + row] = col[row]
240 241  
241 242 # Get remote obs_id
242 243 remote_obs = []
... ... @@ -472,14 +473,14 @@ class csiactcopy(ctools.cscript):
472 473 for row in range(table.nrows()):
473 474  
474 475 # Get observation ID
475   - obs_id = table['OBS_ID'][row]
476   - file_dir = table['FILE_DIR'][row]
477   - file_name = table['FILE_NAME'][row]
  476 + obs_id = table['OBS_ID'][row]
  477 + file_dir = table['FILE_DIR'][row]
  478 + file_name = table['FILE_NAME'][row]
478 479  
479 480 # Skip if filename is empty
480 481 if file_name == '':
481 482 continue
482   -
  483 +
483 484 # Check if we need to consider an input runlist
484 485 if len(self._runs):
485 486  
... ... @@ -499,7 +500,7 @@ class csiactcopy(ctools.cscript):
499 500 if has_size and newlen > oldlen:
500 501 cp_size += table['SIZE'][row]
501 502  
502   - # Otherwise add every file
  503 + # Otherwise add every file
503 504 else:
504 505 # Get filename
505 506 fname = os.path.join(os.path.dirname(remote_hdu),
... ... @@ -531,7 +532,7 @@ class csiactcopy(ctools.cscript):
531 532 for filename in files:
532 533 self._log(str(filename)+'\n')
533 534  
534   - # Close HDU index file
  535 + # Close HDU index file
535 536 fits.close()
536 537  
537 538 # If prodname is not found just log that we skip the config
... ... @@ -541,15 +542,15 @@ class csiactcopy(ctools.cscript):
541 542 self._log.header3('Skipping config "'+
542 543 str(config['name'])+'"')
543 544 self._log('\n')
544   -
545   - # Raise Exception if prodname was not found
  545 +
  546 + # Raise Exception if prodname was not found
546 547 if not has_prod:
547 548 msg = '*** ERROR: FITS production "'+self._prodname+'" not '
548 549 msg += 'available. Available productions are:\n'
549 550 for config in configs:
550 551 msg += ' - '+config['name']+'\n'
551 552 raise RuntimeError(msg)
552   -
  553 +
553 554 # Logging
554 555 if self._logNormal():
555 556 self._log('\n')
... ... @@ -624,7 +625,7 @@ class csiactcopy(ctools.cscript):
624 625  
625 626 if self._logTerse():
626 627 self._log('\n')
627   - self._log.header3('OBS index')
  628 + self._log.header3('OBS index')
628 629  
629 630 # Merge remote index files with local files
630 631 self._merge(local_obs, remote_obs, 'OBS_INDEX', self._clobber())
... ... @@ -678,7 +679,7 @@ class csiactcopy(ctools.cscript):
678 679 self._log('Keeping "'+str(config['name'])+'"')
679 680 self._log('\n')
680 681  
681   - # Signals that downloaded config is available
  682 + # Signals that downloaded config is available
682 683 if config['name'] == self._prodname:
683 684 has_config = True
684 685  
... ... @@ -697,7 +698,7 @@ class csiactcopy(ctools.cscript):
697 698 f = open(localmaster, 'w')
698 699 data['datasets'] = newconfigs
699 700 json.dump(data, f, indent=2)
700   - f.close()
  701 + f.close()
701 702  
702 703 # Log summary
703 704 if self._logNormal():
... ...
cscripts/csiactdata.py
... ... @@ -18,11 +18,11 @@
18 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19 #
20 20 # ==========================================================================
21   -import gammalib
22   -import ctools
23 21 import sys
24 22 import os
25 23 import json
  24 +import gammalib
  25 +import ctools
26 26  
27 27  
28 28 # ================ #
... ... @@ -30,7 +30,7 @@ import json
30 30 # ================ #
31 31 class csiactdata(ctools.cscript):
32 32 """
33   - Inspect an IACT data storage.
  33 + Inspect an IACT data storage
34 34  
35 35 This script inspects the available FITS data storage on the user machine
36 36 and writes information about the available FITS configurations into a log
... ... @@ -44,12 +44,12 @@ class csiactdata(ctools.cscript):
44 44 Constructor.
45 45 """
46 46 # Set name
47   - self._name = "csiactdata"
48   - self._version = "1.1.0"
49   - self._datapath = os.getenv("VHEFITS","")
  47 + self._name = 'csiactdata'
  48 + self._version = '1.1.0'
  49 + self._datapath = os.getenv('VHEFITS','')
50 50 self._prodnames = []
51   - self._master_indx = ""
52   - self._master_file = ""
  51 + self._master_indx = ''
  52 + self._master_file = ''
53 53  
54 54 # Initialise application by calling the appropriate class
55 55 # constructor.
... ... @@ -62,18 +62,18 @@ class csiactdata(ctools.cscript):
62 62 # Private methods
63 63 def _get_parameters(self):
64 64 """
65   - Get parameters from parfile and setup the observation.
  65 + Get parameters from parfile and setup the observation
66 66 """
67 67  
68 68 # Get datapath if not already set
69   - if self._datapath == "":
70   - self._datapath = self["datapath"].string()
  69 + if self._datapath == '':
  70 + self._datapath = self['datapath'].string()
71 71  
72 72 # Expand environment
73 73 self._datapath = gammalib.expand_env(self._datapath)
74 74  
75 75 # Get filename of master index file
76   - self._master_indx = self["master_indx"].string()
  76 + self._master_indx = self['master_indx'].string()
77 77 self._master_file = os.path.join(self._datapath, self._master_indx)
78 78  
79 79 # Check for presence of master index file
... ... @@ -86,7 +86,7 @@ class csiactdata(ctools.cscript):
86 86 # Write input parameters into logger
87 87 if self._logTerse():
88 88 self._log_parameters()
89   - self._log("\n")
  89 + self._log('\n')
90 90  
91 91 # Return
92 92 return
... ... @@ -94,28 +94,28 @@ class csiactdata(ctools.cscript):
94 94 # Log configuration
95 95 def _log_configuration(self, config):
96 96 """
97   - Log configuration.
  97 + Log configuration
98 98 """
99 99 # Log information
100 100 if self._logTerse():
101   - self._log.header3(str(config["name"]))
102   - self._log.parformat("Name")
103   - self._log(str(config["name"]))
104   - self._log("\n")
105   - self._log.parformat("Observation index")
106   - self._log(str(config["obsindx"]))
107   - self._log("\n")
108   - self._log.parformat("HDU index")
109   - self._log(str(config["hduindx"]))
110   - self._log("\n")
  101 + self._log.header3(str(config['name']))
  102 + self._log.parformat('Name')
  103 + self._log(str(config['name']))
  104 + self._log('\n')
  105 + self._log.parformat('Observation index')
  106 + self._log(str(config['obsindx']))
  107 + self._log('\n')
  108 + self._log.parformat('HDU index')
  109 + self._log(str(config['hduindx']))
  110 + self._log('\n')
111 111  
112 112 # Print additional information
113 113 for key in config:
114   - if key in ["name","hduindx","obsindx"]:
  114 + if key in ['name','hduindx','obsindx']:
115 115 continue
116 116 self._log.parformat(str(key))
117 117 self._log(str(config[key]))
118   - self._log("\n")
  118 + self._log('\n')
119 119  
120 120 # Return
121 121 return
... ... @@ -124,7 +124,7 @@ class csiactdata(ctools.cscript):
124 124 # Public methods
125 125 def run(self):
126 126 """
127   - Run the script.
  127 + Run the script
128 128 """
129 129 # Switch screen logging on in debug mode
130 130 if self._logDebug():
... ... @@ -135,39 +135,39 @@ class csiactdata(ctools.cscript):
135 135  
136 136 # Write header into logger
137 137 if self._logTerse():
138   - self._log("\n")
139   - self._log.header1("Data storage entries")
140   - self._log.parformat("Master index file")
  138 + self._log('\n')
  139 + self._log.header1('Data storage entries')
  140 + self._log.parformat('Master index file')
141 141 self._log(self._master_file)
142   - self._log("\n")
  142 + self._log('\n')
143 143  
144 144 # Open and load JSON file
145 145 json_data = open(self._master_file).read()
146 146 data = json.loads(json_data)
147   - configs = data["datasets"]
  147 + configs = data['datasets']
148 148  
149 149 # Initialise array for available names
150 150 self._prodnames = []
151 151  
152 152 # Write header into logger
153   - self._log("\n")
154   - self._log.header2("Available data configs")
  153 + self._log('\n')
  154 + self._log.header2('Available data configs')
155 155  
156 156 # Loop over configs and log available configs
157 157 for config in configs:
158 158  
159 159 # Create hdu and obs index files
160   - hdu = os.path.join(self._datapath, config["hduindx"])
161   - obs = os.path.join(self._datapath, config["obsindx"])
162   - filename_hdu = gammalib.GFilename(str(hdu)+"[HDU_INDEX]")
163   - filename_obs = gammalib.GFilename(str(obs)+"[OBS_INDEX]")
  160 + hdu = os.path.join(self._datapath, config['hduindx'])
  161 + obs = os.path.join(self._datapath, config['obsindx'])
  162 + filename_hdu = gammalib.GFilename(str(hdu)+'[HDU_INDEX]')
  163 + filename_obs = gammalib.GFilename(str(obs)+'[OBS_INDEX]')
164 164  
165 165 # If index files are available then log configuration
166 166 # information ...
167 167 if (filename_hdu.is_fits() and filename_obs.is_fits()):
168 168  
169 169 # Append to available names
170   - self._prodnames.append(str(config["name"]))
  170 + self._prodnames.append(str(config['name']))
171 171  
172 172 # Log information
173 173 self._log_configuration(config)
... ... @@ -175,15 +175,15 @@ class csiactdata(ctools.cscript):
175 175 # ... otherwise log that the configuration is not available
176 176 else:
177 177 if self._logTerse():
178   - self._log.header3(str(config["name"]))
179   - self._log(" Not available\n")
  178 + self._log.header3(str(config['name']))
  179 + self._log(' Not available\n')
180 180  
181 181 # Return
182 182 return
183 183  
184 184 def execute(self):
185 185 """
186   - Execute the script.
  186 + Execute the script
187 187 """
188 188 # Open logfile
189 189 self.logFileOpen()
... ... @@ -198,11 +198,12 @@ class csiactdata(ctools.cscript):
198 198 """
199 199 Return available FITS production names
200 200  
201   - Returns:
  201 + Returns
  202 + -------
  203 + names : list of str
202 204 List of available FITS production names.
203 205 """
204   -
205   - # Return
  206 + # Return
206 207 return self._prodnames
207 208  
208 209  
... ...
cscripts/csiactobs.py
... ... @@ -18,11 +18,11 @@
18 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19 #
20 20 # ==========================================================================
21   -import gammalib
22   -import ctools
23 21 import sys
24 22 import os
25 23 import json
  24 +import gammalib
  25 +import ctools
26 26  
27 27  
28 28 # =============== #
... ... @@ -30,7 +30,7 @@ import json
30 30 # =============== #
31 31 class csiactobs(ctools.cscript):
32 32 """
33   - Generates an IACT observation definition XML file.
  33 + Generates an IACT observation definition XML file
34 34  
35 35 This class implements the creation of a observation xml file for IACT
36 36 data analysis. This class is dedicated for use inside a IACT
... ... @@ -143,8 +143,8 @@ class csiactobs(ctools.cscript):
143 143 self._ev_hiera = self['ev_hiera'].string().split('|')
144 144 self._aeff_hiera = self['aeff_hiera'].string().split('|')
145 145 self._psf_hiera = self['psf_hiera'].string().split('|')
146   - self._bkg_hiera = self['bkg_hiera'].string().split('|')
147   - self._edisp_hiera = self['edisp_hiera'].string().split('|')
  146 + self._bkg_hiera = self['bkg_hiera'].string().split('|')
  147 + self._edisp_hiera = self['edisp_hiera'].string().split('|')
148 148 self._bkg_mod_hiera = self['bkg_mod_hiera'].string().split('|')
149 149  
150 150 # Read hidden background parameters
... ... @@ -264,7 +264,7 @@ class csiactobs(ctools.cscript):
264 264 spec[1].fix()
265 265 else:
266 266 spec[0].free()
267   - spec[1].free()
  267 + spec[1].free()
268 268  
269 269 else:
270 270  
... ... @@ -319,7 +319,8 @@ class csiactobs(ctools.cscript):
319 319 bck = gammalib.GCTAModelRadialAcceptance(radial, spec)
320 320  
321 321 else:
322   - sys.exit('Background type "'+self._bkgtype+'" unsupported')
  322 + msg = 'Background type "'+self._bkgtype+'" unsupported'
  323 + raise RuntimeError(msg)
323 324  
324 325 # Copy model
325 326 model = bck.clone()
... ... @@ -366,7 +367,7 @@ class csiactobs(ctools.cscript):
366 367 self._log.header1('Looping over '+str(len(self._runlist))+' runs')
367 368  
368 369 # Initialise energy range values for logging
369   - self._ebounds.clear()
  370 + self._ebounds.clear()
370 371  
371 372 # Loop over runs
372 373 for obs_id in self._runlist:
... ... @@ -396,12 +397,15 @@ class csiactobs(ctools.cscript):
396 397 index = formats.index(version)
397 398 break
398 399 if index >= 0:
399   - eventfile = os.path.join(self._subdir, hduindx_hdu['FILE_DIR'][index], hduindx_hdu['FILE_NAME'][index])
  400 + eventfile = os.path.join(self._subdir,
  401 + hduindx_hdu['FILE_DIR'][index],
  402 + hduindx_hdu['FILE_NAME'][index])
400 403 eventhdu = hduindx_hdu['HDU_NAME'][index]
401 404 eventfile += '['+eventhdu+']'
402 405 if not gammalib.GFilename(eventfile).is_fits():
403 406 if self._logTerse():
404   - self._log('Skipping observation '+str(obs_id)+': eventfile "'+eventfile+'" not found\n')
  407 + self._log('Skipping observation '+str(obs_id)+
  408 + ': eventfile "'+eventfile+'" not found\n')
405 409 continue
406 410  
407 411 # Handle Aeff
... ... @@ -412,12 +416,15 @@ class csiactobs(ctools.cscript):
412 416 index = formats.index(version)
413 417 break
414 418 if index >= 0:
415   - aefffile = os.path.join(self._subdir, hduindx_hdu['FILE_DIR'][index], hduindx_hdu['FILE_NAME'][index])
  419 + aefffile = os.path.join(self._subdir,
  420 + hduindx_hdu['FILE_DIR'][index],
  421 + hduindx_hdu['FILE_NAME'][index])
416 422 aeffhdu = hduindx_hdu['HDU_NAME'][index]
417 423 aefffile += '['+aeffhdu+']'
418 424 if not gammalib.GFilename(aefffile).is_fits():
419 425 if self._logTerse():
420   - self._log('Skipping observation '+str(obs_id)+': effective area "'+aefffile+'" not found\n')
  426 + self._log('Skipping observation '+str(obs_id)+
  427 + ': effective area "'+aefffile+'" not found\n')
421 428 continue
422 429  
423 430 # Handle psf
... ... @@ -428,11 +435,15 @@ class csiactobs(ctools.cscript):
428 435 index = formats.index(version)
429 436 break
430 437 if index >= 0:
431   - psffile = os.path.join(self._subdir, hduindx_hdu['FILE_DIR'][index], hduindx_hdu['FILE_NAME'][index])
  438 + psffile = os.path.join(self._subdir,
  439 + hduindx_hdu['FILE_DIR'][index],
  440 + hduindx_hdu['FILE_NAME'][index])
432 441 psffile += '['+hduindx_hdu['HDU_NAME'][index]+']'
433 442 if not gammalib.GFilename(psffile).is_fits():
434 443 if self._logTerse():
435   - self._log('Skipping observation '+str(obs_id)+': point spread function "'+psffile+'" not found\n')
  444 + self._log('Skipping observation '+str(obs_id)+
  445 + ': point spread function "'+psffile+
  446 + '" not found\n')
436 447 continue
437 448  
438 449 # Handle edisp
... ... @@ -443,11 +454,15 @@ class csiactobs(ctools.cscript):
443 454 index = formats.index(version)
444 455 break
445 456 if index >= 0:
446   - edispfile = os.path.join(self._subdir, hduindx_hdu['FILE_DIR'][index], hduindx_hdu['FILE_NAME'][index])
  457 + edispfile = os.path.join(self._subdir,
  458 + hduindx_hdu['FILE_DIR'][index],
  459 + hduindx_hdu['FILE_NAME'][index])
447 460 edispfile += '['+hduindx_hdu['HDU_NAME'][index]+']'
448 461 if not gammalib.GFilename(edispfile).is_fits():
449 462 if self._logTerse():
450   - self._log('Warning: observation '+str(obs_id)+' has no energy dispersion "'+edispfile+'" information\n')
  463 + self._log('Warning: observation '+str(obs_id)+
  464 + ' has no energy dispersion "'+edispfile+
  465 + '" information\n')
451 466 edispfile = ''
452 467  
453 468 # Handle background
... ... @@ -459,20 +474,27 @@ class csiactobs(ctools.cscript):
459 474 index = formats.index(version)
460 475 break
461 476 if index >= 0:
462   - bkgfile = os.path.join(self._subdir, hduindx_hdu['FILE_DIR'][index], hduindx_hdu['FILE_NAME'][index])
  477 + bkgfile = os.path.join(self._subdir,
  478 + hduindx_hdu['FILE_DIR'][index],
  479 + hduindx_hdu['FILE_NAME'][index])
463 480 bkgfile += '['+hduindx_hdu['HDU_NAME'][index]+']'
464 481 if 'irf' in bkg_mod_hierarchy and not gammalib.GFilename(bkgfile).is_fits():
465 482 bkg_mod_hierarchy.remove('irf')
466 483 if self._logTerse():
467   - self._log('Warning: observation '+str(obs_id)+' has no background information (file="'+bkgfile+'"). IRF background cannot be used\n')
  484 + self._log('Warning: observation '+str(obs_id)+
  485 + ' has no background information (file="'+
  486 + bkgfile+'"). IRF background cannot be used\n')
468 487 bkgfile = ''
469 488 if len(bkg_mod_hierarchy) == 0:
470 489 if self._logTerse():
471   - self._log('Skipping observation '+str(obs_id)+': No background can be used\n')
  490 + self._log('Skipping observation '+str(obs_id)+
  491 + ': No background can be used\n')
472 492 continue
473 493 else:
474 494 if self._logTerse():
475   - self._log('Observation '+str(obs_id)+': Falling back to background "'+bkg_mod_hierarchy[0]+'"\n')
  495 + self._log('Observation '+str(obs_id)+
  496 + ': Falling back to background "'+
  497 + bkg_mod_hierarchy[0]+'"\n')
476 498  
477 499 # Close hdu index file
478 500 hduindx.close()
... ... @@ -480,15 +502,15 @@ class csiactobs(ctools.cscript):
480 502 # Handle background scale information if available
481 503 bkg_scale = 1.0
482 504 if self._use_bkg_scale:
483   - obsindx = gammalib.GFits(self._obs_index+'[OBS_INDEX]'+obs_selection)
  505 + obsindx = gammalib.GFits(self._obs_index+'[OBS_INDEX]'+obs_selection)
484 506 bkg_scale = obsindx['OBS_INDEX']['BKG_SCALE'][0]
485 507 obsindx.close()
486 508  
487 509 # Open fits file to determine the observation name
488   - fits = gammalib.GFits(eventfile)
489   - events = fits[eventhdu]
  510 + fits = gammalib.GFits(eventfile)
  511 + events = fits[eventhdu]
490 512 object_name = events.string('OBJECT')
491   - telescope = events.string('TELESCOP')
  513 + telescope = events.string('TELESCOP')
492 514  
493 515 # Close FITS file
494 516 fits.close()
... ... @@ -516,11 +538,17 @@ class csiactobs(ctools.cscript):
516 538 aeff_fits.close()
517 539  
518 540 # Append instrumental background model
519   - self._models.append(self._iact_background(telescope, obs_id, bkg_scale, bkg_mod_hierarchy[0], run_emin.TeV(), run_emax.TeV()))
  541 + self._models.append(self._iact_background(telescope,
  542 + obs_id,
  543 + bkg_scale,
  544 + bkg_mod_hierarchy[0],
  545 + run_emin.TeV(),
  546 + run_emax.TeV()))
520 547  
521 548 # Logging
522 549 if self._logTerse():
523   - self._log('Adding observation '+str(obs_id)+' ("'+object_name+'")\n')
  550 + self._log('Adding observation '+str(obs_id)+
  551 + ' ("'+object_name+'")\n')
524 552  
525 553 if self._logExplicit():
526 554 self._log(' Event file: '+eventfile+'\n')
... ... @@ -606,7 +634,7 @@ class csiactobs(ctools.cscript):
606 634  
607 635 def execute(self):
608 636 """
609   - Execute the script.
  637 + Execute the script
610 638 """
611 639 # Open logfile
612 640 self.logFileOpen()
... ... @@ -621,7 +649,9 @@ class csiactobs(ctools.cscript):
621 649 return
622 650  
623 651 def save(self):
624   -
  652 + """
  653 + Save model definition XML file
  654 + """
625 655 # Save observation XML file
626 656 self._xml.save(self._outobs)
627 657  
... ... @@ -633,8 +663,9 @@ class csiactobs(ctools.cscript):
633 663  
634 664 def ebounds(self):
635 665 """
636   - Returns runlist energy range
  666 + Return runlist energy boundaries
637 667 """
  668 + # Return energy boundaries
638 669 return self._ebounds
639 670  
640 671 def obs(self):
... ...
cscripts/csmodelinfo.py
... ... @@ -18,9 +18,9 @@
18 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19 #
20 20 # ==========================================================================
  21 +import sys
21 22 import gammalib
22 23 import ctools
23   -import sys
24 24  
25 25  
26 26 # ================= #
... ...
cscripts/csmodelmerge.py
... ... @@ -18,10 +18,10 @@
18 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19 #
20 20 # ==========================================================================
21   -import gammalib
22   -import ctools
23 21 import sys
24 22 import glob
  23 +import gammalib
  24 +import ctools
25 25  
26 26  
27 27 # ================== #
... ... @@ -29,7 +29,7 @@ import glob
29 29 # ================== #
30 30 class csmodelmerge(ctools.cscript):
31 31 """
32   - Merge model definition XML files.
  32 + Merge model definition XML files
33 33  
34 34 An arbitrary number of model definition XML files will be merged into
35 35 a single model definition XML file.
... ... @@ -41,8 +41,8 @@ class csmodelmerge(ctools.cscript):
41 41 Constructor.
42 42 """
43 43 # Set name
44   - self._name = "csmodelmerge"
45   - self._version = "1.1.0"
  44 + self._name = 'csmodelmerge'
  45 + self._version = '1.1.0'
46 46  
47 47 # Initialise class members
48 48 self._files = None
... ... @@ -59,45 +59,45 @@ class csmodelmerge(ctools.cscript):
59 59 # Private methods
60 60 def _get_parameters(self):
61 61 """
62   - Get parameters from parfile.
  62 + Get parameters from parfile
63 63 """
64 64 # Get input models string
65   - inmodels = self["inmodels"].string()
  65 + inmodels = self['inmodels'].string()
66 66  
67 67 # Handle ascii files
68   - if "@" == inmodels[0]:
69   - self._files = open(inmodels.replace("@","")).read().splitlines()
  68 + if '@' == inmodels[0]:
  69 + self._files = open(inmodels.replace('@','')).read().splitlines()
70 70  
71 71 # Handle wild card strings
72   - elif "*" in inmodels:
  72 + elif '*' in inmodels:
73 73 self._files = glob.glob(inmodels)
74 74  
75 75 # Handle space separated list
76   - elif " " in inmodels:
77   - self._files = inmodels.split(" ")
  76 + elif ' ' in inmodels:
  77 + self._files = inmodels.split(' ')
78 78  
79 79 # Handle semi-colon separated list
80   - elif ";" in inmodels:
81   - self._files = inmodels.split(";")
  80 + elif ';' in inmodels:
  81 + self._files = inmodels.split(';')
82 82  
83 83 # Throw exception if input models cannot be decoded
84 84 else:
85   - msg = "Parameter \"inmodels\" must contain either an @ASCII "\
86   - "file, a semi-colon-separated or whitespace-separated "\
87   - "list of files or a wildcard string."
88   - raise RuntimeError(msg)
  85 + msg = 'Parameter "inmodels" must contain either an @ASCII '\
  86 + 'file, a semi-colon-separated or whitespace-separated '\
  87 + 'list of files or a wildcard string.'
  88 + raise RuntimeError(msg)
89 89  
90 90 # Read ahead output filename
91 91 if self._read_ahead():
92   - self["outmodel"].filename()
  92 + self['outmodel'].filename()
93 93  
94 94 # Get clobber parameter
95   - self._clobber = self["clobber"].boolean()
  95 + self._clobber = self['clobber'].boolean()
96 96  
97 97 # Write input parameters into logger
98 98 if self._logTerse():
99 99 self._log_parameters()
100   - self._log("\n")
  100 + self._log('\n')
101 101  
102 102 # Return
103 103 return
... ... @@ -106,7 +106,7 @@ class csmodelmerge(ctools.cscript):
106 106 # Public methods
107 107 def run(self):
108 108 """
109   - Run the script.
  109 + Run the script
110 110 """
111 111 # Switch screen logging on in debug mode
112 112 if self._logDebug():
... ... @@ -117,8 +117,8 @@ class csmodelmerge(ctools.cscript):
117 117  
118 118 # Write header
119 119 if self._logTerse():
120   - self._log("\n")
121   - self._log.header1("Merge models")
  120 + self._log('\n')
  121 + self._log.header1('Merge models')
122 122  
123 123 # Initialise model container
124 124 self._models = gammalib.GModels()
... ... @@ -133,23 +133,23 @@ class csmodelmerge(ctools.cscript):
133 133 if self._logTerse():
134 134 nmodels = models.size()
135 135 if nmodels == 0:
136   - self._log(gammalib.parformat("Add no model from file"))
  136 + self._log(gammalib.parformat('Add no model from file'))
137 137 elif nmodels == 1:
138   - self._log(gammalib.parformat("Add 1 model from file"))
  138 + self._log(gammalib.parformat('Add 1 model from file'))
139 139 else:
140   - self._log(gammalib.parformat("Add %d models from file" %
  140 + self._log(gammalib.parformat('Add %d models from file' %
141 141 nmodels))
142 142 self._log(file_)
143   - self._log("\n")
  143 + self._log('\n')
144 144  
145 145 # Extend model container by adding all models in the model file
146 146 self._models.extend(models)
147 147  
148 148 # Log total number of models
149 149 if self._logTerse():
150   - self._log(gammalib.parformat("Models after merging"))
  150 + self._log(gammalib.parformat('Models after merging'))
151 151 self._log(self._models.size())
152   - self._log("\n")
  152 + self._log('\n')
153 153  
154 154 # Return
155 155 return
... ... @@ -160,29 +160,25 @@ class csmodelmerge(ctools.cscript):
160 160 """
161 161 # Write header
162 162 if self._logTerse():
163   - self._log("\n")
164   - self._log.header1("Save models")
  163 + self._log('\n')
  164 + self._log.header1('Save models')
165 165  
166 166 # Get output filename in case it was not read ahead
167   - outmodel = self["outmodel"].filename()
  167 + outmodel = self['outmodel'].filename()
168 168  
169   - # Check if file exists and apply clobber if false
  169 + # If file exists and clobber flag is false then raise an exception
170 170 if outmodel.exists() and not self._clobber:
171   -
172   - # Set error message
173   - msg = "Cannot save \""+outmodel.url()+"\": File already exists "
174   - msg += "Use parameter clobber=yes to allow overwriting of files."
175   -
176   - # Throw exception since file cannnot be overwritten
  171 + msg = 'Cannot save ""+outmodel.url()+"": File already exists. '\
  172 + 'Use parameter clobber=yes to allow overwriting of files.'
177 173 raise RuntimeError(msg)
178 174  
179 175 else:
180 176  
181 177 # Log filename
182 178 if self._logTerse():
183   - self._log(gammalib.parformat("Model definition XML file"))
  179 + self._log(gammalib.parformat('Model definition XML file'))
184 180 self._log(outmodel.url())
185   - self._log("\n")
  181 + self._log('\n')
186 182  
187 183 # Save models
188 184 self._models.save(outmodel)
... ... @@ -192,7 +188,7 @@ class csmodelmerge(ctools.cscript):
192 188  
193 189 def execute(self):
194 190 """
195   - Execute the script.
  191 + Execute the script
196 192 """
197 193 # Open logfile
198 194 self.logFileOpen()
... ...
cscripts/csobsinfo.py
... ... @@ -18,9 +18,9 @@
18 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19 #
20 20 # ==========================================================================
  21 +import sys
21 22 import gammalib
22 23 import ctools
23   -import sys
24 24  
25 25  
26 26 # =============== #
... ... @@ -28,7 +28,7 @@ import sys
28 28 # =============== #
29 29 class csobsinfo(ctools.cscript):
30 30 """
31   - Shows the content of an observation container.
  31 + Shows the content of an observation container
32 32 """
33 33  
34 34 # Constructor
... ... @@ -37,8 +37,8 @@ class csobsinfo(ctools.cscript):
37 37 Constructor.
38 38 """
39 39 # Set name
40   - self._name = "csobsinfo"
41   - self._version = "1.1.0"
  40 + self._name = 'csobsinfo'
  41 + self._version = '1.1.0'
42 42  
43 43 # Initialise class members
44 44 self._obj_dir = None
... ... @@ -65,31 +65,31 @@ class csobsinfo(ctools.cscript):
65 65 # Private methods
66 66 def _get_parameters(self):
67 67 """
68   - Get parameters from parfile and setup the observation.
  68 + Get parameters from parfile and setup the observation
69 69 """
70 70 # Get parameters
71 71 if self._obs.size() == 0:
72   - self._require_inobs("csobsinfo::get_parameters")
  72 + self._require_inobs('csobsinfo::get_parameters')
73 73 self._obs = self._get_observations(False)
74 74  
75 75 # Initialise object position
76 76 self._obj_dir = gammalib.GSkyDir()
77 77  
78 78 # Get (optional) offset parameters
79   - self._compute_offset = self["offset"].boolean()
  79 + self._compute_offset = self['offset'].boolean()
80 80 if self._compute_offset:
81   - ra = self["ra"].real()
82   - dec = self["dec"].real()
  81 + ra = self['ra'].real()
  82 + dec = self['dec'].real()
83 83 self._obj_dir.radec_deg(ra,dec)
84 84  
85 85 # Read ahead DS9 filename
86 86 if self._read_ahead():
87   - self["ds9file"].filename()
  87 + self['ds9file'].filename()
88 88  
89 89 # Write input parameters into logger
90 90 if self._logTerse():
91 91 self._log_parameters()
92   - self._log("\n")
  92 + self._log('\n')
93 93  
94 94 # Return
95 95 return
... ... @@ -98,7 +98,7 @@ class csobsinfo(ctools.cscript):
98 98 # Public methods
99 99 def run(self):
100 100 """
101   - Run the script.
  101 + Run the script
102 102 """
103 103 # Switch screen logging on in debug mode
104 104 if self._logDebug():
... ... @@ -128,23 +128,20 @@ class csobsinfo(ctools.cscript):
128 128  
129 129 # Write header
130 130 if self._logTerse():
131   - self._log("\n")
132   - if self._obs.size() > 1:
133   - self._log.header1("Observations")
134   - else:
135   - self._log.header1("Observation")
  131 + self._log('\n')
  132 + self._log.header1(gammalib.number('Observation', self._obs.size()))
136 133  
137 134 # Loop over observations
138 135 for obs in self._obs:
139 136  
140 137 # Skip non-CTA observations
141   - if not obs.classname() == "GCTAObservation":
142   - self._log("Skipping "+obs.instrument()+" observation\n")
  138 + if not obs.classname() == 'GCTAObservation':
  139 + self._log('Skipping '+obs.instrument()+' observation\n')
143 140 continue
144 141  
145 142 # Use observed object as observation name if name is not given
146 143 obs_name = obs.name()
147   - if obs_name == "":
  144 + if obs_name == '':
148 145 obs_name = obs.object()
149 146  
150 147 # Logging
... ... @@ -180,24 +177,24 @@ class csobsinfo(ctools.cscript):
180 177 livetime += obs.livetime()
181 178  
182 179 # Bookkeeping
183   - if obs.eventtype() == "CountsCube":
  180 + if obs.eventtype() == 'CountsCube':
184 181 n_eventbins += obs.events().size()
185 182 n_obs_binned += 1
186 183 if self._logTerse():
187   - self._log.parformat("Binned")
188   - self._log("yes\n")
189   - self._log.parformat("Number of bins")
  184 + self._log.parformat('Binned')
  185 + self._log('yes\n')
  186 + self._log.parformat('Number of bins')
190 187 self._log(str(obs.events().size()))
191   - self._log("\n")
  188 + self._log('\n')
192 189 else:
193 190 n_events += obs.events().size()
194 191 n_obs_unbinned += 1
195 192 if self._logTerse():
196   - self._log.parformat("Binned")
197   - self._log("no\n")
198   - self._log.parformat("Number of events")
  193 + self._log.parformat('Binned')
  194 + self._log('no\n')
  195 + self._log.parformat('Number of events')
199 196 self._log(str(obs.events().size()))
200   - self._log("\n")
  197 + self._log('\n')
201 198  
202 199 # Retrieve zenith and azimuth and store for later use
203 200 zenith = obs.pointing().zenith()
... ... @@ -216,98 +213,98 @@ class csobsinfo(ctools.cscript):
216 213 if self._logTerse():
217 214  
218 215 # Log the observation energy range (if available)
219   - self._log.parformat("Energy range")
  216 + self._log.parformat('Energy range')
220 217 if obs_bounds.size() == 0:
221   - self._log("undefined")
  218 + self._log('undefined')
222 219 else:
223 220 self._log(str(obs_bounds.emin()))
224   - self._log(" - ")
  221 + self._log(' - ')
225 222 self._log(str(obs_bounds.emax()))
226   - self._log("\n")
  223 + self._log('\n')
227 224  
228 225 # Log observation time interval
229   - self._log.parformat("Time range (MJD)")
  226 + self._log.parformat('Time range (MJD)')
230 227 if obs_gti.size() == 0:
231   - self._log("undefined")
  228 + self._log('undefined')
232 229 else:
233 230 self._log(str(obs_gti.tstart().mjd()))
234   - self._log(" - ")
  231 + self._log(' - ')
235 232 self._log(str(obs_gti.tstop().mjd()))
236   - self._log("\n")
  233 + self._log('\n')
237 234  
238 235 # Log ontime
239   - self._log.parformat("Ontime")
  236 + self._log.parformat('Ontime')
240 237 self._log(str(obs.ontime()))
241   - self._log(" s\n")
  238 + self._log(' s\n')
242 239  
243 240 # Log livetime
244   - self._log.parformat("Livetime")
  241 + self._log.parformat('Livetime')
245 242 self._log(str(obs.livetime()))
246   - self._log(" s\n")
  243 + self._log(' s\n')
247 244  
248 245 # Log dead time fraction
249   - self._log.parformat("Deadtime fraction (%)")
250   - self._log("%.3f" % (deadfrac))
251   - self._log("\n")
  246 + self._log.parformat('Deadtime fraction (%)')
  247 + self._log('%.3f' % (deadfrac))
  248 + self._log('\n')
252 249  
253 250 # Log pointing direction
254   - self._log.parformat("Pointing")
  251 + self._log.parformat('Pointing')
255 252 self._log(str(pnt_dir))
256   - self._log("\n")
  253 + self._log('\n')
257 254  
258 255 # Optionally log offset with respect to target direction
259 256 if self._compute_offset:
260   - self._log.parformat("Offset from target")
261   - self._log("%.2f" % (offset))
262   - self._log(" deg\n")
  257 + self._log.parformat('Offset from target')
  258 + self._log('%.2f' % (offset))
  259 + self._log(' deg\n')
263 260  
264 261 # Log Zenith and Azimuth if required
265   - self._log.parformat("Zenith angle")
266   - self._log("%.2f" % (zenith))
267   - self._log(" deg\n")
268   - self._log.parformat("Azimuth angle")
269   - self._log("%.2f" % (azimuth))
270   - self._log(" deg\n")
  262 + self._log.parformat('Zenith angle')
  263 + self._log('%.2f' % (zenith))
  264 + self._log(' deg\n')
  265 + self._log.parformat('Azimuth angle')
  266 + self._log('%.2f' % (azimuth))
  267 + self._log(' deg\n')
271 268  
272 269 # Log summary
273 270 if self._logTerse():
274 271  
275 272 # Write header
276   - self._log("\n")
277   - self._log.header1("Summary")
  273 + self._log('\n')
  274 + self._log.header1('Summary')
278 275  
279 276 # Log general summary
280   - self._log.header3("Observations")
281   - self._log.parformat("Unbinned observations")
  277 + self._log.header3('Observations')
  278 + self._log.parformat('Unbinned observations')
282 279 self._log(str(n_obs_unbinned))
283   - self._log("\n")
284   - self._log.parformat("Binned observations")
  280 + self._log('\n')
  281 + self._log.parformat('Binned observations')
285 282 self._log(str(n_obs_binned))
286   - self._log("\n")
287   - self._log.header3("Events")
288   - self._log.parformat("Number of events")
  283 + self._log('\n')
  284 + self._log.header3('Events')
  285 + self._log.parformat('Number of events')
289 286 self._log(str(n_events))
290   - self._log("\n")
291   - self._log.parformat("Number of bins")
  287 + self._log('\n')
  288 + self._log.parformat('Number of bins')
292 289 self._log(str(n_eventbins))
293   - self._log("\n")
  290 + self._log('\n')
294 291  
295 292 # Log pointing summary
296   - self._log.header3("Pointings")
  293 + self._log.header3('Pointings')
297 294  
298 295 # Log mean offset if possible
299 296 if self._compute_offset:
300   - self._log.parformat("Mean offset angle")
301   - self._log("%.2f" % (sum(self._offsets)/len(self._offsets)))
302   - self._log(" deg\n")
  297 + self._log.parformat('Mean offset angle')
  298 + self._log('%.2f' % (sum(self._offsets)/len(self._offsets)))
  299 + self._log(' deg\n')
303 300  
304 301 # Log mean azimuth and zenith angle
305   - self._log.parformat("Mean zenith angle")
306   - self._log("%.2f" % (sum(self._zeniths)/len(self._zeniths)))
307   - self._log(" deg\n")
308   - self._log.parformat("Mean azimuth angle")
309   - self._log("%.2f" % (sum(self._azimuths)/len(self._azimuths)))
310   - self._log(" deg\n")
  302 + self._log.parformat('Mean zenith angle')
  303 + self._log('%.2f' % (sum(self._zeniths)/len(self._zeniths)))
  304 + self._log(' deg\n')
  305 + self._log.parformat('Mean azimuth angle')
  306 + self._log('%.2f' % (sum(self._azimuths)/len(self._azimuths)))
  307 + self._log(' deg\n')
311 308  
312 309 # Optionally log names of observations. Note that the set class
313 310 # is used to extract all different observation names from the
... ... @@ -316,49 +313,51 @@ class csobsinfo(ctools.cscript):
316 313 if self._logExplicit() and sys.version_info >= (2,4):
317 314 obs_set = set(obs_names)
318 315 for name in obs_set:
319   - self._log.parformat("\""+name+"\"")
  316 + self._log.parformat('"'+name+'"')
320 317 self._log(str(obs_names.count(name)))
321   - self._log("\n")
322   - self._log("\n")
  318 + self._log('\n')
  319 + self._log('\n')
323 320  
324 321 # Log energy range
325   - self._log.header3("Energy range")
326   - self._log.parformat("Minimum energy")
  322 + self._log.header3('Energy range')
  323 + self._log.parformat('Minimum energy')
327 324 if self._ebounds.size() == 0:
328   - self._log("undefined")
  325 + self._log('undefined')
329 326 else:
330 327 self._log(str(self._ebounds.emin()))
331   - self._log("\n")
332   - self._log.parformat("Maximum energy")
  328 + self._log('\n')
  329 + self._log.parformat('Maximum energy')
333 330 if self._ebounds.size() == 0:
334   - self._log("undefined")
  331 + self._log('undefined')
335 332 else:
336 333 self._log(str(self._ebounds.emax()))
337   - self._log("\n")
  334 + self._log('\n')
338 335  
339 336 # Log time range
340   - self._log.header3("Time range")
341   - self._log.parformat("Start (MJD)")
  337 + self._log.header3('Time range')
  338 + self._log.parformat('Start (MJD)')
342 339 self._log(str(self._gti.tstart().mjd()))
343   - self._log("\n")
344   - self._log.parformat("Stop (MJD)")
  340 + self._log('\n')
  341 + self._log.parformat('Stop (MJD)')
345 342 self._log(str(self._gti.tstop().mjd()))
346   - self._log("\n")
  343 + self._log('\n')
347 344  
348 345 # Log ontime and livetime in different units
349   - self._log.parformat("Total ontime")
350   - self._log("%.2f s = %.2f min = %.2f h" % (ontime, ontime/60., ontime/3600.))
351   - self._log("\n")
352   - self._log.parformat("Total livetime")
353   - self._log("%.2f s = %.2f min = %.2f h" % (livetime, livetime/60.0, livetime/3600.))
354   - self._log("\n")
  346 + self._log.parformat('Total ontime')
  347 + self._log('%.2f s = %.2f min = %.2f h' %
  348 + (ontime, ontime/60., ontime/3600.))
  349 + self._log('\n')
  350 + self._log.parformat('Total livetime')
  351 + self._log('%.2f s = %.2f min = %.2f h' %
  352 + (livetime, livetime/60.0, livetime/3600.))
  353 + self._log('\n')
355 354  
356 355 # Return
357 356 return
358 357  
359 358 def save(self):
360 359 """
361   - Save pointings into DS9 region file.
  360 + Save pointings into DS9 region file
362 361  
363 362 This method saves all pointing directions that are found in the
364 363 observation container into a DS9 region file. If "NONE" is
... ... @@ -366,35 +365,35 @@ class csobsinfo(ctools.cscript):
366 365 """
367 366  
368 367 # Get output filename in case it was not read ahead
369   - ds9file = self["ds9file"].filename()
  368 + ds9file = self['ds9file'].filename()
370 369  
371 370 # Check if DS9 file is valid
372   - if ds9file.url() != "NONE":
  371 + if ds9file.url() != 'NONE':
373 372  
374 373 # Write header
375 374 if self._logTerse():
376   - self._log("\n")
377   - self._log.header1("Save pointings in DS9 file")
  375 + self._log('\n')
  376 + self._log.header1('Save pointings in DS9 file')
378 377  
379 378 # Log filename
380 379 if self._logTerse():
381   - self._log(gammalib.parformat("DS9 filename"))
  380 + self._log(gammalib.parformat('DS9 filename'))
382 381 self._log(ds9file.url())
383   - self._log("\n")
  382 + self._log('\n')
384 383  
385 384 # Open file
386   - f = open(ds9file.url(),"w")
  385 + f = open(ds9file.url(),'w')
387 386  
388 387 # Write coordinate system
389   - f.write("fk5\n")
  388 + f.write('fk5\n')
390 389  
391 390 # Loop over pointings
392 391 for i in range(len(self._pnt_ra)):
393 392  
394 393 # Create string
395   - line = "point("
396   - line+=str(self._pnt_ra[i])+","+str(self._pnt_dec[i])+")"
397   - line+=" # point=cross 20 width=3 \n"
  394 + line = 'point('
  395 + line += str(self._pnt_ra[i])+','+str(self._pnt_dec[i])+')'
  396 + line += ' # point=cross 20 width=3\n'
398 397  
399 398 # Write to file
400 399 f.write(line)
... ...