Commit 04b1443dd9033b392fc1268d25a4e83e4f694df3

Authored by Jürgen Knödlseder
1 parent 4d321317

Adapt ctools to new GApplication logger methods (#1828)

Since the new GApplication logger methods are more compact than the old format the "logTerse()" etc. constructs have been replaced by the new logger methods. At the same time, the chattiness levels have been reviewed with the following behaviour:
- TERSE: only headers
- NORMAL: standard output, only main results or computations
- EXPLICIT: detailed output
- VERBOSE: verbose output, mainly for diagnostics
pyext/ctool.i
... ... @@ -95,6 +95,12 @@ public:
95 95 %rename(_require_inobs) require_inobs(const std::string& method);
96 96 %rename(_require_inobs_nolist) require_inobs_nolist(const std::string& method);
97 97 %rename(_require_inobs_nocube) require_inobs_nocube(const std::string& method);
  98 + %rename(_log_observations) log_observations(const GChatter& chatter,
  99 + const GObservations& obs,
  100 + const std::string& what);
  101 + %rename(_log_models) log_models(const GChatter& chatter,
  102 + const GModels& models,
  103 + const std::string& what);
98 104 %rename(_set_response) set_response(GObservations& obs);
99 105 %rename(_set_obs_response) set_obs_response(GCTAObservation* obs);
100 106 %rename(_set_obs_bounds) set_obs_bounds(GObservations& obs);
... ... @@ -119,6 +125,14 @@ public:
119 125 void require_inobs_nolist(const std::string& method);
120 126 void require_inobs_nocube(const std::string& method);
121 127  
  128 + // Protected methods for logging
  129 + void log_observations(const GChatter& chatter,
  130 + const GObservations& obs,
  131 + const std::string& what = "Observation");
  132 + void log_models(const GChatter& chatter,
  133 + const GModels& models,
  134 + const std::string& what = "Model");
  135 +
122 136 // Protected support methods
123 137 void set_response(GObservations& obs);
124 138 void set_obs_response(GCTAObservation* obs);
... ...
src/ctbin/ctbin.cpp
... ... @@ -40,7 +40,6 @@
40 40 /* __ Debug definitions __________________________________________________ */
41 41  
42 42 /* __ Coding definitions _________________________________________________ */
43   -#define G_PLAW_WEIGHTS //!< Use power law in energy weight computation
44 43  
45 44 /* __ Constants __________________________________________________________ */
46 45  
... ... @@ -227,16 +226,16 @@ void ctbin::run(void)
227 226 get_parameters();
228 227  
229 228 // Write input observation container into logger
230   - log_observations(NORMAL, m_obs);
  229 + log_observations(NORMAL, m_obs, "Input observation");
231 230  
232   - // Write header
  231 + // Write header into logger
233 232 log_header1(TERSE, gammalib::number("Bin observation", m_obs.size()));
234 233  
235 234 // Loop over all observations in the container
236 235 for (int i = 0; i < m_obs.size(); ++i) {
237 236  
238   - // Write header for observation
239   - log_header3(NORMAL, get_obs_header(m_obs[i]));
  237 + // Write header for the current observation
  238 + log_header3(TERSE, get_obs_header(m_obs[i]));
240 239  
241 240 // Get CTA observation
242 241 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
... ... @@ -244,7 +243,7 @@ void ctbin::run(void)
244 243 // Skip observation if it's not CTA
245 244 if (obs == NULL) {
246 245 std::string msg = " Skipping "+m_obs[i]->instrument()+
247   - " observation\n";
  246 + " observation";
248 247 log_string(NORMAL, msg);
249 248 continue;
250 249 }
... ... @@ -252,7 +251,7 @@ void ctbin::run(void)
252 251 // Skip observation if we have a binned observation
253 252 if (obs->eventtype() == "CountsCube") {
254 253 std::string msg = " Skipping binned "+m_obs[i]->instrument()+
255   - " observation\n";
  254 + " observation";
256 255 log_string(NORMAL, msg);
257 256 continue;
258 257 }
... ... @@ -332,7 +331,7 @@ void ctbin::save(void)
332 331 ***************************************************************************/
333 332 void ctbin::publish(const std::string& name)
334 333 {
335   - // Write header
  334 + // Write header into logger
336 335 log_header1(TERSE, "Publish counts cube");
337 336  
338 337 // Set default name is user name is empty
... ... @@ -486,108 +485,97 @@ void ctbin::get_parameters(void)
486 485 * @exception GException::invalid_value
487 486 * No event list or valid RoI found in observation.
488 487 *
489   - * Fills the events from an event list in the counts cube setup by init_cube.
  488 + * Fills the events from an event list into the counts cube.
490 489 ***************************************************************************/
491 490 void ctbin::fill_cube(GCTAObservation* obs)
492 491 {
493   - // Continue only if observation pointer is valid
494   - if (obs != NULL) {
495   -
496   - // Make sure that the observation holds a CTA event list. If this
497   - // is not the case then throw an exception.
498   - const GCTAEventList* events = dynamic_cast<const GCTAEventList*>
499   - (obs->events());
500   - if (events == NULL) {
501   - std::string msg = "CTA Observation does not contain an event "
502   - "list. An event list is needed to fill the "
503   - "counts cube.";
504   - throw GException::invalid_value(G_FILL_CUBE, msg);
505   - }
506   -
507   - // Get the RoI
508   - const GCTARoi& roi = events->roi();
509   -
510   - // Check for RoI sanity
511   - if (!roi.is_valid()) {
512   - std::string msg = "No valid RoI found in input observation "
513   - "\""+obs->name()+"\". Run ctselect to specify "
514   - "an RoI for this observation before running "
515   - "ctbin.";
516   - throw GException::invalid_value(G_FILL_CUBE, msg);
517   - }
518   -
519   - // Get counts cube usage flags
520   - std::vector<bool> usage = cube_layer_usage(events->ebounds());
  492 + // Make sure that the observation holds a CTA event list. If this
  493 + // is not the case then throw an exception.
  494 + const GCTAEventList* events = dynamic_cast<const GCTAEventList*>
  495 + (obs->events());
  496 + if (events == NULL) {
  497 + std::string msg = "CTA Observation does not contain an event "
  498 + "list. An event list is needed to fill the "
  499 + "counts cube.";
  500 + throw GException::invalid_value(G_FILL_CUBE, msg);
  501 + }
521 502  
522   - // Initialise binning statistics
523   - int num_outside_roi = 0;
524   - int num_outside_map = 0;
525   - int num_outside_ebds = 0;
526   - int num_in_map = 0;
  503 + // Get the RoI
  504 + const GCTARoi& roi = events->roi();
527 505  
528   - // Fill counts sky map
529   - for (int i = 0; i < events->size(); ++i) {
  506 + // Check for RoI sanity
  507 + if (!roi.is_valid()) {
  508 + std::string msg = "No valid RoI found in input observation "
  509 + "\""+obs->name()+"\". Run ctselect to specify "
  510 + "an RoI for this observation before running "
  511 + "ctbin.";
  512 + throw GException::invalid_value(G_FILL_CUBE, msg);
  513 + }
530 514  
531   - // Get event
532   - const GCTAEventAtom* event = (*events)[i];
  515 + // Get counts cube usage flags
  516 + std::vector<bool> usage = cube_layer_usage(events->ebounds());
533 517  
534   - // Determine sky pixel
535   - GCTAInstDir* inst = (GCTAInstDir*)&(event->dir());
536   - GSkyDir dir = inst->dir();
537   - GSkyPixel pixel = m_counts.dir2pix(dir);
  518 + // Initialise binning statistics
  519 + int num_outside_roi = 0;
  520 + int num_outside_map = 0;
  521 + int num_outside_ebds = 0;
  522 + int num_in_map = 0;
538 523  
539   - // Skip event if corresponding counts cube pixel is outside RoI
540   - if (roi.centre().dir().dist_deg(dir) > roi.radius()) {
541   - num_outside_roi++;
542   - continue;
543   - }
  524 + // Fill counts sky map
  525 + for (int i = 0; i < events->size(); ++i) {
544 526  
545   - // Skip event if corresponding counts cube pixel is outside the
546   - // counts cube map range
547   - if (pixel.x() < -0.5 || pixel.x() > (m_counts.nx()-0.5) ||
548   - pixel.y() < -0.5 || pixel.y() > (m_counts.ny()-0.5)) {
549   - num_outside_map++;
550   - continue;
551   - }
  527 + // Get event
  528 + const GCTAEventAtom* event = (*events)[i];
552 529  
553   - // Determine counts cube energy bin
554   - int iebin = m_ebounds.index(event->energy());
  530 + // Determine sky pixel
  531 + GCTAInstDir* inst = (GCTAInstDir*)&(event->dir());
  532 + GSkyDir dir = inst->dir();
  533 + GSkyPixel pixel = m_counts.dir2pix(dir);
555 534  
556   - // Skip event if the corresponding counts cube energy bin is not
557   - // fully contained in the event list energy range. This avoids
558   - // having partially filled bins.
559   - if (!usage[iebin]) {
560   - num_outside_ebds++;
561   - continue;
562   - }
  535 + // Skip event if corresponding counts cube pixel is outside RoI
  536 + if (roi.centre().dir().dist_deg(dir) > roi.radius()) {
  537 + num_outside_roi++;
  538 + continue;
  539 + }
563 540  
564   - // Fill event in skymap
565   - m_counts(pixel, iebin) += 1.0;
566   - num_in_map++;
  541 + // Skip event if corresponding counts cube pixel is outside the
  542 + // counts cube map range
  543 + if (pixel.x() < -0.5 || pixel.x() > (m_counts.nx()-0.5) ||
  544 + pixel.y() < -0.5 || pixel.y() > (m_counts.ny()-0.5)) {
  545 + num_outside_map++;
  546 + continue;
  547 + }
567 548  
568   - // Signal that bin was filled
569   - m_weights(pixel, iebin) = 1.0;
  549 + // Determine counts cube energy bin
  550 + int iebin = m_ebounds.index(event->energy());
570 551  
571   - } // endfor: looped over all events
  552 + // Skip event if the corresponding counts cube energy bin is not
  553 + // fully contained in the event list energy range. This avoids
  554 + // having partially filled bins.
  555 + if (!usage[iebin]) {
  556 + num_outside_ebds++;
  557 + continue;
  558 + }
572 559  
573   - // Append GTIs
574   - m_gti.extend(events->gti());
  560 + // Fill event in skymap
  561 + m_counts(pixel, iebin) += 1.0;
  562 + num_in_map++;
575 563  
576   - // Update ontime and livetime
577   - m_ontime += obs->ontime();
578   - m_livetime += obs->livetime();
  564 + } // endfor: looped over all events
579 565  
580   - // Log filling results
581   - log_value(TERSE, "Events in list", obs->events()->size());
582   - log_value(TERSE, "Events in cube", num_in_map);
583   - log_value(TERSE, "Event bins outside RoI", num_outside_roi);
584   - log_value(TERSE, "Events outside cube area", num_outside_map);
585   - log_value(TERSE, "Events outside energy bins", num_outside_ebds);
  566 + // Append GTIs
  567 + m_gti.extend(events->gti());
586 568  
587   - // Log cube
588   - log_string(EXPLICIT, m_counts.print());
  569 + // Update ontime and livetime
  570 + m_ontime += obs->ontime();
  571 + m_livetime += obs->livetime();
589 572  
590   - } // endif: observation was valid
  573 + // Log filling results
  574 + log_value(NORMAL, "Events in list", obs->events()->size());
  575 + log_value(NORMAL, "Events in cube", num_in_map);
  576 + log_value(NORMAL, "Event bins outside RoI", num_outside_roi);
  577 + log_value(NORMAL, "Events outside cube area", num_outside_map);
  578 + log_value(NORMAL, "Events outside energy bins", num_outside_ebds);
591 579  
592 580 // Return
593 581 return;
... ... @@ -607,61 +595,56 @@ void ctbin::fill_cube(GCTAObservation* obs)
607 595 ***************************************************************************/
608 596 void ctbin::set_weights(GCTAObservation* obs)
609 597 {
610   - // Continue only if observation pointer is valid
611   - if (obs != NULL) {
612   -
613   - // Make sure that the observation holds a CTA event list. If this
614   - // is not the case then throw an exception.
615   - const GCTAEventList* events = dynamic_cast<const GCTAEventList*>
616   - (obs->events());
617   - if (events == NULL) {
618   - std::string msg = "CTA Observation does not contain an event "
619   - "list. An event list is needed to fill the "
620   - "counts cube.";
621   - throw GException::invalid_value(G_SET_WEIGHTS, msg);
622   - }
623   -
624   - // Get the RoI
625   - const GCTARoi& roi = events->roi();
  598 + // Make sure that the observation holds a CTA event list. If this
  599 + // is not the case then throw an exception.
  600 + const GCTAEventList* events = dynamic_cast<const GCTAEventList*>
  601 + (obs->events());
  602 + if (events == NULL) {
  603 + std::string msg = "CTA Observation does not contain an event "
  604 + "list. An event list is needed to fill the "
  605 + "counts cube.";
  606 + throw GException::invalid_value(G_SET_WEIGHTS, msg);
  607 + }
626 608  
627   - // Check for RoI sanity
628   - if (!roi.is_valid()) {
629   - std::string msg = "No valid RoI found in input observation "
630   - "\""+obs->name()+"\". Run ctselect to specify "
631   - "an RoI for this observation before running "
632   - "ctbin.";
633   - throw GException::invalid_value(G_SET_WEIGHTS, msg);
634   - }
  609 + // Get the RoI
  610 + const GCTARoi& roi = events->roi();
635 611  
636   - // Get counts cube usage flags
637   - std::vector<bool> usage = cube_layer_usage(events->ebounds());
  612 + // Check for RoI sanity
  613 + if (!roi.is_valid()) {
  614 + std::string msg = "No valid RoI found in input observation "
  615 + "\""+obs->name()+"\". Run ctselect to specify "
  616 + "an RoI for this observation before running "
  617 + "ctbin.";
  618 + throw GException::invalid_value(G_SET_WEIGHTS, msg);
  619 + }
638 620  
639   - // Loop over all pixels in counts cube
640   - for (int pixel = 0; pixel < m_counts.npix(); ++pixel) {
  621 + // Get counts cube usage flags
  622 + std::vector<bool> usage = cube_layer_usage(events->ebounds());
641 623  
642   - // Get pixel sky direction
643   - GSkyDir dir = m_counts.inx2dir(pixel);
  624 + // Loop over all pixels in counts cube
  625 + for (int pixel = 0; pixel < m_counts.npix(); ++pixel) {
644 626  
645   - // Skip pixel if it is outside the RoI
646   - if (roi.centre().dir().dist_deg(dir) > roi.radius()) {
647   - continue;
648   - }
  627 + // Get pixel sky direction
  628 + GSkyDir dir = m_counts.inx2dir(pixel);
649 629  
650   - // Loop over all energy layers of counts cube
651   - for (int iebin = 0; iebin < m_ebounds.size(); ++iebin){
  630 + // Skip pixel if it is outside the RoI
  631 + if (roi.centre().dir().dist_deg(dir) > roi.radius()) {
  632 + continue;
  633 + }
652 634  
653   - // Skip energy layer if the usage flag is false
654   - if (!usage[iebin]) {
655   - continue;
656   - }
657   - // Signal that bin was filled
658   - m_weights(pixel, iebin) = 1.0;
  635 + // Loop over all energy layers of counts cube
  636 + for (int iebin = 0; iebin < m_ebounds.size(); ++iebin){
659 637  
660   - } // endfor: looped over energy layers of counts cube
  638 + // Skip energy layer if the usage flag is false
  639 + if (!usage[iebin]) {
  640 + continue;
  641 + }
  642 + // Signal that bin was filled
  643 + m_weights(pixel, iebin) = 1.0;
661 644  
662   - } // endfor: looped over pixels of counts cube
  645 + } // endfor: looped over energy layers of counts cube
663 646  
664   - } // endif: observation was valid
  647 + } // endfor: looped over pixels of counts cube
665 648  
666 649 // Return
667 650 return;
... ... @@ -792,8 +775,6 @@ void ctbin::obs_cube(void)
792 775 }
793 776  
794 777  
795   -
796   -
797 778 /***********************************************************************//**
798 779 * @brief Determine the counts cube layer usage.
799 780 *
... ...
src/ctbkgcube/ctbkgcube.cpp
... ... @@ -216,48 +216,28 @@ void ctbkgcube::run(void)
216 216 double logEmin = std::log10(m_background.energies()[0].TeV());
217 217 double logEmax = std::log10(m_background.energies()[n-1].TeV());
218 218 int nrequired = int((logEmax - logEmin) * 25.0);
219   - if ((n < nrequired) && logTerse()) {
220   - log << std::endl;
221   - log << "WARNING: ";
222   - log << "Only " << n-1 << " energy bins have been requested. This may be "
223   - "too few energy bins.";
224   - log << std::endl << " ";
225   - log << "At least 25 bins per decade in energy are recommended, which "
226   - "in your case";
227   - log << std::endl << " ";
228   - log << "would be " << nrequired-1 << " bins. Consider increasing the "
229   - "number of energy bins.";
230   - log << std::endl;
231   - }
232   -
233   - // Write header
234   - if (logTerse()) {
235   - log << std::endl;
236   - log.header1("Initialise background cube");
  219 + if (n < nrequired) {
  220 + std::string msg = "\nWARNING: Only "+gammalib::str(n-1)+" energy bins "
  221 + "have been requested. This may be too few energy "
  222 + "bins.\n At least 25 bins per decade in "
  223 + "energy are recommended, which in your case\n"
  224 + " would be "+gammalib::str(nrequired-1)+
  225 + " bins. Consider increasing the number of energy "
  226 + "bins.";
  227 + log_string(TERSE, msg);
237 228 }
238 229  
239 230 // Initialise exposure cube
240 231 init_cube();
241 232  
242   - // Write observation(s) into logger
243   - if (logTerse()) {
244   - log << std::endl;
245   - log.header1(gammalib::number("Observation",m_obs.size()));
246   - log << m_obs.print(m_chatter) << std::endl;
247   - }
  233 + // Write input observation container into logger
  234 + log_observations(NORMAL, m_obs, "Input observation");
248 235  
249   - // Log input model
250   - if (logTerse()) {
251   - log << std::endl;
252   - log.header1("Input model");
253   - log << m_obs.models().print(m_chatter) << std::endl;
254   - }
  236 + // Write input model container into logger
  237 + log_models(NORMAL, m_obs.models(), "Input model");
255 238  
256 239 // Write header
257   - if (logTerse()) {
258   - log << std::endl;
259   - log.header1("Prepare model");
260   - }
  240 + log_header1(TERSE, "Prepare model");
261 241  
262 242 // Copy models from observation container and reset output model
263 243 // container
... ... @@ -289,22 +269,11 @@ void ctbkgcube::run(void)
289 269 } // endif: had a background model
290 270 } // endif: had a CTA, HESS, MAGIC or VERITAS model
291 271  
292   - // Log results
293   - if (logTerse()) {
294   - if (remove) {
295   - log << gammalib::parformat("Remove model");
296   - }
297   - else {
298   - log << gammalib::parformat("Keep model");
299   - }
300   - log << m_bkgmdl[i]->name();
301   - log << " ";
302   - log << m_bkgmdl[i]->type();
303   - log << "(";
304   - log << m_bkgmdl[i]->instruments();
305   - log << ")";
306   - log << std::endl;
307   - }
  272 + // Log model removal or keeping
  273 + std::string what = (remove) ? "Remove model" : "Keep model";
  274 + std::string value = m_bkgmdl[i]->name()+" "+m_bkgmdl[i]->type()+"("+
  275 + m_bkgmdl[i]->instruments()+")";
  276 + log_value(NORMAL, what, value);
308 277  
309 278 // If removal is requested, append model to output container and
310 279 // remove it from the background model container ...
... ... @@ -316,16 +285,16 @@ void ctbkgcube::run(void)
316 285 } // endfor: looped over all background models
317 286  
318 287 // Write header
319   - if (logTerse()) {
320   - log << std::endl;
321   - log.header1("Generate background cube");
322   - }
  288 + log_header1(TERSE, "Generate background cube");
323 289  
324 290 // Assign background models to container
325 291 m_obs.models(m_bkgmdl);
326 292  
  293 + // Set pointer on logger depending on chattiness
  294 + GLog* logp = (logNormal()) ? &log : NULL;
  295 +
327 296 // Fill background cube from observations
328   - m_background.fill(m_obs, &log);
  297 + m_background.fill(m_obs, logp);
329 298  
330 299 // Create a background model for the output background cube and append
331 300 // that model to the input model in place of the original
... ... @@ -347,17 +316,11 @@ void ctbkgcube::run(void)
347 316 // Append model to output container
348 317 m_outmdl.append(model);
349 318  
350   - // Log background cube
351   - if (logTerse()) {
352   - log << m_background.print(m_chatter) << std::endl;
353   - }
  319 + // Write background cube into logger
  320 + log_string(NORMAL, m_background.print(m_chatter));
354 321  
355   - // Log output model
356   - if (logTerse()) {
357   - log << std::endl;
358   - log.header1("Output model");
359   - log << m_outmdl << std::endl;
360   - }
  322 + // Write input model container into logger
  323 + log_models(NORMAL, m_outmdl, "Output model");
361 324  
362 325 // Recover original models
363 326 m_obs.models(models_orig);
... ... @@ -381,10 +344,7 @@ void ctbkgcube::run(void)
381 344 void ctbkgcube::save(void)
382 345 {
383 346 // Write header
384   - if (logTerse()) {
385   - log << std::endl;
386   - log.header1("Save background cube");
387   - }
  347 + log_header1(TERSE, "Save background cube");
388 348  
389 349 // Get background cube and model file names
390 350 m_outcube = (*this)["outcube"].filename();
... ... @@ -393,11 +353,8 @@ void ctbkgcube::save(void)
393 353 // Save only if filename is non-empty
394 354 if (!m_outcube.is_empty()) {
395 355  
396   - // Log filename
397   - if (logTerse()) {
398   - log << gammalib::parformat("Background cube file");
399   - log << m_outcube.url() << std::endl;
400   - }
  356 + // Log background cube file name
  357 + log_value(NORMAL, "Background cube file", m_outcube.url());
401 358  
402 359 // Save background cube
403 360 m_background.save(m_outcube, clobber());
... ... @@ -408,11 +365,8 @@ void ctbkgcube::save(void)
408 365 if ((!m_outmodel.is_empty()) &&
409 366 (gammalib::tolower(m_outmodel.url()) != "none")) {
410 367  
411   - // Log filename
412   - if (logTerse()) {
413   - log << gammalib::parformat("Model definition file");
414   - log << m_outmodel.url() << std::endl;
415   - }
  368 + // Log model definition file name
  369 + log_value(NORMAL, "Model definition file", m_outmodel.url());
416 370  
417 371 // Save output model for stacked analyses
418 372 m_outmdl.save(m_outmodel.url());
... ... @@ -432,10 +386,7 @@ void ctbkgcube::save(void)
432 386 void ctbkgcube::publish(const std::string& name)
433 387 {
434 388 // Write header
435   - if (logTerse()) {
436   - log << std::endl;
437   - log.header1("Publish background cube");
438   - }
  389 + log_header1(TERSE, "Publish background cube");
439 390  
440 391 // Set default name is user name is empty
441 392 std::string user_name(name);
... ... @@ -443,11 +394,8 @@ void ctbkgcube::publish(const std::string&amp; name)
443 394 user_name = CTBKGCUBE_NAME;
444 395 }
445 396  
446   - // Log filename
447   - if (logTerse()) {
448   - log << gammalib::parformat("Publish background cube");
449   - log << user_name << std::endl;
450   - }
  397 + // Log background cube name
  398 + log_value(NORMAL, "Publish background cube", user_name);
451 399  
452 400 // Publish exposure cube
453 401 m_background.cube().publish(user_name);
... ... @@ -614,6 +562,9 @@ void ctbkgcube::get_parameters(void)
614 562 ***************************************************************************/
615 563 void ctbkgcube::init_cube(void)
616 564 {
  565 + // Write header
  566 + log_header1(TERSE, "Initialise background cube");
  567 +
617 568 // Extract exposure cube definition
618 569 const GWcs* proj = static_cast<const GWcs*>(m_background.cube().projection());
619 570 std::string wcs = m_background.cube().projection()->code();
... ... @@ -631,11 +582,8 @@ void ctbkgcube::init_cube(void)
631 582 // If requested, insert energies at all event list energy boundaries
632 583 if (m_addbounds) {
633 584  
634   - // Set logger
635   - GLog* logger = NULL;
636   - if (logTerse()) {
637   - logger = &log;
638   - }
  585 + // Set pointer on logger depending on chattiness
  586 + GLog* logp = (logNormal()) ? &log : NULL;
639 587  
640 588 // Loop over all observations
641 589 for (int i = 0; i < m_obs.size(); ++i) {
... ... @@ -655,7 +603,7 @@ void ctbkgcube::init_cube(void)
655 603 }
656 604  
657 605 // Insert energy boundaries
658   - energies = insert_energy_boundaries(energies, *cta, logger);
  606 + energies = insert_energy_boundaries(energies, *cta, logp);
659 607  
660 608 } // endfor: looped over all observations
661 609  
... ... @@ -664,10 +612,8 @@ void ctbkgcube::init_cube(void)
664 612 // Setup background cube
665 613 m_background = GCTACubeBackground(wcs, coords, x, y, dx, dy, nx, ny, energies);
666 614  
667   - // Log background cube
668   - if (logTerse()) {
669   - log << m_background.print(m_chatter) << std::endl;
670   - }
  615 + // Write background cube into logger
  616 + log_string(NORMAL, m_background.print(m_chatter));
671 617  
672 618 // Return
673 619 return;
... ...
src/ctbutterfly/ctbutterfly.cpp
... ... @@ -223,26 +223,14 @@ void ctbutterfly::run(void)
223 223 }
224 224 }
225 225  
226   - // Write observation(s) into logger
227   - if (logTerse()) {
228   - log << std::endl;
229   - if (m_obs.size() > 1) {
230   - log.header1("Observations");
231   - }
232   - else {
233   - log.header1("Observation");
234   - }
235   - log << m_obs << std::endl;
236   - }
  226 + // Write input observation container into logger
  227 + log_observations(NORMAL, m_obs, "Input observation");
237 228  
238 229 // If fit is selected then do maximum likelihood fit
239 230 if (m_fit) {
240 231  
241   - // Write header
242   - if (logTerse()) {
243   - log << std::endl;
244   - log.header1("Compute best-fit likelihood");
245   - }
  232 + // Write header into logger
  233 + log_header1(TERSE, "Compute best-fit likelihood");
246 234  
247 235 // Optimize and compute errors
248 236 m_obs.optimize(m_opt);
... ... @@ -254,12 +242,10 @@ void ctbutterfly::run(void)
254 242 GObservations::likelihood likelihood = m_obs.function();
255 243 m_covariance = likelihood.curvature()->invert();
256 244  
257   - // Write optimised model and covariance matrix into logger
258   - if (logTerse()) {
259   - log << m_opt << std::endl;
260   - log << m_obs.models() << std::endl;
261   - log << m_covariance << std::endl;
262   - }
  245 + // Write optimizer, optimised model and covariance matrix into logger
  246 + log_string(NORMAL, m_opt.print(m_chatter));
  247 + log_string(NORMAL, m_obs.models().print(m_chatter));
  248 + log_string(EXPLICIT, m_covariance.print(m_chatter));
263 249  
264 250 } // endif: fit selected
265 251  
... ... @@ -270,11 +256,8 @@ void ctbutterfly::run(void)
270 256 // then compute now the covariance matrix
271 257 if (!m_fit && m_covariance.size() == 0) {
272 258  
273   - // Write header
274   - if (logTerse()) {
275   - log << std::endl;
276   - log.header1("Compute covariance matrix");
277   - }
  259 + // Write header into logger
  260 + log_header1(TERSE, "Compute covariance matrix");
278 261  
279 262 // Evaluate curvature matrix at the actual parameters
280 263 GOptimizerPars pars = models.pars();
... ... @@ -286,18 +269,13 @@ void ctbutterfly::run(void)
286 269 // to scale them before we can proceed.
287 270 m_covariance = likelihood.curvature()->invert();
288 271  
289   - // Log covariance matrix
290   - if (logTerse()) {
291   - log << m_covariance << std::endl;
292   - }
  272 + // Write covariance matrix into logger
  273 + log_string(EXPLICIT, m_covariance.print(m_chatter));
293 274  
294 275 } // endif: covariance computation needed
295 276  
296   - // Write header
297   - if (logTerse()) {
298   - log << std::endl;
299   - log.header1("Prepare butterfly computation");
300   - }
  277 + // Write header into logger
  278 + log_header1(TERSE, "Prepare butterfly computation");
301 279  
302 280 // Find parameter indices. We do this by the memory location of the
303 281 // model parameters.
... ... @@ -315,8 +293,6 @@ void ctbutterfly::run(void)
315 293 }
316 294 }
317 295  
318   - // Check indices
319   -
320 296 // Store model values and scales
321 297 double prefactor_mean = (*skymodel)["Prefactor"].value();
322 298 double index_mean = (*skymodel)["Index"].value();
... ... @@ -325,16 +301,12 @@ void ctbutterfly::run(void)
325 301 double index_scale = (*skymodel)["Index"].scale();
326 302 GEnergy pivot(pivot_mean, "MeV");
327 303  
328   - // Show parameter indices
329   - if (logTerse()) {
330   - log << gammalib::parformat("Prefactor");
331   - log << prefactor_mean << " ph/cm2/s/MeV (";
332   - log << inx_prefactor << ")" << std::endl;
333   - log << gammalib::parformat("Index");
334   - log << index_mean << " (" << inx_index << ")" << std::endl;
335   - log << gammalib::parformat("Pivot energy");
336   - log << pivot << std::endl;
337   - }
  304 + // Write parameter indices into logger
  305 + log_value(NORMAL, "Prefactor", gammalib::str(prefactor_mean)+
  306 + " ph/cm2/s/MeV ("+gammalib::str(inx_prefactor)+")");
  307 + log_value(NORMAL, "Index", gammalib::str(index_mean)+
  308 + " ("+gammalib::str(inx_index)+")");
  309 + log_value(NORMAL, "Pivot energy", pivot.print());
338 310  
339 311 // Extract covariance elements
340 312 double cov_pp = m_covariance(inx_prefactor,inx_prefactor);
... ... @@ -353,35 +325,26 @@ void ctbutterfly::run(void)
353 325 eigenvectors(cov_pp, cov_pg, cov_pg, cov_gg,
354 326 &lambda1, &lambda2, &vector1, &vector2);
355 327  
356   - // Show eigenvectors and eigenvalues
357   - if (logTerse()) {
358   - log << gammalib::parformat("Eigenvalue 1") << lambda1 << std::endl;
359   - log << gammalib::parformat("Eigenvalue 2") << lambda2 << std::endl;
360   - log << gammalib::parformat("Eigenvector 1") << vector1 << std::endl;
361   - log << gammalib::parformat("Eigenvector 2") << vector2 << std::endl;
362   - }
  328 + // Write eigenvectors and eigenvalues into logger
  329 + log_value(NORMAL, "Eigenvalue 1", lambda1);
  330 + log_value(NORMAL, "Eigenvalue 2", lambda2);
  331 + log_value(NORMAL, "Eigenvector 1", vector1.print());
  332 + log_value(NORMAL, "Eigenvector 2", vector2.print());
363 333  
364 334 // Confidence scaling
365 335 double sigma = gammalib::erfinv(m_confidence) * gammalib::sqrt_two;
366 336 double scale = (sigma*sigma);
367 337  
368   - // Show confidence stuff
369   - if (logTerse()) {
370   - log << gammalib::parformat("Confidence level");
371   - log << m_confidence << std::endl;
372   - log << gammalib::parformat("Corresponding scaling");
373   - log << scale << std::endl;
374   - }
  338 + // Write confidence level information into logger
  339 + log_value(NORMAL, "Confidence level", m_confidence);
  340 + log_value(NORMAL, "Corresponding scaling", scale);
375 341  
376 342 // Compute minor and major axes of error ellipse
377 343 double major = scale*std::sqrt(lambda1);
378 344 double minor = scale*std::sqrt(lambda2);
379 345  
380   - // Write header
381   - if (logTerse()) {
382   - log << std::endl;
383   - log.header1("Generate butterfly");
384   - }
  346 + // Write header into logger
  347 + log_header1(TERSE, "Generate butterfly");
385 348  
386 349 // Walk around the error ellipse
387 350 int nt = 360;
... ... @@ -401,12 +364,10 @@ void ctbutterfly::run(void)
401 364 minor * sin_t * vector2[1]) * index_scale +
402 365 index_mean;
403 366  
404   - // Show prefactor and index
405   - if (logTerse()) {
406   - log << gammalib::parformat("Angle "+gammalib::str(t*gammalib::rad2deg));
407   - log << prefactor << " ph/cm2/s/MeV; ";
408   - log << index << std::endl;
409   - }
  367 + // Write prefactor and index into logger
  368 + log_value(EXPLICIT, "Angle "+gammalib::str(t*gammalib::rad2deg),
  369 + gammalib::str(prefactor)+" ph/cm2/s/MeV; "+
  370 + gammalib::str(index));
410 371  
411 372 // Setup power law model
412 373 GModelSpectralPlaw plaw(prefactor, index, pivot);
... ... @@ -434,11 +395,8 @@ void ctbutterfly::run(void)
434 395  
435 396 } // endfor: looped over all angles
436 397  
437   - // Write header
438   - if (logTerse()) {
439   - log << std::endl;
440   - log.header1("Results");
441   - }
  398 + // Write header into logger
  399 + log_header1(TERSE, "Results");
442 400  
443 401 // Setup power law model
444 402 GModelSpectralPlaw plaw(prefactor_mean, index_mean, pivot);
... ... @@ -457,17 +415,11 @@ void ctbutterfly::run(void)
457 415 m_energies.push_back(energy.MeV());
458 416 m_intensities.push_back(intensity);
459 417  
460   - // Log information
461   - if (logTerse()) {
462   - log << gammalib::parformat("Intensity at "+energy.print());
463   - log << intensity;
464   - log << " (";
465   - log << m_min_intensities[k];
466   - log << ", ";
467   - log << m_max_intensities[k];
468   - log << ") ph/cm2/s/MeV";
469   - log << std::endl;
470   - }
  418 + // Write results into logger
  419 + log_value(NORMAL, "Intensity at "+energy.print(),
  420 + gammalib::str(intensity)+" ("+
  421 + gammalib::str(m_min_intensities[k])+", "+
  422 + gammalib::str(m_max_intensities[k])+") ph/cm2/s/MeV");
471 423  
472 424 } // endfor
473 425  
... ... @@ -492,11 +444,8 @@ void ctbutterfly::run(void)
492 444 ***************************************************************************/
493 445 void ctbutterfly::save(void)
494 446 {
495   - // Write header
496   - if (logTerse()) {
497   - log << std::endl;
498   - log.header1("Save Butterfly diagram");
499   - }
  447 + // Write header into logger
  448 + log_header1(TERSE, "Save Butterfly diagram");
500 449  
501 450 // Get output filename
502 451 m_outfile = (*this)["outfile"].filename();
... ... @@ -504,11 +453,8 @@ void ctbutterfly::save(void)
504 453 // Save only if filename is non-empty
505 454 if (!m_outfile.is_empty()) {
506 455  
507   - // Log filename
508   - if (logTerse()) {
509   - log << "Save butterfly diagram into file \""+m_outfile+"\".";
510   - log << std::endl;
511   - }
  456 + // Log butterfly diagram file name
  457 + log_value(NORMAL, "Butterfly file", m_outfile.url());
512 458  
513 459 // Create CSV table with 4 columns
514 460 GCsv table(m_energies.size(), 4);
... ... @@ -522,7 +468,7 @@ void ctbutterfly::save(void)
522 468 }
523 469  
524 470 // Save CSV table
525   - table.save(m_outfile, " ", clobber());
  471 + table.save(m_outfile.url(), " ", clobber());
526 472  
527 473 }
528 474  
... ... @@ -548,6 +494,7 @@ void ctbutterfly::init_members(void)
548 494 m_max_iter = 50;
549 495 m_apply_edisp = false;
550 496 m_fit = false;
  497 + m_chatter = static_cast<GChatter>(2);
551 498 m_ebounds.clear();
552 499 m_outfile.clear();
553 500  
... ... @@ -582,6 +529,7 @@ void ctbutterfly::copy_members(const ctbutterfly&amp; app)
582 529 m_max_iter = app.m_max_iter;
583 530 m_apply_edisp = app.m_apply_edisp;
584 531 m_fit = app.m_fit;
  532 + m_chatter = app.m_chatter;
585 533 m_ebounds = app.m_ebounds;
586 534 m_outfile = app.m_outfile;
587 535  
... ... @@ -668,12 +616,11 @@ void ctbutterfly::get_parameters(void)
668 616 // m_covariance.load(matrixfilename);
669 617 }
670 618  
671   - // Read energy dispersion flag
  619 + // Get remaining parameters
672 620 m_apply_edisp = (*this)["edisp"].boolean();
673   -
674   - // Read other parameters
675   - m_confidence = (*this)["confidence"].real();
676   - m_fit = (*this)["fit"].boolean();
  621 + m_confidence = (*this)["confidence"].real();
  622 + m_fit = (*this)["fit"].boolean();
  623 + m_chatter = static_cast<GChatter>((*this)["chatter"].integer());
677 624  
678 625 // Optionally read ahead parameters so that they get correctly
679 626 // dumped into the log file
... ...
src/ctbutterfly/ctbutterfly.hpp
... ... @@ -96,6 +96,7 @@ protected:
96 96 bool m_fit; //!< Do fit?
97 97 GEbounds m_ebounds; //!< Energy binning definition
98 98 GFilename m_outfile; //!< Output ASCII file name
  99 + GChatter m_chatter; //!< Chattiness
99 100  
100 101 // Protected members
101 102 GOptimizerLM m_opt; //!< Optimizer
... ...
src/ctcubemask/ctcubemask.cpp
... ... @@ -212,18 +212,11 @@ void ctcubemask::run(void)
212 212 // Get parameters
213 213 get_parameters();
214 214  
215   - // Write observation(s) into logger
216   - if (logTerse()) {
217   - log << std::endl;
218   - log.header1("Observations");
219   - log << m_obs << std::endl;
220   - }
  215 + // Write input observation container into logger
  216 + log_observations(NORMAL, m_obs, "Input observation");
221 217  
222   - // Write header
223   - if (logTerse()) {
224   - log << std::endl;
225   - log.header1("Apply mask");
226   - }
  218 + // Write header into logger
  219 + log_header1(TERSE, "Apply mask");
227 220  
228 221 // Initialise counters
229 222 int n_observations = 0;
... ... @@ -240,15 +233,8 @@ void ctcubemask::run(void)
240 233 // Continue only if observation is a CTA observation
241 234 if (obs != NULL) {
242 235  
243   - // Write header for observation
244   - if (logTerse()) {
245   - if (obs->name().length() > 1) {
246   - log.header3("Observation "+obs->name());
247   - }
248   - else {
249   - log.header3("Observation");
250   - }
251   - }
  236 + // Write header for the current observation
  237 + log_header3(TERSE, get_obs_header(obs));
252 238  
253 239 // Increment counter
254 240 n_observations++;
... ... @@ -269,12 +255,8 @@ void ctcubemask::run(void)
269 255 m_use_xml = true;
270 256 }
271 257  
272   - // Write observation(s) into logger
273   - if (logTerse()) {
274   - log << std::endl;
275   - log.header1("Observations after event bin masking");
276   - log << m_obs << std::endl;
277   - }
  258 + // Write resulting observation container into logger
  259 + log_observations(NORMAL, m_obs, "Observations after event bin masking");
278 260  
279 261 // Optionally publish counts cube
280 262 if (m_publish) {
... ... @@ -307,16 +289,8 @@ void ctcubemask::run(void)
307 289 ***************************************************************************/
308 290 void ctcubemask::save(void)
309 291 {
310   - // Write header
311   - if (logTerse()) {
312   - log << std::endl;
313   - if (m_obs.size() > 1) {
314   - log.header1("Save counts cubes");
315   - }
316   - else {
317   - log.header1("Save counts cube");
318   - }
319   - }
  292 + // Write header into logger
  293 + log_header1(TERSE, gammalib::number("Save counts cube", m_obs.size()));
320 294  
321 295 // Get counts cube filename
322 296 m_outcube = (*this)["outcube"].filename();
... ... @@ -351,11 +325,8 @@ void ctcubemask::save(void)
351 325 ***************************************************************************/
352 326 void ctcubemask::publish(const std::string& name)
353 327 {
354   - // Write header
355   - if (logTerse()) {
356   - log << std::endl;
357   - log.header1("Publish counts cube");
358   - }
  328 + // Write header into logger
  329 + log_header1(TERSE, "Publish counts cube");
359 330  
360 331 // Set default name is user name is empty
361 332 std::string user_name(name);
... ... @@ -371,10 +342,8 @@ void ctcubemask::publish(const std::string&amp; name)
371 342 GCTAEventCube* cube = dynamic_cast<GCTAEventCube*>(obs->events());
372 343 if (cube != NULL) {
373 344  
374   - // Log filename
375   - if (logTerse()) {
376   - log << "Publish \""+user_name+"\" counts cube." << std::endl;
377   - }
  345 + // Log counts cube name
  346 + log_value(NORMAL, "Counts cube name", user_name);
378 347  
379 348 // Publish counts cube
380 349 cube->counts().publish(user_name);
... ... @@ -387,6 +356,80 @@ void ctcubemask::publish(const std::string&amp; name)
387 356 }
388 357  
389 358  
  359 +/*==========================================================================
  360 + = =
  361 + = Private methods =
  362 + = =
  363 + ==========================================================================*/
  364 +
  365 +/***********************************************************************//**
  366 + * @brief Initialise class members
  367 + ***************************************************************************/
  368 +void ctcubemask::init_members(void)
  369 +{
  370 + // Initialise parameters
  371 + m_regfile.clear();
  372 + m_outcube.clear();
  373 + m_prefix.clear();
  374 + m_usepnt = false;
  375 + m_ra = 0.0;
  376 + m_dec = 0.0;
  377 + m_rad = 0.0;
  378 + m_emin = 0.0;
  379 + m_emax = 0.0;
  380 + m_publish = false;
  381 +
  382 + // Initialise protected members
  383 + m_obs.clear();
  384 + m_infiles.clear();
  385 + m_select_energy = true;
  386 + m_select_roi = true;
  387 +
  388 + // Return
  389 + return;
  390 +}
  391 +
  392 +
  393 +/***********************************************************************//**
  394 + * @brief Copy class members
  395 + *
  396 + * @param[in] app Application.
  397 + ***************************************************************************/
  398 +void ctcubemask::copy_members(const ctcubemask& app)
  399 +{
  400 + // Copy parameters
  401 + m_regfile = app.m_regfile;
  402 + m_outcube = app.m_outcube;
  403 + m_prefix = app.m_prefix;
  404 + m_usepnt = app.m_usepnt;
  405 + m_ra = app.m_ra;
  406 + m_dec = app.m_dec;
  407 + m_rad = app.m_rad;
  408 + m_emin = app.m_emin;
  409 + m_emax = app.m_emax;
  410 + m_publish = app.m_publish;
  411 +
  412 + // Copy protected members
  413 + m_obs = app.m_obs;
  414 + m_infiles = app.m_infiles;
  415 + m_select_energy = app.m_select_energy;
  416 + m_select_roi = app.m_select_roi;
  417 +
  418 + // Return
  419 + return;
  420 +}
  421 +
  422 +
  423 +/***********************************************************************//**
  424 + * @brief Delete class members
  425 + ***************************************************************************/
  426 +void ctcubemask::free_members(void)
  427 +{
  428 + // Return
  429 + return;
  430 +}
  431 +
  432 +
390 433 /***********************************************************************//**
391 434 * @brief Get application parameters
392 435 *
... ... @@ -485,7 +528,8 @@ void ctcubemask::get_parameters(void)
485 528 void ctcubemask::apply_mask(GCTAObservation* obs)
486 529 {
487 530 // Get pointer to CTA event cube. Continue only if we have a cube
488   - GCTAEventCube* cube = dynamic_cast<GCTAEventCube*>(const_cast<GEvents*>(obs->events()));
  531 + GCTAEventCube* cube = dynamic_cast<GCTAEventCube*>
  532 + (const_cast<GEvents*>(obs->events()));
489 533 if (cube != NULL) {
490 534  
491 535 // Extract event cube and energy boundaries
... ... @@ -545,14 +589,11 @@ void ctcubemask::apply_mask(GCTAObservation* obs)
545 589 }
546 590  
547 591 // Log selected energy band
548   - if (logTerse()) {
549   - log << gammalib::parformat("Selected energy band");
550   - log << ebounds.emin(e_idx1).TeV() << " - ";
551   - log << ebounds.emax(e_idx2).TeV() << " TeV";
552   - log << std::endl;
553   - }
  592 + log_value(NORMAL, "Selected energy band",
  593 + gammalib::str(ebounds.emin(e_idx1).TeV())+" - "+
  594 + gammalib::str(ebounds.emax(e_idx2).TeV())+" TeV");
554 595  
555   - // Set all pixels inside selected energy bands but outside ROI
  596 + // Set all pixels inside selected energy bands but outside RoI
556 597 // to -1.0 if requested
557 598 if (m_select_roi) {
558 599 GSkyRegionCircle roi(m_ra, m_dec, m_rad);
... ... @@ -565,15 +606,13 @@ void ctcubemask::apply_mask(GCTAObservation* obs)
565 606 }
566 607 }
567 608  
568   - // Log selected energy band
569   - if (logTerse()) {
570   - log << gammalib::parformat("Selected ROI");
571   - log << "RA=" << m_ra << " deg, ";
572   - log << "DEC=" << m_dec << " deg, ";
573   - log << "Radius=" << m_rad << " deg";
574   - log << std::endl;
575   - }
576   - }
  609 + // Log selected RoI
  610 + log_value(NORMAL, "Selected RoI",
  611 + "RA="+gammalib::str(m_ra)+" deg, "+
  612 + "DEC="+gammalib::str(m_dec)+" deg, "+
  613 + "Radius="+gammalib::str(m_rad)+" deg");
  614 +
  615 + } // endif: applied RoI selection
577 616  
578 617 // Set all pixels inside selected energy bands and inside exclusion
579 618 // regions to -1.0
... ... @@ -587,20 +626,15 @@ void ctcubemask::apply_mask(GCTAObservation* obs)
587 626 }
588 627 }
589 628 }
590   - if (logTerse()) {
591   - log << gammalib::parformat("Exclusion regions");
592   - log << std::endl;
593   - log.indent(1);
594   - log << regions.print();
595   - log << std::endl;
596   - log.indent(0);
  629 +
  630 + // Log exclusion regions
  631 + for (int i = 0; i < regions.size(); ++i) {
  632 + log_value(NORMAL, "Exclusion region "+gammalib::str(i+1),
  633 + region_string(*(regions[i])));
597 634 }
598 635 }
599 636 else {
600   - if (logTerse()) {
601   - log << gammalib::parformat("Exclusion regions");
602   - log << "None" << std::endl;
603   - }
  637 + log_value(NORMAL, "Exclusion regions", "None");
604 638 }
605 639  
606 640 // Determine number of events after masking
... ... @@ -613,13 +647,9 @@ void ctcubemask::apply_mask(GCTAObservation* obs)
613 647 }
614 648 }
615 649  
616   - // Dump number of events before and after masking
617   - if (logTerse()) {
618   - log << gammalib::parformat("Events before masking");
619   - log << sum_before << std::endl;
620   - log << gammalib::parformat("Events after masking");
621   - log << sum_after << std::endl;
622   - }
  650 + // Write number of events before and after masking into logger
  651 + log_value(NORMAL, "Events before masking", sum_before);
  652 + log_value(NORMAL, "Events after masking", sum_after);
623 653  
624 654 // Put back map into the event cube
625 655 cube->counts(map);
... ... @@ -631,77 +661,31 @@ void ctcubemask::apply_mask(GCTAObservation* obs)
631 661 }
632 662  
633 663  
634   -/*==========================================================================
635   - = =
636   - = Private methods =
637   - = =
638   - ==========================================================================*/
639   -
640 664 /***********************************************************************//**
641   - * @brief Initialise class members
642   - ***************************************************************************/
643   -void ctcubemask::init_members(void)
644   -{
645   - // Initialise parameters
646   - m_regfile.clear();
647   - m_outcube.clear();
648   - m_prefix.clear();
649   - m_usepnt = false;
650   - m_ra = 0.0;
651   - m_dec = 0.0;
652   - m_rad = 0.0;
653   - m_emin = 0.0;
654   - m_emax = 0.0;
655   - m_publish = false;
656   -
657   - // Initialise protected members
658   - m_obs.clear();
659   - m_infiles.clear();
660   - m_select_energy = true;
661   - m_select_roi = true;
662   -
663   - // Return
664   - return;
665   -}
666   -
667   -
668   -/***********************************************************************//**
669   - * @brief Copy class members
  665 + * @brief Return region string
670 666 *
671   - * @param[in] app Application.
  667 + * @param[in] region Sky region.
  668 + *
  669 + * Returns a formatted region string for logging.
672 670 ***************************************************************************/
673   -void ctcubemask::copy_members(const ctcubemask& app)
  671 +std::string ctcubemask::region_string(const GSkyRegion& region) const
674 672 {
675   - // Copy parameters
676   - m_regfile = app.m_regfile;
677   - m_outcube = app.m_outcube;
678   - m_prefix = app.m_prefix;
679   - m_usepnt = app.m_usepnt;
680   - m_ra = app.m_ra;
681   - m_dec = app.m_dec;
682   - m_rad = app.m_rad;
683   - m_emin = app.m_emin;
684   - m_emax = app.m_emax;
685   - m_publish = app.m_publish;
686   -
687   - // Copy protected members
688   - m_obs = app.m_obs;
689   - m_infiles = app.m_infiles;
690   - m_select_energy = app.m_select_energy;
691   - m_select_roi = app.m_select_roi;
692   -
693   - // Return
694   - return;
695   -}
696   -
  673 + // Initialise region string
  674 + std::string rstring;
  675 +
  676 + // Get pointer to circle
  677 + const GSkyRegionCircle* circle = dynamic_cast<const GSkyRegionCircle*>(&region);
  678 +
  679 + // If the sky region is a circle then append Right Ascenscion, Declination
  680 + // and Radius to the region string
  681 + if (circle != NULL) {
  682 + rstring.append("RA="+gammalib::str(circle->centre().ra_deg())+" deg, "+
  683 + "DEC="+gammalib::str(circle->centre().dec_deg())+" deg, "+
  684 + "Radius="+gammalib::str(circle->radius())+" deg");
  685 + }
697 686  
698   -/***********************************************************************//**
699   - * @brief Delete class members
700   - ***************************************************************************/
701   -void ctcubemask::free_members(void)
702   -{
703   - // Return
704   - return;
  687 + // Return region string
  688 + return rstring;
705 689 }
706 690  
707 691  
... ... @@ -741,11 +725,8 @@ void ctcubemask::save_fits(void)
741 725 // Get CTA observation from observation container
742 726 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]);
743 727  
744   - // Log filename
745   - if (logTerse()) {
746   - log << gammalib::parformat("Counts cube file");
747   - log << m_outcube.url() << std::endl;
748   - }
  728 + // Log counts cube file name
  729 + log_value(NORMAL, "Counts cube file", m_outcube.url());
749 730  
750 731 // Save event list
751 732 save_counts_map(obs, m_outcube);
... ... @@ -771,15 +752,16 @@ void ctcubemask::save_fits(void)
771 752 void ctcubemask::save_xml(void)
772 753 {
773 754 // Issue warning if output filename has no .xml suffix
774   - std::string suffix = gammalib::tolower(m_outcube.url().substr(m_outcube.length()-4,4));
  755 + std::string suffix = gammalib::tolower(m_outcube.url().substr(
  756 + m_outcube.length()-4,4));
775 757 if (suffix != ".xml") {
776   - log << "*** WARNING: Name of observation definition output file \""+
777   - m_outcube+"\"" << std::endl;
778   - log << "*** WARNING: does not terminate with \".xml\"." << std::endl;
779   - log << "*** WARNING: This is not an error, but might be misleading."
780   - " It is recommended" << std::endl;
781   - log << "*** WARNING: to use the suffix \".xml\" for observation"
782   - " definition files." << std::endl;
  758 + std::string msg = "\nWARNING: Name of observation definition output "
  759 + "file \""+m_outcube+"\" does not terminate with\n"
  760 + " \".xml\". This is not an error, but may "
  761 + "be misleading. It is recommended to use the\n"
  762 + " suffix \".xml\" for observation definition "
  763 + "files.";
  764 + log_string(TERSE, msg);
783 765 }
784 766  
785 767 // Loop over all observation in the container
... ... @@ -797,11 +779,8 @@ void ctcubemask::save_xml(void)
797 779 // Store output file name in observation
798 780 obs->eventfile(outfile);
799 781  
800   - // Log filename
801   - if (logTerse()) {
802   - log << gammalib::parformat("Counts cube file");
803   - log << outfile << std::endl;
804   - }
  782 + // Log counts cube file name
  783 + log_value(NORMAL, "Counts cube file", outfile);
805 784  
806 785 // Save event list
807 786 save_counts_map(obs, outfile);
... ...
src/ctcubemask/ctcubemask.hpp
... ... @@ -71,6 +71,7 @@ protected:
71 71 void free_members(void);
72 72 void get_parameters(void);
73 73 void apply_mask(GCTAObservation* obs);
  74 + std::string region_string(const GSkyRegion& region) const;
74 75 std::string set_outfile_name(const std::string& filename) const;
75 76 void save_fits(void);
76 77 void save_xml(void);
... ...
src/support/ctool.cpp
... ... @@ -928,6 +928,40 @@ void ctool::log_observations(const GChatter&amp; chatter,
928 928  
929 929  
930 930 /***********************************************************************//**
  931 + * @brief Log model container
  932 + *
  933 + * @param[in] chatter Minimum required chattiness
  934 + * @param[in] models Model container
  935 + * @param[in] what String specifying the container content
  936 + *
  937 + * Log models if chattiness is at least @p chatter.
  938 + ***************************************************************************/
  939 +void ctool::log_models(const GChatter& chatter,
  940 + const GModels& models,
  941 + const std::string& what)
  942 +{
  943 + // Get chattiness of ctool
  944 + GChatter chattiness = static_cast<GChatter>((*this)["chatter"].integer());
  945 +
  946 + // Only write message if chattiness is at least equal to the minimum
  947 + // required chattiness
  948 + if (chattiness >= chatter) {
  949 +
  950 + // Log observation header
  951 + log << std::endl;
  952 + log.header1(gammalib::number(what, models.size()));
  953 +
  954 + // Log observation content dependent on chattiness
  955 + log << models.print(chattiness) << std::endl;
  956 +
  957 + } // endif: Chattiness satisfied minimum required level
  958 +
  959 + // Return
  960 + return;
  961 +}
  962 +
  963 +
  964 +/***********************************************************************//**
931 965 * @brief Set response for all CTA observations in container
932 966 *
933 967 * @param[in,out] obs Observation container
... ...
src/support/ctool.hpp
... ... @@ -86,9 +86,12 @@ protected:
86 86 void require_inobs_nocube(const std::string& method);
87 87  
88 88 // Protected methods for logging
89   - void log_observations(const GChatter& chatter,
90   - const GObservations& obs,
91   - const std::string& what = "Observation");
  89 + void log_observations(const GChatter& chatter,
  90 + const GObservations& obs,
  91 + const std::string& what = "Observation");
  92 + void log_models(const GChatter& chatter,
  93 + const GModels& models,
  94 + const std::string& what = "Model");
92 95  
93 96 // Protected support methods
94 97 void set_response(GObservations& obs);
... ...
test/test_ctbin.py
... ... @@ -94,7 +94,7 @@ class Test(test):
94 94 ' emin=0.1 emax=100.0 enumbins=10 ebinalg="LOG"'+ \
95 95 ' nxpix=40 nypix=40 binsz=0.1 coordsys="CEL"'+ \
96 96 ' xref=83.63 yref=22.01 proj="CAR"'+ \
97   - ' logfile="ctbin_cmd1.log" chatter=1'
  97 + ' logfile="ctbin_cmd2.log" chatter=1'
98 98  
99 99 # Check if execution failed
100 100 self.test_assert(self._execute(cmd) != 0,
... ... @@ -162,6 +162,7 @@ class Test(test):
162 162 # Run copy of ctbin tool again
163 163 cpy_bin['logfile'] = 'ctbin_py2.log'
164 164 cpy_bin['chatter'] = 3
  165 + cpy_bin.logFileOpen()
165 166 cpy_bin.run()
166 167  
167 168 # Check content of observation container and counts cube. Now an empty
... ... @@ -213,9 +214,10 @@ class Test(test):
213 214 bin['yref'] = 22.01
214 215 bin['publish'] = True
215 216 bin['logfile'] = 'ctbin_py3.log'
216   - bin['chatter'] = 4
  217 + bin['chatter'] = 3
217 218  
218 219 # Execute ctbin tool
  220 + bin.logFileOpen()
219 221 bin.execute()
220 222  
221 223 # Check content of observation and cube (need multiplier=3 since
... ...
test/test_ctbutterfly.py
... ... @@ -124,6 +124,27 @@ class Test(test):
124 124 # Check result file
125 125 self._check_result_file('ctbutterfly_py1.dat')
126 126  
  127 + # Set-up ctbutterfly
  128 + butterfly = ctools.ctbutterfly()
  129 + butterfly['inobs'] = self._events
  130 + butterfly['inmodel'] = self._model
  131 + butterfly['srcname'] = 'Crab'
  132 + butterfly['caldb'] = self._caldb
  133 + butterfly['irf'] = self._irf
  134 + butterfly['emin'] = 0.1
  135 + butterfly['emax'] = 100.0
  136 + butterfly['fit'] = True
  137 + butterfly['outfile'] = 'ctbutterfly_py2.dat'
  138 + butterfly['logfile'] = 'ctbutterfly_py2.log'
  139 + butterfly['chatter'] = 3
  140 +
  141 + # Run ctbutterfly tool
  142 + butterfly.logFileOpen() # Make sure we get a log file
  143 + butterfly.execute()
  144 +
  145 + # Check result file
  146 + self._check_result_file('ctbutterfly_py2.dat')
  147 +
127 148 # Return
128 149 return
129 150  
... ...
test/test_ctcubemask.py
... ... @@ -110,12 +110,12 @@ class Test(test):
110 110 mask = ctools.ctcubemask()
111 111 mask['inobs'] = self._cntcube
112 112 mask['regfile'] = self._exclusion
113   - mask['outcube'] = 'ctcubemask_py1.fits'
114 113 mask['ra'] = 83.63
115 114 mask['dec'] = 22.01
116 115 mask['rad'] = 2.0
117 116 mask['emin'] = 0.1
118 117 mask['emax'] = 100.0
  118 + mask['outcube'] = 'ctcubemask_py1.fits'
119 119 mask['logfile'] = 'ctcubemask_py1.log'
120 120 mask['chatter'] = 2
121 121  
... ... @@ -127,11 +127,31 @@ class Test(test):
127 127 # Check result file
128 128 self._check_result_file('ctcubemask_py1.fits')
129 129  
  130 + # Set-up ctcubemask without exclusion regions
  131 + mask = ctools.ctcubemask()
  132 + mask['inobs'] = self._cntcube
  133 + mask['regfile'] = 'NONE'
  134 + mask['ra'] = 83.63
  135 + mask['dec'] = 22.01
  136 + mask['rad'] = 3.0
  137 + mask['emin'] = 0.1
  138 + mask['emax'] = 100.0
  139 + mask['outcube'] = 'ctcubemask_py2.fits'
  140 + mask['logfile'] = 'ctcubemask_py2.log'
  141 + mask['chatter'] = 3
  142 +
  143 + # Execute ctcubemask tool
  144 + mask.logFileOpen() # Make sure we get a log file
  145 + mask.execute()
  146 +
  147 + # Check result file
  148 + self._check_result_file('ctcubemask_py2.fits', events=5542)
  149 +
130 150 # Return
131 151 return
132 152  
133 153 # Check result file
134   - def _check_result_file(self, filename):
  154 + def _check_result_file(self, filename, events=4921):
135 155 """
136 156 Check result file
137 157 """
... ... @@ -139,8 +159,8 @@ class Test(test):
139 159 cube = gammalib.GCTAEventCube(filename)
140 160  
141 161 # Check counts cube
142   - self.test_value(cube.size(), 800000, 'Check for 800000 cube bins')
143   - self.test_value(cube.number(), 4921, 'Check for 4921 events')
  162 + self.test_value(cube.size(), 800000, 'Check for number of cube bins')
  163 + self.test_value(cube.number(), events, 'Check for number of events')
144 164  
145 165 # Return
146 166 return
... ...