Commit 74bcfe43362af53c2d26c0766c6ad4724cb3eb61

Authored by Jürgen Knödlseder
1 parent 7de3c72c

Tune cspull scripts and associated scripts

(still need to remove some debug statements later)
cscripts/cspull.py
... ... @@ -30,22 +30,16 @@ from cscripts import obsutils
30 30 # ============ #
31 31 class cspull(ctools.cscript):
32 32 """
33   - Generates pull distributions for a model.
34   -
35   - This class implements the pull distribution generation script. It derives
36   - from the ctools.cscript class which provides support for parameter
37   - files, command line arguments, and logging. In that way the Python
38   - script behaves just as a regular ctool.
  33 + Generates pull distributions for a model
39 34 """
40   -
41 35 # Constructor
42 36 def __init__(self, *argv):
43 37 """
44 38 Constructor.
45 39 """
46 40 # Set name
47   - self._name = "cspull"
48   - self._version = "1.1.0"
  41 + self._name = 'cspull'
  42 + self._version = '1.1.0'
49 43  
50 44 # Initialise some members
51 45 self._edisp = False
... ... @@ -54,15 +48,15 @@ class cspull(ctools.cscript):
54 48 self._bckcube = None
55 49 self._edispcube = None
56 50 self._stackmodels = None
57   - self._coordsys = "CEL"
58   - self._proj = "TAN"
59   - self._log_clients = False
  51 + self._coordsys = 'CEL'
  52 + self._proj = 'TAN'
  53 + self._log_clients = False # Static parameter
60 54 self._offset = 0.0
61 55 self._ntrials = 0
62 56 self._outfile = gammalib.GFilename()
63 57 self._npix = 0
64 58 self._binsz = 0.0
65   - self._pattern = "single"
  59 + self._pattern = 'single'
66 60 self._enumbins = 0
67 61 self._seed = 1
68 62 self._chatter = 2
... ... @@ -81,7 +75,7 @@ class cspull(ctools.cscript):
81 75 # Private methods
82 76 def _get_parameters(self):
83 77 """
84   - Get parameters from parfile.
  78 + Get parameters from parfile
85 79 """
86 80 # If there are no observations in container then get some ...
87 81 if self._obs.size() == 0:
... ... @@ -89,8 +83,8 @@ class cspull(ctools.cscript):
89 83  
90 84 # Check for requested pattern and use above
91 85 # observation parameters to set wobble pattern
92   - self._pattern = self["pattern"].string()
93   - if self._pattern == "four":
  86 + self._pattern = self['pattern'].string()
  87 + if self._pattern == 'four':
94 88 self._obs = self._set_obs()
95 89  
96 90 # ... otherwise add response information and energy boundaries
... ... @@ -99,153 +93,173 @@ class cspull(ctools.cscript):
99 93 self._setup_observations(self._obs)
100 94  
101 95 # Get number of energy bins
102   - self._enumbins = self["enumbins"].integer()
  96 + self._enumbins = self['enumbins'].integer()
103 97  
104 98 # Read parameters for binned if requested
105 99 if self._enumbins != 0:
106   - self._npix = self["npix"].integer()
107   - self._binsz = self["binsz"].real()
108   - self._coordsys = self["coordsys"].string()
109   - self._proj = self["proj"].string()
  100 + self._npix = self['npix'].integer()
  101 + self._binsz = self['binsz'].real()
  102 + self._coordsys = self['coordsys'].string()
  103 + self._proj = self['proj'].string()
110 104  
111 105 # Set models if we have none
112 106 if self._obs.models().size() == 0:
113   - self._obs.models(self["inmodel"].filename())
  107 + self._obs.models(self['inmodel'].filename())
114 108  
115 109 # Read other parameters
116   - self._outfile = self["outfile"].filename()
117   - self._ntrials = self["ntrials"].integer()
118   - self._edisp = self["edisp"].boolean()
119   - self._offset = self["offset"].real()
120   - self._seed = self["seed"].integer()
121   - self._chatter = self["chatter"].integer()
  110 + self._outfile = self['outfile'].filename()
  111 + self._ntrials = self['ntrials'].integer()
  112 + self._edisp = self['edisp'].boolean()
  113 + self._offset = self['offset'].real()
  114 + self._seed = self['seed'].integer()
  115 + self._chatter = self['chatter'].integer()
122 116  
123 117 # Query some parameters
124   - self["profile"].boolean()
  118 + self['profile'].boolean()
125 119  
126 120 # Write input parameters into logger
127 121 if self._logTerse():
128 122 self._log_parameters()
129   - self._log("\n")
  123 + self._log('\n')
130 124  
131 125 # Return
132 126 return
133 127  
134 128 def _set_obs(self):
135 129 """
136   - Set CTA observation(s).
  130 + Set CTA observation(s)
137 131  
138   - Returns:
139   - An observation container.
  132 + Returns
  133 + -------
  134 + obs : `~gammalib.GObservations`
  135 + Observation container.
140 136 """
141 137 # Setup observation definition list
142 138 obsdeflist = obsutils.set_obs_patterns(self._pattern,
143   - ra=self["ra"].real(),
144   - dec=self["dec"].real(),
145   - offset=self["offset"].real())
  139 + ra=self['ra'].real(),
  140 + dec=self['dec'].real(),
  141 + offset=self['offset'].real())
146 142  
147 143 # Create list of observations
148 144 obs = obsutils.set_obs_list(obsdeflist,
149   - tstart=self["tmin"].real(),
150   - duration=self["tmax"].real()-self["tmin"].real(),
151   - deadc=self["deadc"].real(),
152   - emin=self["emin"].real(),
153   - emax=self["emax"].real(),
154   - rad=self["rad"].real(),
155   - irf=self["irf"].string(),
156   - caldb=self["caldb"].string())
  145 + tstart=self['tmin'].real(),
  146 + duration=self['tmax'].real()-self['tmin'].real(),
  147 + deadc=self['deadc'].real(),
  148 + emin=self['emin'].real(),
  149 + emax=self['emax'].real(),
  150 + rad=self['rad'].real(),
  151 + irf=self['irf'].string(),
  152 + caldb=self['caldb'].string())
157 153  
158 154 # Return observation container
159 155 return obs
160 156  
161 157 def _set_stacked_irf(self):
162 158 """
163   - For stacked analysis prepare stacked irfs
  159 + Prepare stacked IRFs for stacked analysis
164 160 """
165 161 # Write header into logger
166 162 if self._logTerse():
167   - self._log("\n")
168   - self._log.header1("Compute stacked response")
  163 + self._log('\n')
  164 + self._log.header1('Compute stacked response')
169 165  
170 166 # Get stacked exposure
171 167 expcube = ctools.ctexpcube(self._obs)
172   - expcube["incube"] = "NONE"
173   - expcube["usepnt"] = True
174   - expcube["ebinalg"] = "LOG"
175   - expcube["binsz"] = self._binsz
176   - expcube["nxpix"] = self._npix
177   - expcube["nypix"] = self._npix
178   - expcube["enumbins"] = self._enumbins
179   - expcube["emin"] = self["emin"].real()
180   - expcube["emax"] = self["emax"].real()
181   - expcube["coordsys"] = self._coordsys
182   - expcube["proj"] = self._proj
  168 + expcube['incube'] = 'NONE'
  169 + expcube['usepnt'] = True
  170 + expcube['ebinalg'] = 'LOG'
  171 + expcube['binsz'] = self._binsz
  172 + expcube['nxpix'] = self._npix
  173 + expcube['nypix'] = self._npix
  174 + expcube['enumbins'] = self._enumbins
  175 + expcube['emin'] = self['emin'].real()
  176 + expcube['emax'] = self['emax'].real()
  177 + expcube['coordsys'] = self._coordsys
  178 + expcube['proj'] = self._proj
  179 + expcube['chatter'] = self._chatter
  180 + expcube['debug'] = self._logDebug()
183 181 expcube.run()
  182 + # JK: Debug
  183 + expcube['outcube'] = 'expcube.fits'
  184 + expcube.save()
184 185  
185 186 # Notify exposure computation
186 187 if self._logTerse():
187   - self._log("Computed exposure cube\n")
  188 + self._log('Computed exposure cube\n')
188 189  
189 190 # Get stacked Psf
190 191 psfcube = ctools.ctpsfcube(self._obs)
191   - psfcube["incube"] = "NONE"
192   - psfcube["usepnt"] = True
193   - psfcube["ebinalg"] = "LOG"
194   - psfcube["binsz"] = self._binsz*10.0
195   - psfcube["nxpix"] = self._npix/10
196   - psfcube["nypix"] = self._npix/10
197   - psfcube["enumbins"] = self._enumbins
198   - psfcube["emin"] = self["emin"].real()
199   - psfcube["emax"] = self["emax"].real()
200   - psfcube["coordsys"] = self._coordsys
201   - psfcube["proj"] = self._proj
  192 + psfcube['incube'] = 'NONE'
  193 + psfcube['usepnt'] = True
  194 + psfcube['ebinalg'] = 'LOG'
  195 + psfcube['binsz'] = self._binsz*10.0
  196 + psfcube['nxpix'] = self._npix/10
  197 + psfcube['nypix'] = self._npix/10
  198 + psfcube['enumbins'] = self._enumbins
  199 + psfcube['emin'] = self['emin'].real()
  200 + psfcube['emax'] = self['emax'].real()
  201 + psfcube['coordsys'] = self._coordsys
  202 + psfcube['proj'] = self._proj
  203 + psfcube['chatter'] = self._chatter
  204 + psfcube['debug'] = self._logDebug()
202 205 psfcube.run()
  206 + # JK: Debug
  207 + psfcube['outcube'] = 'psfcube.fits'
  208 + psfcube.save()
203 209  
204 210 # Notify Psf computation
205 211 if self._logTerse():
206   - self._log("Computed point spread function cube\n")
  212 + self._log('Computed point spread function cube\n')
207 213  
208 214 # Optionally get stacked Edisp
209 215 if self._edisp:
210 216 edispcube = ctools.ctedispcube(self._obs)
211   - edispcube["incube"] = "NONE"
212   - edispcube["usepnt"] = True
213   - edispcube["ebinalg"] = "LOG"
214   - edispcube["binsz"] = self._binsz*10.0
215   - edispcube["nxpix"] = self._npix/10
216   - edispcube["nypix"] = self._npix/10
217   - edispcube["enumbins"] = self._enumbins
218   - edispcube["emin"] = self["emin"].real()
219   - edispcube["emax"] = self["emax"].real()
220   - edispcube["coordsys"] = self._coordsys
221   - edispcube["proj"] = self._proj
222   - edispcube.run()
  217 + edispcube['incube'] = 'NONE'
  218 + edispcube['usepnt'] = True
  219 + edispcube['ebinalg'] = 'LOG'
  220 + edispcube['binsz'] = self._binsz*10.0
  221 + edispcube['nxpix'] = self._npix/10
  222 + edispcube['nypix'] = self._npix/10
  223 + edispcube['enumbins'] = self._enumbins
  224 + edispcube['emin'] = self['emin'].real()
  225 + edispcube['emax'] = self['emax'].real()
  226 + edispcube['coordsys'] = self._coordsys
  227 + edispcube['proj'] = self._proj
  228 + edispcube['chatter'] = self._chatter
  229 + edispcube['debug'] = self._logDebug()
  230 + edispcube.run()
223 231  
224 232 # Store result
225 233 self._edispcube = edispcube.edispcube().copy()
226 234  
227 235 # Logging
228 236 if self._logTerse():
229   - self._log("Computed energy dispersion cube\n")
  237 + self._log('Computed energy dispersion cube\n')
230 238  
231 239 # Get stacked background
232 240 bkgcube = ctools.ctbkgcube(self._obs)
233   - bkgcube["incube"] = "NONE"
234   - bkgcube["usepnt"] = True
235   - bkgcube["ebinalg"] = "LOG"
236   - bkgcube["binsz"] = self._binsz
237   - bkgcube["nxpix"] = self._npix
238   - bkgcube["nypix"] = self._npix
239   - bkgcube["enumbins"] = self._enumbins
240   - bkgcube["emin"] = self["emin"].real()
241   - bkgcube["emax"] = self["emax"].real()
242   - bkgcube["coordsys"] = self._coordsys
243   - bkgcube["proj"] = self._proj
  241 + bkgcube['incube'] = 'NONE'
  242 + bkgcube['usepnt'] = True
  243 + bkgcube['ebinalg'] = 'LOG'
  244 + bkgcube['binsz'] = self._binsz
  245 + bkgcube['nxpix'] = self._npix
  246 + bkgcube['nypix'] = self._npix
  247 + bkgcube['enumbins'] = self._enumbins
  248 + bkgcube['emin'] = self['emin'].real()
  249 + bkgcube['emax'] = self['emax'].real()
  250 + bkgcube['coordsys'] = self._coordsys
  251 + bkgcube['proj'] = self._proj
  252 + bkgcube['chatter'] = self._chatter
  253 + bkgcube['debug'] = self._logDebug()
244 254 bkgcube.run()
  255 + # JK: Debug
  256 + bkgcube['outcube'] = 'bkgcube.fits'
  257 + bkgcube['outmodel'] = 'cube_model.xml'
  258 + bkgcube.save()
245 259  
246 260 # Notify background cube computation
247 261 if self._logTerse():
248   - self._log("Computed background cube\n")
  262 + self._log('Computed background cube\n')
249 263  
250 264 # Store results
251 265 self._exposure = expcube.expcube().copy()
... ... @@ -256,19 +270,63 @@ class cspull(ctools.cscript):
256 270 # Return
257 271 return
258 272  
259   - def _trial(self, seed):
  273 + def _obs_string(self, obs):
260 274 """
261   - Compute the pull for a single trial.
  275 + Generate summary string for observation
  276 +
  277 + Parameters
  278 + ----------
  279 + obs : `~gammalib.GCTAObservation`
  280 + Observation
262 281  
263   - Args:
264   - seed: Random number generator seed.
  282 + Returns
  283 + -------
  284 + text : str
  285 + Summary string
  286 + """
  287 + # Extract information from observation
  288 + emin = obs.events().ebounds().emin().TeV()
  289 + emax = obs.events().ebounds().emax().TeV()
  290 + events = obs.events().number()
  291 + binned = (obs.events().classname() == 'GCTAEventCube')
  292 + if binned:
  293 + mode = 'binned'
  294 + else:
  295 + mode = 'unbinned'
  296 +
  297 + # Compose summary string
  298 + if events > 0:
  299 + text = '%d events, %.3f-%.3f TeV, %s' % (events, emin, emax, mode)
  300 + else:
  301 + text = '%.3f-%.3f TeV, %s' % (emin, emax, mode)
  302 +
  303 + # Return summary string
  304 + return text
  305 +
  306 + def _trial(self, seed, stacked):
  307 + """
  308 + Compute the pull for a single trial
  309 +
  310 + Parameters
  311 + ----------
  312 + seed : int
  313 + Random number generator seed
  314 + stacked : bool
  315 + Use stacked analysis
  316 +
  317 + Returns
  318 + -------
  319 + result : dict
  320 + Dictionary of results
265 321 """
266 322 # Write header
267 323 if self._logNormal():
268   - self._log.header2("Trial "+str(seed+1))
  324 + self._log.header2('Trial '+str(seed-self._seed+1))
269 325  
270 326 # Simulate events
271 327 obs = obsutils.sim(self._obs,
  328 + emin=self['emin'].real(),
  329 + emax=self['emax'].real(),
272 330 nbins=self._enumbins,
273 331 seed=seed,
274 332 binsz=self._binsz,
... ... @@ -281,7 +339,7 @@ class cspull(ctools.cscript):
281 339 chatter=self._chatter)
282 340  
283 341 # Set response for a stacked observation
284   - if self._obs.size() > 1 and self._enumbins > 0:
  342 + if stacked:
285 343 if self._edisp:
286 344 obs[0].response(self._exposure, self._psfcube,
287 345 self._edispcube, self._bckcube)
... ... @@ -289,6 +347,8 @@ class cspull(ctools.cscript):
289 347 obs[0].response(self._exposure, self._psfcube,
290 348 self._bckcube)
291 349 obs.models(self._stackmodels)
  350 + # JK: Test
  351 + obs[0].save('stacked_cube.fits', True)
292 352  
293 353 # Determine number of events in simulation
294 354 nevents = 0.0
... ... @@ -297,13 +357,21 @@ class cspull(ctools.cscript):
297 357  
298 358 # Write simulation results
299 359 if self._logNormal():
300   - self._log.header3("Simulation")
301   - self._log.parformat("Number of simulated events")
  360 + self._log.header3('Simulation')
  361 + for run in self._obs:
  362 + self._log.parformat('Input observation %s' % (run.id()))
  363 + self._log(self._obs_string(run))
  364 + self._log('\n')
  365 + for run in obs:
  366 + self._log.parformat('Output observation %s' % (run.id()))
  367 + self._log(self._obs_string(run))
  368 + self._log('\n')
  369 + self._log.parformat('Number of simulated events')
302 370 self._log(nevents)
303   - self._log("\n")
  371 + self._log('\n')
304 372  
305 373 # Fit model
306   - if self["profile"].boolean():
  374 + if self['profile'].boolean():
307 375 models = self._obs.models()
308 376 for i in range(models.size()):
309 377 model_name = models[i].name()
... ... @@ -324,17 +392,17 @@ class cspull(ctools.cscript):
324 392  
325 393 # Write result header
326 394 if self._logNormal():
327   - self._log.header3("Pulls")
  395 + self._log.header3('Pulls')
328 396  
329 397 # Gather results
330 398 colnames = []
331 399 values = {}
332   - colnames.append("LogL")
333   - colnames.append("Sim_Events")
334   - colnames.append("Npred_Events")
335   - values["LogL"] = logL
336   - values["Sim_Events"] = nevents
337   - values["Npred_Events"] = npred
  400 + colnames.append('LogL')
  401 + colnames.append('Sim_Events')
  402 + colnames.append('Npred_Events')
  403 + values['LogL'] = logL
  404 + values['Sim_Events'] = nevents
  405 + values['Npred_Events'] = npred
338 406 for i in range(models.size()):
339 407 model = models[i]
340 408 model_name = model.name()
... ... @@ -343,12 +411,12 @@ class cspull(ctools.cscript):
343 411 if par.is_free():
344 412  
345 413 # Set parameter name
346   - name = model_name+"_"+par.name()
  414 + name = model_name+'_'+par.name()
347 415  
348 416 # Append parameter, Pull_parameter and Unc_parameter
349 417 colnames.append(name)
350   - colnames.append("Pull_"+name)
351   - colnames.append("Unc_"+name)
  418 + colnames.append('Pull_'+name)
  419 + colnames.append('Unc_'+name)
352 420  
353 421 # Compute pull
354 422 fitted_value = par.value()
... ... @@ -361,18 +429,18 @@ class cspull(ctools.cscript):
361 429  
362 430 # Store results
363 431 values[name] = fitted_value
364   - values["Pull_"+name] = pull
365   - values["Unc_"+name] = error
  432 + values['Pull_'+name] = pull
  433 + values['Unc_'+name] = error
366 434  
367 435 # Write result
368 436 if self._logNormal():
369 437 self._log.parformat(name)
370 438 self._log(pull)
371   - self._log(" (")
  439 + self._log(' (')
372 440 self._log(fitted_value)
373   - self._log(" +/- ")
  441 + self._log(' +/- ')
374 442 self._log(error)
375   - self._log(")\n")
  443 + self._log(')\n')
376 444  
377 445 # Bundle together results
378 446 result = {'colnames': colnames, 'values': values}
... ... @@ -384,7 +452,7 @@ class cspull(ctools.cscript):
384 452 # Public methods
385 453 def run(self):
386 454 """
387   - Run the script.
  455 + Run the script
388 456 """
389 457 # Switch screen logging on in debug mode
390 458 if self._logDebug():
... ... @@ -395,25 +463,29 @@ class cspull(ctools.cscript):
395 463  
396 464 # Write observation into logger
397 465 if self._logTerse():
398   - self._log("\n")
399   - self._log.header1("Observation(s)")
  466 + self._log('\n')
  467 + self._log.header1(gammalib.number('Observation',len(self._obs)))
400 468 self._log(str(self._obs))
401   - self._log("\n")
  469 + self._log('\n')
  470 +
  471 + # Signal if stacked analysis is requested
  472 + #stacked = self._obs.size() > 1 and self._enumbins > 0
  473 + stacked = self._enumbins > 0
402 474  
403 475 # If several observations and binned: prepare stacked irfs
404   - if self._obs.size() > 1 and self._enumbins > 0:
  476 + if stacked:
405 477 self._set_stacked_irf()
406 478  
407 479 # Write header
408 480 if self._logTerse():
409   - self._log("\n")
410   - self._log.header1("Generate pull distribution")
  481 + self._log('\n')
  482 + self._log.header1('Generate pull distribution')
411 483  
412 484 # Loop over trials
413 485 for seed in range(self._ntrials):
414 486  
415 487 # Make a trial and add initial seed
416   - result = self._trial(seed + self._seed)
  488 + result = self._trial(seed + self._seed, stacked)
417 489  
418 490 # Write out result immediately
419 491 if seed == 0:
... ... @@ -434,7 +506,7 @@ class cspull(ctools.cscript):
434 506  
435 507 def execute(self):
436 508 """
437   - Execute the script.
  509 + Execute the script
438 510 """
439 511 # Open logfile
440 512 self.logFileOpen()
... ... @@ -447,10 +519,15 @@ class cspull(ctools.cscript):
447 519  
448 520 def models(self, models):
449 521 """
450   - Set model.
  522 + Set model
  523 +
  524 + Parameters
  525 + ----------
  526 + models : `~gammalib.GModels`
  527 + Set model container
451 528 """
452   - # Copy models
453   - self.obs.models(models.copy())
  529 + # Set model container
  530 + self._obs.models(models)
454 531  
455 532 # Return
456 533 return
... ...
cscripts/obsutils.py
... ... @@ -24,46 +24,58 @@ import ctools
24 24 # ===================== #
25 25 # Simulate observations #
26 26 # ===================== #
27   -def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, nbins=0,
28   - binsz=0.05, npix=200, proj="TAN", coord="GAL"):
  27 +def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0,
  28 + emin=None, emax=None, nbins=0,
  29 + binsz=0.05, npix=200, proj='TAN', coord='GAL'):
29 30 """
30   - Simulate events for all observations in the container.
31   -
32   - Args:
33   - obs: Observation container without events
34   -
35   - Kwargs:
36   - log: Create log file(s)
37   - debug: Create console dump?
38   - chatter: Chatter level
39   - edisp: Apply energy dispersion?
40   - seed: Seed value for simulations (default: 0)
41   - nbins: Number of energy bins (default: 0=unbinned)
42   - binsz: Pixel size for binned simulation (deg/pixel)
43   - npix: Number of pixels in X and Y for binned simulation
44   - proj: Projection for binned simulation
45   - coord: Coordinate system for binned simulation
46   -
47   - Returns:
48   - Observation container, filled with simulated events.
  31 + Simulate events for all observations in the container
  32 +
  33 + Parameters
  34 + ----------
  35 + obs : `~gammalib.GObservations`
  36 + Observation container without events
  37 + log : bool, optional
  38 + Create log file(s)
  39 + debug : bool, optional
  40 + Create console dump?
  41 + chatter : int, optional
  42 + Chatter level
  43 + edisp : bool, optional
  44 + Apply energy dispersion?
  45 + seed : int, integer
  46 + Seed value for simulations
  47 + emin : float, optional
  48 + Minimum energy of counts cube for binned (TeV)
  49 + emax : float, optional
  50 + Maximum energy of counts cube for binned (TeV)
  51 + nbins : int, optional
  52 + Number of energy bins (0=unbinned)
  53 + binsz : float, optional
  54 + Pixel size for binned simulation (deg/pixel)
  55 + npix : int, optional
  56 + Number of pixels in X and Y for binned simulation
  57 + proj : str, optional
  58 + Projection for binned simulation
  59 + coord : str, optional
  60 + Coordinate system for binned simulation
  61 +
  62 + Returns
  63 + -------
  64 + obs : `~gammalib.GObservations`
  65 + Observation container filled with simulated events
49 66 """
50 67  
51 68 # Allocate ctobssim application and set parameters
52 69 sim = ctools.ctobssim(obs)
53   - sim["seed"] = seed
54   - sim["edisp"] = edisp
  70 + sim['seed'] = seed
  71 + sim['edisp'] = edisp
  72 + sim['chatter'] = chatter
  73 + sim['debug'] = debug
55 74  
56 75 # Optionally open the log file
57 76 if log:
58 77 sim.logFileOpen()
59 78  
60   - # Optionally switch-on debugging model
61   - if debug:
62   - sim["debug"] = True
63   -
64   - # Set chatter level
65   - sim["chatter"] = chatter
66   -
67 79 # Run ctobssim application. This will loop over all observations in the
68 80 # container and simulation the events for each observation. Note that
69 81 # events are not added together, they still apply to each observation
... ... @@ -73,45 +85,42 @@ def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, nbins=0,
73 85 # Binned option?
74 86 if nbins > 0:
75 87  
76   - # Determine common energy boundaries for observations
77   - emin = None
78   - emax = None
79   - for run in sim.obs():
80   - run_emin = run.events().ebounds().emin().TeV()
81   - run_emax = run.events().ebounds().emax().TeV()
82   - if emin == None:
83   - emin = run_emin
84   - elif run_emin > emin:
85   - emin = run_emin
86   - if emax == None:
87   - emax = run_emax
88   - elif run_emax > emax:
89   - emax = run_emax
  88 + # If energy boundaries are not given then determine common energy
  89 + # boundaries for all observations
  90 + if emin == None or emax == None:
  91 + emin = None
  92 + emax = None
  93 + for run in sim.obs():
  94 + run_emin = run.events().ebounds().emin().TeV()
  95 + run_emax = run.events().ebounds().emax().TeV()
  96 + if emin == None:
  97 + emin = run_emin
  98 + elif run_emin > emin:
  99 + emin = run_emin
  100 + if emax == None:
  101 + emax = run_emax
  102 + elif run_emax > emax:
  103 + emax = run_emax
90 104  
91 105 # Allocate ctbin application and set parameters
92 106 bin = ctools.ctbin(sim.obs())
93   - bin["ebinalg"] = "LOG"
94   - bin["emin"] = emin
95   - bin["emax"] = emax
96   - bin["enumbins"] = nbins
97   - bin["usepnt"] = True # Use pointing for map centre
98   - bin["nxpix"] = npix
99   - bin["nypix"] = npix
100   - bin["binsz"] = binsz
101   - bin["coordsys"] = coord
102   - bin["proj"] = proj
  107 + bin['ebinalg'] = 'LOG'
  108 + bin['emin'] = emin
  109 + bin['emax'] = emax
  110 + bin['enumbins'] = nbins
  111 + bin['usepnt'] = True # Use pointing for map centre
  112 + bin['nxpix'] = npix
  113 + bin['nypix'] = npix
  114 + bin['binsz'] = binsz
  115 + bin['coordsys'] = coord
  116 + bin['proj'] = proj
  117 + bin['chatter'] = chatter
  118 + bin['debug'] = debug
103 119  
104 120 # Optionally open the log file
105 121 if log:
106 122 bin.logFileOpen()
107 123  
108   - # Optionally switch-on debugging model
109   - if debug:
110   - bin["debug"] = True
111   -
112   - # Set chatter level
113   - bin["chatter"] = chatter
114   -
115 124 # Run ctbin application. This will loop over all observations in
116 125 # the container and bin the events in counts maps
117 126 bin.run()
... ...
src/ctexpcube/ctexpcube.cpp
... ... @@ -220,12 +220,7 @@ void ctexpcube::run(void)
220 220 // Write observation(s) into logger
221 221 if (logTerse()) {
222 222 log << std::endl;
223   - if (m_obs.size() > 1) {
224   - log.header1("Observations");
225   - }
226   - else {
227   - log.header1("Observation");
228   - }
  223 + log.header1(gammalib::number("Observation",m_obs.size()));
229 224 log << m_obs << std::endl;
230 225 }
231 226  
... ...
src/ctlike/ctlike.cpp
... ... @@ -230,13 +230,8 @@ void ctlike::run(void)
230 230 // Write observation(s) into logger
231 231 if (logTerse()) {
232 232 log << std::endl;
233   - if (m_obs.size() > 1) {
234   - log.header1("Observations");
235   - }
236   - else {
237   - log.header1("Observation");
238   - }
239   - log << m_obs << std::endl;
  233 + log.header1(gammalib::number("Observation",m_obs.size()));
  234 + log << m_obs.print(m_chatter) << std::endl;
240 235 }
241 236  
242 237 // Optimize model parameters using LM optimizer
... ... @@ -311,7 +306,7 @@ void ctlike::run(void)
311 306 if (logTerse()) {
312 307 log << std::endl;
313 308 log.header1("Maximum likelihood optimisation results");
314   - log << *m_opt << std::endl;
  309 + log << m_opt->print(m_chatter) << std::endl;
315 310 log << gammalib::parformat("Maximum log likelihood");
316 311 log << gammalib::str(m_logL,3) << std::endl;
317 312 log << gammalib::parformat("Observed events (Nobs)");
... ... @@ -321,7 +316,7 @@ void ctlike::run(void)
321 316 log << " (Nobs - Npred = ";
322 317 log << gammalib::str(num_events-npred);
323 318 log << ")" << std::endl;
324   - log << m_obs.models() << std::endl;
  319 + log << m_obs.models().print(m_chatter) << std::endl;
325 320 }
326 321  
327 322 // Restore energy dispersion flag for all CTA observations
... ... @@ -430,6 +425,7 @@ void ctlike::get_parameters(void)
430 425 m_refit = (*this)["refit"].boolean();
431 426 m_apply_edisp = (*this)["edisp"].boolean();
432 427 m_fix_spat_for_ts = (*this)["fix_spat_for_ts"].boolean();
  428 + m_chatter = static_cast<GChatter>((*this)["chatter"].integer());
433 429  
434 430 // Optionally read ahead parameters so that they get correctly
435 431 // dumped into the log file
... ... @@ -592,6 +588,7 @@ void ctlike::init_members(void)
592 588 m_opt = NULL;
593 589 m_apply_edisp = false;
594 590 m_fix_spat_for_ts = false;
  591 + m_chatter = static_cast<GChatter>(2);
595 592  
596 593 // Set logger properties
597 594 log.date(true);
... ... @@ -628,6 +625,7 @@ void ctlike::copy_members(const ctlike&amp; app)
628 625 m_opt = app.m_opt->clone();
629 626 m_apply_edisp = app.m_apply_edisp;
630 627 m_fix_spat_for_ts = app.m_fix_spat_for_ts;
  628 + m_chatter = app.m_chatter;
631 629  
632 630 // Return
633 631 return;
... ...
src/ctlike/ctlike.hpp
... ... @@ -77,6 +77,7 @@ protected:
77 77 GFilename m_outmodel; //!< Source model output XML file name
78 78 bool m_apply_edisp; //!< Apply energy dispersion?
79 79 bool m_fix_spat_for_ts; //!< Fix spatial parameters for TS computation?
  80 + GChatter m_chatter; //!< Chattiness
80 81  
81 82 // Members
82 83 GObservations m_obs; //!< Observations
... ...