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,6 +95,12 @@ public:
95 %rename(_require_inobs) require_inobs(const std::string& method); 95 %rename(_require_inobs) require_inobs(const std::string& method);
96 %rename(_require_inobs_nolist) require_inobs_nolist(const std::string& method); 96 %rename(_require_inobs_nolist) require_inobs_nolist(const std::string& method);
97 %rename(_require_inobs_nocube) require_inobs_nocube(const std::string& method); 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 %rename(_set_response) set_response(GObservations& obs); 104 %rename(_set_response) set_response(GObservations& obs);
99 %rename(_set_obs_response) set_obs_response(GCTAObservation* obs); 105 %rename(_set_obs_response) set_obs_response(GCTAObservation* obs);
100 %rename(_set_obs_bounds) set_obs_bounds(GObservations& obs); 106 %rename(_set_obs_bounds) set_obs_bounds(GObservations& obs);
@@ -119,6 +125,14 @@ public: @@ -119,6 +125,14 @@ public:
119 void require_inobs_nolist(const std::string& method); 125 void require_inobs_nolist(const std::string& method);
120 void require_inobs_nocube(const std::string& method); 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 // Protected support methods 136 // Protected support methods
123 void set_response(GObservations& obs); 137 void set_response(GObservations& obs);
124 void set_obs_response(GCTAObservation* obs); 138 void set_obs_response(GCTAObservation* obs);
src/ctbin/ctbin.cpp
@@ -40,7 +40,6 @@ @@ -40,7 +40,6 @@
40 /* __ Debug definitions __________________________________________________ */ 40 /* __ Debug definitions __________________________________________________ */
41 41
42 /* __ Coding definitions _________________________________________________ */ 42 /* __ Coding definitions _________________________________________________ */
43 -#define G_PLAW_WEIGHTS //!< Use power law in energy weight computation  
44 43
45 /* __ Constants __________________________________________________________ */ 44 /* __ Constants __________________________________________________________ */
46 45
@@ -227,16 +226,16 @@ void ctbin::run(void) @@ -227,16 +226,16 @@ void ctbin::run(void)
227 get_parameters(); 226 get_parameters();
228 227
229 // Write input observation container into logger 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 log_header1(TERSE, gammalib::number("Bin observation", m_obs.size())); 232 log_header1(TERSE, gammalib::number("Bin observation", m_obs.size()));
234 233
235 // Loop over all observations in the container 234 // Loop over all observations in the container
236 for (int i = 0; i < m_obs.size(); ++i) { 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 // Get CTA observation 240 // Get CTA observation
242 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]); 241 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
@@ -244,7 +243,7 @@ void ctbin::run(void) @@ -244,7 +243,7 @@ void ctbin::run(void)
244 // Skip observation if it's not CTA 243 // Skip observation if it's not CTA
245 if (obs == NULL) { 244 if (obs == NULL) {
246 std::string msg = " Skipping "+m_obs[i]->instrument()+ 245 std::string msg = " Skipping "+m_obs[i]->instrument()+
247 - " observation\n"; 246 + " observation";
248 log_string(NORMAL, msg); 247 log_string(NORMAL, msg);
249 continue; 248 continue;
250 } 249 }
@@ -252,7 +251,7 @@ void ctbin::run(void) @@ -252,7 +251,7 @@ void ctbin::run(void)
252 // Skip observation if we have a binned observation 251 // Skip observation if we have a binned observation
253 if (obs->eventtype() == "CountsCube") { 252 if (obs->eventtype() == "CountsCube") {
254 std::string msg = " Skipping binned "+m_obs[i]->instrument()+ 253 std::string msg = " Skipping binned "+m_obs[i]->instrument()+
255 - " observation\n"; 254 + " observation";
256 log_string(NORMAL, msg); 255 log_string(NORMAL, msg);
257 continue; 256 continue;
258 } 257 }
@@ -332,7 +331,7 @@ void ctbin::save(void) @@ -332,7 +331,7 @@ void ctbin::save(void)
332 ***************************************************************************/ 331 ***************************************************************************/
333 void ctbin::publish(const std::string& name) 332 void ctbin::publish(const std::string& name)
334 { 333 {
335 - // Write header 334 + // Write header into logger
336 log_header1(TERSE, "Publish counts cube"); 335 log_header1(TERSE, "Publish counts cube");
337 336
338 // Set default name is user name is empty 337 // Set default name is user name is empty
@@ -486,108 +485,97 @@ void ctbin::get_parameters(void) @@ -486,108 +485,97 @@ void ctbin::get_parameters(void)
486 * @exception GException::invalid_value 485 * @exception GException::invalid_value
487 * No event list or valid RoI found in observation. 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 void ctbin::fill_cube(GCTAObservation* obs) 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 // Return 580 // Return
593 return; 581 return;
@@ -607,61 +595,56 @@ void ctbin::fill_cube(GCTAObservation* obs) @@ -607,61 +595,56 @@ void ctbin::fill_cube(GCTAObservation* obs)
607 ***************************************************************************/ 595 ***************************************************************************/
608 void ctbin::set_weights(GCTAObservation* obs) 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 // Return 649 // Return
667 return; 650 return;
@@ -792,8 +775,6 @@ void ctbin::obs_cube(void) @@ -792,8 +775,6 @@ void ctbin::obs_cube(void)
792 } 775 }
793 776
794 777
795 -  
796 -  
797 /***********************************************************************//** 778 /***********************************************************************//**
798 * @brief Determine the counts cube layer usage. 779 * @brief Determine the counts cube layer usage.
799 * 780 *
src/ctbkgcube/ctbkgcube.cpp
@@ -216,48 +216,28 @@ void ctbkgcube::run(void) @@ -216,48 +216,28 @@ void ctbkgcube::run(void)
216 double logEmin = std::log10(m_background.energies()[0].TeV()); 216 double logEmin = std::log10(m_background.energies()[0].TeV());
217 double logEmax = std::log10(m_background.energies()[n-1].TeV()); 217 double logEmax = std::log10(m_background.energies()[n-1].TeV());
218 int nrequired = int((logEmax - logEmin) * 25.0); 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 // Initialise exposure cube 230 // Initialise exposure cube
240 init_cube(); 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 // Write header 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 // Copy models from observation container and reset output model 242 // Copy models from observation container and reset output model
263 // container 243 // container
@@ -289,22 +269,11 @@ void ctbkgcube::run(void) @@ -289,22 +269,11 @@ void ctbkgcube::run(void)
289 } // endif: had a background model 269 } // endif: had a background model
290 } // endif: had a CTA, HESS, MAGIC or VERITAS model 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 // If removal is requested, append model to output container and 278 // If removal is requested, append model to output container and
310 // remove it from the background model container ... 279 // remove it from the background model container ...
@@ -316,16 +285,16 @@ void ctbkgcube::run(void) @@ -316,16 +285,16 @@ void ctbkgcube::run(void)
316 } // endfor: looped over all background models 285 } // endfor: looped over all background models
317 286
318 // Write header 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 // Assign background models to container 290 // Assign background models to container
325 m_obs.models(m_bkgmdl); 291 m_obs.models(m_bkgmdl);
326 292
  293 + // Set pointer on logger depending on chattiness
  294 + GLog* logp = (logNormal()) ? &log : NULL;
  295 +
327 // Fill background cube from observations 296 // Fill background cube from observations
328 - m_background.fill(m_obs, &log); 297 + m_background.fill(m_obs, logp);
329 298
330 // Create a background model for the output background cube and append 299 // Create a background model for the output background cube and append
331 // that model to the input model in place of the original 300 // that model to the input model in place of the original
@@ -347,17 +316,11 @@ void ctbkgcube::run(void) @@ -347,17 +316,11 @@ void ctbkgcube::run(void)
347 // Append model to output container 316 // Append model to output container
348 m_outmdl.append(model); 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 // Recover original models 325 // Recover original models
363 m_obs.models(models_orig); 326 m_obs.models(models_orig);
@@ -381,10 +344,7 @@ void ctbkgcube::run(void) @@ -381,10 +344,7 @@ void ctbkgcube::run(void)
381 void ctbkgcube::save(void) 344 void ctbkgcube::save(void)
382 { 345 {
383 // Write header 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 // Get background cube and model file names 349 // Get background cube and model file names
390 m_outcube = (*this)["outcube"].filename(); 350 m_outcube = (*this)["outcube"].filename();
@@ -393,11 +353,8 @@ void ctbkgcube::save(void) @@ -393,11 +353,8 @@ void ctbkgcube::save(void)
393 // Save only if filename is non-empty 353 // Save only if filename is non-empty
394 if (!m_outcube.is_empty()) { 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 // Save background cube 359 // Save background cube
403 m_background.save(m_outcube, clobber()); 360 m_background.save(m_outcube, clobber());
@@ -408,11 +365,8 @@ void ctbkgcube::save(void) @@ -408,11 +365,8 @@ void ctbkgcube::save(void)
408 if ((!m_outmodel.is_empty()) && 365 if ((!m_outmodel.is_empty()) &&
409 (gammalib::tolower(m_outmodel.url()) != "none")) { 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 // Save output model for stacked analyses 371 // Save output model for stacked analyses
418 m_outmdl.save(m_outmodel.url()); 372 m_outmdl.save(m_outmodel.url());
@@ -432,10 +386,7 @@ void ctbkgcube::save(void) @@ -432,10 +386,7 @@ void ctbkgcube::save(void)
432 void ctbkgcube::publish(const std::string& name) 386 void ctbkgcube::publish(const std::string& name)
433 { 387 {
434 // Write header 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 // Set default name is user name is empty 391 // Set default name is user name is empty
441 std::string user_name(name); 392 std::string user_name(name);
@@ -443,11 +394,8 @@ void ctbkgcube::publish(const std::string&amp; name) @@ -443,11 +394,8 @@ void ctbkgcube::publish(const std::string&amp; name)
443 user_name = CTBKGCUBE_NAME; 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 // Publish exposure cube 400 // Publish exposure cube
453 m_background.cube().publish(user_name); 401 m_background.cube().publish(user_name);
@@ -614,6 +562,9 @@ void ctbkgcube::get_parameters(void) @@ -614,6 +562,9 @@ void ctbkgcube::get_parameters(void)
614 ***************************************************************************/ 562 ***************************************************************************/
615 void ctbkgcube::init_cube(void) 563 void ctbkgcube::init_cube(void)
616 { 564 {
  565 + // Write header
  566 + log_header1(TERSE, "Initialise background cube");
  567 +
617 // Extract exposure cube definition 568 // Extract exposure cube definition
618 const GWcs* proj = static_cast<const GWcs*>(m_background.cube().projection()); 569 const GWcs* proj = static_cast<const GWcs*>(m_background.cube().projection());
619 std::string wcs = m_background.cube().projection()->code(); 570 std::string wcs = m_background.cube().projection()->code();
@@ -631,11 +582,8 @@ void ctbkgcube::init_cube(void) @@ -631,11 +582,8 @@ void ctbkgcube::init_cube(void)
631 // If requested, insert energies at all event list energy boundaries 582 // If requested, insert energies at all event list energy boundaries
632 if (m_addbounds) { 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 // Loop over all observations 588 // Loop over all observations
641 for (int i = 0; i < m_obs.size(); ++i) { 589 for (int i = 0; i < m_obs.size(); ++i) {
@@ -655,7 +603,7 @@ void ctbkgcube::init_cube(void) @@ -655,7 +603,7 @@ void ctbkgcube::init_cube(void)
655 } 603 }
656 604
657 // Insert energy boundaries 605 // Insert energy boundaries
658 - energies = insert_energy_boundaries(energies, *cta, logger); 606 + energies = insert_energy_boundaries(energies, *cta, logp);
659 607
660 } // endfor: looped over all observations 608 } // endfor: looped over all observations
661 609
@@ -664,10 +612,8 @@ void ctbkgcube::init_cube(void) @@ -664,10 +612,8 @@ void ctbkgcube::init_cube(void)
664 // Setup background cube 612 // Setup background cube
665 m_background = GCTACubeBackground(wcs, coords, x, y, dx, dy, nx, ny, energies); 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 // Return 618 // Return
673 return; 619 return;
src/ctbutterfly/ctbutterfly.cpp
@@ -223,26 +223,14 @@ void ctbutterfly::run(void) @@ -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 // If fit is selected then do maximum likelihood fit 229 // If fit is selected then do maximum likelihood fit
239 if (m_fit) { 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 // Optimize and compute errors 235 // Optimize and compute errors
248 m_obs.optimize(m_opt); 236 m_obs.optimize(m_opt);
@@ -254,12 +242,10 @@ void ctbutterfly::run(void) @@ -254,12 +242,10 @@ void ctbutterfly::run(void)
254 GObservations::likelihood likelihood = m_obs.function(); 242 GObservations::likelihood likelihood = m_obs.function();
255 m_covariance = likelihood.curvature()->invert(); 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 } // endif: fit selected 250 } // endif: fit selected
265 251
@@ -270,11 +256,8 @@ void ctbutterfly::run(void) @@ -270,11 +256,8 @@ void ctbutterfly::run(void)
270 // then compute now the covariance matrix 256 // then compute now the covariance matrix
271 if (!m_fit && m_covariance.size() == 0) { 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 // Evaluate curvature matrix at the actual parameters 262 // Evaluate curvature matrix at the actual parameters
280 GOptimizerPars pars = models.pars(); 263 GOptimizerPars pars = models.pars();
@@ -286,18 +269,13 @@ void ctbutterfly::run(void) @@ -286,18 +269,13 @@ void ctbutterfly::run(void)
286 // to scale them before we can proceed. 269 // to scale them before we can proceed.
287 m_covariance = likelihood.curvature()->invert(); 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 } // endif: covariance computation needed 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 // Find parameter indices. We do this by the memory location of the 280 // Find parameter indices. We do this by the memory location of the
303 // model parameters. 281 // model parameters.
@@ -315,8 +293,6 @@ void ctbutterfly::run(void) @@ -315,8 +293,6 @@ void ctbutterfly::run(void)
315 } 293 }
316 } 294 }
317 295
318 - // Check indices  
319 -  
320 // Store model values and scales 296 // Store model values and scales
321 double prefactor_mean = (*skymodel)["Prefactor"].value(); 297 double prefactor_mean = (*skymodel)["Prefactor"].value();
322 double index_mean = (*skymodel)["Index"].value(); 298 double index_mean = (*skymodel)["Index"].value();
@@ -325,16 +301,12 @@ void ctbutterfly::run(void) @@ -325,16 +301,12 @@ void ctbutterfly::run(void)
325 double index_scale = (*skymodel)["Index"].scale(); 301 double index_scale = (*skymodel)["Index"].scale();
326 GEnergy pivot(pivot_mean, "MeV"); 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 // Extract covariance elements 311 // Extract covariance elements
340 double cov_pp = m_covariance(inx_prefactor,inx_prefactor); 312 double cov_pp = m_covariance(inx_prefactor,inx_prefactor);
@@ -353,35 +325,26 @@ void ctbutterfly::run(void) @@ -353,35 +325,26 @@ void ctbutterfly::run(void)
353 eigenvectors(cov_pp, cov_pg, cov_pg, cov_gg, 325 eigenvectors(cov_pp, cov_pg, cov_pg, cov_gg,
354 &lambda1, &lambda2, &vector1, &vector2); 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 // Confidence scaling 334 // Confidence scaling
365 double sigma = gammalib::erfinv(m_confidence) * gammalib::sqrt_two; 335 double sigma = gammalib::erfinv(m_confidence) * gammalib::sqrt_two;
366 double scale = (sigma*sigma); 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 // Compute minor and major axes of error ellipse 342 // Compute minor and major axes of error ellipse
377 double major = scale*std::sqrt(lambda1); 343 double major = scale*std::sqrt(lambda1);
378 double minor = scale*std::sqrt(lambda2); 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 // Walk around the error ellipse 349 // Walk around the error ellipse
387 int nt = 360; 350 int nt = 360;
@@ -401,12 +364,10 @@ void ctbutterfly::run(void) @@ -401,12 +364,10 @@ void ctbutterfly::run(void)
401 minor * sin_t * vector2[1]) * index_scale + 364 minor * sin_t * vector2[1]) * index_scale +
402 index_mean; 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 // Setup power law model 372 // Setup power law model
412 GModelSpectralPlaw plaw(prefactor, index, pivot); 373 GModelSpectralPlaw plaw(prefactor, index, pivot);
@@ -434,11 +395,8 @@ void ctbutterfly::run(void) @@ -434,11 +395,8 @@ void ctbutterfly::run(void)
434 395
435 } // endfor: looped over all angles 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 // Setup power law model 401 // Setup power law model
444 GModelSpectralPlaw plaw(prefactor_mean, index_mean, pivot); 402 GModelSpectralPlaw plaw(prefactor_mean, index_mean, pivot);
@@ -457,17 +415,11 @@ void ctbutterfly::run(void) @@ -457,17 +415,11 @@ void ctbutterfly::run(void)
457 m_energies.push_back(energy.MeV()); 415 m_energies.push_back(energy.MeV());
458 m_intensities.push_back(intensity); 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 } // endfor 424 } // endfor
473 425
@@ -492,11 +444,8 @@ void ctbutterfly::run(void) @@ -492,11 +444,8 @@ void ctbutterfly::run(void)
492 ***************************************************************************/ 444 ***************************************************************************/
493 void ctbutterfly::save(void) 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 // Get output filename 450 // Get output filename
502 m_outfile = (*this)["outfile"].filename(); 451 m_outfile = (*this)["outfile"].filename();
@@ -504,11 +453,8 @@ void ctbutterfly::save(void) @@ -504,11 +453,8 @@ void ctbutterfly::save(void)
504 // Save only if filename is non-empty 453 // Save only if filename is non-empty
505 if (!m_outfile.is_empty()) { 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 // Create CSV table with 4 columns 459 // Create CSV table with 4 columns
514 GCsv table(m_energies.size(), 4); 460 GCsv table(m_energies.size(), 4);
@@ -522,7 +468,7 @@ void ctbutterfly::save(void) @@ -522,7 +468,7 @@ void ctbutterfly::save(void)
522 } 468 }
523 469
524 // Save CSV table 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,6 +494,7 @@ void ctbutterfly::init_members(void)
548 m_max_iter = 50; 494 m_max_iter = 50;
549 m_apply_edisp = false; 495 m_apply_edisp = false;
550 m_fit = false; 496 m_fit = false;
  497 + m_chatter = static_cast<GChatter>(2);
551 m_ebounds.clear(); 498 m_ebounds.clear();
552 m_outfile.clear(); 499 m_outfile.clear();
553 500
@@ -582,6 +529,7 @@ void ctbutterfly::copy_members(const ctbutterfly&amp; app) @@ -582,6 +529,7 @@ void ctbutterfly::copy_members(const ctbutterfly&amp; app)
582 m_max_iter = app.m_max_iter; 529 m_max_iter = app.m_max_iter;
583 m_apply_edisp = app.m_apply_edisp; 530 m_apply_edisp = app.m_apply_edisp;
584 m_fit = app.m_fit; 531 m_fit = app.m_fit;
  532 + m_chatter = app.m_chatter;
585 m_ebounds = app.m_ebounds; 533 m_ebounds = app.m_ebounds;
586 m_outfile = app.m_outfile; 534 m_outfile = app.m_outfile;
587 535
@@ -668,12 +616,11 @@ void ctbutterfly::get_parameters(void) @@ -668,12 +616,11 @@ void ctbutterfly::get_parameters(void)
668 // m_covariance.load(matrixfilename); 616 // m_covariance.load(matrixfilename);
669 } 617 }
670 618
671 - // Read energy dispersion flag 619 + // Get remaining parameters
672 m_apply_edisp = (*this)["edisp"].boolean(); 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 // Optionally read ahead parameters so that they get correctly 625 // Optionally read ahead parameters so that they get correctly
679 // dumped into the log file 626 // dumped into the log file
src/ctbutterfly/ctbutterfly.hpp
@@ -96,6 +96,7 @@ protected: @@ -96,6 +96,7 @@ protected:
96 bool m_fit; //!< Do fit? 96 bool m_fit; //!< Do fit?
97 GEbounds m_ebounds; //!< Energy binning definition 97 GEbounds m_ebounds; //!< Energy binning definition
98 GFilename m_outfile; //!< Output ASCII file name 98 GFilename m_outfile; //!< Output ASCII file name
  99 + GChatter m_chatter; //!< Chattiness
99 100
100 // Protected members 101 // Protected members
101 GOptimizerLM m_opt; //!< Optimizer 102 GOptimizerLM m_opt; //!< Optimizer
src/ctcubemask/ctcubemask.cpp
@@ -212,18 +212,11 @@ void ctcubemask::run(void) @@ -212,18 +212,11 @@ void ctcubemask::run(void)
212 // Get parameters 212 // Get parameters
213 get_parameters(); 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 // Initialise counters 221 // Initialise counters
229 int n_observations = 0; 222 int n_observations = 0;
@@ -240,15 +233,8 @@ void ctcubemask::run(void) @@ -240,15 +233,8 @@ void ctcubemask::run(void)
240 // Continue only if observation is a CTA observation 233 // Continue only if observation is a CTA observation
241 if (obs != NULL) { 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 // Increment counter 239 // Increment counter
254 n_observations++; 240 n_observations++;
@@ -269,12 +255,8 @@ void ctcubemask::run(void) @@ -269,12 +255,8 @@ void ctcubemask::run(void)
269 m_use_xml = true; 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 // Optionally publish counts cube 261 // Optionally publish counts cube
280 if (m_publish) { 262 if (m_publish) {
@@ -307,16 +289,8 @@ void ctcubemask::run(void) @@ -307,16 +289,8 @@ void ctcubemask::run(void)
307 ***************************************************************************/ 289 ***************************************************************************/
308 void ctcubemask::save(void) 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 // Get counts cube filename 295 // Get counts cube filename
322 m_outcube = (*this)["outcube"].filename(); 296 m_outcube = (*this)["outcube"].filename();
@@ -351,11 +325,8 @@ void ctcubemask::save(void) @@ -351,11 +325,8 @@ void ctcubemask::save(void)
351 ***************************************************************************/ 325 ***************************************************************************/
352 void ctcubemask::publish(const std::string& name) 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 // Set default name is user name is empty 331 // Set default name is user name is empty
361 std::string user_name(name); 332 std::string user_name(name);
@@ -371,10 +342,8 @@ void ctcubemask::publish(const std::string&amp; name) @@ -371,10 +342,8 @@ void ctcubemask::publish(const std::string&amp; name)
371 GCTAEventCube* cube = dynamic_cast<GCTAEventCube*>(obs->events()); 342 GCTAEventCube* cube = dynamic_cast<GCTAEventCube*>(obs->events());
372 if (cube != NULL) { 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 // Publish counts cube 348 // Publish counts cube
380 cube->counts().publish(user_name); 349 cube->counts().publish(user_name);
@@ -387,6 +356,80 @@ void ctcubemask::publish(const std::string&amp; 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 * @brief Get application parameters 434 * @brief Get application parameters
392 * 435 *
@@ -485,7 +528,8 @@ void ctcubemask::get_parameters(void) @@ -485,7 +528,8 @@ void ctcubemask::get_parameters(void)
485 void ctcubemask::apply_mask(GCTAObservation* obs) 528 void ctcubemask::apply_mask(GCTAObservation* obs)
486 { 529 {
487 // Get pointer to CTA event cube. Continue only if we have a cube 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 if (cube != NULL) { 533 if (cube != NULL) {
490 534
491 // Extract event cube and energy boundaries 535 // Extract event cube and energy boundaries
@@ -545,14 +589,11 @@ void ctcubemask::apply_mask(GCTAObservation* obs) @@ -545,14 +589,11 @@ void ctcubemask::apply_mask(GCTAObservation* obs)
545 } 589 }
546 590
547 // Log selected energy band 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 // to -1.0 if requested 597 // to -1.0 if requested
557 if (m_select_roi) { 598 if (m_select_roi) {
558 GSkyRegionCircle roi(m_ra, m_dec, m_rad); 599 GSkyRegionCircle roi(m_ra, m_dec, m_rad);
@@ -565,15 +606,13 @@ void ctcubemask::apply_mask(GCTAObservation* obs) @@ -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 // Set all pixels inside selected energy bands and inside exclusion 617 // Set all pixels inside selected energy bands and inside exclusion
579 // regions to -1.0 618 // regions to -1.0
@@ -587,20 +626,15 @@ void ctcubemask::apply_mask(GCTAObservation* obs) @@ -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 else { 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 // Determine number of events after masking 640 // Determine number of events after masking
@@ -613,13 +647,9 @@ void ctcubemask::apply_mask(GCTAObservation* obs) @@ -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 // Put back map into the event cube 654 // Put back map into the event cube
625 cube->counts(map); 655 cube->counts(map);
@@ -631,77 +661,31 @@ void ctcubemask::apply_mask(GCTAObservation* obs) @@ -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,11 +725,8 @@ void ctcubemask::save_fits(void)
741 // Get CTA observation from observation container 725 // Get CTA observation from observation container
742 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]); 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 // Save event list 731 // Save event list
751 save_counts_map(obs, m_outcube); 732 save_counts_map(obs, m_outcube);
@@ -771,15 +752,16 @@ void ctcubemask::save_fits(void) @@ -771,15 +752,16 @@ void ctcubemask::save_fits(void)
771 void ctcubemask::save_xml(void) 752 void ctcubemask::save_xml(void)
772 { 753 {
773 // Issue warning if output filename has no .xml suffix 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 if (suffix != ".xml") { 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 // Loop over all observation in the container 767 // Loop over all observation in the container
@@ -797,11 +779,8 @@ void ctcubemask::save_xml(void) @@ -797,11 +779,8 @@ void ctcubemask::save_xml(void)
797 // Store output file name in observation 779 // Store output file name in observation
798 obs->eventfile(outfile); 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 // Save event list 785 // Save event list
807 save_counts_map(obs, outfile); 786 save_counts_map(obs, outfile);
src/ctcubemask/ctcubemask.hpp
@@ -71,6 +71,7 @@ protected: @@ -71,6 +71,7 @@ protected:
71 void free_members(void); 71 void free_members(void);
72 void get_parameters(void); 72 void get_parameters(void);
73 void apply_mask(GCTAObservation* obs); 73 void apply_mask(GCTAObservation* obs);
  74 + std::string region_string(const GSkyRegion& region) const;
74 std::string set_outfile_name(const std::string& filename) const; 75 std::string set_outfile_name(const std::string& filename) const;
75 void save_fits(void); 76 void save_fits(void);
76 void save_xml(void); 77 void save_xml(void);
src/support/ctool.cpp
@@ -928,6 +928,40 @@ void ctool::log_observations(const GChatter&amp; chatter, @@ -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 * @brief Set response for all CTA observations in container 965 * @brief Set response for all CTA observations in container
932 * 966 *
933 * @param[in,out] obs Observation container 967 * @param[in,out] obs Observation container
src/support/ctool.hpp
@@ -86,9 +86,12 @@ protected: @@ -86,9 +86,12 @@ protected:
86 void require_inobs_nocube(const std::string& method); 86 void require_inobs_nocube(const std::string& method);
87 87
88 // Protected methods for logging 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 // Protected support methods 96 // Protected support methods
94 void set_response(GObservations& obs); 97 void set_response(GObservations& obs);
test/test_ctbin.py
@@ -94,7 +94,7 @@ class Test(test): @@ -94,7 +94,7 @@ class Test(test):
94 ' emin=0.1 emax=100.0 enumbins=10 ebinalg="LOG"'+ \ 94 ' emin=0.1 emax=100.0 enumbins=10 ebinalg="LOG"'+ \
95 ' nxpix=40 nypix=40 binsz=0.1 coordsys="CEL"'+ \ 95 ' nxpix=40 nypix=40 binsz=0.1 coordsys="CEL"'+ \
96 ' xref=83.63 yref=22.01 proj="CAR"'+ \ 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 # Check if execution failed 99 # Check if execution failed
100 self.test_assert(self._execute(cmd) != 0, 100 self.test_assert(self._execute(cmd) != 0,
@@ -162,6 +162,7 @@ class Test(test): @@ -162,6 +162,7 @@ class Test(test):
162 # Run copy of ctbin tool again 162 # Run copy of ctbin tool again
163 cpy_bin['logfile'] = 'ctbin_py2.log' 163 cpy_bin['logfile'] = 'ctbin_py2.log'
164 cpy_bin['chatter'] = 3 164 cpy_bin['chatter'] = 3
  165 + cpy_bin.logFileOpen()
165 cpy_bin.run() 166 cpy_bin.run()
166 167
167 # Check content of observation container and counts cube. Now an empty 168 # Check content of observation container and counts cube. Now an empty
@@ -213,9 +214,10 @@ class Test(test): @@ -213,9 +214,10 @@ class Test(test):
213 bin['yref'] = 22.01 214 bin['yref'] = 22.01
214 bin['publish'] = True 215 bin['publish'] = True
215 bin['logfile'] = 'ctbin_py3.log' 216 bin['logfile'] = 'ctbin_py3.log'
216 - bin['chatter'] = 4 217 + bin['chatter'] = 3
217 218
218 # Execute ctbin tool 219 # Execute ctbin tool
  220 + bin.logFileOpen()
219 bin.execute() 221 bin.execute()
220 222
221 # Check content of observation and cube (need multiplier=3 since 223 # Check content of observation and cube (need multiplier=3 since
test/test_ctbutterfly.py
@@ -124,6 +124,27 @@ class Test(test): @@ -124,6 +124,27 @@ class Test(test):
124 # Check result file 124 # Check result file
125 self._check_result_file('ctbutterfly_py1.dat') 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 # Return 148 # Return
128 return 149 return
129 150
test/test_ctcubemask.py
@@ -110,12 +110,12 @@ class Test(test): @@ -110,12 +110,12 @@ class Test(test):
110 mask = ctools.ctcubemask() 110 mask = ctools.ctcubemask()
111 mask['inobs'] = self._cntcube 111 mask['inobs'] = self._cntcube
112 mask['regfile'] = self._exclusion 112 mask['regfile'] = self._exclusion
113 - mask['outcube'] = 'ctcubemask_py1.fits'  
114 mask['ra'] = 83.63 113 mask['ra'] = 83.63
115 mask['dec'] = 22.01 114 mask['dec'] = 22.01
116 mask['rad'] = 2.0 115 mask['rad'] = 2.0
117 mask['emin'] = 0.1 116 mask['emin'] = 0.1
118 mask['emax'] = 100.0 117 mask['emax'] = 100.0
  118 + mask['outcube'] = 'ctcubemask_py1.fits'
119 mask['logfile'] = 'ctcubemask_py1.log' 119 mask['logfile'] = 'ctcubemask_py1.log'
120 mask['chatter'] = 2 120 mask['chatter'] = 2
121 121
@@ -127,11 +127,31 @@ class Test(test): @@ -127,11 +127,31 @@ class Test(test):
127 # Check result file 127 # Check result file
128 self._check_result_file('ctcubemask_py1.fits') 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 # Return 150 # Return
131 return 151 return
132 152
133 # Check result file 153 # Check result file
134 - def _check_result_file(self, filename): 154 + def _check_result_file(self, filename, events=4921):
135 """ 155 """
136 Check result file 156 Check result file
137 """ 157 """
@@ -139,8 +159,8 @@ class Test(test): @@ -139,8 +159,8 @@ class Test(test):
139 cube = gammalib.GCTAEventCube(filename) 159 cube = gammalib.GCTAEventCube(filename)
140 160
141 # Check counts cube 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 # Return 165 # Return
146 return 166 return