Commit e25a31e482113e5d8c8dc316d1aa717719382947

Authored by Jürgen Knödlseder
2 parents 6987590f 8a418f5e

Merge branch 'integration' into devel

cscripts/cscaldb.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 glob
25 23 import os
  24 +import gammalib
  25 +import ctools
26 26  
27 27  
28 28 # ============= #
... ...
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 # =============== #
... ... @@ -39,15 +39,15 @@ class csfindobs(ctools.cscript):
39 39 Constructor.
40 40 """
41 41 # Set name
42   - self._name = "csfindobs"
43   - self._version = "1.1.0"
44   - self._datapath = os.getenv("VHEFITS","")
45   - self._prodname = ""
  42 + self._name = 'csfindobs'
  43 + self._version = '1.1.0'
  44 + self._datapath = os.getenv('VHEFITS','')
  45 + self._prodname = ''
46 46 self._select_radec = True
47 47 self._radius = 0.0
48 48 self._ra = 0.0
49 49 self._dec = 0.0
50   - self._obs_index = ""
  50 + self._obs_index = ''
51 51 self._runs = []
52 52  
53 53 # Initialise application by calling the appropriate class
... ... @@ -64,17 +64,17 @@ class csfindobs(ctools.cscript):
64 64 Get parameters from parfile and setup the observation.
65 65 """
66 66 # Get parameters
67   - if self._datapath == "":
68   - self._datapath = self["datapath"].string()
  67 + if self._datapath == '':
  68 + self._datapath = self['datapath'].string()
69 69  
70 70 # Expand environment
71 71 self._datapath = gammalib.expand_env(self._datapath)
72 72  
73 73 # Get production name
74   - self._prodname = self["prodname"].string()
  74 + self._prodname = self['prodname'].string()
75 75  
76 76 # Master index file name
77   - master_indx = self["master_indx"].string()
  77 + master_indx = self['master_indx'].string()
78 78  
79 79 # Intiialise flag if spatial selection is required
80 80 self._select_radec = True
... ... @@ -83,14 +83,14 @@ class csfindobs(ctools.cscript):
83 83 self._radius = 0.0
84 84  
85 85 # Check for vailidity of spatial parameters
86   - if (self["ra"].is_valid() and
87   - self["dec"].is_valid() and
88   - self["rad"].is_valid()):
  86 + if (self['ra'].is_valid() and
  87 + self['dec'].is_valid() and
  88 + self['rad'].is_valid()):
89 89  
90 90 # Read spatial parameters
91   - self._ra = self["ra"].real()
92   - self._dec = self["dec"].real()
93   - self._radius = self["rad"].real()
  91 + self._ra = self['ra'].real()
  92 + self._dec = self['dec'].real()
  93 + self._radius = self['rad'].real()
94 94  
95 95 else:
96 96 self._select_radec = False
... ... @@ -100,12 +100,12 @@ class csfindobs(ctools.cscript):
100 100 self._select_radec = False
101 101  
102 102 # Query other parameters
103   - self["min_qual"].integer()
104   - self["expression"].string()
  103 + self['min_qual'].integer()
  104 + self['expression'].string()
105 105  
106 106 # Read ahead output parameters
107 107 if self._read_ahead():
108   - self["outfile"].filename()
  108 + self['outfile'].filename()
109 109  
110 110 # Open master index file and look for prodname
111 111 master_file = os.path.join(self._datapath, master_indx)
... ... @@ -119,29 +119,29 @@ class csfindobs(ctools.cscript):
119 119 # Open and load JSON file
120 120 json_data = open(master_file).read()
121 121 data = json.loads(json_data)
122   - if not "datasets" in data:
  122 + if not 'datasets' in data:
123 123 raise RuntimeError('Key "datasets" not available in '+
124 124 'master index file.')
125 125  
126 126 # Get configurations
127   - configs = data["datasets"]
  127 + configs = data['datasets']
128 128  
129 129 # Initialise obs index file
130   - self._obs_index = ""
  130 + self._obs_index = ''
131 131  
132 132 # Get HDUs
133 133 for config in configs:
134   - if self._prodname == config["name"]:
  134 + if self._prodname == config['name']:
135 135 self._obs_index = str(os.path.join(self._datapath,
136   - config["obsindx"]))
  136 + config['obsindx']))
137 137 break
138 138  
139 139 # Check HDUs
140   - if self._obs_index == "":
  140 + if self._obs_index == '':
141 141 raise RuntimeError('FITS data store "'+self._prodname+
142 142 '" not available. Run csiactdata to get '+
143 143 'a list of available storage names')
144   - filename = gammalib.GFilename(self._obs_index+"[OBS_INDEX]")
  144 + filename = gammalib.GFilename(self._obs_index+'[OBS_INDEX]')
145 145 if not filename.is_fits():
146 146 raise RuntimeError('Observation index file "'+
147 147 self._obs_index+
... ... @@ -154,7 +154,7 @@ class csfindobs(ctools.cscript):
154 154 # Write input parameters into logger
155 155 if self._logTerse():
156 156 self._log_parameters()
157   - self._log("\n")
  157 + self._log('\n')
158 158  
159 159 # Return
160 160 return
... ... @@ -176,55 +176,62 @@ class csfindobs(ctools.cscript):
176 176 self._runs = []
177 177  
178 178 # Initialise selction expression
179   - expr = ""
  179 + expr = ''
180 180  
181 181 # Add spatial expression if possible
182 182 if self._select_radec:
183   - expr += "ANGSEP("+str(self._ra)+","+str(self._dec)+ \
184   - ",RA_PNT,DEC_PNT)<="+str(self._radius)
  183 + expr += 'ANGSEP('+str(self._ra)+','+str(self._dec)+ \
  184 + ',RA_PNT,DEC_PNT)<='+str(self._radius)
185 185  
186 186 # Add connector if expression is empty
187 187 if len(expr):
188   - expr += "&&"
  188 + expr += '&&'
189 189  
190 190 # Add quality expression
191   - expr += "QUALITY<="+str(self["min_qual"].integer())
  191 + expr += 'QUALITY<='+str(self['min_qual'].integer())
192 192  
193 193 # Add user expression
194   - expression = self["expression"].string()
195   - if (expression != "NONE" and expression != "INDEF" and
  194 + expression = self['expression'].string()
  195 + if (expression != 'NONE' and expression != 'INDEF' and
196 196 len(expression) > 0):
197   - expr += "&&" + expression
  197 + expr += '&&' + expression
198 198  
199 199 # Initialise filename
200   - openfile = self._obs_index+"[OBS_INDEX]["+expr+"]"
  200 + openfile = self._obs_index+'[OBS_INDEX]['+expr+']'
201 201  
202 202 # Open file
203 203 fits = gammalib.GFits(openfile)
204 204  
205 205 # Check for extistence of rows
206   - if fits["OBS_INDEX"].nrows() > 0:
  206 + if fits['OBS_INDEX'].nrows() > 0:
207 207  
208 208 # Get HDU
209   - obs_indx = fits["OBS_INDEX"]
  209 + obs_indx = fits['OBS_INDEX']
210 210  
211 211 # Read observation IDs into array
212 212 for i in range(obs_indx.nrows()):
213   - self._runs.append(obs_indx["OBS_ID"][i])
  213 + self._runs.append(obs_indx['OBS_ID'][i])
214 214  
215 215 # Dump expression
216 216 if self._logNormal():
217   - self._log("\n")
218   - self._log.header3("Expression")
  217 + self._log('\n')
  218 + self._log.header3('Expression')
219 219 self._log(expr)
220   - self._log("\n")
  220 + self._log('\n')
221 221  
222 222 # Dump number of observations
223 223 if self._logTerse():
224   - self._log("\n")
225   - self._log.header3("Observations")
226   - self._log("Found "+str(len(self._runs))+" observations")
227   - self._log("\n")
  224 + self._log('\n')
  225 + self._log.header3('Observations')
  226 + self._log('Found '+str(len(self._runs))+' observations')
  227 + self._log('\n')
  228 +
  229 + # Dump number of observations
  230 + if self._logVerbose():
  231 + self._log('\n')
  232 + self._log.header3('Observation IDs')
  233 + for run in self._runs:
  234 + self._log(str(run)+'\n')
228 235  
229 236 # Close file
230 237 fits.close()
... ... @@ -261,26 +268,26 @@ class csfindobs(ctools.cscript):
261 268 self._log.header1('Save runlist')
262 269  
263 270 # Get filename
264   - outfile = self["outfile"].filename()
  271 + outfile = self['outfile'].filename()
265 272  
266 273 # Check for clobber
267 274 if outfile.exists() and not self._clobber():
268 275 if self._logTerse():
269   - self._log('File "+outfile+" already exists. ')
  276 + self._log('File '+outfile+' already exists. ')
270 277 self._log('Set clobber=yes to overwrite file.')
271 278 self._log('\n')
272 279 else:
273 280  
274 281 # Log file name
275 282 if self._logTerse():
276   - self._log(gammalib.parformat("Runlist file"))
  283 + self._log(gammalib.parformat('Runlist file'))
277 284 self._log(outfile.url())
278   - self._log("\n")
  285 + self._log('\n')
279 286  
280 287 # Write runs to file
281   - f = open(outfile.url(),"w")
  288 + f = open(outfile.url(),'w')
282 289 for run in self._runs:
283   - f.write(str(run)+" \n")
  290 + f.write(str(run)+' \n')
284 291 f.close()
285 292  
286 293 # Return
... ...
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
... ... @@ -43,13 +43,13 @@ class csiactcopy(ctools.cscript):
43 43 Constructor.
44 44 """
45 45 # Set name
46   - self._name = "csiactcopy"
47   - self._version = "1.1.0"
48   - self._datapath = os.getenv("VHEFITS","")
  46 + self._name = 'csiactcopy'
  47 + self._version = '1.1.0'
  48 + self._datapath = os.getenv('VHEFITS','')
49 49 self._remote_master = gammalib.GFilename()
50   - self._remote_base = ""
51   - self._prodname = ""
52   - self._outpath = ""
  50 + self._remote_base = ''
  51 + self._prodname = ''
  52 + self._outpath = ''
53 53 self._runlist = gammalib.GFilename()
54 54 self._runs = []
55 55  
... ... @@ -64,11 +64,11 @@ 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
71   - self._remote_master = self["remote_master"].filename()
  71 + self._remote_master = self['remote_master'].filename()
72 72 if not self._remote_master.exists():
73 73 raise RuntimeError('*** ERROR: FITS data not available. No '
74 74 'master index file found in "'+
... ... @@ -76,14 +76,14 @@ class csiactcopy(ctools.cscript):
76 76 'file system is properly mounted.')
77 77  
78 78 # Get parameters
79   - self._prodname = self["prodname"].string()
80   - self._outpath = gammalib.expand_env(self["outpath"].string())
81   - self._runlist = self["runlist"].filename()
  79 + self._prodname = self['prodname'].string()
  80 + self._outpath = gammalib.expand_env(self['outpath'].string())
  81 + self._runlist = self['runlist'].filename()
82 82  
83 83 # Write input parameters into logger
84 84 if self._logTerse():
85 85 self._log_parameters()
86   - self._log("\n")
  86 + self._log('\n')
87 87  
88 88 # Return
89 89 return
... ... @@ -101,21 +101,21 @@ class csiactcopy(ctools.cscript):
101 101  
102 102 # Logging
103 103 if self._logVerbose():
104   - self._log("\n")
105   - self._log.header3("Copy file")
106   - self._log.parformat("Source")
  104 + self._log('\n')
  105 + self._log.header3('Copy file')
  106 + self._log.parformat('Source')
107 107 self._log(str(source))
108   - self._log("\n")
109   - self._log.parformat("Destination")
  108 + self._log('\n')
  109 + self._log.parformat('Destination')
110 110 self._log(str(destination))
111   - self._log("\n")
112   - self._log.parformat("Already exists")
  111 + self._log('\n')
  112 + self._log.parformat('Already exists')
113 113 self._log(str(os.path.isfile(destination)))
114   - self._log("\n")
115   - self._log.parformat("Overwrite")
  114 + self._log('\n')
  115 + self._log.parformat('Overwrite')
116 116 self._log(str(clobber))
117   - self._log("\n")
118   - self._log.parformat("Copying")
  117 + self._log('\n')
  118 + self._log.parformat('Copying')
119 119  
120 120 # Flag if file destination is already available
121 121 is_file = os.path.isfile(destination)
... ... @@ -123,18 +123,18 @@ class csiactcopy(ctools.cscript):
123 123 # check if file could be skipped because clobber=no
124 124 if is_file and clobber == False:
125 125 if self._logVerbose():
126   - self._log("Skip (clobber=no)")
127   - self._log("\n")
  126 + self._log('Skip (clobber=no)')
  127 + self._log('\n')
128 128  
129 129 # check if file could be skipped because it is the same file
130 130 elif is_file and os.path.samefile(destination, source):
131 131 if self._logVerbose():
132   - self._log("Skip (same file)")
133   - self._log("\n")
  132 + self._log('Skip (same file)')
  133 + self._log('\n')
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  
... ... @@ -146,34 +146,35 @@ class csiactcopy(ctools.cscript):
146 146  
147 147 # Logging
148 148 if self._logVerbose():
149   - self._log("Done!")
150   - self._log("\n")
  149 + self._log('Done!')
  150 + self._log('\n')
151 151  
152 152 # Return
153 153 return filesize
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():
162   - self._log.parformat("Local file")
  163 + self._log.parformat('Local file')
163 164 self._log(str(localfits))
164   - self._log("\n")
165   - self._log.parformat("Remote file")
  165 + self._log('\n')
  166 + self._log.parformat('Remote file')
166 167 self._log(str(remotefits))
167   - self._log("\n")
168   - self._log.parformat("HDU name")
  168 + self._log('\n')
  169 + self._log.parformat('HDU name')
169 170 self._log(str(hduname))
170   - self._log("\n")
171   - self._log.parformat("Conflict preference")
  171 + self._log('\n')
  172 + self._log.parformat('Conflict preference')
172 173 if clobber:
173   - self._log("Remote")
  174 + self._log('Remote')
174 175 else:
175   - self._log("Local")
176   - self._log("\n")
  176 + self._log('Local')
  177 + self._log('\n')
177 178  
178 179 # Check if local fits file is available
179 180 if os.path.isfile(localfits):
... ... @@ -187,40 +188,70 @@ class csiactcopy(ctools.cscript):
187 188  
188 189 # find local obs_id
189 190 local_obs = []
190   - lobs_col = local_hdu["OBS_ID"]
  191 + lobs_col = local_hdu['OBS_ID']
191 192 for obs_id in lobs_col:
192 193 local_obs.append(obs_id)
193   -
194   - # Create selection expression for opening remote fits file
195   - selection = ""
196   - if len(self._runs):
197   - selection += "["+hduname+"]["
198   - for run in self._runs:
199   - selection += "OBS_ID=="+str(run)
200   - selection += "||"
201   - selection = selection[:-2]
202   - selection += "]"
203   -
204   - # Create file name
205   - remotefile = remotefits + selection
206   -
207   - # open remote fits file
208   - remote = gammalib.GFits(str(remotefile))
209   - remote_hdu = remote[hduname]
210   -
  194 +
  195 + # Initialise list of runlists
  196 + # This is kluge: to circumvent a too long file name, we split the
  197 + # runlists into chunks of 50 observations maximum
  198 + runlists = []
  199 + runs_per_chunk = 50
  200 + for i in range(len(self._runs) / runs_per_chunk + 1):
  201 + chunk = self._runs[i * runs_per_chunk : (i + 1) * runs_per_chunk]
  202 + runlists.append(chunk)
  203 +
  204 + # Loop over runlist chunks
  205 + for i, runlist in enumerate(runlists):
  206 +
  207 + # Create selection expression for opening remote fits file
  208 + selection = ''
  209 + if len(runlist):
  210 + selection += '['+hduname+']['
  211 + for run in runlist:
  212 + selection += 'OBS_ID=='+str(run)
  213 + selection += '||'
  214 + selection = selection[:-2]
  215 + selection += ']'
  216 +
  217 + # Create file name
  218 + remotefile = remotefits + selection
  219 +
  220 + # Open remote fits file
  221 + remote = gammalib.GFits(str(remotefile))
  222 +
  223 + # If first iteration, create clone of FITS column for later use
  224 + if i == 0:
  225 + remote_hdu = remote[hduname].clone()
  226 + else:
  227 +
  228 + # get temporary hdu to be added to current HDU
  229 + tmp_hdu = remote[hduname]
  230 +
  231 + # Get old size of remote HDU
  232 + size = remote_hdu.size()
  233 +
  234 + # Extend remote HDU
  235 + remote_hdu.append_rows(tmp_hdu.nrows())
  236 +
  237 + # Loop over rows and columns to copy over values exteding remote HDU
  238 + for col in tmp_hdu:
  239 + for row in range(col.length()):
  240 + remote_hdu[col.name()][size + row] = col[row]
  241 +
211 242 # Get remote obs_id
212 243 remote_obs = []
213   - robs_col = remote_hdu["OBS_ID"]
  244 + robs_col = remote_hdu['OBS_ID']
214 245 for obs_id in robs_col:
215 246 remote_obs.append(obs_id)
216 247  
217 248 if self._logTerse():
218   - self._log.parformat("Remote entries")
  249 + self._log.parformat('Remote entries')
219 250 self._log(str(len(remote_obs)))
220   - self._log("\n")
221   - self._log.parformat("Local entries")
  251 + self._log('\n')
  252 + self._log.parformat('Local entries')
222 253 self._log(str(len(local_obs)))
223   - self._log("\n")
  254 + self._log('\n')
224 255  
225 256 # initialise counter for logging
226 257 removed_rows = 0
... ... @@ -239,13 +270,13 @@ class csiactcopy(ctools.cscript):
239 270 table_has_obsid = True
240 271 while table_has_obsid:
241 272 for i in range(local_hdu.nrows()):
242   - if remote_obs_id == local_hdu["OBS_ID"][i]:
  273 + if remote_obs_id == local_hdu['OBS_ID'][i]:
243 274 local_hdu.remove_rows(i,1)
244 275 removed_rows += 1
245 276 break
246 277 table_has_obsid = False
247 278 for i in range(local_hdu.nrows()):
248   - if remote_obs_id == local_hdu["OBS_ID"][i]:
  279 + if remote_obs_id == local_hdu['OBS_ID'][i]:
249 280 table_has_obsid = True
250 281 break
251 282  
... ... @@ -262,13 +293,13 @@ class csiactcopy(ctools.cscript):
262 293 table_has_obsid = True
263 294 while table_has_obsid:
264 295 for i in range(remote_hdu.nrows()):
265   - if local_obs_id == remote_hdu["OBS_ID"][i]:
  296 + if local_obs_id == remote_hdu['OBS_ID'][i]:
266 297 remote_hdu.remove_rows(i,1)
267 298 removed_rows += 1
268 299 break
269 300 table_has_obsid = False
270 301 for i in range(remote_hdu.nrows()):
271   - if local_obs_id == remote_hdu["OBS_ID"][i]:
  302 + if local_obs_id == remote_hdu['OBS_ID'][i]:
272 303 table_has_obsid = True
273 304 break
274 305  
... ... @@ -280,11 +311,11 @@ class csiactcopy(ctools.cscript):
280 311  
281 312 if self._logTerse():
282 313 if clobber:
283   - self._log.parformat("Removed local rows")
  314 + self._log.parformat('Removed local rows')
284 315 else:
285   - self._log.parformat("Skipped remote rows")
  316 + self._log.parformat('Skipped remote rows')
286 317 self._log(str(removed_rows))
287   - self._log("\n")
  318 + self._log('\n')
288 319  
289 320 # Loop over columns
290 321 for i in range(local_hdu.ncols()):
... ... @@ -322,8 +353,8 @@ class csiactcopy(ctools.cscript):
322 353  
323 354 # Log output
324 355 if self._logTerse():
325   - self._log("\n")
326   - self._log.header2("Runlist information")
  356 + self._log('\n')
  357 + self._log.header2('Runlist information')
327 358  
328 359 # Initialise runlist array
329 360 self._runs = []
... ... @@ -342,15 +373,15 @@ class csiactcopy(ctools.cscript):
342 373  
343 374 # Logging
344 375 if self._logTerse():
345   - self._log.parformat("Number of observations")
  376 + self._log.parformat('Number of observations')
346 377 self._log(str(len(self._runs)))
347   - self._log("\n")
  378 + self._log('\n')
348 379  
349   - # Copy all data if runlist file is "NONE"
350   - elif self._runlist == "NONE":
  380 + # Copy all data if runlist file is 'NONE'
  381 + elif self._runlist == 'NONE':
351 382 if self._logTerse():
352   - self._log("Copy all available data")
353   - self._log("\n")
  383 + self._log('Copy all available data')
  384 + self._log('\n')
354 385  
355 386 # Raise exception if file not valid
356 387 else:
... ... @@ -365,13 +396,13 @@ class csiactcopy(ctools.cscript):
365 396 # Retrieve json data from remote master
366 397 json_data = open(self._remote_master.url()).read()
367 398 data = json.loads(json_data)
368   - if not "datasets" in data:
  399 + if not 'datasets' in data:
369 400 raise RuntimeError('*** ERROR: Key "datasets" not available '
370 401 'in remote master index file "'+
371 402 self._remote_master+'".')
372 403  
373 404 # Get array of configurations
374   - configs = data["datasets"]
  405 + configs = data['datasets']
375 406  
376 407 # Get remote paths
377 408 self._remote_base = self._remote_master.path()
... ... @@ -384,25 +415,25 @@ class csiactcopy(ctools.cscript):
384 415  
385 416 # Logging
386 417 if self._logTerse():
387   - self._log("\n")
388   - self._log.header2("Loop over remote configs")
  418 + self._log('\n')
  419 + self._log.header2('Loop over remote configs')
389 420  
390 421 # Loop over configs
391 422 for config in configs:
392 423  
393 424 # Logging
394 425 if self._logVerbose():
395   - self._log.header2(str(config["name"]))
  426 + self._log.header2(str(config['name']))
396 427  
397 428 # Check if prodname was found
398   - if config["name"] == self._prodname:
  429 + if config['name'] == self._prodname:
399 430  
400 431 # Inidicate that prodname has been found
401 432 has_prod = True
402 433  
403 434 # Build path of index files
404   - remote_hdu = os.path.join(self._remote_base, config["hduindx"])
405   - remote_obs = os.path.join(self._remote_base, config["obsindx"])
  435 + remote_hdu = os.path.join(self._remote_base, config['hduindx'])
  436 + remote_obs = os.path.join(self._remote_base, config['obsindx'])
406 437  
407 438 # Log information
408 439 if self._logTerse():
... ... @@ -416,10 +447,10 @@ class csiactcopy(ctools.cscript):
416 447  
417 448 # Open remote HDU index file
418 449 fits = gammalib.GFits(str(remote_hdu))
419   - table = fits["HDU_INDEX"]
  450 + table = fits['HDU_INDEX']
420 451  
421 452 # Initialise flag if SIZE column is present
422   - has_size = table.contains("SIZE")
  453 + has_size = table.contains('SIZE')
423 454  
424 455 if has_size:
425 456 # Initialise file size
... ... @@ -428,7 +459,7 @@ class csiactcopy(ctools.cscript):
428 459 # Initialise remote observation IDs
429 460 remote_ids = set()
430 461 for row in range(table.nrows()):
431   - remote_ids.add(table["OBS_ID"][row])
  462 + remote_ids.add(table['OBS_ID'][row])
432 463  
433 464 # Log runs that are not available remotely
434 465 for run in self._runs:
... ... @@ -442,14 +473,14 @@ class csiactcopy(ctools.cscript):
442 473 for row in range(table.nrows()):
443 474  
444 475 # Get observation ID
445   - obs_id = table["OBS_ID"][row]
446   - file_dir = table["FILE_DIR"][row]
447   - 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]
448 479  
449 480 # Skip if filename is empty
450   - if file_name == "":
  481 + if file_name == '':
451 482 continue
452   -
  483 +
453 484 # Check if we need to consider an input runlist
454 485 if len(self._runs):
455 486  
... ... @@ -467,9 +498,9 @@ class csiactcopy(ctools.cscript):
467 498  
468 499 # Add file size
469 500 if has_size and newlen > oldlen:
470   - cp_size += table["SIZE"][row]
  501 + cp_size += table['SIZE'][row]
471 502  
472   - # Otherwise add every file
  503 + # Otherwise add every file
473 504 else:
474 505 # Get filename
475 506 fname = os.path.join(os.path.dirname(remote_hdu),
... ... @@ -482,48 +513,48 @@ class csiactcopy(ctools.cscript):
482 513  
483 514 # Add file size
484 515 if has_size and newlen > oldlen:
485   - cp_size += table["SIZE"][row]
  516 + cp_size += table['SIZE'][row]
486 517  
487 518 # Log file information
488 519 if self._logTerse():
489   - self._log("\n")
490   - self._log.header2("File information")
491   - self._log.parformat("Number of files")
  520 + self._log('\n')
  521 + self._log.header2('File information')
  522 + self._log.parformat('Number of files')
492 523 self._log(str(len(files)))
493   - self._log("\n")
  524 + self._log('\n')
494 525 if has_size:
495   - self._log.parformat("Size")
496   - self._log("%.2f"%(float(cp_size)*1e-6)+" MB")
497   - self._log("\n")
  526 + self._log.parformat('Size')
  527 + self._log('%.2f'%(float(cp_size)*1e-6)+' MB')
  528 + self._log('\n')
498 529 if self._logVerbose():
499   - self._log("\n")
500   - self._log.header3("File names")
  530 + self._log('\n')
  531 + self._log.header3('File names')
501 532 for filename in files:
502   - self._log(str(filename)+"\n")
  533 + self._log(str(filename)+'\n')
503 534  
504   - # Close HDU index file
  535 + # Close HDU index file
505 536 fits.close()
506 537  
507 538 # If prodname is not found just log that we skip the config
508 539 else:
509 540 if self._logExplicit():
510   - self._log("\n")
  541 + self._log('\n')
511 542 self._log.header3('Skipping config "'+
512   - str(config["name"])+'"')
513   - self._log("\n")
514   -
515   - # Raise Exception if prodname was not found
  543 + str(config['name'])+'"')
  544 + self._log('\n')
  545 +
  546 + # Raise Exception if prodname was not found
516 547 if not has_prod:
517   - msg = '*** ERROR: FITS production "'+self._prodname+\
518   - '" not available. Available productions are:\n'
  548 + msg = '*** ERROR: FITS production "'+self._prodname+'" not '
  549 + msg += 'available. Available productions are:\n'
519 550 for config in configs:
520   - msg += " - "+config["name"]+"\n"
  551 + msg += ' - '+config['name']+'\n'
521 552 raise RuntimeError(msg)
522   -
  553 +
523 554 # Logging
524 555 if self._logNormal():
525   - self._log("\n")
526   - self._log.header1("Copying files")
  556 + self._log('\n')
  557 + self._log.header1('Copying files')
527 558  
528 559 # intialise counter
529 560 k = 0
... ... @@ -549,9 +580,9 @@ class csiactcopy(ctools.cscript):
549 580 fraction = float(k) / float(len(files)) * 100.0
550 581 while fraction > last_fraction:
551 582 if self._logNormal() and not self._logVerbose():
552   - self._log.parformat("Status")
553   - self._log(str(int(last_fraction))+"%")
554   - self._log("\n")
  583 + self._log.parformat('Status')
  584 + self._log(str(int(last_fraction))+'%')
  585 + self._log('\n')
555 586 last_fraction += fraction_increment
556 587  
557 588 # Copy file
... ... @@ -566,12 +597,12 @@ class csiactcopy(ctools.cscript):
566 597  
567 598 # Logging
568 599 if self._logNormal() and not self._logVerbose():
569   - self._log.parformat("Status")
570   - self._log("Finished")
571   - self._log("\n")
  600 + self._log.parformat('Status')
  601 + self._log('Finished')
  602 + self._log('\n')
572 603 if self._logTerse():
573   - self._log("\n")
574   - self._log.header1("Updating index files")
  604 + self._log('\n')
  605 + self._log.header1('Updating index files')
575 606  
576 607 # Build local index file names
577 608 local_hdu = os.path.join(self._outpath,
... ... @@ -586,18 +617,18 @@ class csiactcopy(ctools.cscript):
586 617  
587 618 # Logging
588 619 if self._logTerse():
589   - self._log("\n")
590   - self._log.header3("HDU index")
  620 + self._log('\n')
  621 + self._log.header3('HDU index')
591 622  
592 623 # Merge remote index files with local files
593   - self._merge(local_hdu, remote_hdu, "HDU_INDEX", self._clobber())
  624 + self._merge(local_hdu, remote_hdu, 'HDU_INDEX', self._clobber())
594 625  
595 626 if self._logTerse():
596   - self._log("\n")
597   - self._log.header3("OBS index")
  627 + self._log('\n')
  628 + self._log.header3('OBS index')
598 629  
599 630 # Merge remote index files with local files
600   - self._merge(local_obs, remote_obs, "OBS_INDEX", self._clobber())
  631 + self._merge(local_obs, remote_obs, 'OBS_INDEX', self._clobber())
601 632  
602 633 else:
603 634 # If all files were copied, just copy index files too
... ... @@ -605,11 +636,11 @@ class csiactcopy(ctools.cscript):
605 636 self._copy(remote_obs, self._clobber())
606 637  
607 638 if self._logTerse():
608   - self._log("\n")
609   - self._log.header3("Master index file")
  639 + self._log('\n')
  640 + self._log.header3('Master index file')
610 641  
611 642 # Adding prodname to local master
612   - localmaster = os.path.join(self._outpath, "master.json")
  643 + localmaster = os.path.join(self._outpath, 'master.json')
613 644  
614 645 # If no local master is found, copy master over first
615 646 if not os.path.isfile(localmaster):
... ... @@ -618,7 +649,7 @@ class csiactcopy(ctools.cscript):
618 649 # Load local master
619 650 json_data = open(localmaster).read()
620 651 data = json.loads(json_data)
621   - configs = data["datasets"]
  652 + configs = data['datasets']
622 653  
623 654 # Initialise flag indicating if we already have prodname in master
624 655 # file
... ... @@ -631,66 +662,66 @@ class csiactcopy(ctools.cscript):
631 662 for config in configs:
632 663  
633 664 # Get hdu and obs index files
634   - hdu = os.path.join(self._outpath, config["hduindx"])
635   - obs = os.path.join(self._outpath, config["obsindx"])
  665 + hdu = os.path.join(self._outpath, config['hduindx'])
  666 + obs = os.path.join(self._outpath, config['obsindx'])
636 667  
637 668 # Check if index files are available
638 669 if not (gammalib.GFilename(str(hdu)).is_fits() and
639 670 gammalib.GFilename(str(obs)).is_fits()):
640 671 if self._logTerse():
641   - self._log('Removing "'+str(config["name"])+'" ')
  672 + self._log('Removing "'+str(config['name'])+'" ')
642 673 self._log('(not available)')
643 674 self._log('\n')
644 675 else:
645 676 # Append config if valid
646 677 newconfigs.append(config)
647 678 if self._logTerse():
648   - self._log('Keeping "'+str(config["name"])+'"')
  679 + self._log('Keeping "'+str(config['name'])+'"')
649 680 self._log('\n')
650 681  
651   - # Signals that downloaded config is available
652   - if config["name"] == self._prodname:
  682 + # Signals that downloaded config is available
  683 + if config['name'] == self._prodname:
653 684 has_config = True
654 685  
655 686 # Create new entry if config was not available
656 687 if not has_config:
657   - newdict = dict.fromkeys(["name","hduindx","obsindx"])
658   - newdict["name"] = self._prodname
659   - newdict["hduindx"] = os.path.relpath(local_hdu, self._outpath)
660   - newdict["obsindx"] = os.path.relpath(local_obs, self._outpath)
  688 + newdict = dict.fromkeys(['name','hduindx','obsindx'])
  689 + newdict['name'] = self._prodname
  690 + newdict['hduindx'] = os.path.relpath(local_hdu, self._outpath)
  691 + newdict['obsindx'] = os.path.relpath(local_obs, self._outpath)
661 692 newconfigs.append(newdict)
662 693 if self._logTerse():
663   - self._log('Adding "'+str(newdict["name"])+'"')
  694 + self._log('Adding "'+str(newdict['name'])+'"')
664 695 self._log('\n')
665 696  
666 697 # Write new json master file
667   - f = open(localmaster, "w")
668   - data["datasets"] = newconfigs
  698 + f = open(localmaster, 'w')
  699 + data['datasets'] = newconfigs
669 700 json.dump(data, f, indent=2)
670   - f.close()
  701 + f.close()
671 702  
672 703 # Log summary
673 704 if self._logNormal():
674   - self._log("\n")
675   - self._log.header1("Summary")
676   - self._log.parformat("Data files found")
  705 + self._log('\n')
  706 + self._log.header1('Summary')
  707 + self._log.parformat('Data files found')
677 708 self._log(str(len(files)))
678   - self._log("\n")
679   - self._log.parformat("Data files copied")
  709 + self._log('\n')
  710 + self._log.parformat('Data files copied')
680 711 self._log(str(n_copied))
681   - self._log("\n")
682   - self._log.parformat("Size")
683   - self._log("%.2f"%(float(total_size)*1e-6)+" MB")
684   - self._log("\n")
685   - self._log.parformat("Local configs")
  712 + self._log('\n')
  713 + self._log.parformat('Size')
  714 + self._log('%.2f'%(float(total_size)*1e-6)+' MB')
  715 + self._log('\n')
  716 + self._log.parformat('Local configs')
686 717 self._log(str(len(newconfigs)))
687   - self._log("\n")
  718 + self._log('\n')
688 719 if self._logTerse():
689   - self._log("\n")
690   - self._log.header3("Content of master index")
  720 + self._log('\n')
  721 + self._log.header3('Content of master index')
691 722 for config in newconfigs:
692   - self._log(str(config["name"]))
693   - self._log("\n")
  723 + self._log(str(config['name']))
  724 + self._log('\n')
694 725  
695 726 # Return
696 727 return
... ...
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.par
... ... @@ -18,7 +18,7 @@
18 18 # Input and output parameters
19 19 #============================
20 20 datapath, s, a, $VHEFITS,,, "Path were data is located"
21   -prodname, s, a, ,,, "Data storage name"
  21 +prodname, s, a, fits-prod-name,,, "Data storage name"
22 22 infile, f, a, runlist.lis,,, "Input runlist file"
23 23 inmodel, f, h, NONE,,, "Input model definition XML file (optional)"
24 24 master_indx, s, h, master.json,,, "Input master index file"
... ...
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
... ... @@ -46,14 +46,14 @@ class csiactobs(ctools.cscript):
46 46 Constructor.
47 47 """
48 48 # Set name and version
49   - self._name = "csiactobs"
50   - self._version = "1.1.0"
  49 + self._name = 'csiactobs'
  50 + self._version = '1.1.0'
51 51  
52 52 # Initialise some members
53 53 self._ebounds = gammalib.GEbounds()
54   - self._datapath = os.getenv("VHEFITS","")
  54 + self._datapath = os.getenv('VHEFITS','')
55 55 self._inmodels = gammalib.GModels()
56   - self._prodname = ""
  56 + self._prodname = ''
57 57 self._xml = gammalib.GXml()
58 58 self._models = gammalib.GModels()
59 59 self._runlist = []
... ... @@ -61,23 +61,23 @@ class csiactobs(ctools.cscript):
61 61 self._bkgpars = 0
62 62 self._outmodel = gammalib.GFilename()
63 63 self._outobs = gammalib.GFilename()
64   - self._master_indx = ""
  64 + self._master_indx = ''
65 65 self._use_bkg_scale = False
66   - self._ev_hiera = [""]
67   - self._aeff_hiera = [""]
68   - self._psf_hiera = [""]
69   - self._bkg_hiera = [""]
70   - self._edisp_hiera = [""]
71   - self._bkg_mod_hiera = [""]
  66 + self._ev_hiera = ['']
  67 + self._aeff_hiera = ['']
  68 + self._psf_hiera = ['']
  69 + self._bkg_hiera = ['']
  70 + self._edisp_hiera = ['']
  71 + self._bkg_mod_hiera = ['']
72 72 self._bkg_gauss_norm = 1.0
73 73 self._bkg_gauss_index = 0.0
74 74 self._bkg_gauss_sigma = 1.0
75 75 self._bkg_aeff_index = 0.0
76 76 self._bkg_aeff_norm = 1.0
77 77 self._bkg_range_factor = 1.0
78   - self._hdu_index = ""
79   - self._obs_index = ""
80   - self._subdir = ""
  78 + self._hdu_index = ''
  79 + self._obs_index = ''
  80 + self._subdir = ''
81 81 self._debug = False
82 82  
83 83 # Initialise application by calling the appropriate class
... ... @@ -94,24 +94,24 @@ class csiactobs(ctools.cscript):
94 94 Get parameters from parfile and setup the observation.
95 95 """
96 96 # Set data path
97   - if self._datapath == "":
98   - self._datapath = self["datapath"].string()
  97 + if self._datapath == '':
  98 + self._datapath = self['datapath'].string()
99 99  
100 100 # Check for input models
101   - if not self["inmodel"].filename() == "NONE":
102   - self._inmodels = gammalib.GModels(self["inmodel"].filename())
  101 + if not self['inmodel'].filename() == 'NONE':
  102 + self._inmodels = gammalib.GModels(self['inmodel'].filename())
103 103  
104 104 # Expand environment
105 105 self._datapath = gammalib.expand_env(self._datapath)
106 106  
107 107 # Read FITS production
108   - self._prodname = self["prodname"].string()
  108 + self._prodname = self['prodname'].string()
109 109  
110 110 # Read runlist file if list not already filled
111 111 if len(self._runlist) == 0:
112 112  
113 113 # Get file name
114   - self._runlistfile = self["infile"].filename()
  114 + self._runlistfile = self['infile'].filename()
115 115  
116 116 # Read runlist from file
117 117 runfile = open(self._runlistfile.url())
... ... @@ -125,73 +125,73 @@ class csiactobs(ctools.cscript):
125 125 runfile.close()
126 126  
127 127 # Read number of background parameters
128   - self._bkgpars = self["bkgpars"].integer()
  128 + self._bkgpars = self['bkgpars'].integer()
129 129  
130 130 # Output model file
131   - self._outmodel = self["outmodel"].filename()
  131 + self._outmodel = self['outmodel'].filename()
132 132  
133 133 # Observation outfile
134   - self._outobs = self["outobs"].filename()
  134 + self._outobs = self['outobs'].filename()
135 135  
136 136 # Master index file name
137   - self._master_indx = self["master_indx"].string()
  137 + self._master_indx = self['master_indx'].string()
138 138  
139 139 # Read flag for background scaling factor
140   - self._use_bkg_scale = self["bkg_scale"].boolean()
  140 + self._use_bkg_scale = self['bkg_scale'].boolean()
141 141  
142 142 # Read hierarchy of file loading
143   - self._ev_hiera = self["ev_hiera"].string().split("|")
144   - self._aeff_hiera = self["aeff_hiera"].string().split("|")
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("|")
148   - self._bkg_mod_hiera = self["bkg_mod_hiera"].string().split("|")
  143 + self._ev_hiera = self['ev_hiera'].string().split('|')
  144 + self._aeff_hiera = self['aeff_hiera'].string().split('|')
  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('|')
  148 + self._bkg_mod_hiera = self['bkg_mod_hiera'].string().split('|')
149 149  
150 150 # Read hidden background parameters
151   - self._bkg_gauss_norm = self["bkg_gauss_norm"].real()
152   - self._bkg_gauss_index = self["bkg_gauss_index"].real()
153   - self._bkg_gauss_sigma = self["bkg_gauss_sigma"].real()
154   - self._bkg_aeff_index = self["bkg_aeff_index"].real()
155   - self._bkg_aeff_norm = self["bkg_aeff_norm"].real()
156   - self._bkg_range_factor = self["bkg_range_factor"].real()
  151 + self._bkg_gauss_norm = self['bkg_gauss_norm'].real()
  152 + self._bkg_gauss_index = self['bkg_gauss_index'].real()
  153 + self._bkg_gauss_sigma = self['bkg_gauss_sigma'].real()
  154 + self._bkg_aeff_index = self['bkg_aeff_index'].real()
  155 + self._bkg_aeff_norm = self['bkg_aeff_norm'].real()
  156 + self._bkg_range_factor = self['bkg_range_factor'].real()
157 157  
158 158 # Open master index file and look for prodname
159 159 master_file = os.path.join(self._datapath, self._master_indx)
160 160 if not os.path.isfile(master_file):
161   - raise RuntimeError("FITS data store not available. No master index file found. Make sure the file is copied from the server and your datapath is set correctly.")
  161 + raise RuntimeError('FITS data store not available. No master index file found. Make sure the file is copied from the server and your datapath is set correctly.')
162 162  
163 163 # Open and load JSON file
164 164 json_data = open(master_file).read()
165 165 data = json.loads(json_data)
166   - if not "datasets" in data:
167   - raise RuntimeError("Key \"datasets\" not available in master index file.")
  166 + if not 'datasets' in data:
  167 + raise RuntimeError('Key "datasets" not available in master index file.')
168 168  
169 169 # Get configurations
170   - configs = data["datasets"]
  170 + configs = data['datasets']
171 171  
172 172 # Initialise HDUs
173   - self._hdu_index = self._obs_index = ""
  173 + self._hdu_index = self._obs_index = ''
174 174  
175 175 # Get HDUs
176 176 for config in configs:
177   - if self._prodname == config["name"]:
178   - self._hdu_index = str(os.path.join(self._datapath, config["hduindx"]))
179   - self._obs_index = str(os.path.join(self._datapath, config["obsindx"]))
  177 + if self._prodname == config['name']:
  178 + self._hdu_index = str(os.path.join(self._datapath, config['hduindx']))
  179 + self._obs_index = str(os.path.join(self._datapath, config['obsindx']))
180 180 break
181 181  
182 182 # Check HDUs
183   - if self._hdu_index == "" or self._obs_index == "":
184   - raise RuntimeError("*** ERROR: FITS data store \""+self._prodname+"\" not available. Run csiactdata to get a list of available storage names")
185   - filename = gammalib.GFilename(self._hdu_index+"[HDU_INDEX]")
  183 + if self._hdu_index == '' or self._obs_index == '':
  184 + raise RuntimeError('*** ERROR: FITS data store "'+self._prodname+'" not available. Run csiactdata to get a list of available storage names')
  185 + filename = gammalib.GFilename(self._hdu_index+'[HDU_INDEX]')
186 186 if not filename.is_fits():
187   - raise RuntimeError("*** ERROR: HDU index file \""+self._hdu_index+"[HDU_INDEX]\" for FITS data store \""+self._prodname+"\" not available. Check your master index file or run csiactdata to get a list of available storage names.")
  187 + raise RuntimeError('*** ERROR: HDU index file "'+self._hdu_index+'[HDU_INDEX]" for FITS data store "'+self._prodname+'" not available. Check your master index file or run csiactdata to get a list of available storage names.')
188 188  
189   - # Check for existence of "BKG_SCALE" in the observation index file if required
  189 + # Check for existence of 'BKG_SCALE' in the observation index file if required
190 190 if self._use_bkg_scale:
191   - filename = gammalib.GFilename(self._obs_index+"[OBS_INDEX]")
  191 + filename = gammalib.GFilename(self._obs_index+'[OBS_INDEX]')
192 192 if filename.is_fits():
193 193 fits = gammalib.GFits(self._obs_index)
194   - if not fits["OBS_INDEX"].contains("BKG_SCALE"):
  194 + if not fits['OBS_INDEX'].contains('BKG_SCALE'):
195 195 self._use_bkg_scale = False
196 196 fits.close()
197 197 else:
... ... @@ -204,7 +204,7 @@ class csiactobs(ctools.cscript):
204 204 # Write input parameters into logger
205 205 if self._logTerse():
206 206 self._log_parameters()
207   - self._log("\n")
  207 + self._log('\n')
208 208  
209 209 # Return
210 210 return
... ... @@ -223,7 +223,7 @@ class csiactobs(ctools.cscript):
223 223 except:
224 224  
225 225 # raise error if wrong type detected
226   - raise RuntimeError("Argument of csiactobs.runlist() must be of type 'list'")
  226 + raise RuntimeError('Argument of csiactobs.runlist() must be of type "list"')
227 227  
228 228 # Return
229 229 return
... ... @@ -233,24 +233,24 @@ class csiactobs(ctools.cscript):
233 233 # Handle constant spectral model
234 234 if index == 0.0 and self._bkgpars <= 1:
235 235 spec = gammalib.GModelSpectralConst()
236   - spec["Value"].min(prefactor / self._bkg_range_factor)
237   - spec["Value"].max(prefactor * self._bkg_range_factor)
238   - spec["Value"].value(prefactor)
  236 + spec['Value'].min(prefactor / self._bkg_range_factor)
  237 + spec['Value'].max(prefactor * self._bkg_range_factor)
  238 + spec['Value'].value(prefactor)
239 239 if self._bkgpars == 0:
240   - spec["Value"].fix()
  240 + spec['Value'].fix()
241 241 else:
242   - spec["Value"].free()
  242 + spec['Value'].free()
243 243  
244 244 else:
245 245  
246 246 # Create power law model
247 247 if self._bkgpars <= 2:
248   - e = gammalib.GEnergy(1.0,"TeV")
  248 + e = gammalib.GEnergy(1.0,'TeV')
249 249 spec = gammalib.GModelSpectralPlaw(prefactor, index, e)
250 250  
251 251 # Set parameter ranges
252   - spec[0].min(0.01 * prefactor)
253   - spec[0].max(100.0 * prefactor)
  252 + spec[0].min(prefactor / self._bkg_range_factor)
  253 + spec[0].max(prefactor * self._bkg_range_factor)
254 254 spec[1].scale(1)
255 255 spec[1].min(-5.0)
256 256 spec[1].max(5.0)
... ... @@ -264,25 +264,27 @@ 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  
271 271 # Create reference powerlaw
272   - plaw = gammalib.GModelSpectralPlaw(prefactor, index, gammalib.GEnergy(1.0,"TeV"))
  272 + plaw = gammalib.GModelSpectralPlaw(prefactor, index, gammalib.GEnergy(1.0,'TeV'))
273 273  
274 274 # Create spectral model and energy values
275 275 spec = gammalib.GModelSpectralNodes()
276   - bounds = gammalib.GEbounds(self._bkgpars,gammalib.GEnergy(emin,"TeV"),gammalib.GEnergy(emax,"TeV"), True)
  276 + bounds = gammalib.GEbounds(self._bkgpars,gammalib.GEnergy(emin,'TeV'),gammalib.GEnergy(emax,'TeV'), True)
277 277 for i in range(bounds.size()):
278 278 energy = bounds.elogmean(i)
279 279 value = plaw.eval(energy, gammalib.GTime())
280 280 spec.append(energy, value)
281 281 for par in spec:
282 282  
283   - if "Energy" in par.name():
  283 + if 'Energy' in par.name():
284 284 par.fix()
285   - elif "Intensity" in par.name():
  285 + elif 'Intensity' in par.name():
  286 + value = par.value()
  287 + par.scale(value)
286 288 par.min(value / self._bkg_range_factor)
287 289 par.max(value * self._bkg_range_factor)
288 290  
... ... @@ -292,7 +294,7 @@ class csiactobs(ctools.cscript):
292 294 def _iact_background(self, telescope, obs_id, bkg_scale, bkgtype, emin=0.01, emax=100):
293 295  
294 296 # handle IrfBackground
295   - if bkgtype == "irf":
  297 + if bkgtype == 'irf':
296 298 prefactor = 1.0
297 299 index = 0.0
298 300 prefactor *= bkg_scale
... ... @@ -302,7 +304,7 @@ class csiactobs(ctools.cscript):
302 304 bck = gammalib.GCTAModelIrfBackground(spec)
303 305  
304 306 # Set AeffBackground
305   - elif bkgtype == "aeff":
  307 + elif bkgtype == 'aeff':
306 308 prefactor = bkg_scale * self._bkg_aeff_norm
307 309 spec = self._background_spectrum(obs_id, prefactor, self._bkg_aeff_index, emin, emax)
308 310  
... ... @@ -310,14 +312,15 @@ class csiactobs(ctools.cscript):
310 312 bck = gammalib.GCTAModelAeffBackground(spec)
311 313  
312 314 # Set Gaussian Background
313   - elif bkgtype == "gauss":
  315 + elif bkgtype == 'gauss':
314 316 prefactor = bkg_scale * self._bkg_gauss_norm
315 317 spec = self._background_spectrum(obs_id, prefactor, self._bkg_gauss_index, emin, emax)
316 318 radial = gammalib.GCTAModelRadialGauss(self._bkg_gauss_sigma)
317 319 bck = gammalib.GCTAModelRadialAcceptance(radial, spec)
318 320  
319 321 else:
320   - sys.exit("Background type \""+self._bkgtype+"\" unsupported")
  322 + msg = 'Background type "'+self._bkgtype+'" unsupported'
  323 + raise RuntimeError(msg)
321 324  
322 325 # Copy model
323 326 model = bck.clone()
... ... @@ -329,7 +332,7 @@ class csiactobs(ctools.cscript):
329 332 model.instruments(telescope)
330 333  
331 334 # Set name (arbitrary)
332   - model.name("bkg_"+str(obs_id))
  335 + model.name('bkg_'+str(obs_id))
333 336  
334 337 # Turn off TS calculation for background model
335 338 model.tscalc(False)
... ... @@ -355,13 +358,13 @@ class csiactobs(ctools.cscript):
355 358  
356 359 # Clear xml file and append an observation list
357 360 self._xml.clear()
358   - self._xml.append(gammalib.GXmlElement("observation_list title=\"observation list\""))
359   - lib = self._xml.element("observation_list", 0)
  361 + self._xml.append(gammalib.GXmlElement('observation_list title="observation list"'))
  362 + lib = self._xml.element('observation_list', 0)
360 363  
361 364 # Log output
362 365 if self._logTerse():
363   - self._log("\n")
364   - self._log.header1("Looping over "+str(len(self._runlist))+" runs")
  366 + self._log('\n')
  367 + self._log.header1('Looping over '+str(len(self._runlist))+' runs')
365 368  
366 369 # Initialise energy range values for logging
367 370 self._ebounds.clear()
... ... @@ -370,21 +373,21 @@ class csiactobs(ctools.cscript):
370 373 for obs_id in self._runlist:
371 374  
372 375 # Create selection string
373   - obs_selection = "[OBS_ID=="+str(obs_id)+"]"
  376 + obs_selection = '[OBS_ID=='+str(obs_id)+']'
374 377  
375 378 # Open HDU index file
376   - hduindx = gammalib.GFits(self._hdu_index+"[HDU_INDEX]"+obs_selection)
377   - hduindx_hdu = hduindx["HDU_INDEX"]
  379 + hduindx = gammalib.GFits(self._hdu_index+'[HDU_INDEX]'+obs_selection)
  380 + hduindx_hdu = hduindx['HDU_INDEX']
378 381  
379 382 # Initialise files and hdu names
380   - eventfile = aefffile = psffile = edispfile = bkgfile = ""
381   - eventhdu = aeffhdu = ""
  383 + eventfile = aefffile = psffile = edispfile = bkgfile = ''
  384 + eventhdu = aeffhdu = ''
382 385  
383 386 types = []
384 387 formats = []
385 388 for i in range(hduindx_hdu.nrows()):
386   - types.append(hduindx_hdu["HDU_TYPE"][i])
387   - formats.append(hduindx_hdu["HDU_CLASS"][i])
  389 + types.append(hduindx_hdu['HDU_TYPE'][i])
  390 + formats.append(hduindx_hdu['HDU_CLASS'][i])
388 391  
389 392 # Handle events
390 393 index = -1
... ... @@ -394,12 +397,15 @@ class csiactobs(ctools.cscript):
394 397 index = formats.index(version)
395 398 break
396 399 if index >= 0:
397   - eventfile = os.path.join(self._subdir, hduindx_hdu["FILE_DIR"][index], hduindx_hdu["FILE_NAME"][index])
398   - eventhdu = hduindx_hdu["HDU_NAME"][index]
399   - eventfile += "["+eventhdu+"]"
  400 + eventfile = os.path.join(self._subdir,
  401 + hduindx_hdu['FILE_DIR'][index],
  402 + hduindx_hdu['FILE_NAME'][index])
  403 + eventhdu = hduindx_hdu['HDU_NAME'][index]
  404 + eventfile += '['+eventhdu+']'
400 405 if not gammalib.GFilename(eventfile).is_fits():
401 406 if self._logTerse():
402   - 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')
403 409 continue
404 410  
405 411 # Handle Aeff
... ... @@ -410,12 +416,15 @@ class csiactobs(ctools.cscript):
410 416 index = formats.index(version)
411 417 break
412 418 if index >= 0:
413   - aefffile = os.path.join(self._subdir, hduindx_hdu["FILE_DIR"][index], hduindx_hdu["FILE_NAME"][index])
414   - aeffhdu = hduindx_hdu["HDU_NAME"][index]
415   - aefffile += "["+aeffhdu+"]"
  419 + aefffile = os.path.join(self._subdir,
  420 + hduindx_hdu['FILE_DIR'][index],
  421 + hduindx_hdu['FILE_NAME'][index])
  422 + aeffhdu = hduindx_hdu['HDU_NAME'][index]
  423 + aefffile += '['+aeffhdu+']'
416 424 if not gammalib.GFilename(aefffile).is_fits():
417 425 if self._logTerse():
418   - 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')
419 428 continue
420 429  
421 430 # Handle psf
... ... @@ -426,11 +435,15 @@ class csiactobs(ctools.cscript):
426 435 index = formats.index(version)
427 436 break
428 437 if index >= 0:
429   - psffile = os.path.join(self._subdir, hduindx_hdu["FILE_DIR"][index], hduindx_hdu["FILE_NAME"][index])
430   - psffile += "["+hduindx_hdu["HDU_NAME"][index]+"]"
  438 + psffile = os.path.join(self._subdir,
  439 + hduindx_hdu['FILE_DIR'][index],
  440 + hduindx_hdu['FILE_NAME'][index])
  441 + psffile += '['+hduindx_hdu['HDU_NAME'][index]+']'
431 442 if not gammalib.GFilename(psffile).is_fits():
432 443 if self._logTerse():
433   - 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')
434 447 continue
435 448  
436 449 # Handle edisp
... ... @@ -441,12 +454,16 @@ class csiactobs(ctools.cscript):
441 454 index = formats.index(version)
442 455 break
443 456 if index >= 0:
444   - edispfile = os.path.join(self._subdir, hduindx_hdu["FILE_DIR"][index], hduindx_hdu["FILE_NAME"][index])
445   - edispfile += "["+hduindx_hdu["HDU_NAME"][index]+"]"
  457 + edispfile = os.path.join(self._subdir,
  458 + hduindx_hdu['FILE_DIR'][index],
  459 + hduindx_hdu['FILE_NAME'][index])
  460 + edispfile += '['+hduindx_hdu['HDU_NAME'][index]+']'
446 461 if not gammalib.GFilename(edispfile).is_fits():
447 462 if self._logTerse():
448   - self._log("Warning: observation "+str(obs_id)+" has no energy dispersion \""+edispfile+"\" information\n")
449   - edispfile = ""
  463 + self._log('Warning: observation '+str(obs_id)+
  464 + ' has no energy dispersion "'+edispfile+
  465 + '" information\n')
  466 + edispfile = ''
450 467  
451 468 # Handle background
452 469 index = -1
... ... @@ -457,14 +474,27 @@ class csiactobs(ctools.cscript):
457 474 index = formats.index(version)
458 475 break
459 476 if index >= 0:
460   - bkgfile = os.path.join(self._subdir, hduindx_hdu["FILE_DIR"][index], hduindx_hdu["FILE_NAME"][index])
461   - bkgfile += "["+hduindx_hdu["HDU_NAME"][index]+"]"
462   - if not gammalib.GFilename(bkgfile).is_fits():
  477 + bkgfile = os.path.join(self._subdir,
  478 + hduindx_hdu['FILE_DIR'][index],
  479 + hduindx_hdu['FILE_NAME'][index])
  480 + bkgfile += '['+hduindx_hdu['HDU_NAME'][index]+']'
  481 + if 'irf' in bkg_mod_hierarchy and not gammalib.GFilename(bkgfile).is_fits():
  482 + bkg_mod_hierarchy.remove('irf')
463 483 if self._logTerse():
464   - self._log("Warning: observation "+str(obs_id)+" has no background information (file=\""+bkgfile+"\"). IRF background cannot be used\n")
465   - bkgfile = ""
466   - if "irf" in bkg_mod_hierarchy:
467   - bkg_mod_hierarchy.remove("irf")
  484 + self._log('Warning: observation '+str(obs_id)+
  485 + ' has no background information (file="'+
  486 + bkgfile+'"). IRF background cannot be used\n')
  487 + bkgfile = ''
  488 + if len(bkg_mod_hierarchy) == 0:
  489 + if self._logTerse():
  490 + self._log('Skipping observation '+str(obs_id)+
  491 + ': No background can be used\n')
  492 + continue
  493 + else:
  494 + if self._logTerse():
  495 + self._log('Observation '+str(obs_id)+
  496 + ': Falling back to background "'+
  497 + bkg_mod_hierarchy[0]+'"\n')
468 498  
469 499 # Close hdu index file
470 500 hduindx.close()
... ... @@ -472,15 +502,15 @@ class csiactobs(ctools.cscript):
472 502 # Handle background scale information if available
473 503 bkg_scale = 1.0
474 504 if self._use_bkg_scale:
475   - obsindx = gammalib.GFits(self._obs_index+"[OBS_INDEX]"+obs_selection)
476   - bkg_scale = obsindx["OBS_INDEX"]["BKG_SCALE"][0]
  505 + obsindx = gammalib.GFits(self._obs_index+'[OBS_INDEX]'+obs_selection)
  506 + bkg_scale = obsindx['OBS_INDEX']['BKG_SCALE'][0]
477 507 obsindx.close()
478 508  
479 509 # Open fits file to determine the observation name
480   - fits = gammalib.GFits(eventfile)
481   - events = fits[eventhdu]
482   - object_name = events.string("OBJECT")
483   - telescope = events.string("TELESCOP")
  510 + fits = gammalib.GFits(eventfile)
  511 + events = fits[eventhdu]
  512 + object_name = events.string('OBJECT')
  513 + telescope = events.string('TELESCOP')
484 514  
485 515 # Close FITS file
486 516 fits.close()
... ... @@ -490,65 +520,71 @@ class csiactobs(ctools.cscript):
490 520 aeff_table = aeff_fits[aeffhdu]
491 521  
492 522 # Set energy range from header keyword if present
493   - if aeff_table.has_card("LO_THRES") and aeff_table.has_card("HI_THRES"):
  523 + if aeff_table.has_card('LO_THRES') and aeff_table.has_card('HI_THRES'):
494 524  
495 525 # Get safe energy range
496   - run_emin = gammalib.GEnergy(aeff_table.real("LO_THRES"), "TeV")
497   - run_emax = gammalib.GEnergy(aeff_table.real("HI_THRES"), "TeV")
  526 + run_emin = gammalib.GEnergy(aeff_table.real('LO_THRES'), 'TeV')
  527 + run_emax = gammalib.GEnergy(aeff_table.real('HI_THRES'), 'TeV')
498 528  
499 529 # Append to ebounds
500 530 self._ebounds.append(run_emin, run_emax)
501 531  
502 532 else:
503 533 # Set default values for energy range
504   - run_emin = gammalib.GEnergy(10,"GeV")
505   - run_emax = gammalib.GEnergy(100,"TeV")
  534 + run_emin = gammalib.GEnergy(10,'GeV')
  535 + run_emax = gammalib.GEnergy(100,'TeV')
506 536  
507 537 # Close Aeff fits file
508 538 aeff_fits.close()
509 539  
510 540 # Append instrumental background model
511   - 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()))
512 547  
513 548 # Logging
514 549 if self._logTerse():
515   - self._log("Adding observation "+str(obs_id)+" (\""+object_name+"\")\n")
  550 + self._log('Adding observation '+str(obs_id)+
  551 + ' ("'+object_name+'")\n')
516 552  
517 553 if self._logExplicit():
518   - self._log(" Event file: "+eventfile+"\n")
519   - self._log(" Effective area: "+aefffile+"\n")
520   - self._log(" Point spread function: "+psffile+"\n")
521   - self._log(" Energy dispersion: "+edispfile+"\n")
522   - self._log(" Background file: "+bkgfile+"\n")
  554 + self._log(' Event file: '+eventfile+'\n')
  555 + self._log(' Effective area: '+aefffile+'\n')
  556 + self._log(' Point spread function: '+psffile+'\n')
  557 + self._log(' Energy dispersion: '+edispfile+'\n')
  558 + self._log(' Background file: '+bkgfile+'\n')
523 559 if self._use_bkg_scale:
524   - self._log(" Background scale: "+str(bkg_scale)+"\n")
525   - self._log("\n")
  560 + self._log(' Background scale: '+str(bkg_scale)+'\n')
  561 + self._log('\n')
526 562  
527 563 # Append observation to XML and set attributes
528   - obs = lib.append("observation")
529   - obs.attribute("name", object_name)
530   - obs.attribute("id", str(obs_id))
531   - obs.attribute("instrument", telescope)
  564 + obs = lib.append('observation')
  565 + obs.attribute('name', object_name)
  566 + obs.attribute('id', str(obs_id))
  567 + obs.attribute('instrument', telescope)
532 568  
533 569 # Append event file
534   - ev = gammalib.GXmlElement("parameter name=\"EventList\"")
535   - ev.attribute("file", eventfile)
  570 + ev = gammalib.GXmlElement('parameter name="EventList"')
  571 + ev.attribute('file', eventfile)
536 572  
537 573 # Append effective area
538   - aeff = gammalib.GXmlElement("parameter name=\"EffectiveArea\"")
539   - aeff.attribute("file",aefffile)
  574 + aeff = gammalib.GXmlElement('parameter name="EffectiveArea"')
  575 + aeff.attribute('file',aefffile)
540 576  
541 577 # Append PSF
542   - psf = gammalib.GXmlElement("parameter name=\"PointSpreadFunction\"")
543   - psf.attribute("file",psffile)
  578 + psf = gammalib.GXmlElement('parameter name="PointSpreadFunction"')
  579 + psf.attribute('file',psffile)
544 580  
545 581 # Append energy dispersion
546   - edisp = gammalib.GXmlElement("parameter name=\"EnergyDispersion\"")
547   - edisp.attribute("file",edispfile)
  582 + edisp = gammalib.GXmlElement('parameter name="EnergyDispersion"')
  583 + edisp.attribute('file',edispfile)
548 584  
549 585 # Append background
550   - bck = gammalib.GXmlElement("parameter name=\"Background\"")
551   - bck.attribute("file",bkgfile)
  586 + bck = gammalib.GXmlElement('parameter name="Background"')
  587 + bck.attribute('file',bkgfile)
552 588  
553 589 # assign events and IRFs to observation
554 590 obs.append(ev)
... ... @@ -562,35 +598,35 @@ class csiactobs(ctools.cscript):
562 598  
563 599 # Log header of energy range
564 600 if self._logTerse():
565   - self._log("\n")
566   - self._log.header3("Energy range of obervation list")
  601 + self._log('\n')
  602 + self._log.header3('Energy range of obervation list')
567 603  
568 604 # Logging if energy range is available
569 605 if self._ebounds.size() > 0:
570 606  
571 607 # Write energy range into log file
572   - self._log(str(self._ebounds.emin())+" - "+str(self._ebounds.emax()))
573   - self._log("\n")
  608 + self._log(str(self._ebounds.emin())+' - '+str(self._ebounds.emax()))
  609 + self._log('\n')
574 610  
575 611 else:
576 612  
577 613 # Write 'not available' into log file
578   - self._log("not available")
579   - self._log("\n")
  614 + self._log('not available')
  615 + self._log('\n')
580 616  
581 617 else:
582   - self._log.header2("WARNING: No observation from given runlist available")
  618 + self._log.header2('WARNING: No observation from given runlist available')
583 619  
584 620 # Append models provided by 'inmodels' if necessary
585 621 if not self._inmodels == None:
586 622 if self._logTerse():
587   - self._log("\n")
588   - self._log.header1("Appending models")
  623 + self._log('\n')
  624 + self._log.header1('Appending models')
589 625  
590 626 # Loop over input models
591 627 for model in self._inmodels:
592 628 if self._logTerse():
593   - self._log.header3("Adding model \""+model.name()+"\"")
  629 + self._log.header3('Adding model "'+model.name()+'"')
594 630 self._models.append(model)
595 631  
596 632 # Return
... ... @@ -598,7 +634,7 @@ class csiactobs(ctools.cscript):
598 634  
599 635 def execute(self):
600 636 """
601   - Execute the script.
  637 + Execute the script
602 638 """
603 639 # Open logfile
604 640 self.logFileOpen()
... ... @@ -613,7 +649,9 @@ class csiactobs(ctools.cscript):
613 649 return
614 650  
615 651 def save(self):
616   -
  652 + """
  653 + Save model definition XML file
  654 + """
617 655 # Save observation XML file
618 656 self._xml.save(self._outobs)
619 657  
... ... @@ -625,8 +663,9 @@ class csiactobs(ctools.cscript):
625 663  
626 664 def ebounds(self):
627 665 """
628   - Returns runlist energy range
  666 + Return runlist energy boundaries
629 667 """
  668 + # Return energy boundaries
630 669 return self._ebounds
631 670  
632 671 def obs(self):
... ...
cscripts/cslightcrv.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/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 # ================= #
... ... @@ -430,10 +430,6 @@ class csmodelinfo(ctools.cscript):
430 430 """
431 431 Save models to ds9 region file if required
432 432 """
433   - # Write header
434   - if self._logTerse():
435   - self._log("\n")
436   - self._log.header1("Save models in DS9 file")
437 433  
438 434 # Get output filename in case it was not read ahead
439 435 self._ds9file = self["ds9file"].filename()
... ... @@ -441,6 +437,11 @@ class csmodelinfo(ctools.cscript):
441 437 # Check if DS9 file is valid
442 438 if self._ds9file != "NONE":
443 439  
  440 + # Write header
  441 + if self._logTerse():
  442 + self._log("\n")
  443 + self._log.header1("Save models in DS9 file")
  444 +
444 445 # Log filename
445 446 if self._logTerse():
446 447 self._log(gammalib.parformat("DS9 filename"))
... ...
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,42 +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 +
  94 + # Get clobber parameter
  95 + self._clobber = self['clobber'].boolean()
93 96  
94 97 # Write input parameters into logger
95 98 if self._logTerse():
96 99 self._log_parameters()
97   - self._log("\n")
  100 + self._log('\n')
98 101  
99 102 # Return
100 103 return
... ... @@ -103,7 +106,7 @@ class csmodelmerge(ctools.cscript):
103 106 # Public methods
104 107 def run(self):
105 108 """
106   - Run the script.
  109 + Run the script
107 110 """
108 111 # Switch screen logging on in debug mode
109 112 if self._logDebug():
... ... @@ -114,8 +117,8 @@ class csmodelmerge(ctools.cscript):
114 117  
115 118 # Write header
116 119 if self._logTerse():
117   - self._log("\n")
118   - self._log.header1("Merge models")
  120 + self._log('\n')
  121 + self._log.header1('Merge models')
119 122  
120 123 # Initialise model container
121 124 self._models = gammalib.GModels()
... ... @@ -130,23 +133,23 @@ class csmodelmerge(ctools.cscript):
130 133 if self._logTerse():
131 134 nmodels = models.size()
132 135 if nmodels == 0:
133   - self._log(gammalib.parformat("Add no model from file"))
  136 + self._log(gammalib.parformat('Add no model from file'))
134 137 elif nmodels == 1:
135   - self._log(gammalib.parformat("Add 1 model from file"))
  138 + self._log(gammalib.parformat('Add 1 model from file'))
136 139 else:
137   - self._log(gammalib.parformat("Add %d models from file" %
  140 + self._log(gammalib.parformat('Add %d models from file' %
138 141 nmodels))
139 142 self._log(file_)
140   - self._log("\n")
  143 + self._log('\n')
141 144  
142 145 # Extend model container by adding all models in the model file
143 146 self._models.extend(models)
144 147  
145 148 # Log total number of models
146 149 if self._logTerse():
147   - self._log(gammalib.parformat("Models after merging"))
  150 + self._log(gammalib.parformat('Models after merging'))
148 151 self._log(self._models.size())
149   - self._log("\n")
  152 + self._log('\n')
150 153  
151 154 # Return
152 155 return
... ... @@ -157,27 +160,35 @@ class csmodelmerge(ctools.cscript):
157 160 """
158 161 # Write header
159 162 if self._logTerse():
160   - self._log("\n")
161   - self._log.header1("Save models")
  163 + self._log('\n')
  164 + self._log.header1('Save models')
162 165  
163 166 # Get output filename in case it was not read ahead
164   - outmodel = self["outmodel"].filename()
  167 + outmodel = self['outmodel'].filename()
165 168  
166   - # Log filename
167   - if self._logTerse():
168   - self._log(gammalib.parformat("Model definition XML file"))
169   - self._log(outmodel.url())
170   - self._log("\n")
171   -
172   - # Save models
173   - self._models.save(outmodel)
  169 + # If file exists and clobber flag is false then raise an exception
  170 + if outmodel.exists() and not self._clobber:
  171 + msg = 'Cannot save ""+outmodel.url()+"": File already exists. '\
  172 + 'Use parameter clobber=yes to allow overwriting of files.'
  173 + raise RuntimeError(msg)
  174 +
  175 + else:
  176 +
  177 + # Log filename
  178 + if self._logTerse():
  179 + self._log(gammalib.parformat('Model definition XML file'))
  180 + self._log(outmodel.url())
  181 + self._log('\n')
  182 +
  183 + # Save models
  184 + self._models.save(outmodel)
174 185  
175 186 # Return
176 187 return
177 188  
178 189 def execute(self):
179 190 """
180   - Execute the script.
  191 + Execute the script
181 192 """
182 193 # Open logfile
183 194 self.logFileOpen()
... ...
cscripts/csobs2caldb.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 datetime
  24 +import gammalib
  25 +import ctools
26 26  
27 27  
28 28 # ================= #
... ...
cscripts/csobsdef.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/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,84 +313,87 @@ 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
365 364 specified for the "ds9file" parameter the method does nothing.
366 365 """
367   - # Write header
368   - if self._logTerse():
369   - self._log("\n")
370   - self._log.header1("Save pointings in DS9 file")
371 366  
372 367 # Get output filename in case it was not read ahead
373   - ds9file = self["ds9file"].filename()
  368 + ds9file = self['ds9file'].filename()
374 369  
375 370 # Check if DS9 file is valid
376   - if ds9file.url() != "NONE":
  371 + if ds9file.url() != 'NONE':
  372 +
  373 + # Write header
  374 + if self._logTerse():
  375 + self._log('\n')
  376 + self._log.header1('Save pointings in DS9 file')
377 377  
378 378 # Log filename
379 379 if self._logTerse():
380   - self._log(gammalib.parformat("DS9 filename"))
  380 + self._log(gammalib.parformat('DS9 filename'))
381 381 self._log(ds9file.url())
382   - self._log("\n")
  382 + self._log('\n')
383 383  
384 384 # Open file
385   - f = open(ds9file.url(),"w")
  385 + f = open(ds9file.url(),'w')
386 386  
387 387 # Write coordinate system
388   - f.write("fk5\n")
  388 + f.write('fk5\n')
389 389  
390 390 # Loop over pointings
391 391 for i in range(len(self._pnt_ra)):
392 392  
393 393 # Create string
394   - line = "point("
395   - line+=str(self._pnt_ra[i])+","+str(self._pnt_dec[i])+")"
396   - 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'
397 397  
398 398 # Write to file
399 399 f.write(line)
... ...
cscripts/cspull.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 sys
  22 +import csv
21 23 import gammalib
22 24 import ctools
23 25 from cscripts import obsutils
24   -import sys
25   -import csv
26 26  
27 27  
28 28 # ============ #
... ...
cscripts/csresmap.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/csroot2caldb.py
... ... @@ -21,9 +21,9 @@
21 21 import os
22 22 import sys
23 23 import math
  24 +from datetime import datetime
24 25 import gammalib
25 26 import ctools
26   -from datetime import datetime
27 27  
28 28 # Optional ROOT import
29 29 try:
... ...
cscripts/cssens.py
... ... @@ -18,12 +18,12 @@
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   -from cscripts import obsutils
24 21 import sys
25 22 import csv
26 23 import math
  24 +import gammalib
  25 +import ctools
  26 +from cscripts import obsutils
27 27  
28 28  
29 29 # ============ #
... ...
cscripts/csspec.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/cstsdist.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 sys
  22 +import csv
21 23 import gammalib
22 24 import ctools
23 25 from cscripts import obsutils
24   -import sys
25   -import csv
26 26  
27 27  
28 28 # ============== #
... ...
cscripts/cstsmapmerge.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 glob
25 23 import os
  24 +import gammalib
  25 +import ctools
26 26  
27 27  
28 28 # ================== #
... ...
cscripts/csworkflow.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 sys
21 22 import gammalib
22 23 import ctools
23 24 import cscripts
24   -import sys
25 25  
26 26  
27 27 # ================ #
... ...
cscripts/lsmodel.py
... ... @@ -18,8 +18,8 @@
18 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19 #
20 20 # ==========================================================================
21   -import gammalib
22 21 import sys
  22 +import gammalib
23 23  
24 24  
25 25 # ============= #
... ...
cscripts/obsutils.py
... ... @@ -19,7 +19,6 @@
19 19 # ==========================================================================
20 20 import gammalib
21 21 import ctools
22   -#import math
23 22  
24 23  
25 24 # ===================== #
... ...