Commit 8a418f5e0589018ef7bc70da31a7e4913a518526

Authored by Jürgen Knödlseder
2 parents 02c80714 105497eb

Merge branch '1813-improvement-of-cscripts' into integration

cscripts/cscaldb.py
@@ -18,11 +18,11 @@ @@ -18,11 +18,11 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
21 -import gammalib  
22 -import ctools  
23 import sys 21 import sys
24 import glob 22 import glob
25 import os 23 import os
  24 +import gammalib
  25 +import ctools
26 26
27 27
28 # ============= # 28 # ============= #
cscripts/csfindobs.py
@@ -18,11 +18,11 @@ @@ -18,11 +18,11 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
21 -import gammalib  
22 -import ctools  
23 import sys 21 import sys
24 import os 22 import os
25 import json 23 import json
  24 +import gammalib
  25 +import ctools
26 26
27 27
28 # =============== # 28 # =============== #
@@ -39,15 +39,15 @@ class csfindobs(ctools.cscript): @@ -39,15 +39,15 @@ class csfindobs(ctools.cscript):
39 Constructor. 39 Constructor.
40 """ 40 """
41 # Set name 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 self._select_radec = True 46 self._select_radec = True
47 self._radius = 0.0 47 self._radius = 0.0
48 self._ra = 0.0 48 self._ra = 0.0
49 self._dec = 0.0 49 self._dec = 0.0
50 - self._obs_index = "" 50 + self._obs_index = ''
51 self._runs = [] 51 self._runs = []
52 52
53 # Initialise application by calling the appropriate class 53 # Initialise application by calling the appropriate class
@@ -64,17 +64,17 @@ class csfindobs(ctools.cscript): @@ -64,17 +64,17 @@ class csfindobs(ctools.cscript):
64 Get parameters from parfile and setup the observation. 64 Get parameters from parfile and setup the observation.
65 """ 65 """
66 # Get parameters 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 # Expand environment 70 # Expand environment
71 self._datapath = gammalib.expand_env(self._datapath) 71 self._datapath = gammalib.expand_env(self._datapath)
72 72
73 # Get production name 73 # Get production name
74 - self._prodname = self["prodname"].string() 74 + self._prodname = self['prodname'].string()
75 75
76 # Master index file name 76 # Master index file name
77 - master_indx = self["master_indx"].string() 77 + master_indx = self['master_indx'].string()
78 78
79 # Intiialise flag if spatial selection is required 79 # Intiialise flag if spatial selection is required
80 self._select_radec = True 80 self._select_radec = True
@@ -83,14 +83,14 @@ class csfindobs(ctools.cscript): @@ -83,14 +83,14 @@ class csfindobs(ctools.cscript):
83 self._radius = 0.0 83 self._radius = 0.0
84 84
85 # Check for vailidity of spatial parameters 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 # Read spatial parameters 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 else: 95 else:
96 self._select_radec = False 96 self._select_radec = False
@@ -100,12 +100,12 @@ class csfindobs(ctools.cscript): @@ -100,12 +100,12 @@ class csfindobs(ctools.cscript):
100 self._select_radec = False 100 self._select_radec = False
101 101
102 # Query other parameters 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 # Read ahead output parameters 106 # Read ahead output parameters
107 if self._read_ahead(): 107 if self._read_ahead():
108 - self["outfile"].filename() 108 + self['outfile'].filename()
109 109
110 # Open master index file and look for prodname 110 # Open master index file and look for prodname
111 master_file = os.path.join(self._datapath, master_indx) 111 master_file = os.path.join(self._datapath, master_indx)
@@ -119,29 +119,29 @@ class csfindobs(ctools.cscript): @@ -119,29 +119,29 @@ class csfindobs(ctools.cscript):
119 # Open and load JSON file 119 # Open and load JSON file
120 json_data = open(master_file).read() 120 json_data = open(master_file).read()
121 data = json.loads(json_data) 121 data = json.loads(json_data)
122 - if not "datasets" in data: 122 + if not 'datasets' in data:
123 raise RuntimeError('Key "datasets" not available in '+ 123 raise RuntimeError('Key "datasets" not available in '+
124 'master index file.') 124 'master index file.')
125 125
126 # Get configurations 126 # Get configurations
127 - configs = data["datasets"] 127 + configs = data['datasets']
128 128
129 # Initialise obs index file 129 # Initialise obs index file
130 - self._obs_index = "" 130 + self._obs_index = ''
131 131
132 # Get HDUs 132 # Get HDUs
133 for config in configs: 133 for config in configs:
134 - if self._prodname == config["name"]: 134 + if self._prodname == config['name']:
135 self._obs_index = str(os.path.join(self._datapath, 135 self._obs_index = str(os.path.join(self._datapath,
136 - config["obsindx"])) 136 + config['obsindx']))
137 break 137 break
138 138
139 # Check HDUs 139 # Check HDUs
140 - if self._obs_index == "": 140 + if self._obs_index == '':
141 raise RuntimeError('FITS data store "'+self._prodname+ 141 raise RuntimeError('FITS data store "'+self._prodname+
142 '" not available. Run csiactdata to get '+ 142 '" not available. Run csiactdata to get '+
143 'a list of available storage names') 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 if not filename.is_fits(): 145 if not filename.is_fits():
146 raise RuntimeError('Observation index file "'+ 146 raise RuntimeError('Observation index file "'+
147 self._obs_index+ 147 self._obs_index+
@@ -154,7 +154,7 @@ class csfindobs(ctools.cscript): @@ -154,7 +154,7 @@ class csfindobs(ctools.cscript):
154 # Write input parameters into logger 154 # Write input parameters into logger
155 if self._logTerse(): 155 if self._logTerse():
156 self._log_parameters() 156 self._log_parameters()
157 - self._log("\n") 157 + self._log('\n')
158 158
159 # Return 159 # Return
160 return 160 return
@@ -176,55 +176,62 @@ class csfindobs(ctools.cscript): @@ -176,55 +176,62 @@ class csfindobs(ctools.cscript):
176 self._runs = [] 176 self._runs = []
177 177
178 # Initialise selction expression 178 # Initialise selction expression
179 - expr = "" 179 + expr = ''
180 180
181 # Add spatial expression if possible 181 # Add spatial expression if possible
182 if self._select_radec: 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 # Add connector if expression is empty 186 # Add connector if expression is empty
187 if len(expr): 187 if len(expr):
188 - expr += "&&" 188 + expr += '&&'
189 189
190 # Add quality expression 190 # Add quality expression
191 - expr += "QUALITY<="+str(self["min_qual"].integer()) 191 + expr += 'QUALITY<='+str(self['min_qual'].integer())
192 192
193 # Add user expression 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 len(expression) > 0): 196 len(expression) > 0):
197 - expr += "&&" + expression 197 + expr += '&&' + expression
198 198
199 # Initialise filename 199 # Initialise filename
200 - openfile = self._obs_index+"[OBS_INDEX]["+expr+"]" 200 + openfile = self._obs_index+'[OBS_INDEX]['+expr+']'
201 201
202 # Open file 202 # Open file
203 fits = gammalib.GFits(openfile) 203 fits = gammalib.GFits(openfile)
204 204
205 # Check for extistence of rows 205 # Check for extistence of rows
206 - if fits["OBS_INDEX"].nrows() > 0: 206 + if fits['OBS_INDEX'].nrows() > 0:
207 207
208 # Get HDU 208 # Get HDU
209 - obs_indx = fits["OBS_INDEX"] 209 + obs_indx = fits['OBS_INDEX']
210 210
211 # Read observation IDs into array 211 # Read observation IDs into array
212 for i in range(obs_indx.nrows()): 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 # Dump expression 215 # Dump expression
216 if self._logNormal(): 216 if self._logNormal():
217 - self._log("\n")  
218 - self._log.header3("Expression") 217 + self._log('\n')
  218 + self._log.header3('Expression')
219 self._log(expr) 219 self._log(expr)
220 - self._log("\n") 220 + self._log('\n')
221 221
222 # Dump number of observations 222 # Dump number of observations
223 if self._logTerse(): 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 # Close file 236 # Close file
230 fits.close() 237 fits.close()
@@ -261,26 +268,26 @@ class csfindobs(ctools.cscript): @@ -261,26 +268,26 @@ class csfindobs(ctools.cscript):
261 self._log.header1('Save runlist') 268 self._log.header1('Save runlist')
262 269
263 # Get filename 270 # Get filename
264 - outfile = self["outfile"].filename() 271 + outfile = self['outfile'].filename()
265 272
266 # Check for clobber 273 # Check for clobber
267 if outfile.exists() and not self._clobber(): 274 if outfile.exists() and not self._clobber():
268 if self._logTerse(): 275 if self._logTerse():
269 - self._log('File "+outfile+" already exists. ') 276 + self._log('File '+outfile+' already exists. ')
270 self._log('Set clobber=yes to overwrite file.') 277 self._log('Set clobber=yes to overwrite file.')
271 self._log('\n') 278 self._log('\n')
272 else: 279 else:
273 280
274 # Log file name 281 # Log file name
275 if self._logTerse(): 282 if self._logTerse():
276 - self._log(gammalib.parformat("Runlist file")) 283 + self._log(gammalib.parformat('Runlist file'))
277 self._log(outfile.url()) 284 self._log(outfile.url())
278 - self._log("\n") 285 + self._log('\n')
279 286
280 # Write runs to file 287 # Write runs to file
281 - f = open(outfile.url(),"w") 288 + f = open(outfile.url(),'w')
282 for run in self._runs: 289 for run in self._runs:
283 - f.write(str(run)+" \n") 290 + f.write(str(run)+' \n')
284 f.close() 291 f.close()
285 292
286 # Return 293 # Return
cscripts/csiactcopy.py
@@ -18,19 +18,19 @@ @@ -18,19 +18,19 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
21 -import gammalib  
22 -import ctools  
23 import sys 21 import sys
24 import os 22 import os
25 import json 23 import json
26 import shutil 24 import shutil
  25 +import gammalib
  26 +import ctools
27 27
28 # ================ # 28 # ================ #
29 # csiactdata class # 29 # csiactdata class #
30 # ================ # 30 # ================ #
31 class csiactcopy(ctools.cscript): 31 class csiactcopy(ctools.cscript):
32 """ 32 """
33 - Copies IACT data from remote machine. 33 + Copies IACT data from remote machine
34 34
35 This script copies IACT data from one location to another. It can 35 This script copies IACT data from one location to another. It can
36 take a list of observation IDs to allow the download specific 36 take a list of observation IDs to allow the download specific
@@ -43,13 +43,13 @@ class csiactcopy(ctools.cscript): @@ -43,13 +43,13 @@ class csiactcopy(ctools.cscript):
43 Constructor. 43 Constructor.
44 """ 44 """
45 # Set name 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 self._remote_master = gammalib.GFilename() 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 self._runlist = gammalib.GFilename() 53 self._runlist = gammalib.GFilename()
54 self._runs = [] 54 self._runs = []
55 55
@@ -64,11 +64,11 @@ class csiactcopy(ctools.cscript): @@ -64,11 +64,11 @@ class csiactcopy(ctools.cscript):
64 # Private methods 64 # Private methods
65 def _get_parameters(self): 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 # Get Parameters 70 # Get Parameters
71 - self._remote_master = self["remote_master"].filename() 71 + self._remote_master = self['remote_master'].filename()
72 if not self._remote_master.exists(): 72 if not self._remote_master.exists():
73 raise RuntimeError('*** ERROR: FITS data not available. No ' 73 raise RuntimeError('*** ERROR: FITS data not available. No '
74 'master index file found in "'+ 74 'master index file found in "'+
@@ -76,14 +76,14 @@ class csiactcopy(ctools.cscript): @@ -76,14 +76,14 @@ class csiactcopy(ctools.cscript):
76 'file system is properly mounted.') 76 'file system is properly mounted.')
77 77
78 # Get parameters 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 # Write input parameters into logger 83 # Write input parameters into logger
84 if self._logTerse(): 84 if self._logTerse():
85 self._log_parameters() 85 self._log_parameters()
86 - self._log("\n") 86 + self._log('\n')
87 87
88 # Return 88 # Return
89 return 89 return
@@ -101,21 +101,21 @@ class csiactcopy(ctools.cscript): @@ -101,21 +101,21 @@ class csiactcopy(ctools.cscript):
101 101
102 # Logging 102 # Logging
103 if self._logVerbose(): 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 self._log(str(source)) 107 self._log(str(source))
108 - self._log("\n")  
109 - self._log.parformat("Destination") 108 + self._log('\n')
  109 + self._log.parformat('Destination')
110 self._log(str(destination)) 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 self._log(str(os.path.isfile(destination))) 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 self._log(str(clobber)) 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 # Flag if file destination is already available 120 # Flag if file destination is already available
121 is_file = os.path.isfile(destination) 121 is_file = os.path.isfile(destination)
@@ -123,18 +123,18 @@ class csiactcopy(ctools.cscript): @@ -123,18 +123,18 @@ class csiactcopy(ctools.cscript):
123 # check if file could be skipped because clobber=no 123 # check if file could be skipped because clobber=no
124 if is_file and clobber == False: 124 if is_file and clobber == False:
125 if self._logVerbose(): 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 # check if file could be skipped because it is the same file 129 # check if file could be skipped because it is the same file
130 elif is_file and os.path.samefile(destination, source): 130 elif is_file and os.path.samefile(destination, source):
131 if self._logVerbose(): 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 else: 135 else:
136 # Create directory if not existent 136 # Create directory if not existent
137 - dest_dir = os.path.dirname(destination) 137 + dest_dir = os.path.dirname(destination)
138 if not os.path.isdir(dest_dir): 138 if not os.path.isdir(dest_dir):
139 os.makedirs(dest_dir) 139 os.makedirs(dest_dir)
140 140
@@ -146,34 +146,35 @@ class csiactcopy(ctools.cscript): @@ -146,34 +146,35 @@ class csiactcopy(ctools.cscript):
146 146
147 # Logging 147 # Logging
148 if self._logVerbose(): 148 if self._logVerbose():
149 - self._log("Done!")  
150 - self._log("\n") 149 + self._log('Done!')
  150 + self._log('\n')
151 151
152 # Return 152 # Return
153 return filesize 153 return filesize
154 154
155 def _merge(self, localfits, remotefits, hduname, clobber): 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 if self._logTerse(): 162 if self._logTerse():
162 - self._log.parformat("Local file") 163 + self._log.parformat('Local file')
163 self._log(str(localfits)) 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 self._log(str(remotefits)) 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 self._log(str(hduname)) 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 if clobber: 173 if clobber:
173 - self._log("Remote") 174 + self._log('Remote')
174 else: 175 else:
175 - self._log("Local")  
176 - self._log("\n") 176 + self._log('Local')
  177 + self._log('\n')
177 178
178 # Check if local fits file is available 179 # Check if local fits file is available
179 if os.path.isfile(localfits): 180 if os.path.isfile(localfits):
@@ -187,40 +188,70 @@ class csiactcopy(ctools.cscript): @@ -187,40 +188,70 @@ class csiactcopy(ctools.cscript):
187 188
188 # find local obs_id 189 # find local obs_id
189 local_obs = [] 190 local_obs = []
190 - lobs_col = local_hdu["OBS_ID"] 191 + lobs_col = local_hdu['OBS_ID']
191 for obs_id in lobs_col: 192 for obs_id in lobs_col:
192 local_obs.append(obs_id) 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 # Get remote obs_id 242 # Get remote obs_id
212 remote_obs = [] 243 remote_obs = []
213 - robs_col = remote_hdu["OBS_ID"] 244 + robs_col = remote_hdu['OBS_ID']
214 for obs_id in robs_col: 245 for obs_id in robs_col:
215 remote_obs.append(obs_id) 246 remote_obs.append(obs_id)
216 247
217 if self._logTerse(): 248 if self._logTerse():
218 - self._log.parformat("Remote entries") 249 + self._log.parformat('Remote entries')
219 self._log(str(len(remote_obs))) 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 self._log(str(len(local_obs))) 253 self._log(str(len(local_obs)))
223 - self._log("\n") 254 + self._log('\n')
224 255
225 # initialise counter for logging 256 # initialise counter for logging
226 removed_rows = 0 257 removed_rows = 0
@@ -239,13 +270,13 @@ class csiactcopy(ctools.cscript): @@ -239,13 +270,13 @@ class csiactcopy(ctools.cscript):
239 table_has_obsid = True 270 table_has_obsid = True
240 while table_has_obsid: 271 while table_has_obsid:
241 for i in range(local_hdu.nrows()): 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 local_hdu.remove_rows(i,1) 274 local_hdu.remove_rows(i,1)
244 removed_rows += 1 275 removed_rows += 1
245 break 276 break
246 table_has_obsid = False 277 table_has_obsid = False
247 for i in range(local_hdu.nrows()): 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 table_has_obsid = True 280 table_has_obsid = True
250 break 281 break
251 282
@@ -262,13 +293,13 @@ class csiactcopy(ctools.cscript): @@ -262,13 +293,13 @@ class csiactcopy(ctools.cscript):
262 table_has_obsid = True 293 table_has_obsid = True
263 while table_has_obsid: 294 while table_has_obsid:
264 for i in range(remote_hdu.nrows()): 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 remote_hdu.remove_rows(i,1) 297 remote_hdu.remove_rows(i,1)
267 removed_rows += 1 298 removed_rows += 1
268 break 299 break
269 table_has_obsid = False 300 table_has_obsid = False
270 for i in range(remote_hdu.nrows()): 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 table_has_obsid = True 303 table_has_obsid = True
273 break 304 break
274 305
@@ -280,11 +311,11 @@ class csiactcopy(ctools.cscript): @@ -280,11 +311,11 @@ class csiactcopy(ctools.cscript):
280 311
281 if self._logTerse(): 312 if self._logTerse():
282 if clobber: 313 if clobber:
283 - self._log.parformat("Removed local rows") 314 + self._log.parformat('Removed local rows')
284 else: 315 else:
285 - self._log.parformat("Skipped remote rows") 316 + self._log.parformat('Skipped remote rows')
286 self._log(str(removed_rows)) 317 self._log(str(removed_rows))
287 - self._log("\n") 318 + self._log('\n')
288 319
289 # Loop over columns 320 # Loop over columns
290 for i in range(local_hdu.ncols()): 321 for i in range(local_hdu.ncols()):
@@ -322,8 +353,8 @@ class csiactcopy(ctools.cscript): @@ -322,8 +353,8 @@ class csiactcopy(ctools.cscript):
322 353
323 # Log output 354 # Log output
324 if self._logTerse(): 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 # Initialise runlist array 359 # Initialise runlist array
329 self._runs = [] 360 self._runs = []
@@ -342,15 +373,15 @@ class csiactcopy(ctools.cscript): @@ -342,15 +373,15 @@ class csiactcopy(ctools.cscript):
342 373
343 # Logging 374 # Logging
344 if self._logTerse(): 375 if self._logTerse():
345 - self._log.parformat("Number of observations") 376 + self._log.parformat('Number of observations')
346 self._log(str(len(self._runs))) 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 if self._logTerse(): 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 # Raise exception if file not valid 386 # Raise exception if file not valid
356 else: 387 else:
@@ -365,13 +396,13 @@ class csiactcopy(ctools.cscript): @@ -365,13 +396,13 @@ class csiactcopy(ctools.cscript):
365 # Retrieve json data from remote master 396 # Retrieve json data from remote master
366 json_data = open(self._remote_master.url()).read() 397 json_data = open(self._remote_master.url()).read()
367 data = json.loads(json_data) 398 data = json.loads(json_data)
368 - if not "datasets" in data: 399 + if not 'datasets' in data:
369 raise RuntimeError('*** ERROR: Key "datasets" not available ' 400 raise RuntimeError('*** ERROR: Key "datasets" not available '
370 'in remote master index file "'+ 401 'in remote master index file "'+
371 self._remote_master+'".') 402 self._remote_master+'".')
372 403
373 # Get array of configurations 404 # Get array of configurations
374 - configs = data["datasets"] 405 + configs = data['datasets']
375 406
376 # Get remote paths 407 # Get remote paths
377 self._remote_base = self._remote_master.path() 408 self._remote_base = self._remote_master.path()
@@ -384,25 +415,25 @@ class csiactcopy(ctools.cscript): @@ -384,25 +415,25 @@ class csiactcopy(ctools.cscript):
384 415
385 # Logging 416 # Logging
386 if self._logTerse(): 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 # Loop over configs 421 # Loop over configs
391 for config in configs: 422 for config in configs:
392 423
393 # Logging 424 # Logging
394 if self._logVerbose(): 425 if self._logVerbose():
395 - self._log.header2(str(config["name"])) 426 + self._log.header2(str(config['name']))
396 427
397 # Check if prodname was found 428 # Check if prodname was found
398 - if config["name"] == self._prodname: 429 + if config['name'] == self._prodname:
399 430
400 # Inidicate that prodname has been found 431 # Inidicate that prodname has been found
401 has_prod = True 432 has_prod = True
402 433
403 # Build path of index files 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 # Log information 438 # Log information
408 if self._logTerse(): 439 if self._logTerse():
@@ -416,10 +447,10 @@ class csiactcopy(ctools.cscript): @@ -416,10 +447,10 @@ class csiactcopy(ctools.cscript):
416 447
417 # Open remote HDU index file 448 # Open remote HDU index file
418 fits = gammalib.GFits(str(remote_hdu)) 449 fits = gammalib.GFits(str(remote_hdu))
419 - table = fits["HDU_INDEX"] 450 + table = fits['HDU_INDEX']
420 451
421 # Initialise flag if SIZE column is present 452 # Initialise flag if SIZE column is present
422 - has_size = table.contains("SIZE") 453 + has_size = table.contains('SIZE')
423 454
424 if has_size: 455 if has_size:
425 # Initialise file size 456 # Initialise file size
@@ -428,7 +459,7 @@ class csiactcopy(ctools.cscript): @@ -428,7 +459,7 @@ class csiactcopy(ctools.cscript):
428 # Initialise remote observation IDs 459 # Initialise remote observation IDs
429 remote_ids = set() 460 remote_ids = set()
430 for row in range(table.nrows()): 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 # Log runs that are not available remotely 464 # Log runs that are not available remotely
434 for run in self._runs: 465 for run in self._runs:
@@ -442,14 +473,14 @@ class csiactcopy(ctools.cscript): @@ -442,14 +473,14 @@ class csiactcopy(ctools.cscript):
442 for row in range(table.nrows()): 473 for row in range(table.nrows()):
443 474
444 # Get observation ID 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 # Skip if filename is empty 480 # Skip if filename is empty
450 - if file_name == "": 481 + if file_name == '':
451 continue 482 continue
452 - 483 +
453 # Check if we need to consider an input runlist 484 # Check if we need to consider an input runlist
454 if len(self._runs): 485 if len(self._runs):
455 486
@@ -467,9 +498,9 @@ class csiactcopy(ctools.cscript): @@ -467,9 +498,9 @@ class csiactcopy(ctools.cscript):
467 498
468 # Add file size 499 # Add file size
469 if has_size and newlen > oldlen: 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 else: 504 else:
474 # Get filename 505 # Get filename
475 fname = os.path.join(os.path.dirname(remote_hdu), 506 fname = os.path.join(os.path.dirname(remote_hdu),
@@ -482,48 +513,48 @@ class csiactcopy(ctools.cscript): @@ -482,48 +513,48 @@ class csiactcopy(ctools.cscript):
482 513
483 # Add file size 514 # Add file size
484 if has_size and newlen > oldlen: 515 if has_size and newlen > oldlen:
485 - cp_size += table["SIZE"][row] 516 + cp_size += table['SIZE'][row]
486 517
487 # Log file information 518 # Log file information
488 if self._logTerse(): 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 self._log(str(len(files))) 523 self._log(str(len(files)))
493 - self._log("\n") 524 + self._log('\n')
494 if has_size: 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 if self._logVerbose(): 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 for filename in files: 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 fits.close() 536 fits.close()
506 537
507 # If prodname is not found just log that we skip the config 538 # If prodname is not found just log that we skip the config
508 else: 539 else:
509 if self._logExplicit(): 540 if self._logExplicit():
510 - self._log("\n") 541 + self._log('\n')
511 self._log.header3('Skipping config "'+ 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 if not has_prod: 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 for config in configs: 550 for config in configs:
520 - msg += " - "+config["name"]+"\n" 551 + msg += ' - '+config['name']+'\n'
521 raise RuntimeError(msg) 552 raise RuntimeError(msg)
522 - 553 +
523 # Logging 554 # Logging
524 if self._logNormal(): 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 # intialise counter 559 # intialise counter
529 k = 0 560 k = 0
@@ -549,9 +580,9 @@ class csiactcopy(ctools.cscript): @@ -549,9 +580,9 @@ class csiactcopy(ctools.cscript):
549 fraction = float(k) / float(len(files)) * 100.0 580 fraction = float(k) / float(len(files)) * 100.0
550 while fraction > last_fraction: 581 while fraction > last_fraction:
551 if self._logNormal() and not self._logVerbose(): 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 last_fraction += fraction_increment 586 last_fraction += fraction_increment
556 587
557 # Copy file 588 # Copy file
@@ -566,12 +597,12 @@ class csiactcopy(ctools.cscript): @@ -566,12 +597,12 @@ class csiactcopy(ctools.cscript):
566 597
567 # Logging 598 # Logging
568 if self._logNormal() and not self._logVerbose(): 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 if self._logTerse(): 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 # Build local index file names 607 # Build local index file names
577 local_hdu = os.path.join(self._outpath, 608 local_hdu = os.path.join(self._outpath,
@@ -586,18 +617,18 @@ class csiactcopy(ctools.cscript): @@ -586,18 +617,18 @@ class csiactcopy(ctools.cscript):
586 617
587 # Logging 618 # Logging
588 if self._logTerse(): 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 # Merge remote index files with local files 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 if self._logTerse(): 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 # Merge remote index files with local files 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 else: 633 else:
603 # If all files were copied, just copy index files too 634 # If all files were copied, just copy index files too
@@ -605,11 +636,11 @@ class csiactcopy(ctools.cscript): @@ -605,11 +636,11 @@ class csiactcopy(ctools.cscript):
605 self._copy(remote_obs, self._clobber()) 636 self._copy(remote_obs, self._clobber())
606 637
607 if self._logTerse(): 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 # Adding prodname to local master 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 # If no local master is found, copy master over first 645 # If no local master is found, copy master over first
615 if not os.path.isfile(localmaster): 646 if not os.path.isfile(localmaster):
@@ -618,7 +649,7 @@ class csiactcopy(ctools.cscript): @@ -618,7 +649,7 @@ class csiactcopy(ctools.cscript):
618 # Load local master 649 # Load local master
619 json_data = open(localmaster).read() 650 json_data = open(localmaster).read()
620 data = json.loads(json_data) 651 data = json.loads(json_data)
621 - configs = data["datasets"] 652 + configs = data['datasets']
622 653
623 # Initialise flag indicating if we already have prodname in master 654 # Initialise flag indicating if we already have prodname in master
624 # file 655 # file
@@ -631,66 +662,66 @@ class csiactcopy(ctools.cscript): @@ -631,66 +662,66 @@ class csiactcopy(ctools.cscript):
631 for config in configs: 662 for config in configs:
632 663
633 # Get hdu and obs index files 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 # Check if index files are available 668 # Check if index files are available
638 if not (gammalib.GFilename(str(hdu)).is_fits() and 669 if not (gammalib.GFilename(str(hdu)).is_fits() and
639 gammalib.GFilename(str(obs)).is_fits()): 670 gammalib.GFilename(str(obs)).is_fits()):
640 if self._logTerse(): 671 if self._logTerse():
641 - self._log('Removing "'+str(config["name"])+'" ') 672 + self._log('Removing "'+str(config['name'])+'" ')
642 self._log('(not available)') 673 self._log('(not available)')
643 self._log('\n') 674 self._log('\n')
644 else: 675 else:
645 # Append config if valid 676 # Append config if valid
646 newconfigs.append(config) 677 newconfigs.append(config)
647 if self._logTerse(): 678 if self._logTerse():
648 - self._log('Keeping "'+str(config["name"])+'"') 679 + self._log('Keeping "'+str(config['name'])+'"')
649 self._log('\n') 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 has_config = True 684 has_config = True
654 685
655 # Create new entry if config was not available 686 # Create new entry if config was not available
656 if not has_config: 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 newconfigs.append(newdict) 692 newconfigs.append(newdict)
662 if self._logTerse(): 693 if self._logTerse():
663 - self._log('Adding "'+str(newdict["name"])+'"') 694 + self._log('Adding "'+str(newdict['name'])+'"')
664 self._log('\n') 695 self._log('\n')
665 696
666 # Write new json master file 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 json.dump(data, f, indent=2) 700 json.dump(data, f, indent=2)
670 - f.close() 701 + f.close()
671 702
672 # Log summary 703 # Log summary
673 if self._logNormal(): 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 self._log(str(len(files))) 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 self._log(str(n_copied)) 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 self._log(str(len(newconfigs))) 717 self._log(str(len(newconfigs)))
687 - self._log("\n") 718 + self._log('\n')
688 if self._logTerse(): 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 for config in newconfigs: 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 # Return 726 # Return
696 return 727 return
cscripts/csiactdata.py
@@ -18,11 +18,11 @@ @@ -18,11 +18,11 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
21 -import gammalib  
22 -import ctools  
23 import sys 21 import sys
24 import os 22 import os
25 import json 23 import json
  24 +import gammalib
  25 +import ctools
26 26
27 27
28 # ================ # 28 # ================ #
@@ -30,7 +30,7 @@ import json @@ -30,7 +30,7 @@ import json
30 # ================ # 30 # ================ #
31 class csiactdata(ctools.cscript): 31 class csiactdata(ctools.cscript):
32 """ 32 """
33 - Inspect an IACT data storage. 33 + Inspect an IACT data storage
34 34
35 This script inspects the available FITS data storage on the user machine 35 This script inspects the available FITS data storage on the user machine
36 and writes information about the available FITS configurations into a log 36 and writes information about the available FITS configurations into a log
@@ -44,12 +44,12 @@ class csiactdata(ctools.cscript): @@ -44,12 +44,12 @@ class csiactdata(ctools.cscript):
44 Constructor. 44 Constructor.
45 """ 45 """
46 # Set name 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 self._prodnames = [] 50 self._prodnames = []
51 - self._master_indx = ""  
52 - self._master_file = "" 51 + self._master_indx = ''
  52 + self._master_file = ''
53 53
54 # Initialise application by calling the appropriate class 54 # Initialise application by calling the appropriate class
55 # constructor. 55 # constructor.
@@ -62,18 +62,18 @@ class csiactdata(ctools.cscript): @@ -62,18 +62,18 @@ class csiactdata(ctools.cscript):
62 # Private methods 62 # Private methods
63 def _get_parameters(self): 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 # Get datapath if not already set 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 # Expand environment 72 # Expand environment
73 self._datapath = gammalib.expand_env(self._datapath) 73 self._datapath = gammalib.expand_env(self._datapath)
74 74
75 # Get filename of master index file 75 # Get filename of master index file
76 - self._master_indx = self["master_indx"].string() 76 + self._master_indx = self['master_indx'].string()
77 self._master_file = os.path.join(self._datapath, self._master_indx) 77 self._master_file = os.path.join(self._datapath, self._master_indx)
78 78
79 # Check for presence of master index file 79 # Check for presence of master index file
@@ -86,7 +86,7 @@ class csiactdata(ctools.cscript): @@ -86,7 +86,7 @@ class csiactdata(ctools.cscript):
86 # Write input parameters into logger 86 # Write input parameters into logger
87 if self._logTerse(): 87 if self._logTerse():
88 self._log_parameters() 88 self._log_parameters()
89 - self._log("\n") 89 + self._log('\n')
90 90
91 # Return 91 # Return
92 return 92 return
@@ -94,28 +94,28 @@ class csiactdata(ctools.cscript): @@ -94,28 +94,28 @@ class csiactdata(ctools.cscript):
94 # Log configuration 94 # Log configuration
95 def _log_configuration(self, config): 95 def _log_configuration(self, config):
96 """ 96 """
97 - Log configuration. 97 + Log configuration
98 """ 98 """
99 # Log information 99 # Log information
100 if self._logTerse(): 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 # Print additional information 112 # Print additional information
113 for key in config: 113 for key in config:
114 - if key in ["name","hduindx","obsindx"]: 114 + if key in ['name','hduindx','obsindx']:
115 continue 115 continue
116 self._log.parformat(str(key)) 116 self._log.parformat(str(key))
117 self._log(str(config[key])) 117 self._log(str(config[key]))
118 - self._log("\n") 118 + self._log('\n')
119 119
120 # Return 120 # Return
121 return 121 return
@@ -124,7 +124,7 @@ class csiactdata(ctools.cscript): @@ -124,7 +124,7 @@ class csiactdata(ctools.cscript):
124 # Public methods 124 # Public methods
125 def run(self): 125 def run(self):
126 """ 126 """
127 - Run the script. 127 + Run the script
128 """ 128 """
129 # Switch screen logging on in debug mode 129 # Switch screen logging on in debug mode
130 if self._logDebug(): 130 if self._logDebug():
@@ -135,39 +135,39 @@ class csiactdata(ctools.cscript): @@ -135,39 +135,39 @@ class csiactdata(ctools.cscript):
135 135
136 # Write header into logger 136 # Write header into logger
137 if self._logTerse(): 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 self._log(self._master_file) 141 self._log(self._master_file)
142 - self._log("\n") 142 + self._log('\n')
143 143
144 # Open and load JSON file 144 # Open and load JSON file
145 json_data = open(self._master_file).read() 145 json_data = open(self._master_file).read()
146 data = json.loads(json_data) 146 data = json.loads(json_data)
147 - configs = data["datasets"] 147 + configs = data['datasets']
148 148
149 # Initialise array for available names 149 # Initialise array for available names
150 self._prodnames = [] 150 self._prodnames = []
151 151
152 # Write header into logger 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 # Loop over configs and log available configs 156 # Loop over configs and log available configs
157 for config in configs: 157 for config in configs:
158 158
159 # Create hdu and obs index files 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 # If index files are available then log configuration 165 # If index files are available then log configuration
166 # information ... 166 # information ...
167 if (filename_hdu.is_fits() and filename_obs.is_fits()): 167 if (filename_hdu.is_fits() and filename_obs.is_fits()):
168 168
169 # Append to available names 169 # Append to available names
170 - self._prodnames.append(str(config["name"])) 170 + self._prodnames.append(str(config['name']))
171 171
172 # Log information 172 # Log information
173 self._log_configuration(config) 173 self._log_configuration(config)
@@ -175,15 +175,15 @@ class csiactdata(ctools.cscript): @@ -175,15 +175,15 @@ class csiactdata(ctools.cscript):
175 # ... otherwise log that the configuration is not available 175 # ... otherwise log that the configuration is not available
176 else: 176 else:
177 if self._logTerse(): 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 # Return 181 # Return
182 return 182 return
183 183
184 def execute(self): 184 def execute(self):
185 """ 185 """
186 - Execute the script. 186 + Execute the script
187 """ 187 """
188 # Open logfile 188 # Open logfile
189 self.logFileOpen() 189 self.logFileOpen()
@@ -198,11 +198,12 @@ class csiactdata(ctools.cscript): @@ -198,11 +198,12 @@ class csiactdata(ctools.cscript):
198 """ 198 """
199 Return available FITS production names 199 Return available FITS production names
200 200
201 - Returns: 201 + Returns
  202 + -------
  203 + names : list of str
202 List of available FITS production names. 204 List of available FITS production names.
203 """ 205 """
204 -  
205 - # Return 206 + # Return
206 return self._prodnames 207 return self._prodnames
207 208
208 209
cscripts/csiactobs.par
@@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
18 # Input and output parameters 18 # Input and output parameters
19 #============================ 19 #============================
20 datapath, s, a, $VHEFITS,,, "Path were data is located" 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 infile, f, a, runlist.lis,,, "Input runlist file" 22 infile, f, a, runlist.lis,,, "Input runlist file"
23 inmodel, f, h, NONE,,, "Input model definition XML file (optional)" 23 inmodel, f, h, NONE,,, "Input model definition XML file (optional)"
24 master_indx, s, h, master.json,,, "Input master index file" 24 master_indx, s, h, master.json,,, "Input master index file"
cscripts/csiactobs.py
@@ -18,11 +18,11 @@ @@ -18,11 +18,11 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
21 -import gammalib  
22 -import ctools  
23 import sys 21 import sys
24 import os 22 import os
25 import json 23 import json
  24 +import gammalib
  25 +import ctools
26 26
27 27
28 # =============== # 28 # =============== #
@@ -30,7 +30,7 @@ import json @@ -30,7 +30,7 @@ import json
30 # =============== # 30 # =============== #
31 class csiactobs(ctools.cscript): 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 This class implements the creation of a observation xml file for IACT 35 This class implements the creation of a observation xml file for IACT
36 data analysis. This class is dedicated for use inside a IACT 36 data analysis. This class is dedicated for use inside a IACT
@@ -46,14 +46,14 @@ class csiactobs(ctools.cscript): @@ -46,14 +46,14 @@ class csiactobs(ctools.cscript):
46 Constructor. 46 Constructor.
47 """ 47 """
48 # Set name and version 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 # Initialise some members 52 # Initialise some members
53 self._ebounds = gammalib.GEbounds() 53 self._ebounds = gammalib.GEbounds()
54 - self._datapath = os.getenv("VHEFITS","") 54 + self._datapath = os.getenv('VHEFITS','')
55 self._inmodels = gammalib.GModels() 55 self._inmodels = gammalib.GModels()
56 - self._prodname = "" 56 + self._prodname = ''
57 self._xml = gammalib.GXml() 57 self._xml = gammalib.GXml()
58 self._models = gammalib.GModels() 58 self._models = gammalib.GModels()
59 self._runlist = [] 59 self._runlist = []
@@ -61,23 +61,23 @@ class csiactobs(ctools.cscript): @@ -61,23 +61,23 @@ class csiactobs(ctools.cscript):
61 self._bkgpars = 0 61 self._bkgpars = 0
62 self._outmodel = gammalib.GFilename() 62 self._outmodel = gammalib.GFilename()
63 self._outobs = gammalib.GFilename() 63 self._outobs = gammalib.GFilename()
64 - self._master_indx = "" 64 + self._master_indx = ''
65 self._use_bkg_scale = False 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 self._bkg_gauss_norm = 1.0 72 self._bkg_gauss_norm = 1.0
73 self._bkg_gauss_index = 0.0 73 self._bkg_gauss_index = 0.0
74 self._bkg_gauss_sigma = 1.0 74 self._bkg_gauss_sigma = 1.0
75 self._bkg_aeff_index = 0.0 75 self._bkg_aeff_index = 0.0
76 self._bkg_aeff_norm = 1.0 76 self._bkg_aeff_norm = 1.0
77 self._bkg_range_factor = 1.0 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 self._debug = False 81 self._debug = False
82 82
83 # Initialise application by calling the appropriate class 83 # Initialise application by calling the appropriate class
@@ -94,24 +94,24 @@ class csiactobs(ctools.cscript): @@ -94,24 +94,24 @@ class csiactobs(ctools.cscript):
94 Get parameters from parfile and setup the observation. 94 Get parameters from parfile and setup the observation.
95 """ 95 """
96 # Set data path 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 # Check for input models 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 # Expand environment 104 # Expand environment
105 self._datapath = gammalib.expand_env(self._datapath) 105 self._datapath = gammalib.expand_env(self._datapath)
106 106
107 # Read FITS production 107 # Read FITS production
108 - self._prodname = self["prodname"].string() 108 + self._prodname = self['prodname'].string()
109 109
110 # Read runlist file if list not already filled 110 # Read runlist file if list not already filled
111 if len(self._runlist) == 0: 111 if len(self._runlist) == 0:
112 112
113 # Get file name 113 # Get file name
114 - self._runlistfile = self["infile"].filename() 114 + self._runlistfile = self['infile'].filename()
115 115
116 # Read runlist from file 116 # Read runlist from file
117 runfile = open(self._runlistfile.url()) 117 runfile = open(self._runlistfile.url())
@@ -125,73 +125,73 @@ class csiactobs(ctools.cscript): @@ -125,73 +125,73 @@ class csiactobs(ctools.cscript):
125 runfile.close() 125 runfile.close()
126 126
127 # Read number of background parameters 127 # Read number of background parameters
128 - self._bkgpars = self["bkgpars"].integer() 128 + self._bkgpars = self['bkgpars'].integer()
129 129
130 # Output model file 130 # Output model file
131 - self._outmodel = self["outmodel"].filename() 131 + self._outmodel = self['outmodel'].filename()
132 132
133 # Observation outfile 133 # Observation outfile
134 - self._outobs = self["outobs"].filename() 134 + self._outobs = self['outobs'].filename()
135 135
136 # Master index file name 136 # Master index file name
137 - self._master_indx = self["master_indx"].string() 137 + self._master_indx = self['master_indx'].string()
138 138
139 # Read flag for background scaling factor 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 # Read hierarchy of file loading 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 # Read hidden background parameters 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 # Open master index file and look for prodname 158 # Open master index file and look for prodname
159 master_file = os.path.join(self._datapath, self._master_indx) 159 master_file = os.path.join(self._datapath, self._master_indx)
160 if not os.path.isfile(master_file): 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 # Open and load JSON file 163 # Open and load JSON file
164 json_data = open(master_file).read() 164 json_data = open(master_file).read()
165 data = json.loads(json_data) 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 # Get configurations 169 # Get configurations
170 - configs = data["datasets"] 170 + configs = data['datasets']
171 171
172 # Initialise HDUs 172 # Initialise HDUs
173 - self._hdu_index = self._obs_index = "" 173 + self._hdu_index = self._obs_index = ''
174 174
175 # Get HDUs 175 # Get HDUs
176 for config in configs: 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 break 180 break
181 181
182 # Check HDUs 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 if not filename.is_fits(): 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 if self._use_bkg_scale: 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 if filename.is_fits(): 192 if filename.is_fits():
193 fits = gammalib.GFits(self._obs_index) 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 self._use_bkg_scale = False 195 self._use_bkg_scale = False
196 fits.close() 196 fits.close()
197 else: 197 else:
@@ -204,7 +204,7 @@ class csiactobs(ctools.cscript): @@ -204,7 +204,7 @@ class csiactobs(ctools.cscript):
204 # Write input parameters into logger 204 # Write input parameters into logger
205 if self._logTerse(): 205 if self._logTerse():
206 self._log_parameters() 206 self._log_parameters()
207 - self._log("\n") 207 + self._log('\n')
208 208
209 # Return 209 # Return
210 return 210 return
@@ -223,7 +223,7 @@ class csiactobs(ctools.cscript): @@ -223,7 +223,7 @@ class csiactobs(ctools.cscript):
223 except: 223 except:
224 224
225 # raise error if wrong type detected 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 # Return 228 # Return
229 return 229 return
@@ -233,24 +233,24 @@ class csiactobs(ctools.cscript): @@ -233,24 +233,24 @@ class csiactobs(ctools.cscript):
233 # Handle constant spectral model 233 # Handle constant spectral model
234 if index == 0.0 and self._bkgpars <= 1: 234 if index == 0.0 and self._bkgpars <= 1:
235 spec = gammalib.GModelSpectralConst() 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 if self._bkgpars == 0: 239 if self._bkgpars == 0:
240 - spec["Value"].fix() 240 + spec['Value'].fix()
241 else: 241 else:
242 - spec["Value"].free() 242 + spec['Value'].free()
243 243
244 else: 244 else:
245 245
246 # Create power law model 246 # Create power law model
247 if self._bkgpars <= 2: 247 if self._bkgpars <= 2:
248 - e = gammalib.GEnergy(1.0,"TeV") 248 + e = gammalib.GEnergy(1.0,'TeV')
249 spec = gammalib.GModelSpectralPlaw(prefactor, index, e) 249 spec = gammalib.GModelSpectralPlaw(prefactor, index, e)
250 250
251 # Set parameter ranges 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 spec[1].scale(1) 254 spec[1].scale(1)
255 spec[1].min(-5.0) 255 spec[1].min(-5.0)
256 spec[1].max(5.0) 256 spec[1].max(5.0)
@@ -264,25 +264,27 @@ class csiactobs(ctools.cscript): @@ -264,25 +264,27 @@ class csiactobs(ctools.cscript):
264 spec[1].fix() 264 spec[1].fix()
265 else: 265 else:
266 spec[0].free() 266 spec[0].free()
267 - spec[1].free() 267 + spec[1].free()
268 268
269 else: 269 else:
270 270
271 # Create reference powerlaw 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 # Create spectral model and energy values 274 # Create spectral model and energy values
275 spec = gammalib.GModelSpectralNodes() 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 for i in range(bounds.size()): 277 for i in range(bounds.size()):
278 energy = bounds.elogmean(i) 278 energy = bounds.elogmean(i)
279 value = plaw.eval(energy, gammalib.GTime()) 279 value = plaw.eval(energy, gammalib.GTime())
280 spec.append(energy, value) 280 spec.append(energy, value)
281 for par in spec: 281 for par in spec:
282 282
283 - if "Energy" in par.name(): 283 + if 'Energy' in par.name():
284 par.fix() 284 par.fix()
285 - elif "Intensity" in par.name(): 285 + elif 'Intensity' in par.name():
  286 + value = par.value()
  287 + par.scale(value)
286 par.min(value / self._bkg_range_factor) 288 par.min(value / self._bkg_range_factor)
287 par.max(value * self._bkg_range_factor) 289 par.max(value * self._bkg_range_factor)
288 290
@@ -292,7 +294,7 @@ class csiactobs(ctools.cscript): @@ -292,7 +294,7 @@ class csiactobs(ctools.cscript):
292 def _iact_background(self, telescope, obs_id, bkg_scale, bkgtype, emin=0.01, emax=100): 294 def _iact_background(self, telescope, obs_id, bkg_scale, bkgtype, emin=0.01, emax=100):
293 295
294 # handle IrfBackground 296 # handle IrfBackground
295 - if bkgtype == "irf": 297 + if bkgtype == 'irf':
296 prefactor = 1.0 298 prefactor = 1.0
297 index = 0.0 299 index = 0.0
298 prefactor *= bkg_scale 300 prefactor *= bkg_scale
@@ -302,7 +304,7 @@ class csiactobs(ctools.cscript): @@ -302,7 +304,7 @@ class csiactobs(ctools.cscript):
302 bck = gammalib.GCTAModelIrfBackground(spec) 304 bck = gammalib.GCTAModelIrfBackground(spec)
303 305
304 # Set AeffBackground 306 # Set AeffBackground
305 - elif bkgtype == "aeff": 307 + elif bkgtype == 'aeff':
306 prefactor = bkg_scale * self._bkg_aeff_norm 308 prefactor = bkg_scale * self._bkg_aeff_norm
307 spec = self._background_spectrum(obs_id, prefactor, self._bkg_aeff_index, emin, emax) 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,14 +312,15 @@ class csiactobs(ctools.cscript):
310 bck = gammalib.GCTAModelAeffBackground(spec) 312 bck = gammalib.GCTAModelAeffBackground(spec)
311 313
312 # Set Gaussian Background 314 # Set Gaussian Background
313 - elif bkgtype == "gauss": 315 + elif bkgtype == 'gauss':
314 prefactor = bkg_scale * self._bkg_gauss_norm 316 prefactor = bkg_scale * self._bkg_gauss_norm
315 spec = self._background_spectrum(obs_id, prefactor, self._bkg_gauss_index, emin, emax) 317 spec = self._background_spectrum(obs_id, prefactor, self._bkg_gauss_index, emin, emax)
316 radial = gammalib.GCTAModelRadialGauss(self._bkg_gauss_sigma) 318 radial = gammalib.GCTAModelRadialGauss(self._bkg_gauss_sigma)
317 bck = gammalib.GCTAModelRadialAcceptance(radial, spec) 319 bck = gammalib.GCTAModelRadialAcceptance(radial, spec)
318 320
319 else: 321 else:
320 - sys.exit("Background type \""+self._bkgtype+"\" unsupported") 322 + msg = 'Background type "'+self._bkgtype+'" unsupported'
  323 + raise RuntimeError(msg)
321 324
322 # Copy model 325 # Copy model
323 model = bck.clone() 326 model = bck.clone()
@@ -329,7 +332,7 @@ class csiactobs(ctools.cscript): @@ -329,7 +332,7 @@ class csiactobs(ctools.cscript):
329 model.instruments(telescope) 332 model.instruments(telescope)
330 333
331 # Set name (arbitrary) 334 # Set name (arbitrary)
332 - model.name("bkg_"+str(obs_id)) 335 + model.name('bkg_'+str(obs_id))
333 336
334 # Turn off TS calculation for background model 337 # Turn off TS calculation for background model
335 model.tscalc(False) 338 model.tscalc(False)
@@ -355,13 +358,13 @@ class csiactobs(ctools.cscript): @@ -355,13 +358,13 @@ class csiactobs(ctools.cscript):
355 358
356 # Clear xml file and append an observation list 359 # Clear xml file and append an observation list
357 self._xml.clear() 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 # Log output 364 # Log output
362 if self._logTerse(): 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 # Initialise energy range values for logging 369 # Initialise energy range values for logging
367 self._ebounds.clear() 370 self._ebounds.clear()
@@ -370,21 +373,21 @@ class csiactobs(ctools.cscript): @@ -370,21 +373,21 @@ class csiactobs(ctools.cscript):
370 for obs_id in self._runlist: 373 for obs_id in self._runlist:
371 374
372 # Create selection string 375 # Create selection string
373 - obs_selection = "[OBS_ID=="+str(obs_id)+"]" 376 + obs_selection = '[OBS_ID=='+str(obs_id)+']'
374 377
375 # Open HDU index file 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 # Initialise files and hdu names 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 types = [] 386 types = []
384 formats = [] 387 formats = []
385 for i in range(hduindx_hdu.nrows()): 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 # Handle events 392 # Handle events
390 index = -1 393 index = -1
@@ -394,12 +397,15 @@ class csiactobs(ctools.cscript): @@ -394,12 +397,15 @@ class csiactobs(ctools.cscript):
394 index = formats.index(version) 397 index = formats.index(version)
395 break 398 break
396 if index >= 0: 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 if not gammalib.GFilename(eventfile).is_fits(): 405 if not gammalib.GFilename(eventfile).is_fits():
401 if self._logTerse(): 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 continue 409 continue
404 410
405 # Handle Aeff 411 # Handle Aeff
@@ -410,12 +416,15 @@ class csiactobs(ctools.cscript): @@ -410,12 +416,15 @@ class csiactobs(ctools.cscript):
410 index = formats.index(version) 416 index = formats.index(version)
411 break 417 break
412 if index >= 0: 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 if not gammalib.GFilename(aefffile).is_fits(): 424 if not gammalib.GFilename(aefffile).is_fits():
417 if self._logTerse(): 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 continue 428 continue
420 429
421 # Handle psf 430 # Handle psf
@@ -426,11 +435,15 @@ class csiactobs(ctools.cscript): @@ -426,11 +435,15 @@ class csiactobs(ctools.cscript):
426 index = formats.index(version) 435 index = formats.index(version)
427 break 436 break
428 if index >= 0: 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 if not gammalib.GFilename(psffile).is_fits(): 442 if not gammalib.GFilename(psffile).is_fits():
432 if self._logTerse(): 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 continue 447 continue
435 448
436 # Handle edisp 449 # Handle edisp
@@ -441,12 +454,16 @@ class csiactobs(ctools.cscript): @@ -441,12 +454,16 @@ class csiactobs(ctools.cscript):
441 index = formats.index(version) 454 index = formats.index(version)
442 break 455 break
443 if index >= 0: 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 if not gammalib.GFilename(edispfile).is_fits(): 461 if not gammalib.GFilename(edispfile).is_fits():
447 if self._logTerse(): 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 # Handle background 468 # Handle background
452 index = -1 469 index = -1
@@ -457,14 +474,27 @@ class csiactobs(ctools.cscript): @@ -457,14 +474,27 @@ class csiactobs(ctools.cscript):
457 index = formats.index(version) 474 index = formats.index(version)
458 break 475 break
459 if index >= 0: 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 if self._logTerse(): 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 # Close hdu index file 499 # Close hdu index file
470 hduindx.close() 500 hduindx.close()
@@ -472,15 +502,15 @@ class csiactobs(ctools.cscript): @@ -472,15 +502,15 @@ class csiactobs(ctools.cscript):
472 # Handle background scale information if available 502 # Handle background scale information if available
473 bkg_scale = 1.0 503 bkg_scale = 1.0
474 if self._use_bkg_scale: 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 obsindx.close() 507 obsindx.close()
478 508
479 # Open fits file to determine the observation name 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 # Close FITS file 515 # Close FITS file
486 fits.close() 516 fits.close()
@@ -490,65 +520,71 @@ class csiactobs(ctools.cscript): @@ -490,65 +520,71 @@ class csiactobs(ctools.cscript):
490 aeff_table = aeff_fits[aeffhdu] 520 aeff_table = aeff_fits[aeffhdu]
491 521
492 # Set energy range from header keyword if present 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 # Get safe energy range 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 # Append to ebounds 529 # Append to ebounds
500 self._ebounds.append(run_emin, run_emax) 530 self._ebounds.append(run_emin, run_emax)
501 531
502 else: 532 else:
503 # Set default values for energy range 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 # Close Aeff fits file 537 # Close Aeff fits file
508 aeff_fits.close() 538 aeff_fits.close()
509 539
510 # Append instrumental background model 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 # Logging 548 # Logging
514 if self._logTerse(): 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 if self._logExplicit(): 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 if self._use_bkg_scale: 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 # Append observation to XML and set attributes 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 # Append event file 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 # Append effective area 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 # Append PSF 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 # Append energy dispersion 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 # Append background 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 # assign events and IRFs to observation 589 # assign events and IRFs to observation
554 obs.append(ev) 590 obs.append(ev)
@@ -562,35 +598,35 @@ class csiactobs(ctools.cscript): @@ -562,35 +598,35 @@ class csiactobs(ctools.cscript):
562 598
563 # Log header of energy range 599 # Log header of energy range
564 if self._logTerse(): 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 # Logging if energy range is available 604 # Logging if energy range is available
569 if self._ebounds.size() > 0: 605 if self._ebounds.size() > 0:
570 606
571 # Write energy range into log file 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 else: 611 else:
576 612
577 # Write 'not available' into log file 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 else: 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 # Append models provided by 'inmodels' if necessary 620 # Append models provided by 'inmodels' if necessary
585 if not self._inmodels == None: 621 if not self._inmodels == None:
586 if self._logTerse(): 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 # Loop over input models 626 # Loop over input models
591 for model in self._inmodels: 627 for model in self._inmodels:
592 if self._logTerse(): 628 if self._logTerse():
593 - self._log.header3("Adding model \""+model.name()+"\"") 629 + self._log.header3('Adding model "'+model.name()+'"')
594 self._models.append(model) 630 self._models.append(model)
595 631
596 # Return 632 # Return
@@ -598,7 +634,7 @@ class csiactobs(ctools.cscript): @@ -598,7 +634,7 @@ class csiactobs(ctools.cscript):
598 634
599 def execute(self): 635 def execute(self):
600 """ 636 """
601 - Execute the script. 637 + Execute the script
602 """ 638 """
603 # Open logfile 639 # Open logfile
604 self.logFileOpen() 640 self.logFileOpen()
@@ -613,7 +649,9 @@ class csiactobs(ctools.cscript): @@ -613,7 +649,9 @@ class csiactobs(ctools.cscript):
613 return 649 return
614 650
615 def save(self): 651 def save(self):
616 - 652 + """
  653 + Save model definition XML file
  654 + """
617 # Save observation XML file 655 # Save observation XML file
618 self._xml.save(self._outobs) 656 self._xml.save(self._outobs)
619 657
@@ -625,8 +663,9 @@ class csiactobs(ctools.cscript): @@ -625,8 +663,9 @@ class csiactobs(ctools.cscript):
625 663
626 def ebounds(self): 664 def ebounds(self):
627 """ 665 """
628 - Returns runlist energy range 666 + Return runlist energy boundaries
629 """ 667 """
  668 + # Return energy boundaries
630 return self._ebounds 669 return self._ebounds
631 670
632 def obs(self): 671 def obs(self):
cscripts/cslightcrv.py
@@ -18,9 +18,9 @@ @@ -18,9 +18,9 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
  21 +import sys
21 import gammalib 22 import gammalib
22 import ctools 23 import ctools
23 -import sys  
24 24
25 25
26 # ================ # 26 # ================ #
cscripts/csmodelinfo.py
@@ -18,9 +18,9 @@ @@ -18,9 +18,9 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
  21 +import sys
21 import gammalib 22 import gammalib
22 import ctools 23 import ctools
23 -import sys  
24 24
25 25
26 # ================= # 26 # ================= #
@@ -430,10 +430,6 @@ class csmodelinfo(ctools.cscript): @@ -430,10 +430,6 @@ class csmodelinfo(ctools.cscript):
430 """ 430 """
431 Save models to ds9 region file if required 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 # Get output filename in case it was not read ahead 434 # Get output filename in case it was not read ahead
439 self._ds9file = self["ds9file"].filename() 435 self._ds9file = self["ds9file"].filename()
@@ -441,6 +437,11 @@ class csmodelinfo(ctools.cscript): @@ -441,6 +437,11 @@ class csmodelinfo(ctools.cscript):
441 # Check if DS9 file is valid 437 # Check if DS9 file is valid
442 if self._ds9file != "NONE": 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 # Log filename 445 # Log filename
445 if self._logTerse(): 446 if self._logTerse():
446 self._log(gammalib.parformat("DS9 filename")) 447 self._log(gammalib.parformat("DS9 filename"))
cscripts/csmodelmerge.py
@@ -18,10 +18,10 @@ @@ -18,10 +18,10 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
21 -import gammalib  
22 -import ctools  
23 import sys 21 import sys
24 import glob 22 import glob
  23 +import gammalib
  24 +import ctools
25 25
26 26
27 # ================== # 27 # ================== #
@@ -29,7 +29,7 @@ import glob @@ -29,7 +29,7 @@ import glob
29 # ================== # 29 # ================== #
30 class csmodelmerge(ctools.cscript): 30 class csmodelmerge(ctools.cscript):
31 """ 31 """
32 - Merge model definition XML files. 32 + Merge model definition XML files
33 33
34 An arbitrary number of model definition XML files will be merged into 34 An arbitrary number of model definition XML files will be merged into
35 a single model definition XML file. 35 a single model definition XML file.
@@ -41,8 +41,8 @@ class csmodelmerge(ctools.cscript): @@ -41,8 +41,8 @@ class csmodelmerge(ctools.cscript):
41 Constructor. 41 Constructor.
42 """ 42 """
43 # Set name 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 # Initialise class members 47 # Initialise class members
48 self._files = None 48 self._files = None
@@ -59,42 +59,45 @@ class csmodelmerge(ctools.cscript): @@ -59,42 +59,45 @@ class csmodelmerge(ctools.cscript):
59 # Private methods 59 # Private methods
60 def _get_parameters(self): 60 def _get_parameters(self):
61 """ 61 """
62 - Get parameters from parfile. 62 + Get parameters from parfile
63 """ 63 """
64 # Get input models string 64 # Get input models string
65 - inmodels = self["inmodels"].string() 65 + inmodels = self['inmodels'].string()
66 66
67 # Handle ascii files 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 # Handle wild card strings 71 # Handle wild card strings
72 - elif "*" in inmodels: 72 + elif '*' in inmodels:
73 self._files = glob.glob(inmodels) 73 self._files = glob.glob(inmodels)
74 74
75 # Handle space separated list 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 # Handle semi-colon separated list 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 # Throw exception if input models cannot be decoded 83 # Throw exception if input models cannot be decoded
84 else: 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 # Read ahead output filename 90 # Read ahead output filename
91 if self._read_ahead(): 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 # Write input parameters into logger 97 # Write input parameters into logger
95 if self._logTerse(): 98 if self._logTerse():
96 self._log_parameters() 99 self._log_parameters()
97 - self._log("\n") 100 + self._log('\n')
98 101
99 # Return 102 # Return
100 return 103 return
@@ -103,7 +106,7 @@ class csmodelmerge(ctools.cscript): @@ -103,7 +106,7 @@ class csmodelmerge(ctools.cscript):
103 # Public methods 106 # Public methods
104 def run(self): 107 def run(self):
105 """ 108 """
106 - Run the script. 109 + Run the script
107 """ 110 """
108 # Switch screen logging on in debug mode 111 # Switch screen logging on in debug mode
109 if self._logDebug(): 112 if self._logDebug():
@@ -114,8 +117,8 @@ class csmodelmerge(ctools.cscript): @@ -114,8 +117,8 @@ class csmodelmerge(ctools.cscript):
114 117
115 # Write header 118 # Write header
116 if self._logTerse(): 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 # Initialise model container 123 # Initialise model container
121 self._models = gammalib.GModels() 124 self._models = gammalib.GModels()
@@ -130,23 +133,23 @@ class csmodelmerge(ctools.cscript): @@ -130,23 +133,23 @@ class csmodelmerge(ctools.cscript):
130 if self._logTerse(): 133 if self._logTerse():
131 nmodels = models.size() 134 nmodels = models.size()
132 if nmodels == 0: 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 elif nmodels == 1: 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 else: 139 else:
137 - self._log(gammalib.parformat("Add %d models from file" % 140 + self._log(gammalib.parformat('Add %d models from file' %
138 nmodels)) 141 nmodels))
139 self._log(file_) 142 self._log(file_)
140 - self._log("\n") 143 + self._log('\n')
141 144
142 # Extend model container by adding all models in the model file 145 # Extend model container by adding all models in the model file
143 self._models.extend(models) 146 self._models.extend(models)
144 147
145 # Log total number of models 148 # Log total number of models
146 if self._logTerse(): 149 if self._logTerse():
147 - self._log(gammalib.parformat("Models after merging")) 150 + self._log(gammalib.parformat('Models after merging'))
148 self._log(self._models.size()) 151 self._log(self._models.size())
149 - self._log("\n") 152 + self._log('\n')
150 153
151 # Return 154 # Return
152 return 155 return
@@ -157,27 +160,35 @@ class csmodelmerge(ctools.cscript): @@ -157,27 +160,35 @@ class csmodelmerge(ctools.cscript):
157 """ 160 """
158 # Write header 161 # Write header
159 if self._logTerse(): 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 # Get output filename in case it was not read ahead 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 # Return 186 # Return
176 return 187 return
177 188
178 def execute(self): 189 def execute(self):
179 """ 190 """
180 - Execute the script. 191 + Execute the script
181 """ 192 """
182 # Open logfile 193 # Open logfile
183 self.logFileOpen() 194 self.logFileOpen()
cscripts/csobs2caldb.py
@@ -18,11 +18,11 @@ @@ -18,11 +18,11 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
21 -import gammalib  
22 -import ctools  
23 import sys 21 import sys
24 import os 22 import os
25 import datetime 23 import datetime
  24 +import gammalib
  25 +import ctools
26 26
27 27
28 # ================= # 28 # ================= #
cscripts/csobsdef.py
@@ -18,9 +18,9 @@ @@ -18,9 +18,9 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
  21 +import sys
21 import gammalib 22 import gammalib
22 import ctools 23 import ctools
23 -import sys  
24 24
25 25
26 # ============== # 26 # ============== #
cscripts/csobsinfo.py
@@ -18,9 +18,9 @@ @@ -18,9 +18,9 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
  21 +import sys
21 import gammalib 22 import gammalib
22 import ctools 23 import ctools
23 -import sys  
24 24
25 25
26 # =============== # 26 # =============== #
@@ -28,7 +28,7 @@ import sys @@ -28,7 +28,7 @@ import sys
28 # =============== # 28 # =============== #
29 class csobsinfo(ctools.cscript): 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 # Constructor 34 # Constructor
@@ -37,8 +37,8 @@ class csobsinfo(ctools.cscript): @@ -37,8 +37,8 @@ class csobsinfo(ctools.cscript):
37 Constructor. 37 Constructor.
38 """ 38 """
39 # Set name 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 # Initialise class members 43 # Initialise class members
44 self._obj_dir = None 44 self._obj_dir = None
@@ -65,31 +65,31 @@ class csobsinfo(ctools.cscript): @@ -65,31 +65,31 @@ class csobsinfo(ctools.cscript):
65 # Private methods 65 # Private methods
66 def _get_parameters(self): 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 # Get parameters 70 # Get parameters
71 if self._obs.size() == 0: 71 if self._obs.size() == 0:
72 - self._require_inobs("csobsinfo::get_parameters") 72 + self._require_inobs('csobsinfo::get_parameters')
73 self._obs = self._get_observations(False) 73 self._obs = self._get_observations(False)
74 74
75 # Initialise object position 75 # Initialise object position
76 self._obj_dir = gammalib.GSkyDir() 76 self._obj_dir = gammalib.GSkyDir()
77 77
78 # Get (optional) offset parameters 78 # Get (optional) offset parameters
79 - self._compute_offset = self["offset"].boolean() 79 + self._compute_offset = self['offset'].boolean()
80 if self._compute_offset: 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 self._obj_dir.radec_deg(ra,dec) 83 self._obj_dir.radec_deg(ra,dec)
84 84
85 # Read ahead DS9 filename 85 # Read ahead DS9 filename
86 if self._read_ahead(): 86 if self._read_ahead():
87 - self["ds9file"].filename() 87 + self['ds9file'].filename()
88 88
89 # Write input parameters into logger 89 # Write input parameters into logger
90 if self._logTerse(): 90 if self._logTerse():
91 self._log_parameters() 91 self._log_parameters()
92 - self._log("\n") 92 + self._log('\n')
93 93
94 # Return 94 # Return
95 return 95 return
@@ -98,7 +98,7 @@ class csobsinfo(ctools.cscript): @@ -98,7 +98,7 @@ class csobsinfo(ctools.cscript):
98 # Public methods 98 # Public methods
99 def run(self): 99 def run(self):
100 """ 100 """
101 - Run the script. 101 + Run the script
102 """ 102 """
103 # Switch screen logging on in debug mode 103 # Switch screen logging on in debug mode
104 if self._logDebug(): 104 if self._logDebug():
@@ -128,23 +128,20 @@ class csobsinfo(ctools.cscript): @@ -128,23 +128,20 @@ class csobsinfo(ctools.cscript):
128 128
129 # Write header 129 # Write header
130 if self._logTerse(): 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 # Loop over observations 134 # Loop over observations
138 for obs in self._obs: 135 for obs in self._obs:
139 136
140 # Skip non-CTA observations 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 continue 140 continue
144 141
145 # Use observed object as observation name if name is not given 142 # Use observed object as observation name if name is not given
146 obs_name = obs.name() 143 obs_name = obs.name()
147 - if obs_name == "": 144 + if obs_name == '':
148 obs_name = obs.object() 145 obs_name = obs.object()
149 146
150 # Logging 147 # Logging
@@ -180,24 +177,24 @@ class csobsinfo(ctools.cscript): @@ -180,24 +177,24 @@ class csobsinfo(ctools.cscript):
180 livetime += obs.livetime() 177 livetime += obs.livetime()
181 178
182 # Bookkeeping 179 # Bookkeeping
183 - if obs.eventtype() == "CountsCube": 180 + if obs.eventtype() == 'CountsCube':
184 n_eventbins += obs.events().size() 181 n_eventbins += obs.events().size()
185 n_obs_binned += 1 182 n_obs_binned += 1
186 if self._logTerse(): 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 self._log(str(obs.events().size())) 187 self._log(str(obs.events().size()))
191 - self._log("\n") 188 + self._log('\n')
192 else: 189 else:
193 n_events += obs.events().size() 190 n_events += obs.events().size()
194 n_obs_unbinned += 1 191 n_obs_unbinned += 1
195 if self._logTerse(): 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 self._log(str(obs.events().size())) 196 self._log(str(obs.events().size()))
200 - self._log("\n") 197 + self._log('\n')
201 198
202 # Retrieve zenith and azimuth and store for later use 199 # Retrieve zenith and azimuth and store for later use
203 zenith = obs.pointing().zenith() 200 zenith = obs.pointing().zenith()
@@ -216,98 +213,98 @@ class csobsinfo(ctools.cscript): @@ -216,98 +213,98 @@ class csobsinfo(ctools.cscript):
216 if self._logTerse(): 213 if self._logTerse():
217 214
218 # Log the observation energy range (if available) 215 # Log the observation energy range (if available)
219 - self._log.parformat("Energy range") 216 + self._log.parformat('Energy range')
220 if obs_bounds.size() == 0: 217 if obs_bounds.size() == 0:
221 - self._log("undefined") 218 + self._log('undefined')
222 else: 219 else:
223 self._log(str(obs_bounds.emin())) 220 self._log(str(obs_bounds.emin()))
224 - self._log(" - ") 221 + self._log(' - ')
225 self._log(str(obs_bounds.emax())) 222 self._log(str(obs_bounds.emax()))
226 - self._log("\n") 223 + self._log('\n')
227 224
228 # Log observation time interval 225 # Log observation time interval
229 - self._log.parformat("Time range (MJD)") 226 + self._log.parformat('Time range (MJD)')
230 if obs_gti.size() == 0: 227 if obs_gti.size() == 0:
231 - self._log("undefined") 228 + self._log('undefined')
232 else: 229 else:
233 self._log(str(obs_gti.tstart().mjd())) 230 self._log(str(obs_gti.tstart().mjd()))
234 - self._log(" - ") 231 + self._log(' - ')
235 self._log(str(obs_gti.tstop().mjd())) 232 self._log(str(obs_gti.tstop().mjd()))
236 - self._log("\n") 233 + self._log('\n')
237 234
238 # Log ontime 235 # Log ontime
239 - self._log.parformat("Ontime") 236 + self._log.parformat('Ontime')
240 self._log(str(obs.ontime())) 237 self._log(str(obs.ontime()))
241 - self._log(" s\n") 238 + self._log(' s\n')
242 239
243 # Log livetime 240 # Log livetime
244 - self._log.parformat("Livetime") 241 + self._log.parformat('Livetime')
245 self._log(str(obs.livetime())) 242 self._log(str(obs.livetime()))
246 - self._log(" s\n") 243 + self._log(' s\n')
247 244
248 # Log dead time fraction 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 # Log pointing direction 250 # Log pointing direction
254 - self._log.parformat("Pointing") 251 + self._log.parformat('Pointing')
255 self._log(str(pnt_dir)) 252 self._log(str(pnt_dir))
256 - self._log("\n") 253 + self._log('\n')
257 254
258 # Optionally log offset with respect to target direction 255 # Optionally log offset with respect to target direction
259 if self._compute_offset: 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 # Log Zenith and Azimuth if required 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 # Log summary 269 # Log summary
273 if self._logTerse(): 270 if self._logTerse():
274 271
275 # Write header 272 # Write header
276 - self._log("\n")  
277 - self._log.header1("Summary") 273 + self._log('\n')
  274 + self._log.header1('Summary')
278 275
279 # Log general summary 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 self._log(str(n_obs_unbinned)) 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 self._log(str(n_obs_binned)) 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 self._log(str(n_events)) 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 self._log(str(n_eventbins)) 289 self._log(str(n_eventbins))
293 - self._log("\n") 290 + self._log('\n')
294 291
295 # Log pointing summary 292 # Log pointing summary
296 - self._log.header3("Pointings") 293 + self._log.header3('Pointings')
297 294
298 # Log mean offset if possible 295 # Log mean offset if possible
299 if self._compute_offset: 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 # Log mean azimuth and zenith angle 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 # Optionally log names of observations. Note that the set class 309 # Optionally log names of observations. Note that the set class
313 # is used to extract all different observation names from the 310 # is used to extract all different observation names from the
@@ -316,84 +313,87 @@ class csobsinfo(ctools.cscript): @@ -316,84 +313,87 @@ class csobsinfo(ctools.cscript):
316 if self._logExplicit() and sys.version_info >= (2,4): 313 if self._logExplicit() and sys.version_info >= (2,4):
317 obs_set = set(obs_names) 314 obs_set = set(obs_names)
318 for name in obs_set: 315 for name in obs_set:
319 - self._log.parformat("\""+name+"\"") 316 + self._log.parformat('"'+name+'"')
320 self._log(str(obs_names.count(name))) 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 # Log energy range 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 if self._ebounds.size() == 0: 324 if self._ebounds.size() == 0:
328 - self._log("undefined") 325 + self._log('undefined')
329 else: 326 else:
330 self._log(str(self._ebounds.emin())) 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 if self._ebounds.size() == 0: 330 if self._ebounds.size() == 0:
334 - self._log("undefined") 331 + self._log('undefined')
335 else: 332 else:
336 self._log(str(self._ebounds.emax())) 333 self._log(str(self._ebounds.emax()))
337 - self._log("\n") 334 + self._log('\n')
338 335
339 # Log time range 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 self._log(str(self._gti.tstart().mjd())) 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 self._log(str(self._gti.tstop().mjd())) 342 self._log(str(self._gti.tstop().mjd()))
346 - self._log("\n") 343 + self._log('\n')
347 344
348 # Log ontime and livetime in different units 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 # Return 355 # Return
357 return 356 return
358 357
359 def save(self): 358 def save(self):
360 """ 359 """
361 - Save pointings into DS9 region file. 360 + Save pointings into DS9 region file
362 361
363 This method saves all pointing directions that are found in the 362 This method saves all pointing directions that are found in the
364 observation container into a DS9 region file. If "NONE" is 363 observation container into a DS9 region file. If "NONE" is
365 specified for the "ds9file" parameter the method does nothing. 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 # Get output filename in case it was not read ahead 367 # Get output filename in case it was not read ahead
373 - ds9file = self["ds9file"].filename() 368 + ds9file = self['ds9file'].filename()
374 369
375 # Check if DS9 file is valid 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 # Log filename 378 # Log filename
379 if self._logTerse(): 379 if self._logTerse():
380 - self._log(gammalib.parformat("DS9 filename")) 380 + self._log(gammalib.parformat('DS9 filename'))
381 self._log(ds9file.url()) 381 self._log(ds9file.url())
382 - self._log("\n") 382 + self._log('\n')
383 383
384 # Open file 384 # Open file
385 - f = open(ds9file.url(),"w") 385 + f = open(ds9file.url(),'w')
386 386
387 # Write coordinate system 387 # Write coordinate system
388 - f.write("fk5\n") 388 + f.write('fk5\n')
389 389
390 # Loop over pointings 390 # Loop over pointings
391 for i in range(len(self._pnt_ra)): 391 for i in range(len(self._pnt_ra)):
392 392
393 # Create string 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 # Write to file 398 # Write to file
399 f.write(line) 399 f.write(line)
cscripts/cspull.py
@@ -18,11 +18,11 @@ @@ -18,11 +18,11 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
  21 +import sys
  22 +import csv
21 import gammalib 23 import gammalib
22 import ctools 24 import ctools
23 from cscripts import obsutils 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,9 +18,9 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
  21 +import sys
21 import gammalib 22 import gammalib
22 import ctools 23 import ctools
23 -import sys  
24 24
25 25
26 # ============== # 26 # ============== #
cscripts/csroot2caldb.py
@@ -21,9 +21,9 @@ @@ -21,9 +21,9 @@
21 import os 21 import os
22 import sys 22 import sys
23 import math 23 import math
  24 +from datetime import datetime
24 import gammalib 25 import gammalib
25 import ctools 26 import ctools
26 -from datetime import datetime  
27 27
28 # Optional ROOT import 28 # Optional ROOT import
29 try: 29 try:
cscripts/cssens.py
@@ -18,12 +18,12 @@ @@ -18,12 +18,12 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 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 import sys 21 import sys
25 import csv 22 import csv
26 import math 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,9 +18,9 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
  21 +import sys
21 import gammalib 22 import gammalib
22 import ctools 23 import ctools
23 -import sys  
24 24
25 25
26 # ============ # 26 # ============ #
cscripts/cstsdist.py
@@ -18,11 +18,11 @@ @@ -18,11 +18,11 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
  21 +import sys
  22 +import csv
21 import gammalib 23 import gammalib
22 import ctools 24 import ctools
23 from cscripts import obsutils 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,11 +18,11 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
21 -import gammalib  
22 -import ctools  
23 import sys 21 import sys
24 import glob 22 import glob
25 import os 23 import os
  24 +import gammalib
  25 +import ctools
26 26
27 27
28 # ================== # 28 # ================== #
cscripts/csworkflow.py
@@ -18,10 +18,10 @@ @@ -18,10 +18,10 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
  21 +import sys
21 import gammalib 22 import gammalib
22 import ctools 23 import ctools
23 import cscripts 24 import cscripts
24 -import sys  
25 25
26 26
27 # ================ # 27 # ================ #
cscripts/lsmodel.py
@@ -18,8 +18,8 @@ @@ -18,8 +18,8 @@
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # 19 #
20 # ========================================================================== 20 # ==========================================================================
21 -import gammalib  
22 import sys 21 import sys
  22 +import gammalib
23 23
24 24
25 # ============= # 25 # ============= #
cscripts/obsutils.py
@@ -19,7 +19,6 @@ @@ -19,7 +19,6 @@
19 # ========================================================================== 19 # ==========================================================================
20 import gammalib 20 import gammalib
21 import ctools 21 import ctools
22 -#import math  
23 22
24 23
25 # ===================== # 24 # ===================== #