From 04b1443dd9033b392fc1268d25a4e83e4f694df3 Mon Sep 17 00:00:00 2001 From: Jürgen Knödlseder Date: Wed, 3 Aug 2016 23:12:17 +0200 Subject: [PATCH] Adapt ctools to new GApplication logger methods (#1828) --- pyext/ctool.i | 14 ++++++++++++++ src/ctbin/ctbin.cpp | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------ src/ctbkgcube/ctbkgcube.cpp | 142 ++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------------------- src/ctbutterfly/ctbutterfly.cpp | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------------- src/ctbutterfly/ctbutterfly.hpp | 1 + src/ctcubemask/ctcubemask.cpp | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/ctcubemask/ctcubemask.hpp | 1 + src/support/ctool.cpp | 34 ++++++++++++++++++++++++++++++++++ src/support/ctool.hpp | 9 ++++++--- test/test_ctbin.py | 6 ++++-- test/test_ctbutterfly.py | 21 +++++++++++++++++++++ test/test_ctcubemask.py | 28 ++++++++++++++++++++++++---- 12 files changed, 463 insertions(+), 514 deletions(-) diff --git a/pyext/ctool.i b/pyext/ctool.i index 6ae4b84..0b82c0e 100644 --- a/pyext/ctool.i +++ b/pyext/ctool.i @@ -95,6 +95,12 @@ public: %rename(_require_inobs) require_inobs(const std::string& method); %rename(_require_inobs_nolist) require_inobs_nolist(const std::string& method); %rename(_require_inobs_nocube) require_inobs_nocube(const std::string& method); + %rename(_log_observations) log_observations(const GChatter& chatter, + const GObservations& obs, + const std::string& what); + %rename(_log_models) log_models(const GChatter& chatter, + const GModels& models, + const std::string& what); %rename(_set_response) set_response(GObservations& obs); %rename(_set_obs_response) set_obs_response(GCTAObservation* obs); %rename(_set_obs_bounds) set_obs_bounds(GObservations& obs); @@ -119,6 +125,14 @@ public: void require_inobs_nolist(const std::string& method); void require_inobs_nocube(const std::string& method); + // Protected methods for logging + void log_observations(const GChatter& chatter, + const GObservations& obs, + const std::string& what = "Observation"); + void log_models(const GChatter& chatter, + const GModels& models, + const std::string& what = "Model"); + // Protected support methods void set_response(GObservations& obs); void set_obs_response(GCTAObservation* obs); diff --git a/src/ctbin/ctbin.cpp b/src/ctbin/ctbin.cpp index a55c3bd..8ab6f93 100644 --- a/src/ctbin/ctbin.cpp +++ b/src/ctbin/ctbin.cpp @@ -40,7 +40,6 @@ /* __ Debug definitions __________________________________________________ */ /* __ Coding definitions _________________________________________________ */ -#define G_PLAW_WEIGHTS //!< Use power law in energy weight computation /* __ Constants __________________________________________________________ */ @@ -227,16 +226,16 @@ void ctbin::run(void) get_parameters(); // Write input observation container into logger - log_observations(NORMAL, m_obs); + log_observations(NORMAL, m_obs, "Input observation"); - // Write header + // Write header into logger log_header1(TERSE, gammalib::number("Bin observation", m_obs.size())); // Loop over all observations in the container for (int i = 0; i < m_obs.size(); ++i) { - // Write header for observation - log_header3(NORMAL, get_obs_header(m_obs[i])); + // Write header for the current observation + log_header3(TERSE, get_obs_header(m_obs[i])); // Get CTA observation GCTAObservation* obs = dynamic_cast(m_obs[i]); @@ -244,7 +243,7 @@ void ctbin::run(void) // Skip observation if it's not CTA if (obs == NULL) { std::string msg = " Skipping "+m_obs[i]->instrument()+ - " observation\n"; + " observation"; log_string(NORMAL, msg); continue; } @@ -252,7 +251,7 @@ void ctbin::run(void) // Skip observation if we have a binned observation if (obs->eventtype() == "CountsCube") { std::string msg = " Skipping binned "+m_obs[i]->instrument()+ - " observation\n"; + " observation"; log_string(NORMAL, msg); continue; } @@ -332,7 +331,7 @@ void ctbin::save(void) ***************************************************************************/ void ctbin::publish(const std::string& name) { - // Write header + // Write header into logger log_header1(TERSE, "Publish counts cube"); // Set default name is user name is empty @@ -486,108 +485,97 @@ void ctbin::get_parameters(void) * @exception GException::invalid_value * No event list or valid RoI found in observation. * - * Fills the events from an event list in the counts cube setup by init_cube. + * Fills the events from an event list into the counts cube. ***************************************************************************/ void ctbin::fill_cube(GCTAObservation* obs) { - // Continue only if observation pointer is valid - if (obs != NULL) { - - // Make sure that the observation holds a CTA event list. If this - // is not the case then throw an exception. - const GCTAEventList* events = dynamic_cast - (obs->events()); - if (events == NULL) { - std::string msg = "CTA Observation does not contain an event " - "list. An event list is needed to fill the " - "counts cube."; - throw GException::invalid_value(G_FILL_CUBE, msg); - } - - // Get the RoI - const GCTARoi& roi = events->roi(); - - // Check for RoI sanity - if (!roi.is_valid()) { - std::string msg = "No valid RoI found in input observation " - "\""+obs->name()+"\". Run ctselect to specify " - "an RoI for this observation before running " - "ctbin."; - throw GException::invalid_value(G_FILL_CUBE, msg); - } - - // Get counts cube usage flags - std::vector usage = cube_layer_usage(events->ebounds()); + // Make sure that the observation holds a CTA event list. If this + // is not the case then throw an exception. + const GCTAEventList* events = dynamic_cast + (obs->events()); + if (events == NULL) { + std::string msg = "CTA Observation does not contain an event " + "list. An event list is needed to fill the " + "counts cube."; + throw GException::invalid_value(G_FILL_CUBE, msg); + } - // Initialise binning statistics - int num_outside_roi = 0; - int num_outside_map = 0; - int num_outside_ebds = 0; - int num_in_map = 0; + // Get the RoI + const GCTARoi& roi = events->roi(); - // Fill counts sky map - for (int i = 0; i < events->size(); ++i) { + // Check for RoI sanity + if (!roi.is_valid()) { + std::string msg = "No valid RoI found in input observation " + "\""+obs->name()+"\". Run ctselect to specify " + "an RoI for this observation before running " + "ctbin."; + throw GException::invalid_value(G_FILL_CUBE, msg); + } - // Get event - const GCTAEventAtom* event = (*events)[i]; + // Get counts cube usage flags + std::vector usage = cube_layer_usage(events->ebounds()); - // Determine sky pixel - GCTAInstDir* inst = (GCTAInstDir*)&(event->dir()); - GSkyDir dir = inst->dir(); - GSkyPixel pixel = m_counts.dir2pix(dir); + // Initialise binning statistics + int num_outside_roi = 0; + int num_outside_map = 0; + int num_outside_ebds = 0; + int num_in_map = 0; - // Skip event if corresponding counts cube pixel is outside RoI - if (roi.centre().dir().dist_deg(dir) > roi.radius()) { - num_outside_roi++; - continue; - } + // Fill counts sky map + for (int i = 0; i < events->size(); ++i) { - // Skip event if corresponding counts cube pixel is outside the - // counts cube map range - if (pixel.x() < -0.5 || pixel.x() > (m_counts.nx()-0.5) || - pixel.y() < -0.5 || pixel.y() > (m_counts.ny()-0.5)) { - num_outside_map++; - continue; - } + // Get event + const GCTAEventAtom* event = (*events)[i]; - // Determine counts cube energy bin - int iebin = m_ebounds.index(event->energy()); + // Determine sky pixel + GCTAInstDir* inst = (GCTAInstDir*)&(event->dir()); + GSkyDir dir = inst->dir(); + GSkyPixel pixel = m_counts.dir2pix(dir); - // Skip event if the corresponding counts cube energy bin is not - // fully contained in the event list energy range. This avoids - // having partially filled bins. - if (!usage[iebin]) { - num_outside_ebds++; - continue; - } + // Skip event if corresponding counts cube pixel is outside RoI + if (roi.centre().dir().dist_deg(dir) > roi.radius()) { + num_outside_roi++; + continue; + } - // Fill event in skymap - m_counts(pixel, iebin) += 1.0; - num_in_map++; + // Skip event if corresponding counts cube pixel is outside the + // counts cube map range + if (pixel.x() < -0.5 || pixel.x() > (m_counts.nx()-0.5) || + pixel.y() < -0.5 || pixel.y() > (m_counts.ny()-0.5)) { + num_outside_map++; + continue; + } - // Signal that bin was filled - m_weights(pixel, iebin) = 1.0; + // Determine counts cube energy bin + int iebin = m_ebounds.index(event->energy()); - } // endfor: looped over all events + // Skip event if the corresponding counts cube energy bin is not + // fully contained in the event list energy range. This avoids + // having partially filled bins. + if (!usage[iebin]) { + num_outside_ebds++; + continue; + } - // Append GTIs - m_gti.extend(events->gti()); + // Fill event in skymap + m_counts(pixel, iebin) += 1.0; + num_in_map++; - // Update ontime and livetime - m_ontime += obs->ontime(); - m_livetime += obs->livetime(); + } // endfor: looped over all events - // Log filling results - log_value(TERSE, "Events in list", obs->events()->size()); - log_value(TERSE, "Events in cube", num_in_map); - log_value(TERSE, "Event bins outside RoI", num_outside_roi); - log_value(TERSE, "Events outside cube area", num_outside_map); - log_value(TERSE, "Events outside energy bins", num_outside_ebds); + // Append GTIs + m_gti.extend(events->gti()); - // Log cube - log_string(EXPLICIT, m_counts.print()); + // Update ontime and livetime + m_ontime += obs->ontime(); + m_livetime += obs->livetime(); - } // endif: observation was valid + // Log filling results + log_value(NORMAL, "Events in list", obs->events()->size()); + log_value(NORMAL, "Events in cube", num_in_map); + log_value(NORMAL, "Event bins outside RoI", num_outside_roi); + log_value(NORMAL, "Events outside cube area", num_outside_map); + log_value(NORMAL, "Events outside energy bins", num_outside_ebds); // Return return; @@ -607,61 +595,56 @@ void ctbin::fill_cube(GCTAObservation* obs) ***************************************************************************/ void ctbin::set_weights(GCTAObservation* obs) { - // Continue only if observation pointer is valid - if (obs != NULL) { - - // Make sure that the observation holds a CTA event list. If this - // is not the case then throw an exception. - const GCTAEventList* events = dynamic_cast - (obs->events()); - if (events == NULL) { - std::string msg = "CTA Observation does not contain an event " - "list. An event list is needed to fill the " - "counts cube."; - throw GException::invalid_value(G_SET_WEIGHTS, msg); - } - - // Get the RoI - const GCTARoi& roi = events->roi(); + // Make sure that the observation holds a CTA event list. If this + // is not the case then throw an exception. + const GCTAEventList* events = dynamic_cast + (obs->events()); + if (events == NULL) { + std::string msg = "CTA Observation does not contain an event " + "list. An event list is needed to fill the " + "counts cube."; + throw GException::invalid_value(G_SET_WEIGHTS, msg); + } - // Check for RoI sanity - if (!roi.is_valid()) { - std::string msg = "No valid RoI found in input observation " - "\""+obs->name()+"\". Run ctselect to specify " - "an RoI for this observation before running " - "ctbin."; - throw GException::invalid_value(G_SET_WEIGHTS, msg); - } + // Get the RoI + const GCTARoi& roi = events->roi(); - // Get counts cube usage flags - std::vector usage = cube_layer_usage(events->ebounds()); + // Check for RoI sanity + if (!roi.is_valid()) { + std::string msg = "No valid RoI found in input observation " + "\""+obs->name()+"\". Run ctselect to specify " + "an RoI for this observation before running " + "ctbin."; + throw GException::invalid_value(G_SET_WEIGHTS, msg); + } - // Loop over all pixels in counts cube - for (int pixel = 0; pixel < m_counts.npix(); ++pixel) { + // Get counts cube usage flags + std::vector usage = cube_layer_usage(events->ebounds()); - // Get pixel sky direction - GSkyDir dir = m_counts.inx2dir(pixel); + // Loop over all pixels in counts cube + for (int pixel = 0; pixel < m_counts.npix(); ++pixel) { - // Skip pixel if it is outside the RoI - if (roi.centre().dir().dist_deg(dir) > roi.radius()) { - continue; - } + // Get pixel sky direction + GSkyDir dir = m_counts.inx2dir(pixel); - // Loop over all energy layers of counts cube - for (int iebin = 0; iebin < m_ebounds.size(); ++iebin){ + // Skip pixel if it is outside the RoI + if (roi.centre().dir().dist_deg(dir) > roi.radius()) { + continue; + } - // Skip energy layer if the usage flag is false - if (!usage[iebin]) { - continue; - } - // Signal that bin was filled - m_weights(pixel, iebin) = 1.0; + // Loop over all energy layers of counts cube + for (int iebin = 0; iebin < m_ebounds.size(); ++iebin){ - } // endfor: looped over energy layers of counts cube + // Skip energy layer if the usage flag is false + if (!usage[iebin]) { + continue; + } + // Signal that bin was filled + m_weights(pixel, iebin) = 1.0; - } // endfor: looped over pixels of counts cube + } // endfor: looped over energy layers of counts cube - } // endif: observation was valid + } // endfor: looped over pixels of counts cube // Return return; @@ -792,8 +775,6 @@ void ctbin::obs_cube(void) } - - /***********************************************************************//** * @brief Determine the counts cube layer usage. * diff --git a/src/ctbkgcube/ctbkgcube.cpp b/src/ctbkgcube/ctbkgcube.cpp index 1859c1b..4e88d37 100644 --- a/src/ctbkgcube/ctbkgcube.cpp +++ b/src/ctbkgcube/ctbkgcube.cpp @@ -216,48 +216,28 @@ void ctbkgcube::run(void) double logEmin = std::log10(m_background.energies()[0].TeV()); double logEmax = std::log10(m_background.energies()[n-1].TeV()); int nrequired = int((logEmax - logEmin) * 25.0); - if ((n < nrequired) && logTerse()) { - log << std::endl; - log << "WARNING: "; - log << "Only " << n-1 << " energy bins have been requested. This may be " - "too few energy bins."; - log << std::endl << " "; - log << "At least 25 bins per decade in energy are recommended, which " - "in your case"; - log << std::endl << " "; - log << "would be " << nrequired-1 << " bins. Consider increasing the " - "number of energy bins."; - log << std::endl; - } - - // Write header - if (logTerse()) { - log << std::endl; - log.header1("Initialise background cube"); + if (n < nrequired) { + std::string msg = "\nWARNING: Only "+gammalib::str(n-1)+" energy bins " + "have been requested. This may be too few energy " + "bins.\n At least 25 bins per decade in " + "energy are recommended, which in your case\n" + " would be "+gammalib::str(nrequired-1)+ + " bins. Consider increasing the number of energy " + "bins."; + log_string(TERSE, msg); } // Initialise exposure cube init_cube(); - // Write observation(s) into logger - if (logTerse()) { - log << std::endl; - log.header1(gammalib::number("Observation",m_obs.size())); - log << m_obs.print(m_chatter) << std::endl; - } + // Write input observation container into logger + log_observations(NORMAL, m_obs, "Input observation"); - // Log input model - if (logTerse()) { - log << std::endl; - log.header1("Input model"); - log << m_obs.models().print(m_chatter) << std::endl; - } + // Write input model container into logger + log_models(NORMAL, m_obs.models(), "Input model"); // Write header - if (logTerse()) { - log << std::endl; - log.header1("Prepare model"); - } + log_header1(TERSE, "Prepare model"); // Copy models from observation container and reset output model // container @@ -289,22 +269,11 @@ void ctbkgcube::run(void) } // endif: had a background model } // endif: had a CTA, HESS, MAGIC or VERITAS model - // Log results - if (logTerse()) { - if (remove) { - log << gammalib::parformat("Remove model"); - } - else { - log << gammalib::parformat("Keep model"); - } - log << m_bkgmdl[i]->name(); - log << " "; - log << m_bkgmdl[i]->type(); - log << "("; - log << m_bkgmdl[i]->instruments(); - log << ")"; - log << std::endl; - } + // Log model removal or keeping + std::string what = (remove) ? "Remove model" : "Keep model"; + std::string value = m_bkgmdl[i]->name()+" "+m_bkgmdl[i]->type()+"("+ + m_bkgmdl[i]->instruments()+")"; + log_value(NORMAL, what, value); // If removal is requested, append model to output container and // remove it from the background model container ... @@ -316,16 +285,16 @@ void ctbkgcube::run(void) } // endfor: looped over all background models // Write header - if (logTerse()) { - log << std::endl; - log.header1("Generate background cube"); - } + log_header1(TERSE, "Generate background cube"); // Assign background models to container m_obs.models(m_bkgmdl); + // Set pointer on logger depending on chattiness + GLog* logp = (logNormal()) ? &log : NULL; + // Fill background cube from observations - m_background.fill(m_obs, &log); + m_background.fill(m_obs, logp); // Create a background model for the output background cube and append // that model to the input model in place of the original @@ -347,17 +316,11 @@ void ctbkgcube::run(void) // Append model to output container m_outmdl.append(model); - // Log background cube - if (logTerse()) { - log << m_background.print(m_chatter) << std::endl; - } + // Write background cube into logger + log_string(NORMAL, m_background.print(m_chatter)); - // Log output model - if (logTerse()) { - log << std::endl; - log.header1("Output model"); - log << m_outmdl << std::endl; - } + // Write input model container into logger + log_models(NORMAL, m_outmdl, "Output model"); // Recover original models m_obs.models(models_orig); @@ -381,10 +344,7 @@ void ctbkgcube::run(void) void ctbkgcube::save(void) { // Write header - if (logTerse()) { - log << std::endl; - log.header1("Save background cube"); - } + log_header1(TERSE, "Save background cube"); // Get background cube and model file names m_outcube = (*this)["outcube"].filename(); @@ -393,11 +353,8 @@ void ctbkgcube::save(void) // Save only if filename is non-empty if (!m_outcube.is_empty()) { - // Log filename - if (logTerse()) { - log << gammalib::parformat("Background cube file"); - log << m_outcube.url() << std::endl; - } + // Log background cube file name + log_value(NORMAL, "Background cube file", m_outcube.url()); // Save background cube m_background.save(m_outcube, clobber()); @@ -408,11 +365,8 @@ void ctbkgcube::save(void) if ((!m_outmodel.is_empty()) && (gammalib::tolower(m_outmodel.url()) != "none")) { - // Log filename - if (logTerse()) { - log << gammalib::parformat("Model definition file"); - log << m_outmodel.url() << std::endl; - } + // Log model definition file name + log_value(NORMAL, "Model definition file", m_outmodel.url()); // Save output model for stacked analyses m_outmdl.save(m_outmodel.url()); @@ -432,10 +386,7 @@ void ctbkgcube::save(void) void ctbkgcube::publish(const std::string& name) { // Write header - if (logTerse()) { - log << std::endl; - log.header1("Publish background cube"); - } + log_header1(TERSE, "Publish background cube"); // Set default name is user name is empty std::string user_name(name); @@ -443,11 +394,8 @@ void ctbkgcube::publish(const std::string& name) user_name = CTBKGCUBE_NAME; } - // Log filename - if (logTerse()) { - log << gammalib::parformat("Publish background cube"); - log << user_name << std::endl; - } + // Log background cube name + log_value(NORMAL, "Publish background cube", user_name); // Publish exposure cube m_background.cube().publish(user_name); @@ -614,6 +562,9 @@ void ctbkgcube::get_parameters(void) ***************************************************************************/ void ctbkgcube::init_cube(void) { + // Write header + log_header1(TERSE, "Initialise background cube"); + // Extract exposure cube definition const GWcs* proj = static_cast(m_background.cube().projection()); std::string wcs = m_background.cube().projection()->code(); @@ -631,11 +582,8 @@ void ctbkgcube::init_cube(void) // If requested, insert energies at all event list energy boundaries if (m_addbounds) { - // Set logger - GLog* logger = NULL; - if (logTerse()) { - logger = &log; - } + // Set pointer on logger depending on chattiness + GLog* logp = (logNormal()) ? &log : NULL; // Loop over all observations for (int i = 0; i < m_obs.size(); ++i) { @@ -655,7 +603,7 @@ void ctbkgcube::init_cube(void) } // Insert energy boundaries - energies = insert_energy_boundaries(energies, *cta, logger); + energies = insert_energy_boundaries(energies, *cta, logp); } // endfor: looped over all observations @@ -664,10 +612,8 @@ void ctbkgcube::init_cube(void) // Setup background cube m_background = GCTACubeBackground(wcs, coords, x, y, dx, dy, nx, ny, energies); - // Log background cube - if (logTerse()) { - log << m_background.print(m_chatter) << std::endl; - } + // Write background cube into logger + log_string(NORMAL, m_background.print(m_chatter)); // Return return; diff --git a/src/ctbutterfly/ctbutterfly.cpp b/src/ctbutterfly/ctbutterfly.cpp index 9671fe3..c25f7c5 100644 --- a/src/ctbutterfly/ctbutterfly.cpp +++ b/src/ctbutterfly/ctbutterfly.cpp @@ -223,26 +223,14 @@ void ctbutterfly::run(void) } } - // Write observation(s) into logger - if (logTerse()) { - log << std::endl; - if (m_obs.size() > 1) { - log.header1("Observations"); - } - else { - log.header1("Observation"); - } - log << m_obs << std::endl; - } + // Write input observation container into logger + log_observations(NORMAL, m_obs, "Input observation"); // If fit is selected then do maximum likelihood fit if (m_fit) { - // Write header - if (logTerse()) { - log << std::endl; - log.header1("Compute best-fit likelihood"); - } + // Write header into logger + log_header1(TERSE, "Compute best-fit likelihood"); // Optimize and compute errors m_obs.optimize(m_opt); @@ -254,12 +242,10 @@ void ctbutterfly::run(void) GObservations::likelihood likelihood = m_obs.function(); m_covariance = likelihood.curvature()->invert(); - // Write optimised model and covariance matrix into logger - if (logTerse()) { - log << m_opt << std::endl; - log << m_obs.models() << std::endl; - log << m_covariance << std::endl; - } + // Write optimizer, optimised model and covariance matrix into logger + log_string(NORMAL, m_opt.print(m_chatter)); + log_string(NORMAL, m_obs.models().print(m_chatter)); + log_string(EXPLICIT, m_covariance.print(m_chatter)); } // endif: fit selected @@ -270,11 +256,8 @@ void ctbutterfly::run(void) // then compute now the covariance matrix if (!m_fit && m_covariance.size() == 0) { - // Write header - if (logTerse()) { - log << std::endl; - log.header1("Compute covariance matrix"); - } + // Write header into logger + log_header1(TERSE, "Compute covariance matrix"); // Evaluate curvature matrix at the actual parameters GOptimizerPars pars = models.pars(); @@ -286,18 +269,13 @@ void ctbutterfly::run(void) // to scale them before we can proceed. m_covariance = likelihood.curvature()->invert(); - // Log covariance matrix - if (logTerse()) { - log << m_covariance << std::endl; - } + // Write covariance matrix into logger + log_string(EXPLICIT, m_covariance.print(m_chatter)); } // endif: covariance computation needed - // Write header - if (logTerse()) { - log << std::endl; - log.header1("Prepare butterfly computation"); - } + // Write header into logger + log_header1(TERSE, "Prepare butterfly computation"); // Find parameter indices. We do this by the memory location of the // model parameters. @@ -315,8 +293,6 @@ void ctbutterfly::run(void) } } - // Check indices - // Store model values and scales double prefactor_mean = (*skymodel)["Prefactor"].value(); double index_mean = (*skymodel)["Index"].value(); @@ -325,16 +301,12 @@ void ctbutterfly::run(void) double index_scale = (*skymodel)["Index"].scale(); GEnergy pivot(pivot_mean, "MeV"); - // Show parameter indices - if (logTerse()) { - log << gammalib::parformat("Prefactor"); - log << prefactor_mean << " ph/cm2/s/MeV ("; - log << inx_prefactor << ")" << std::endl; - log << gammalib::parformat("Index"); - log << index_mean << " (" << inx_index << ")" << std::endl; - log << gammalib::parformat("Pivot energy"); - log << pivot << std::endl; - } + // Write parameter indices into logger + log_value(NORMAL, "Prefactor", gammalib::str(prefactor_mean)+ + " ph/cm2/s/MeV ("+gammalib::str(inx_prefactor)+")"); + log_value(NORMAL, "Index", gammalib::str(index_mean)+ + " ("+gammalib::str(inx_index)+")"); + log_value(NORMAL, "Pivot energy", pivot.print()); // Extract covariance elements double cov_pp = m_covariance(inx_prefactor,inx_prefactor); @@ -353,35 +325,26 @@ void ctbutterfly::run(void) eigenvectors(cov_pp, cov_pg, cov_pg, cov_gg, &lambda1, &lambda2, &vector1, &vector2); - // Show eigenvectors and eigenvalues - if (logTerse()) { - log << gammalib::parformat("Eigenvalue 1") << lambda1 << std::endl; - log << gammalib::parformat("Eigenvalue 2") << lambda2 << std::endl; - log << gammalib::parformat("Eigenvector 1") << vector1 << std::endl; - log << gammalib::parformat("Eigenvector 2") << vector2 << std::endl; - } + // Write eigenvectors and eigenvalues into logger + log_value(NORMAL, "Eigenvalue 1", lambda1); + log_value(NORMAL, "Eigenvalue 2", lambda2); + log_value(NORMAL, "Eigenvector 1", vector1.print()); + log_value(NORMAL, "Eigenvector 2", vector2.print()); // Confidence scaling double sigma = gammalib::erfinv(m_confidence) * gammalib::sqrt_two; double scale = (sigma*sigma); - // Show confidence stuff - if (logTerse()) { - log << gammalib::parformat("Confidence level"); - log << m_confidence << std::endl; - log << gammalib::parformat("Corresponding scaling"); - log << scale << std::endl; - } + // Write confidence level information into logger + log_value(NORMAL, "Confidence level", m_confidence); + log_value(NORMAL, "Corresponding scaling", scale); // Compute minor and major axes of error ellipse double major = scale*std::sqrt(lambda1); double minor = scale*std::sqrt(lambda2); - // Write header - if (logTerse()) { - log << std::endl; - log.header1("Generate butterfly"); - } + // Write header into logger + log_header1(TERSE, "Generate butterfly"); // Walk around the error ellipse int nt = 360; @@ -401,12 +364,10 @@ void ctbutterfly::run(void) minor * sin_t * vector2[1]) * index_scale + index_mean; - // Show prefactor and index - if (logTerse()) { - log << gammalib::parformat("Angle "+gammalib::str(t*gammalib::rad2deg)); - log << prefactor << " ph/cm2/s/MeV; "; - log << index << std::endl; - } + // Write prefactor and index into logger + log_value(EXPLICIT, "Angle "+gammalib::str(t*gammalib::rad2deg), + gammalib::str(prefactor)+" ph/cm2/s/MeV; "+ + gammalib::str(index)); // Setup power law model GModelSpectralPlaw plaw(prefactor, index, pivot); @@ -434,11 +395,8 @@ void ctbutterfly::run(void) } // endfor: looped over all angles - // Write header - if (logTerse()) { - log << std::endl; - log.header1("Results"); - } + // Write header into logger + log_header1(TERSE, "Results"); // Setup power law model GModelSpectralPlaw plaw(prefactor_mean, index_mean, pivot); @@ -457,17 +415,11 @@ void ctbutterfly::run(void) m_energies.push_back(energy.MeV()); m_intensities.push_back(intensity); - // Log information - if (logTerse()) { - log << gammalib::parformat("Intensity at "+energy.print()); - log << intensity; - log << " ("; - log << m_min_intensities[k]; - log << ", "; - log << m_max_intensities[k]; - log << ") ph/cm2/s/MeV"; - log << std::endl; - } + // Write results into logger + log_value(NORMAL, "Intensity at "+energy.print(), + gammalib::str(intensity)+" ("+ + gammalib::str(m_min_intensities[k])+", "+ + gammalib::str(m_max_intensities[k])+") ph/cm2/s/MeV"); } // endfor @@ -492,11 +444,8 @@ void ctbutterfly::run(void) ***************************************************************************/ void ctbutterfly::save(void) { - // Write header - if (logTerse()) { - log << std::endl; - log.header1("Save Butterfly diagram"); - } + // Write header into logger + log_header1(TERSE, "Save Butterfly diagram"); // Get output filename m_outfile = (*this)["outfile"].filename(); @@ -504,11 +453,8 @@ void ctbutterfly::save(void) // Save only if filename is non-empty if (!m_outfile.is_empty()) { - // Log filename - if (logTerse()) { - log << "Save butterfly diagram into file \""+m_outfile+"\"."; - log << std::endl; - } + // Log butterfly diagram file name + log_value(NORMAL, "Butterfly file", m_outfile.url()); // Create CSV table with 4 columns GCsv table(m_energies.size(), 4); @@ -522,7 +468,7 @@ void ctbutterfly::save(void) } // Save CSV table - table.save(m_outfile, " ", clobber()); + table.save(m_outfile.url(), " ", clobber()); } @@ -548,6 +494,7 @@ void ctbutterfly::init_members(void) m_max_iter = 50; m_apply_edisp = false; m_fit = false; + m_chatter = static_cast(2); m_ebounds.clear(); m_outfile.clear(); @@ -582,6 +529,7 @@ void ctbutterfly::copy_members(const ctbutterfly& app) m_max_iter = app.m_max_iter; m_apply_edisp = app.m_apply_edisp; m_fit = app.m_fit; + m_chatter = app.m_chatter; m_ebounds = app.m_ebounds; m_outfile = app.m_outfile; @@ -668,12 +616,11 @@ void ctbutterfly::get_parameters(void) // m_covariance.load(matrixfilename); } - // Read energy dispersion flag + // Get remaining parameters m_apply_edisp = (*this)["edisp"].boolean(); - - // Read other parameters - m_confidence = (*this)["confidence"].real(); - m_fit = (*this)["fit"].boolean(); + m_confidence = (*this)["confidence"].real(); + m_fit = (*this)["fit"].boolean(); + m_chatter = static_cast((*this)["chatter"].integer()); // Optionally read ahead parameters so that they get correctly // dumped into the log file diff --git a/src/ctbutterfly/ctbutterfly.hpp b/src/ctbutterfly/ctbutterfly.hpp index a7e79c6..a4e8029 100644 --- a/src/ctbutterfly/ctbutterfly.hpp +++ b/src/ctbutterfly/ctbutterfly.hpp @@ -96,6 +96,7 @@ protected: bool m_fit; //!< Do fit? GEbounds m_ebounds; //!< Energy binning definition GFilename m_outfile; //!< Output ASCII file name + GChatter m_chatter; //!< Chattiness // Protected members GOptimizerLM m_opt; //!< Optimizer diff --git a/src/ctcubemask/ctcubemask.cpp b/src/ctcubemask/ctcubemask.cpp index 8ba0950..3496b8e 100644 --- a/src/ctcubemask/ctcubemask.cpp +++ b/src/ctcubemask/ctcubemask.cpp @@ -212,18 +212,11 @@ void ctcubemask::run(void) // Get parameters get_parameters(); - // Write observation(s) into logger - if (logTerse()) { - log << std::endl; - log.header1("Observations"); - log << m_obs << std::endl; - } + // Write input observation container into logger + log_observations(NORMAL, m_obs, "Input observation"); - // Write header - if (logTerse()) { - log << std::endl; - log.header1("Apply mask"); - } + // Write header into logger + log_header1(TERSE, "Apply mask"); // Initialise counters int n_observations = 0; @@ -240,15 +233,8 @@ void ctcubemask::run(void) // Continue only if observation is a CTA observation if (obs != NULL) { - // Write header for observation - if (logTerse()) { - if (obs->name().length() > 1) { - log.header3("Observation "+obs->name()); - } - else { - log.header3("Observation"); - } - } + // Write header for the current observation + log_header3(TERSE, get_obs_header(obs)); // Increment counter n_observations++; @@ -269,12 +255,8 @@ void ctcubemask::run(void) m_use_xml = true; } - // Write observation(s) into logger - if (logTerse()) { - log << std::endl; - log.header1("Observations after event bin masking"); - log << m_obs << std::endl; - } + // Write resulting observation container into logger + log_observations(NORMAL, m_obs, "Observations after event bin masking"); // Optionally publish counts cube if (m_publish) { @@ -307,16 +289,8 @@ void ctcubemask::run(void) ***************************************************************************/ void ctcubemask::save(void) { - // Write header - if (logTerse()) { - log << std::endl; - if (m_obs.size() > 1) { - log.header1("Save counts cubes"); - } - else { - log.header1("Save counts cube"); - } - } + // Write header into logger + log_header1(TERSE, gammalib::number("Save counts cube", m_obs.size())); // Get counts cube filename m_outcube = (*this)["outcube"].filename(); @@ -351,11 +325,8 @@ void ctcubemask::save(void) ***************************************************************************/ void ctcubemask::publish(const std::string& name) { - // Write header - if (logTerse()) { - log << std::endl; - log.header1("Publish counts cube"); - } + // Write header into logger + log_header1(TERSE, "Publish counts cube"); // Set default name is user name is empty std::string user_name(name); @@ -371,10 +342,8 @@ void ctcubemask::publish(const std::string& name) GCTAEventCube* cube = dynamic_cast(obs->events()); if (cube != NULL) { - // Log filename - if (logTerse()) { - log << "Publish \""+user_name+"\" counts cube." << std::endl; - } + // Log counts cube name + log_value(NORMAL, "Counts cube name", user_name); // Publish counts cube cube->counts().publish(user_name); @@ -387,6 +356,80 @@ void ctcubemask::publish(const std::string& name) } +/*========================================================================== + = = + = Private methods = + = = + ==========================================================================*/ + +/***********************************************************************//** + * @brief Initialise class members + ***************************************************************************/ +void ctcubemask::init_members(void) +{ + // Initialise parameters + m_regfile.clear(); + m_outcube.clear(); + m_prefix.clear(); + m_usepnt = false; + m_ra = 0.0; + m_dec = 0.0; + m_rad = 0.0; + m_emin = 0.0; + m_emax = 0.0; + m_publish = false; + + // Initialise protected members + m_obs.clear(); + m_infiles.clear(); + m_select_energy = true; + m_select_roi = true; + + // Return + return; +} + + +/***********************************************************************//** + * @brief Copy class members + * + * @param[in] app Application. + ***************************************************************************/ +void ctcubemask::copy_members(const ctcubemask& app) +{ + // Copy parameters + m_regfile = app.m_regfile; + m_outcube = app.m_outcube; + m_prefix = app.m_prefix; + m_usepnt = app.m_usepnt; + m_ra = app.m_ra; + m_dec = app.m_dec; + m_rad = app.m_rad; + m_emin = app.m_emin; + m_emax = app.m_emax; + m_publish = app.m_publish; + + // Copy protected members + m_obs = app.m_obs; + m_infiles = app.m_infiles; + m_select_energy = app.m_select_energy; + m_select_roi = app.m_select_roi; + + // Return + return; +} + + +/***********************************************************************//** + * @brief Delete class members + ***************************************************************************/ +void ctcubemask::free_members(void) +{ + // Return + return; +} + + /***********************************************************************//** * @brief Get application parameters * @@ -485,7 +528,8 @@ void ctcubemask::get_parameters(void) void ctcubemask::apply_mask(GCTAObservation* obs) { // Get pointer to CTA event cube. Continue only if we have a cube - GCTAEventCube* cube = dynamic_cast(const_cast(obs->events())); + GCTAEventCube* cube = dynamic_cast + (const_cast(obs->events())); if (cube != NULL) { // Extract event cube and energy boundaries @@ -545,14 +589,11 @@ void ctcubemask::apply_mask(GCTAObservation* obs) } // Log selected energy band - if (logTerse()) { - log << gammalib::parformat("Selected energy band"); - log << ebounds.emin(e_idx1).TeV() << " - "; - log << ebounds.emax(e_idx2).TeV() << " TeV"; - log << std::endl; - } + log_value(NORMAL, "Selected energy band", + gammalib::str(ebounds.emin(e_idx1).TeV())+" - "+ + gammalib::str(ebounds.emax(e_idx2).TeV())+" TeV"); - // Set all pixels inside selected energy bands but outside ROI + // Set all pixels inside selected energy bands but outside RoI // to -1.0 if requested if (m_select_roi) { GSkyRegionCircle roi(m_ra, m_dec, m_rad); @@ -565,15 +606,13 @@ void ctcubemask::apply_mask(GCTAObservation* obs) } } - // Log selected energy band - if (logTerse()) { - log << gammalib::parformat("Selected ROI"); - log << "RA=" << m_ra << " deg, "; - log << "DEC=" << m_dec << " deg, "; - log << "Radius=" << m_rad << " deg"; - log << std::endl; - } - } + // Log selected RoI + log_value(NORMAL, "Selected RoI", + "RA="+gammalib::str(m_ra)+" deg, "+ + "DEC="+gammalib::str(m_dec)+" deg, "+ + "Radius="+gammalib::str(m_rad)+" deg"); + + } // endif: applied RoI selection // Set all pixels inside selected energy bands and inside exclusion // regions to -1.0 @@ -587,20 +626,15 @@ void ctcubemask::apply_mask(GCTAObservation* obs) } } } - if (logTerse()) { - log << gammalib::parformat("Exclusion regions"); - log << std::endl; - log.indent(1); - log << regions.print(); - log << std::endl; - log.indent(0); + + // Log exclusion regions + for (int i = 0; i < regions.size(); ++i) { + log_value(NORMAL, "Exclusion region "+gammalib::str(i+1), + region_string(*(regions[i]))); } } else { - if (logTerse()) { - log << gammalib::parformat("Exclusion regions"); - log << "None" << std::endl; - } + log_value(NORMAL, "Exclusion regions", "None"); } // Determine number of events after masking @@ -613,13 +647,9 @@ void ctcubemask::apply_mask(GCTAObservation* obs) } } - // Dump number of events before and after masking - if (logTerse()) { - log << gammalib::parformat("Events before masking"); - log << sum_before << std::endl; - log << gammalib::parformat("Events after masking"); - log << sum_after << std::endl; - } + // Write number of events before and after masking into logger + log_value(NORMAL, "Events before masking", sum_before); + log_value(NORMAL, "Events after masking", sum_after); // Put back map into the event cube cube->counts(map); @@ -631,77 +661,31 @@ void ctcubemask::apply_mask(GCTAObservation* obs) } -/*========================================================================== - = = - = Private methods = - = = - ==========================================================================*/ - /***********************************************************************//** - * @brief Initialise class members - ***************************************************************************/ -void ctcubemask::init_members(void) -{ - // Initialise parameters - m_regfile.clear(); - m_outcube.clear(); - m_prefix.clear(); - m_usepnt = false; - m_ra = 0.0; - m_dec = 0.0; - m_rad = 0.0; - m_emin = 0.0; - m_emax = 0.0; - m_publish = false; - - // Initialise protected members - m_obs.clear(); - m_infiles.clear(); - m_select_energy = true; - m_select_roi = true; - - // Return - return; -} - - -/***********************************************************************//** - * @brief Copy class members + * @brief Return region string * - * @param[in] app Application. + * @param[in] region Sky region. + * + * Returns a formatted region string for logging. ***************************************************************************/ -void ctcubemask::copy_members(const ctcubemask& app) +std::string ctcubemask::region_string(const GSkyRegion& region) const { - // Copy parameters - m_regfile = app.m_regfile; - m_outcube = app.m_outcube; - m_prefix = app.m_prefix; - m_usepnt = app.m_usepnt; - m_ra = app.m_ra; - m_dec = app.m_dec; - m_rad = app.m_rad; - m_emin = app.m_emin; - m_emax = app.m_emax; - m_publish = app.m_publish; - - // Copy protected members - m_obs = app.m_obs; - m_infiles = app.m_infiles; - m_select_energy = app.m_select_energy; - m_select_roi = app.m_select_roi; - - // Return - return; -} - + // Initialise region string + std::string rstring; + + // Get pointer to circle + const GSkyRegionCircle* circle = dynamic_cast(®ion); + + // If the sky region is a circle then append Right Ascenscion, Declination + // and Radius to the region string + if (circle != NULL) { + rstring.append("RA="+gammalib::str(circle->centre().ra_deg())+" deg, "+ + "DEC="+gammalib::str(circle->centre().dec_deg())+" deg, "+ + "Radius="+gammalib::str(circle->radius())+" deg"); + } -/***********************************************************************//** - * @brief Delete class members - ***************************************************************************/ -void ctcubemask::free_members(void) -{ - // Return - return; + // Return region string + return rstring; } @@ -741,11 +725,8 @@ void ctcubemask::save_fits(void) // Get CTA observation from observation container GCTAObservation* obs = dynamic_cast(m_obs[0]); - // Log filename - if (logTerse()) { - log << gammalib::parformat("Counts cube file"); - log << m_outcube.url() << std::endl; - } + // Log counts cube file name + log_value(NORMAL, "Counts cube file", m_outcube.url()); // Save event list save_counts_map(obs, m_outcube); @@ -771,15 +752,16 @@ void ctcubemask::save_fits(void) void ctcubemask::save_xml(void) { // Issue warning if output filename has no .xml suffix - std::string suffix = gammalib::tolower(m_outcube.url().substr(m_outcube.length()-4,4)); + std::string suffix = gammalib::tolower(m_outcube.url().substr( + m_outcube.length()-4,4)); if (suffix != ".xml") { - log << "*** WARNING: Name of observation definition output file \""+ - m_outcube+"\"" << std::endl; - log << "*** WARNING: does not terminate with \".xml\"." << std::endl; - log << "*** WARNING: This is not an error, but might be misleading." - " It is recommended" << std::endl; - log << "*** WARNING: to use the suffix \".xml\" for observation" - " definition files." << std::endl; + std::string msg = "\nWARNING: Name of observation definition output " + "file \""+m_outcube+"\" does not terminate with\n" + " \".xml\". This is not an error, but may " + "be misleading. It is recommended to use the\n" + " suffix \".xml\" for observation definition " + "files."; + log_string(TERSE, msg); } // Loop over all observation in the container @@ -797,11 +779,8 @@ void ctcubemask::save_xml(void) // Store output file name in observation obs->eventfile(outfile); - // Log filename - if (logTerse()) { - log << gammalib::parformat("Counts cube file"); - log << outfile << std::endl; - } + // Log counts cube file name + log_value(NORMAL, "Counts cube file", outfile); // Save event list save_counts_map(obs, outfile); diff --git a/src/ctcubemask/ctcubemask.hpp b/src/ctcubemask/ctcubemask.hpp index 0d51bf3..d42cfcc 100644 --- a/src/ctcubemask/ctcubemask.hpp +++ b/src/ctcubemask/ctcubemask.hpp @@ -71,6 +71,7 @@ protected: void free_members(void); void get_parameters(void); void apply_mask(GCTAObservation* obs); + std::string region_string(const GSkyRegion& region) const; std::string set_outfile_name(const std::string& filename) const; void save_fits(void); void save_xml(void); diff --git a/src/support/ctool.cpp b/src/support/ctool.cpp index 33d2123..9618266 100644 --- a/src/support/ctool.cpp +++ b/src/support/ctool.cpp @@ -928,6 +928,40 @@ void ctool::log_observations(const GChatter& chatter, /***********************************************************************//** + * @brief Log model container + * + * @param[in] chatter Minimum required chattiness + * @param[in] models Model container + * @param[in] what String specifying the container content + * + * Log models if chattiness is at least @p chatter. + ***************************************************************************/ +void ctool::log_models(const GChatter& chatter, + const GModels& models, + const std::string& what) +{ + // Get chattiness of ctool + GChatter chattiness = static_cast((*this)["chatter"].integer()); + + // Only write message if chattiness is at least equal to the minimum + // required chattiness + if (chattiness >= chatter) { + + // Log observation header + log << std::endl; + log.header1(gammalib::number(what, models.size())); + + // Log observation content dependent on chattiness + log << models.print(chattiness) << std::endl; + + } // endif: Chattiness satisfied minimum required level + + // Return + return; +} + + +/***********************************************************************//** * @brief Set response for all CTA observations in container * * @param[in,out] obs Observation container diff --git a/src/support/ctool.hpp b/src/support/ctool.hpp index 66c4651..b3c20ff 100644 --- a/src/support/ctool.hpp +++ b/src/support/ctool.hpp @@ -86,9 +86,12 @@ protected: void require_inobs_nocube(const std::string& method); // Protected methods for logging - void log_observations(const GChatter& chatter, - const GObservations& obs, - const std::string& what = "Observation"); + void log_observations(const GChatter& chatter, + const GObservations& obs, + const std::string& what = "Observation"); + void log_models(const GChatter& chatter, + const GModels& models, + const std::string& what = "Model"); // Protected support methods void set_response(GObservations& obs); diff --git a/test/test_ctbin.py b/test/test_ctbin.py index c67aebf..52c5e30 100755 --- a/test/test_ctbin.py +++ b/test/test_ctbin.py @@ -94,7 +94,7 @@ class Test(test): ' emin=0.1 emax=100.0 enumbins=10 ebinalg="LOG"'+ \ ' nxpix=40 nypix=40 binsz=0.1 coordsys="CEL"'+ \ ' xref=83.63 yref=22.01 proj="CAR"'+ \ - ' logfile="ctbin_cmd1.log" chatter=1' + ' logfile="ctbin_cmd2.log" chatter=1' # Check if execution failed self.test_assert(self._execute(cmd) != 0, @@ -162,6 +162,7 @@ class Test(test): # Run copy of ctbin tool again cpy_bin['logfile'] = 'ctbin_py2.log' cpy_bin['chatter'] = 3 + cpy_bin.logFileOpen() cpy_bin.run() # Check content of observation container and counts cube. Now an empty @@ -213,9 +214,10 @@ class Test(test): bin['yref'] = 22.01 bin['publish'] = True bin['logfile'] = 'ctbin_py3.log' - bin['chatter'] = 4 + bin['chatter'] = 3 # Execute ctbin tool + bin.logFileOpen() bin.execute() # Check content of observation and cube (need multiplier=3 since diff --git a/test/test_ctbutterfly.py b/test/test_ctbutterfly.py index a6875f3..137f746 100755 --- a/test/test_ctbutterfly.py +++ b/test/test_ctbutterfly.py @@ -124,6 +124,27 @@ class Test(test): # Check result file self._check_result_file('ctbutterfly_py1.dat') + # Set-up ctbutterfly + butterfly = ctools.ctbutterfly() + butterfly['inobs'] = self._events + butterfly['inmodel'] = self._model + butterfly['srcname'] = 'Crab' + butterfly['caldb'] = self._caldb + butterfly['irf'] = self._irf + butterfly['emin'] = 0.1 + butterfly['emax'] = 100.0 + butterfly['fit'] = True + butterfly['outfile'] = 'ctbutterfly_py2.dat' + butterfly['logfile'] = 'ctbutterfly_py2.log' + butterfly['chatter'] = 3 + + # Run ctbutterfly tool + butterfly.logFileOpen() # Make sure we get a log file + butterfly.execute() + + # Check result file + self._check_result_file('ctbutterfly_py2.dat') + # Return return diff --git a/test/test_ctcubemask.py b/test/test_ctcubemask.py index 0d1f502..1c625a9 100755 --- a/test/test_ctcubemask.py +++ b/test/test_ctcubemask.py @@ -110,12 +110,12 @@ class Test(test): mask = ctools.ctcubemask() mask['inobs'] = self._cntcube mask['regfile'] = self._exclusion - mask['outcube'] = 'ctcubemask_py1.fits' mask['ra'] = 83.63 mask['dec'] = 22.01 mask['rad'] = 2.0 mask['emin'] = 0.1 mask['emax'] = 100.0 + mask['outcube'] = 'ctcubemask_py1.fits' mask['logfile'] = 'ctcubemask_py1.log' mask['chatter'] = 2 @@ -127,11 +127,31 @@ class Test(test): # Check result file self._check_result_file('ctcubemask_py1.fits') + # Set-up ctcubemask without exclusion regions + mask = ctools.ctcubemask() + mask['inobs'] = self._cntcube + mask['regfile'] = 'NONE' + mask['ra'] = 83.63 + mask['dec'] = 22.01 + mask['rad'] = 3.0 + mask['emin'] = 0.1 + mask['emax'] = 100.0 + mask['outcube'] = 'ctcubemask_py2.fits' + mask['logfile'] = 'ctcubemask_py2.log' + mask['chatter'] = 3 + + # Execute ctcubemask tool + mask.logFileOpen() # Make sure we get a log file + mask.execute() + + # Check result file + self._check_result_file('ctcubemask_py2.fits', events=5542) + # Return return # Check result file - def _check_result_file(self, filename): + def _check_result_file(self, filename, events=4921): """ Check result file """ @@ -139,8 +159,8 @@ class Test(test): cube = gammalib.GCTAEventCube(filename) # Check counts cube - self.test_value(cube.size(), 800000, 'Check for 800000 cube bins') - self.test_value(cube.number(), 4921, 'Check for 4921 events') + self.test_value(cube.size(), 800000, 'Check for number of cube bins') + self.test_value(cube.number(), events, 'Check for number of events') # Return return -- libgit2 0.21.4