From 1e00ea3def3c7c067f5237bfc76b903b838d5dbc Mon Sep 17 00:00:00 2001 From: Jürgen Knödlseder Date: Thu, 11 Aug 2016 13:58:12 +0200 Subject: [PATCH] Add ctool::is_valid_filename() method (#1828) --- pyext/ctool.i | 2 ++ src/ctbkgcube/ctbkgcube.cpp | 57 +++++++++++++-------------------------------------------- src/ctedispcube/ctedispcube.cpp | 29 ++++++++--------------------- src/cterror/cterror.cpp | 7 +++---- src/ctexpcube/ctexpcube.cpp | 29 ++++++++--------------------- src/ctlike/ctlike.cpp | 7 +++---- src/ctmodel/ctmodel.cpp | 34 +++++++++++++++------------------- src/ctpsfcube/ctpsfcube.cpp | 26 ++++++-------------------- src/support/ctool.cpp | 54 ++++++++++++++++++++++++++++++------------------------ src/support/ctool.hpp | 25 +++++++++++++++++++++++-- 10 files changed, 111 insertions(+), 159 deletions(-) diff --git a/pyext/ctool.i b/pyext/ctool.i index 3296033..05e5324 100644 --- a/pyext/ctool.i +++ b/pyext/ctool.i @@ -107,6 +107,7 @@ public: %rename(_get_obs_header) get_obs_header; %rename(_insert_energy_boundaries) insert_energy_boundaries; %rename(_cube_layer_usage) cube_layer_usage; + %rename(_is_valid_filename) is_valid_filename; %rename(_warn_too_few_energies) warn_too_few_energies; %rename(_warn_xml_suffix) warn_xml_suffix; @@ -154,6 +155,7 @@ public: const GCTAObservation& obs); std::vector cube_layer_usage(const GEbounds& cube_ebounds, const GEbounds& list_ebounds) const; + bool is_valid_filename(const GFilename& filename) const; // Protected warning strings std::string warn_too_few_energies(const GEnergies& energies) const; diff --git a/src/ctbkgcube/ctbkgcube.cpp b/src/ctbkgcube/ctbkgcube.cpp index 7b542f6..e33af8b 100644 --- a/src/ctbkgcube/ctbkgcube.cpp +++ b/src/ctbkgcube/ctbkgcube.cpp @@ -33,7 +33,6 @@ #include "GTools.hpp" /* __ Method name definitions ____________________________________________ */ -#define G_GET_PARAMETERS "ctbkgcube::get_parameters()" /* __ Debug definitions __________________________________________________ */ @@ -344,8 +343,7 @@ void ctbkgcube::save(void) m_outmodel = (*this)["outmodel"].filename(); // Determine whether a model definition file should be written - bool write_moddef = ((!m_outmodel.is_empty()) && - (gammalib::tolower(m_outmodel.url()) != "none")); + bool write_moddef = is_valid_filename(m_outmodel); // Save background cube if filename and the background cube are not empty if (!m_outcube.is_empty() && !m_background.cube().is_empty()) { @@ -465,58 +463,29 @@ void ctbkgcube::free_members(void) /***********************************************************************//** * @brief Get application parameters * - * @exception GException::invalid_value - * No background model definition XML file specified. - * * Get all task parameters from parameter file or (if required) by querying * the user. The parameters are read in the correct order. ***************************************************************************/ void ctbkgcube::get_parameters(void) { - // Setup observations from "inobs" parameter. Do not accept counts cubes. + // Setup observations from "inobs" parameter. Require response and accept + // event lists, but do not accept counts cubes. setup_observations(m_obs, true, true, false); // Get the incube filename std::string incube = (*this)["incube"].filename(); - // Check for filename validity - if ((gammalib::toupper(incube) == "NONE") || - (gammalib::strip_whitespace(incube) == "")) { - - // Create an event cube based on task parameters - GCTAEventCube cube = create_cube(m_obs); - - // Define background cube - m_background = GCTACubeBackground(cube); - - } // endif: filename was not valid - - // ... otherwise setup the background cube from the counts map - else { - - // Load event cube from filename - GCTAEventCube cube(incube); - - // Define background cube from file - m_background = GCTACubeBackground(cube); + // If the "incube" file name is valid then setup the background cube from + // the counts cube. Otherwise create a counts cube from the user + // parameters + GCTAEventCube cube = is_valid_filename(incube) ? GCTAEventCube(incube) + : create_cube(m_obs); - } // endelse: cube was loaded from file - - // If there are no models associated with the observations then load now - // the model definition from the XML file. Throw an exception if the - // input model is not set. - if (m_obs.models().size() == 0) { - std::string inmodel = (*this)["inmodel"].filename(); - if ((gammalib::toupper(inmodel) == "NONE") || - (gammalib::strip_whitespace(inmodel) == "")) { - std::string msg = "No model definition XML file specified. " - "Please set the \"inmodel\" parameter to the " - "XML file that contains the background model " - "definition."; - throw GException::invalid_value(G_GET_PARAMETERS, msg); - } - m_obs.models(GModels(inmodel)); - } + // Define background cube + m_background = GCTACubeBackground(cube); + + // Setup models from "inmodel" parameter + setup_models(m_obs); // Get remaining parameters m_addbounds = (*this)["addbounds"].boolean(); diff --git a/src/ctedispcube/ctedispcube.cpp b/src/ctedispcube/ctedispcube.cpp index 722cc5e..42385e3 100644 --- a/src/ctedispcube/ctedispcube.cpp +++ b/src/ctedispcube/ctedispcube.cpp @@ -356,27 +356,14 @@ void ctedispcube::get_parameters(void) double migramax = (*this)["migramax"].real(); int migrabins = (*this)["migrabins"].integer(); - // Check for filename validity - if ((incube == "NONE") || (gammalib::strip_whitespace(incube) == "")) { - - // Create an event cube based on task parameters - GCTAEventCube cube = create_cube(m_obs); - - // Define edisp cube - m_edispcube = GCTACubeEdisp(cube, migramax, migrabins); - - } - - // ... otherwise setup the energy disperison cube from the counts map - else { - - // Load event cube from filename - GCTAEventCube cube(incube); - - // Define Edisp cube - m_edispcube = GCTACubeEdisp(cube, migramax, migrabins); - - } // endelse: cube loaded from file + // If the "incube" file name is valid then setup the energy dispersion + // cube from the counts cube. Otherwise create a counts cube from the + // user parameters + GCTAEventCube cube = is_valid_filename(incube) ? GCTAEventCube(incube) + : create_cube(m_obs); + + // Define edisp cube + m_edispcube = GCTACubeEdisp(cube, migramax, migrabins); // Get remaining parameters m_addbounds = (*this)["addbounds"].boolean(); diff --git a/src/cterror/cterror.cpp b/src/cterror/cterror.cpp index cd27e5f..66645fd 100644 --- a/src/cterror/cterror.cpp +++ b/src/cterror/cterror.cpp @@ -354,9 +354,8 @@ void cterror::save(void) // Get output filename m_outmodel = (*this)["outmodel"].filename(); - // Save only if filename is not empty and not "NONE" - if (!m_outmodel.is_empty() && - gammalib::toupper(m_outmodel.url()) != "NONE") { + // Save only if filename is valid + if (is_valid_filename(m_outmodel)) { // Log filename log_value(NORMAL, "Model definition file", m_outmodel.url()); @@ -366,7 +365,7 @@ void cterror::save(void) } - // ... otherwise signal that file was not save + // ... otherwise signal that file was not saved else { log_value(NORMAL, "Model definition file", "NONE"); } diff --git a/src/ctexpcube/ctexpcube.cpp b/src/ctexpcube/ctexpcube.cpp index 580ee1f..3167bba 100644 --- a/src/ctexpcube/ctexpcube.cpp +++ b/src/ctexpcube/ctexpcube.cpp @@ -376,27 +376,14 @@ void ctexpcube::get_parameters(void) // Get the incube filename std::string incube = (*this)["incube"].filename(); - // Check for filename validity - if ((incube == "NONE") || (gammalib::strip_whitespace(incube) == "")) { - - // Create an event cube based on task parameters - GCTAEventCube cube = create_cube(m_obs); - - // Define exposure cube - m_expcube = GCTACubeExposure(cube); - - } // endif: filename was not valid - - // ... otherwise setup the exposure cube from the counts map - else { - - // Load event cube from filename - GCTAEventCube cube(incube); - - // Define exposure cube - m_expcube = GCTACubeExposure(cube); - - } // endelse: cube loaded from file + // If the "incube" file name is valid then setup the exposure cube from + // the counts cube. Otherwise create a counts cube from the user + // parameters + GCTAEventCube cube = is_valid_filename(incube) ? GCTAEventCube(incube) + : create_cube(m_obs); + + // Define exposure cube + m_expcube = GCTACubeExposure(cube); // Get remaining parameters m_addbounds = (*this)["addbounds"].boolean(); diff --git a/src/ctlike/ctlike.cpp b/src/ctlike/ctlike.cpp index 1ad0769..ec566be 100644 --- a/src/ctlike/ctlike.cpp +++ b/src/ctlike/ctlike.cpp @@ -319,9 +319,8 @@ void ctlike::save(void) // Get output filename m_outmodel = (*this)["outmodel"].filename(); - // Save only if filename is non-empty - if (!m_outmodel.is_empty() && - gammalib::toupper(m_outmodel.url()) != "NONE") { + // Save only if filename is valid + if (is_valid_filename(m_outmodel)) { // Log filename log_value(NORMAL, "Model definition file", m_outmodel.url()); @@ -331,7 +330,7 @@ void ctlike::save(void) } - // ... otherwise signal that file was not save + // ... otherwise signal that file was not saved else { log_value(NORMAL, "Model definition file", "NONE"); } diff --git a/src/ctmodel/ctmodel.cpp b/src/ctmodel/ctmodel.cpp index 65f9016..7c1d6b2 100644 --- a/src/ctmodel/ctmodel.cpp +++ b/src/ctmodel/ctmodel.cpp @@ -517,19 +517,9 @@ void ctmodel::get_parameters(void) // Read cube definition file std::string incube = (*this)["incube"].filename(); - // If no cube file has been specified then create a cube from - // the task parameters ... - if ((incube == "NONE") || - (gammalib::strip_whitespace(incube) == "")) { - - // Create cube from scratch - m_cube = create_cube(m_obs); - - } - - // ... otherwise load the cube from file and reset all bins - // to zero - else { + // If the cube filename is valid the load the cube and set all cube + // bins to zero + if (is_valid_filename(incube)) { // Load cube from given file m_cube.load(incube); @@ -538,6 +528,12 @@ void ctmodel::get_parameters(void) for (int i = 0; i < m_cube.size(); ++i) { m_cube[i]->counts(0.0); } + + } // endif: cube filename was valid + + // ... otherwise create a cube from the user parameters + else { + m_cube = create_cube(m_obs); } // Signal that cube has been set @@ -601,6 +597,8 @@ void ctmodel::get_parameters(void) * a stacked observation is requested (as detected by the presence of the * "expcube", "psfcube", and "bkgcube" parameters). In that case, it appended * a dummy event cube to the observation. + * + * @TODO Support stacked energy dispersion ***************************************************************************/ void ctmodel::get_obs(void) { @@ -609,7 +607,7 @@ void ctmodel::get_obs(void) // If no observation definition file has been specified then read all // parameters that are necessary to create an observation from scratch - if ((filename == "NONE") || (gammalib::strip_whitespace(filename) == "")) { + if (!is_valid_filename(filename)) { // Get response cube filenames std::string expcube = (*this)["expcube"].filename(); @@ -618,10 +616,8 @@ void ctmodel::get_obs(void) // If the filenames are valid then build an observation from cube // response information - if ((expcube != "NONE") && (psfcube != "NONE") && (bkgcube != "NONE") && - (gammalib::strip_whitespace(expcube) != "") && - (gammalib::strip_whitespace(psfcube) != "") && - (gammalib::strip_whitespace(bkgcube) != "")) { + if (is_valid_filename(expcube) && is_valid_filename(psfcube) && + is_valid_filename(bkgcube)) { // Get exposure, PSF and background cubes GCTACubeExposure exposure(expcube); @@ -667,7 +663,7 @@ void ctmodel::get_obs(void) } - } // endif: filename was "NONE" or "" + } // endif: filename was not valid // ... otherwise we have a file name else { diff --git a/src/ctpsfcube/ctpsfcube.cpp b/src/ctpsfcube/ctpsfcube.cpp index a36d89c..962132b 100644 --- a/src/ctpsfcube/ctpsfcube.cpp +++ b/src/ctpsfcube/ctpsfcube.cpp @@ -340,27 +340,13 @@ void ctpsfcube::get_parameters(void) double amax = (*this)["amax"].real(); int anumbins = (*this)["anumbins"].integer(); - // Check for filename validity - if ((incube == "NONE") || (gammalib::strip_whitespace(incube) == "")) { + // If the "incube" file name is valid then setup the PSF cube from the + // counts cube. Otherwise create a counts cube from the user parameters + GCTAEventCube cube = is_valid_filename(incube) ? GCTAEventCube(incube) + : create_cube(m_obs); - // Create an event cube based on task parameters - GCTAEventCube cube = create_cube(m_obs); - - // Define psf cube - m_psfcube = GCTACubePsf(cube, amax, anumbins); - - } - - // ... otherwise setup the PSF cube from the counts map - else { - - // Load event cube from filename - GCTAEventCube cube(incube); - - // Define psf cube - m_psfcube = GCTACubePsf(cube, amax, anumbins); - - } // endelse: cube loaded from file + // Define PSF cube + m_psfcube = GCTACubePsf(cube, amax, anumbins); // Get remaining parameters m_addbounds = (*this)["addbounds"].boolean(); diff --git a/src/support/ctool.cpp b/src/support/ctool.cpp index f015fe9..f69018d 100644 --- a/src/support/ctool.cpp +++ b/src/support/ctool.cpp @@ -50,7 +50,7 @@ /* __ Method name definitions ____________________________________________ */ #define G_SETUP_OBSERVATION "ctool::setup_observations(GObservations&)" -#define SETUP_MODELS "ctool::setup_models(GObservations&, std::string&)" +#define G_SETUP_MODELS "ctool::setup_models(GObservations&, std::string&)" #define G_GET_MEAN_POINTING "ctool::get_mean_pointing(GObservations&)" #define G_CREATE_EBOUNDS "ctool::create_ebounds()" #define G_RESTORE_EDISP "ctool::restore_edisp(GObservations&, "\ @@ -319,9 +319,9 @@ void ctool::free_members(void) * information from user parameters. * * If the observation container @p obs is empty, the method will extract the - * filename from the "inobs" parameter, and if the filename is neither empty - * nor "NONE", it will load the observation container from the specified file. - * Otherwise, the method will throw an exception. + * filename from the "inobs" parameter and load the observation container + * from the specified file. If the filename is either empty or "NONE" the + * method will throw an exception. * * If the "inobs" file is a FITS file, and depending on the information that * is found in the FITS file, the method will append a single CTA observation @@ -362,8 +362,7 @@ void ctool::setup_observations(GObservations& obs, // Throw an exception if the "inobs" parameter is not a valid // filename - if ((gammalib::toupper(filename.url()) == "NONE") || - filename.is_empty()) { + if (!is_valid_filename(filename)) { std::string msg = "The \"inobs\" parameter \""+filename.url()+ "\" is not a valid filename. Please specify " "a valid event list, counts cube or " @@ -450,7 +449,8 @@ void ctool::setup_observations(GObservations& obs, * @param[in] name Mandatory model name * * @exception GException::invalid_value - * Mandatory model name not found in observation container. + * Model definiton XML filename not valid or mandatory model name + * not found in model container. * * Setup a model container by loading the models from the "inmodel" * parameter. @@ -458,10 +458,12 @@ void ctool::setup_observations(GObservations& obs, * If the model container in the observation container @p obs is empty, the * method will extract the model container filename from the "inmodel" * parameter, load the model container and assign it to the observations - * container. + * container. If the filename is either empty or "NONE" the method will + * throw an exception. * * If a mandatory model name is specified, the method will further check - * whether a model with the name exists in the model container. + * whether a model with the name exists in the model container. If it does + * not exist, an exception is thrown. ***************************************************************************/ void ctool::setup_models(GObservations& obs, const std::string& name) @@ -474,6 +476,15 @@ void ctool::setup_models(GObservations& obs, // Get models XML filename GFilename filename = (*this)["inmodel"].filename(); + // Throw an exception if the "inmodel" parameter is not a valid + // filename + if (!is_valid_filename(filename)) { + std::string msg = "The \"inmodel\" parameter \""+filename.url()+ + "\" is not a valid filename. Please specify " + "a valid model definition XML file."; + throw GException::invalid_value(G_SETUP_MODELS, msg); + } + // Load model container and assign it to observations container obs.models(GModels(filename.url())); @@ -489,7 +500,7 @@ void ctool::setup_models(GObservations& obs, std::string msg = "Model \""+name+"\" not found in model " "container. Please add a model with that name " "or check for possible typos."; - throw GException::invalid_value(SETUP_MODELS, msg); + throw GException::invalid_value(G_SETUP_MODELS, msg); } } // endif: mandatory model name existed @@ -790,18 +801,18 @@ GCTAObservation ctool::create_cta_obs(void) * * @param[in] method Method name. * - * Throw an exception if the inobs parameter is either NONE or an empty + * Throw an exception if the "inobs" parameter is either "NONE" or an empty * string. ***************************************************************************/ void ctool::require_inobs(const std::string& method) { // Get inobs filename - std::string filename = (*this)["inobs"].filename(); + GFilename filename = (*this)["inobs"].filename(); // Throw exception if no infile is given - if (filename == "NONE" || gammalib::strip_whitespace(filename) == "") { + if (!is_valid_filename(filename)) { std::string msg = "A valid file needs to be specified for the " - "\"inobs\" parameter, yet \""+filename+ + "\"inobs\" parameter, yet \""+filename.url()+ "\" was given." " Specify a valid observation definition or " "FITS file to proceed."; @@ -1165,12 +1176,8 @@ void ctool::set_obs_response(GCTAObservation* obs) GFilename bkgcube((*this)["bkgcube"].filename()); // Extract stacked response information if available - if ((gammalib::toupper(expcube.url()) != "NONE") && - (gammalib::toupper(psfcube.url()) != "NONE") && - (gammalib::toupper(bkgcube.url()) != "NONE") && - !expcube.is_empty() && - !psfcube.is_empty() && - !bkgcube.is_empty()) { + if (is_valid_filename(expcube) && is_valid_filename(psfcube) && + is_valid_filename(bkgcube)) { // Load exposure, PSF and background cubes GCTACubeExposure exposure(expcube); @@ -1182,8 +1189,7 @@ void ctool::set_obs_response(GCTAObservation* obs) if (query_edisp) { // If filename is valid then use energy dispersion ... - if ((gammalib::toupper(edispcube.url()) != "NONE") && - !edispcube.is_empty()) { + if (is_valid_filename(edispcube)) { // Load energy dispersion cube GCTACubeEdisp edisp(edispcube); @@ -1355,7 +1361,7 @@ GObservations ctool::get_observations(const bool& get_response) // If no observation definition file has been specified then read all // parameters that are necessary to create an observation from scratch - if ((filename == "NONE") || (gammalib::strip_whitespace(filename) == "")) { + if (!is_valid_filename(filename)) { // Setup a new CTA observation GCTAObservation cta_obs = create_cta_obs(); @@ -1371,7 +1377,7 @@ GObservations ctool::get_observations(const bool& get_response) // Append observation to container obs.append(cta_obs); - } // endif: filename was "NONE" or "" + } // endif: filename was valid // ... otherwise we have a file name else { diff --git a/src/support/ctool.hpp b/src/support/ctool.hpp index 3d46fe6..4cadfca 100644 --- a/src/support/ctool.hpp +++ b/src/support/ctool.hpp @@ -112,6 +112,7 @@ protected: const GCTAObservation& obs); std::vector cube_layer_usage(const GEbounds& cube_ebounds, const GEbounds& list_ebounds) const; + bool is_valid_filename(const GFilename& filename) const; // Protected warning strings std::string warn_too_few_energies(const GEnergies& energies) const; @@ -131,9 +132,14 @@ protected: /***********************************************************************//** - * @brief Return observation container + * @brief Signal whether parameters should be read ahead * - * @return Reference to observation container + * @return True if parameters should be read ahead + * + * Ahead reading of parameter is useful in case that some parameters are only + * required in a late stage of the processing. By reading them ahead it is + * assured that these parameters will be queried at the beginning of the + * tool execution. ***************************************************************************/ inline const bool& ctool::read_ahead(void) const @@ -153,4 +159,19 @@ const GTimeReference& ctool::time_reference(void) const return (m_cta_ref); } + +/***********************************************************************//** + * @brief Check of a filename is valid + * + * @return True if filename is valid + * + * Checks whether a filename is not empty and not "NONE". + ***************************************************************************/ +inline +bool ctool::is_valid_filename(const GFilename& filename) const +{ + return (!filename.is_empty() && + (gammalib::tolower(filename.url()) != "none")); +} + #endif /* CTOOL_HPP */ -- libgit2 0.21.4