diff --git a/pyext/ctool.i b/pyext/ctool.i index 5120da1..3296033 100644 --- a/pyext/ctool.i +++ b/pyext/ctool.i @@ -113,8 +113,12 @@ public: // Protected methods const bool& read_ahead(void) const; const GTimeReference& time_reference(void) const; - GObservations get_observations(const bool& get_response = true); - void setup_observations(GObservations& obs); + + // Protected high-level setup methods + void setup_observations(GObservations& obs, const bool& response = true, + const bool& list = true, + const bool& cube = true); + void setup_models(GObservations& obs, const std::string& name = ""); // Protected methods that create objects from user parameters GEbounds create_ebounds(void); @@ -142,6 +146,7 @@ public: const std::vector& edisp) const; void set_obs_response(GCTAObservation* obs); void set_obs_bounds(GObservations& obs); + GObservations get_observations(const bool& get_response = true); GSkyDir get_mean_pointing(const GObservations& obs); size_t get_current_rss(void); std::string get_obs_header(const GObservation* obs); diff --git a/src/ctbin/ctbin.cpp b/src/ctbin/ctbin.cpp index ec799d9..c2f5584 100644 --- a/src/ctbin/ctbin.cpp +++ b/src/ctbin/ctbin.cpp @@ -437,20 +437,9 @@ void ctbin::free_members(void) ***************************************************************************/ void ctbin::get_parameters(void) { - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { - - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Throw exception if counts cube is given - require_inobs_nocube(G_GET_PARAMETERS); - - // Get observation container without response (not needed) - m_obs = get_observations(false); - - } // endif: there was no observation in the container + // Setup observations from "inobs" parameter. Do not request response + // information and do not accept counts cubes. + setup_observations(m_obs, false, true, false); // Create an event cube based on task parameters GCTAEventCube cube = create_cube(m_obs); diff --git a/src/ctbkgcube/ctbkgcube.cpp b/src/ctbkgcube/ctbkgcube.cpp index c5fb596..7b542f6 100644 --- a/src/ctbkgcube/ctbkgcube.cpp +++ b/src/ctbkgcube/ctbkgcube.cpp @@ -473,26 +473,8 @@ void ctbkgcube::free_members(void) ***************************************************************************/ void ctbkgcube::get_parameters(void) { - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { - - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Throw exception if counts cube is given - require_inobs_nocube(G_GET_PARAMETERS); - - // Build observation container - m_obs = get_observations(); - - } // endif: there was no observation in the container - - // ... otherwise add response information and energy boundaries in case - // that they are missing - else { - setup_observations(m_obs); - } + // Setup observations from "inobs" parameter. Do not accept counts cubes. + setup_observations(m_obs, true, true, false); // Get the incube filename std::string incube = (*this)["incube"].filename(); diff --git a/src/ctbutterfly/ctbutterfly.cpp b/src/ctbutterfly/ctbutterfly.cpp index 2bdac15..93d336a 100644 --- a/src/ctbutterfly/ctbutterfly.cpp +++ b/src/ctbutterfly/ctbutterfly.cpp @@ -584,37 +584,13 @@ void ctbutterfly::free_members(void) ***************************************************************************/ void ctbutterfly::get_parameters(void) { - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { - - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Build observation container - m_obs = get_observations(); - - } // endif: there was no observation in the container - - // ... otherwise add response information and energy boundaries in case - // that they are missing - else { - setup_observations(m_obs); - } - - // If there is are no models associated with the observations then - // load now the model definition - if (m_obs.models().size() == 0) { - - // Get models XML filename - std::string filename = (*this)["inmodel"].filename(); - - // Setup models for optimizing. - m_obs.models(GModels(filename)); - - } // endif: no models were associated with observations + // Setup observations from "inobs" parameter + setup_observations(m_obs); + + // Setup models from "inmodel" parameter + setup_models(m_obs, (*this)["srcname"].string()); - // Get name of test source and check container for this name + // Get name of test source m_srcname = (*this)["srcname"].string(); // Check model name and type diff --git a/src/ctcubemask/ctcubemask.cpp b/src/ctcubemask/ctcubemask.cpp index cbdb7d8..d3ca674 100644 --- a/src/ctcubemask/ctcubemask.cpp +++ b/src/ctcubemask/ctcubemask.cpp @@ -36,7 +36,6 @@ /* __ Method name definitions ____________________________________________ */ #define G_RUN "ctcubemask::run()" #define G_APPLY_MASK "ctcubemask::apply_mask(GCTAObservation*)" -#define G_GET_PARAMETERS "ctcubemask::get_parameters()" /* __ Debug definitions __________________________________________________ */ @@ -439,9 +438,6 @@ void ctcubemask::free_members(void) /***********************************************************************//** * @brief Get application parameters * - * @exception GException::invalid_value - * Parameter "inobs" is required for ctcubemask. - * * Get all task parameters from parameter file or (if required) by querying * the user. * @@ -455,20 +451,9 @@ void ctcubemask::get_parameters(void) m_select_energy = true; m_select_roi = true; - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { - - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Throw exception if event list is given - require_inobs_nolist(G_GET_PARAMETERS); - - // Build observation container without response (not needed) - m_obs = get_observations(false); - - } // endif: there was no observation in the container + // Setup observations from "inobs" parameter. Do not request response + // information and do not accept event lists. + setup_observations(m_obs, false, false, true); // Get parameters m_regfile = (*this)["regfile"].filename(); diff --git a/src/ctedispcube/ctedispcube.cpp b/src/ctedispcube/ctedispcube.cpp index 0b9e43b..722cc5e 100644 --- a/src/ctedispcube/ctedispcube.cpp +++ b/src/ctedispcube/ctedispcube.cpp @@ -346,26 +346,8 @@ void ctedispcube::free_members(void) ***************************************************************************/ void ctedispcube::get_parameters(void) { - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { - - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Throw exception if counts cube is given - require_inobs_nocube(G_GET_PARAMETERS); - - // Build observation container - m_obs = get_observations(); - - } // endif: there was no observation in the container - - // ... otherwise add response information and energy boundaries in case - // that they are missing - else { - setup_observations(m_obs); - } + // Setup observations from "inobs" parameter. Do not accept counts cubes. + setup_observations(m_obs, true, true, false); // Get the incube filename std::string incube = (*this)["incube"].filename(); diff --git a/src/cterror/cterror.cpp b/src/cterror/cterror.cpp index dbfa88e..cd27e5f 100644 --- a/src/cterror/cterror.cpp +++ b/src/cterror/cterror.cpp @@ -34,7 +34,6 @@ #include "GOptimizer.hpp" /* __ Method name definitions ____________________________________________ */ -#define G_GET_PARAMETERS "cterror::get_parameters()" #define G_ERR_BISECTION "cterror::error_bisection(double&, double&)" #define G_EVALUATE "cterror::evaluate(double&)" @@ -455,52 +454,19 @@ void cterror::free_members(void) /***********************************************************************//** * @brief Get application parameters * - * @exception GException::invalid_value - * Test source not found. - * * Get all task parameters from parameter file or (if required) by querying * the user. ***************************************************************************/ void cterror::get_parameters(void) { - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { - - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Build observation container - m_obs = get_observations(); - - } // endif: there was no observation in the container - - // ... otherwise add response information and energy boundaries in case - // that they are missing - else { - setup_observations(m_obs); - } - - // If there are no models associated with the observations then - // load now the model definition - if (m_obs.models().size() == 0) { - - // Get models XML filename - std::string filename = (*this)["inmodel"].filename(); + // Setup observations from "inobs" parameter + setup_observations(m_obs); + + // Setup models from "inmodel" parameter + setup_models(m_obs, (*this)["srcname"].string()); - // Setup models for optimizing. - m_obs.models(GModels(filename)); - - } // endif: no models were associated with observations - - // Get name of test source and check container for this name + // Get name of test source m_srcname = (*this)["srcname"].string(); - if (!m_obs.models().contains(m_srcname)) { - std::string msg = "Source \""+m_srcname+"\" not found in model " - "container. Please add a source with that name " - "or check for possible typos."; - throw GException::invalid_value(G_GET_PARAMETERS, msg); - } // Read energy dispersion flag m_apply_edisp = (*this)["edisp"].boolean(); diff --git a/src/ctexpcube/ctexpcube.cpp b/src/ctexpcube/ctexpcube.cpp index 6245454..580ee1f 100644 --- a/src/ctexpcube/ctexpcube.cpp +++ b/src/ctexpcube/ctexpcube.cpp @@ -34,7 +34,6 @@ #include "GWcs.hpp" /* __ Method name definitions ____________________________________________ */ -#define G_GET_PARAMETERS "ctexpcube::get_parameters()" #define G_SET_FROM_CNTMAP "ctexpcube::set_from_cntmap(std::string&)" /* __ Debug definitions __________________________________________________ */ @@ -371,26 +370,8 @@ void ctexpcube::free_members(void) ***************************************************************************/ void ctexpcube::get_parameters(void) { - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { - - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Throw exception if counts cube is given - require_inobs_nocube(G_GET_PARAMETERS); - - // Build observation container - m_obs = get_observations(); - - } // endif: there was no observation in the container - - // ... otherwise add response information and energy boundaries in case - // that they are missing - else { - setup_observations(m_obs); - } + // Setup observations from "inobs" parameter. Do not accept counts cubes. + setup_observations(m_obs, true, true, false); // Get the incube filename std::string incube = (*this)["incube"].filename(); diff --git a/src/ctlike/ctlike.cpp b/src/ctlike/ctlike.cpp index 50f9c35..1ad0769 100644 --- a/src/ctlike/ctlike.cpp +++ b/src/ctlike/ctlike.cpp @@ -33,7 +33,6 @@ #include "GTools.hpp" /* __ Method name definitions ____________________________________________ */ -#define G_GET_PARAMETERS "ctlike::get_parameters()" /* __ Debug definitions __________________________________________________ */ @@ -361,23 +360,8 @@ void ctlike::save(void) ***************************************************************************/ void ctlike::get_parameters(void) { - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { - - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Get observation container - m_obs = get_observations(); - - } // endif: there was no observation in the container - - // ... otherwise add response information and energy boundaries in case - // that they are missing - else { - setup_observations(m_obs); - } + // Setup observations from "inobs" parameter + setup_observations(m_obs); // If only single observation is used, read statistics parameter if (!m_use_xml) { diff --git a/src/ctpsfcube/ctpsfcube.cpp b/src/ctpsfcube/ctpsfcube.cpp index d35f7b5..a36d89c 100644 --- a/src/ctpsfcube/ctpsfcube.cpp +++ b/src/ctpsfcube/ctpsfcube.cpp @@ -34,7 +34,6 @@ #include "GWcs.hpp" /* __ Method name definitions ____________________________________________ */ -#define G_GET_PARAMETERS "ctpsfcube::get_parameters()" /* __ Debug definitions __________________________________________________ */ @@ -331,26 +330,8 @@ void ctpsfcube::free_members(void) ***************************************************************************/ void ctpsfcube::get_parameters(void) { - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { - - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Throw exception if counts cube is given - require_inobs_nocube(G_GET_PARAMETERS); - - // Build observation container - m_obs = get_observations(); - - } // endif: there was no observation in the container - - // ... otherwise add response information and energy boundaries in case - // that they are missing - else { - setup_observations(m_obs); - } + // Setup observations from "inobs" parameter. Do not accept counts cubes. + setup_observations(m_obs, true, true, false); // Get the incube filename std::string incube = (*this)["incube"].filename(); diff --git a/src/ctselect/ctselect.cpp b/src/ctselect/ctselect.cpp index 5323eb8..7206015 100644 --- a/src/ctselect/ctselect.cpp +++ b/src/ctselect/ctselect.cpp @@ -37,7 +37,6 @@ #define G_SELECT_EVENTS "ctselect::select_events(GCTAObservation*, "\ "std::string&, std::string&, std::string&)" #define G_SET_EBOUNDS "ctselect::set_ebounds(GCTAObservation*, GEbounds&)" -#define G_GET_PARAMETERS "ctselect::get_parameters()" /* __ Debug definitions __________________________________________________ */ @@ -502,20 +501,9 @@ void ctselect::get_parameters(void) m_select_roi = true; m_select_time = true; - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { - - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Throw exception if counts cube is given - require_inobs_nocube(G_GET_PARAMETERS); - - // Get observation container without response (not needed) - m_obs = get_observations(false); - - } // endif: there was no observation in the container + // Setup observations from "inobs" parameter. Do not request response + // information and do not accept counts cubes. + setup_observations(m_obs, false, true, false); // Get parameters m_usepnt = (*this)["usepnt"].boolean(); diff --git a/src/ctskymap/ctskymap.cpp b/src/ctskymap/ctskymap.cpp index cfa1dc2..f705124 100644 --- a/src/ctskymap/ctskymap.cpp +++ b/src/ctskymap/ctskymap.cpp @@ -35,7 +35,6 @@ /* __ Method name definitions ____________________________________________ */ #define G_INIT_MAP "ctskymap::init_map(GCTAObservation* obs)" #define G_BIN_EVENTS "ctskymap::bin_events(GCTAObservation*)" -#define G_GET_PARAMETERS "ctskymap::get_parameters()" /* __ Debug definitions __________________________________________________ */ @@ -402,20 +401,9 @@ void ctskymap::free_members(void) ***************************************************************************/ void ctskymap::get_parameters(void) { - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { - - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Throw exception if counts cube is given - require_inobs_nocube(G_GET_PARAMETERS); - - // Get observation container without response (not needed) - m_obs = get_observations(false); - - } // endif: there was no observation in the container + // Setup observations from "inobs" parameter. Do not request response + // information and do not accept counts cubes. + setup_observations(m_obs, false, true, false); // Create sky map based on task parameters m_skymap = create_map(m_obs); diff --git a/src/cttsmap/cttsmap.cpp b/src/cttsmap/cttsmap.cpp index ce0553e..db730cb 100644 --- a/src/cttsmap/cttsmap.cpp +++ b/src/cttsmap/cttsmap.cpp @@ -500,8 +500,7 @@ void cttsmap::free_members(void) * @brief Get application parameters * * @exception GException::invalid_value - * Test source not found or no RA/DEC parameters found for test - * source. + * Test source has no RA/DEC parameters. * * Get all task parameters from parameter file or (if required) by querying * the user. Most parameters are only required if no observation exists so @@ -511,44 +510,14 @@ void cttsmap::free_members(void) ***************************************************************************/ void cttsmap::get_parameters(void) { - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { + // Setup observations from "inobs" parameter + setup_observations(m_obs); + + // Setup models from "inmodel" parameter + setup_models(m_obs, (*this)["srcname"].string()); - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Get observation container - m_obs = get_observations(); - - } // endif: there was no observation in the container - - // ... otherwise add response information and energy boundaries in case - // that they are missing - else { - setup_observations(m_obs); - } - - // If there is are no models associated with the observations then - // load now the model definition - if (m_obs.models().size() == 0) { - - // Get models XML filename - std::string filename = (*this)["inmodel"].filename(); - - // Setup models for optimizing. - m_obs.models(GModels(filename)); - - } // endif: no models were associated with observations - - // Get name of test source and check container for this name + // Get name of test source m_srcname = (*this)["srcname"].string(); - if (!m_obs.models().contains(m_srcname)) { - std::string msg = "Source \""+m_srcname+"\" not found in model " - "container. Please add a source with that name " - "or check for a possible typos."; - throw GException::invalid_value(G_GET_PARAMETERS, msg); - } // Get Model and store it as protected member m_testsource = m_obs.models()[m_srcname]->clone(); diff --git a/src/ctulimit/ctulimit.cpp b/src/ctulimit/ctulimit.cpp index 693bd14..a087a0d 100644 --- a/src/ctulimit/ctulimit.cpp +++ b/src/ctulimit/ctulimit.cpp @@ -34,7 +34,6 @@ #include "GOptimizer.hpp" /* __ Method name definitions ____________________________________________ */ -#define G_GET_PARAMETERS "ctulimit::get_parameters()" #define G_GET_MODEL_PARAMETER "ctulimit::get_model_parameter()" #define G_UL_BISECTION "ctulimit::ul_bisection(double&, double&)" #define G_EVALUATE "ctulimit::evaluate(double&)" @@ -461,46 +460,18 @@ void ctulimit::free_members(void) /***********************************************************************//** * @brief Get application parameters * - * @exception GException::invalid_value - * Test source not found. - * * Get all task parameters from parameter file or (if required) by querying * the user. ***************************************************************************/ void ctulimit::get_parameters(void) { - // If there are no observations in container then load them via user - // parameters - if (m_obs.size() == 0) { - - // Throw exception if no input observation file is given - require_inobs(G_GET_PARAMETERS); - - // Build observation container - m_obs = get_observations(); - - } // endif: there was no observation in the container - - // ... otherwise add response information and energy boundaries in case - // that they are missing - else { - setup_observations(m_obs); - } - - // If there is are no models associated with the observations then - // load now the model definition - if (m_obs.models().size() == 0) { - - // Get models XML filename - std::string filename = (*this)["inmodel"].filename(); - - // Setup models for optimizing. - m_obs.models(GModels(filename)); - - } // endif: no models were associated with observations + // Setup observations from "inobs" parameter + setup_observations(m_obs); + + // Setup models from "inmodel" parameter + setup_models(m_obs, (*this)["srcname"].string()); - // Get name of test source. The get_model_parameter() method will check - // where a source with the given name exists in the model container. + // Get name of test source m_srcname = (*this)["srcname"].string(); // Get relevant model and parameter for upper limit computation diff --git a/src/support/ctool.cpp b/src/support/ctool.cpp index db5a264..f015fe9 100644 --- a/src/support/ctool.cpp +++ b/src/support/ctool.cpp @@ -50,6 +50,7 @@ /* __ Method name definitions ____________________________________________ */ #define G_SETUP_OBSERVATION "ctool::setup_observations(GObservations&)" +#define 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&, "\ @@ -304,189 +305,194 @@ void ctool::free_members(void) /***********************************************************************//** - * @brief Get observation container + * @brief Setup observation container * - * @param[in] get_response Indicates whether response information should - * be loaded (default: true) + * @param[in] obs Observation container + * @param[in] response Require response + * @param[in] list Accept event list as "inobs" parameter + * @param[in] cube Accept counts cube as "inobs" parameter * - * Get an observation container according to the user parameters. The method - * supports loading of a individual FITS file or an observation definition - * file in XML format. If the input filename is empty, parameters are read - * to build a CTA observation from scratch. + * @exception GException::invalid_value + * Invalid "inobs" parameter encountered. + * + * Setup an observation container by extracting all required missing + * 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. + * + * 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 + * to the observation container, containing either an event list or a counts + * cube. It will set the m_use_xml member to false to signal that no + * observation XML file should be used for saving. The @p list and @p cube + * parameters can be used to specify whether the method actually should accept + * event lists or counts cube. If it shouldn't the method will throw an + * exception. + * + * If the "inobs" file is not a FITS file, the method assumes that an + * observation definition XML file has been specified, and will load that + * file into the observation container. It will set the m_use_xml member to + * true to signal that an observation XML file should be used for saving. No + * checking on event list or counts cubes will be done on the observation + * container. + * + * By default, the method will also setup the response for all CTA + * observations in the container. In case that no response information is + * required, the @p response argument should be set to @p false. See the + * set_response() method for details. + * + * + * The method will also setup the observation boundaries for all CTA + * observations in the container that contain event lists. For details, see + * the set_obs_bounds() method. ***************************************************************************/ -GObservations ctool::get_observations(const bool& get_response) +void ctool::setup_observations(GObservations& obs, + const bool& response, + const bool& list, + const bool& cube) { - // Initialise empty observation container - GObservations obs; - - // Get the filename from the input parameters - std::string filename = (*this)["inobs"].filename(); - - // 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) == "")) { - - // Setup a new CTA observation - GCTAObservation cta_obs = create_cta_obs(); - - // Get response if required - if (get_response) { - - // Set response - set_obs_response(&cta_obs); - - } // endif: response was required - - // Append observation to container - obs.append(cta_obs); - - } // endif: filename was "NONE" or "" + // Load observations if there are none in the container + if (obs.size() == 0) { - // ... otherwise we have a file name - else { + // Get the filename from the "inobs" parameter + GFilename filename = (*this)["inobs"].filename(); - // If file is a FITS file then create an empty CTA observation - // and load file into observation - if (GFilename(filename).is_fits()) { + // Throw an exception if the "inobs" parameter is not a valid + // filename + if ((gammalib::toupper(filename.url()) == "NONE") || + filename.is_empty()) { + std::string msg = "The \"inobs\" parameter \""+filename.url()+ + "\" is not a valid filename. Please specify " + "a valid event list, counts cube or " + "observation definition XML file."; + throw GException::invalid_value(G_SETUP_OBSERVATION, msg); + } - // Allocate empty CTA observation - GCTAObservation cta_obs; + // If file does not exist then throw an exceptions + if (!filename.exists()) { + std::string msg = "The \"inobs\" parameter \""+filename.url()+ + "\" specifies a file that does not " + "exist. Please specify a valid event " + "list, counts cube or observation " + "definition XML file."; + throw GException::invalid_value(G_SETUP_OBSERVATION, msg); + } - // Load data - cta_obs.load(filename); + // If the file is a FITS file then load it into a CTA + // observation and append that observation to the container ... + else if (filename.is_fits()) { - // Get response if required - if (get_response) { + // Load CTA observation + GCTAObservation cta(filename); - // Set response - set_obs_response(&cta_obs); + // If no event list is accepted but an event list has been + // loaded then throw an exception + if (!list && cta.eventtype() == "EventList") { + std::string msg = "The \"inobs\" parameter \""+filename.url()+ + "\" specifies an event list, but this " + "tool does not accept event lists."; + throw GException::invalid_value(G_SETUP_OBSERVATION, msg); + } - } // endif: response was required + // If no counts cube is accepted but a conts cube has been + // loaded then throw an exception + if (!cube && cta.eventtype() == "CountsCube") { + std::string msg = "The \"inobs\" parameter \""+filename.url()+ + "\" specifies a counts cube, but this " + "tool does not accept counts cubes."; + throw GException::invalid_value(G_SETUP_OBSERVATION, msg); + } - // Append observation to container - obs.append(cta_obs); + // Append CTA observation to observation container + obs.append(cta); // Signal that no XML file should be used for storage m_use_xml = false; - } + } // endelse: file was a FITS file - // ... otherwise load file into observation container + // ... otherwise it is assumed that the file is an observation + // definition XML file and the file is loaded into the + // observation container else { - // Load observations from XML file + // Load observation definition file obs.load(filename); - // Get response if required - if (get_response) { - - // For all observations that have no response, set the response - // from the task parameters - set_response(obs); - - } // endif: response was required - - // Set observation boundary parameters (emin, emax, rad) - set_obs_bounds(obs); - // Signal that XML file should be used for storage m_use_xml = true; } // endelse: file was an XML file + } // endif: there were no observations in the container + + // Setup the response for all CTA observations in the observation + // container if response information is required + if (response) { + set_response(obs); } - // Return observation container - return obs; + // Setup boundaries for all CTA observations containing event lists + set_obs_bounds(obs); + + // Return + return; } /***********************************************************************//** - * @brief Setup observation container + * @brief Setup model container * * @param[in] obs Observation container + * @param[in] name Mandatory model name * * @exception GException::invalid_value - * Invalid "inobs" parameter encountered. + * Mandatory model name not found in observation container. * - * Setup an observation container by appending all required information that - * is missing using user parameters. + * Setup a model container by loading the models from the "inmodel" + * parameter. * - * 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", will load the observation container from the specified file. - * If the file is a FITS file, and dependent on the information that is found - * in the FITS file, the method will append a single CTA observation to the - * observation container, containing either an event list or a counts cube. - * Otherwise, the method assumes that the file is an observation definition - * XML file and will load that file into the observation container. - * - * If the filename is empty or "NONE", the method will throw an exception. - * - * The method will then setup the response for all CTA observations in the - * container (see the set_response() method for more information). - * - * The method will furthermore setup the observation boundaries for all CTA - * observations in the container that contain event lists (see the - * set_obs_bounds() method for more information). + * 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. + * + * If a mandatory model name is specified, the method will further check + * whether a model with the name exists in the model container. ***************************************************************************/ -void ctool::setup_observations(GObservations& obs) +void ctool::setup_models(GObservations& obs, + const std::string& name) { - // Load observations if there are none in the container - if (obs.size() == 0) { + // If there are no models in the observation container then load model + // container from the "inmodel" parameter and attach it to the + // observation container + if (obs.models().size() == 0) { - // Get the filename from the "inobs" parameter - GFilename filename((*this)["inobs"].filename()); - - // Load observation container from file if the filename is neither - // "NONE" nor empty ... - if ((gammalib::toupper(filename.url()) != "NONE") && - !filename.is_empty()) { - - // If file does not exist then throw an exceptions - if (!filename.exists()) { - std::string msg = "The \"inobs\" parameter \""+filename+ - "\" specifies a file that does not " - "exist. Please specify a valid event " - "list, counts cube or observation " - "definition XML file."; - throw GException::invalid_value(G_SETUP_OBSERVATION, msg); - } + // Get models XML filename + GFilename filename = (*this)["inmodel"].filename(); - // If the file is a FITS file then load it into a CTA - // observation and append that observation to the container ... - else if (filename.is_fits()) { - GCTAObservation cta(filename); - obs.append(cta); - } + // Load model container and assign it to observations container + obs.models(GModels(filename.url())); - // ... otherwise it is assumed that the file is an observation - // definition XML file and the file is loaded into the - // observation container - else { - obs.load(filename); - } + } // endif: no models were in observations container - } + // If a mandatory model name exists then check whether this model is + // part of the observation container. Throw an exception if the model + // does not exist + if (!name.empty()) { - // ... otherwise, if the filename is "NONE" or empty then throw - // an exception. - else { - std::string msg = "The \"inobs\" parameter \""+filename+ - "\" is not a valid filename. Please specify " - "a valid event list, counts cube or " - "observation definition XML file."; - throw GException::invalid_value(G_SETUP_OBSERVATION, msg); + // Throw an exception if the model name does not exist + if (!obs.models().contains(name)) { + 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); } - } // endif: there were no observations in the container - - // Setup the response for all CTA observations in the observation - // container - set_response(obs); - - // Setup boundaries for all CTA observations containing event lists - set_obs_bounds(obs); + } // endif: mandatory model name existed // Return return; @@ -1329,6 +1335,104 @@ void ctool::set_obs_bounds(GObservations& obs) /***********************************************************************//** + * @brief Get observation container + * + * @param[in] get_response Indicates whether response information should + * be loaded (default: true) + * + * Get an observation container according to the user parameters. The method + * supports loading of a individual FITS file or an observation definition + * file in XML format. If the input filename is empty, parameters are read + * to build a CTA observation from scratch. + ***************************************************************************/ +GObservations ctool::get_observations(const bool& get_response) +{ + // Initialise empty observation container + GObservations obs; + + // Get the filename from the input parameters + std::string filename = (*this)["inobs"].filename(); + + // 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) == "")) { + + // Setup a new CTA observation + GCTAObservation cta_obs = create_cta_obs(); + + // Get response if required + if (get_response) { + + // Set response + set_obs_response(&cta_obs); + + } // endif: response was required + + // Append observation to container + obs.append(cta_obs); + + } // endif: filename was "NONE" or "" + + // ... otherwise we have a file name + else { + + // If file is a FITS file then create an empty CTA observation + // and load file into observation + if (GFilename(filename).is_fits()) { + + // Allocate empty CTA observation + GCTAObservation cta_obs; + + // Load data + cta_obs.load(filename); + + // Get response if required + if (get_response) { + + // Set response + set_obs_response(&cta_obs); + + } // endif: response was required + + // Append observation to container + obs.append(cta_obs); + + // Signal that no XML file should be used for storage + m_use_xml = false; + + } + + // ... otherwise load file into observation container + else { + + // Load observations from XML file + obs.load(filename); + + // Get response if required + if (get_response) { + + // For all observations that have no response, set the response + // from the task parameters + set_response(obs); + + } // endif: response was required + + // Set observation boundary parameters (emin, emax, rad) + set_obs_bounds(obs); + + // Signal that XML file should be used for storage + m_use_xml = true; + + } // endelse: file was an XML file + + } + + // Return observation container + return obs; +} + + +/***********************************************************************//** * @brief Derives mean pointing from CTA observations * * @param[in] obs Observation container. diff --git a/src/support/ctool.hpp b/src/support/ctool.hpp index 427a24e..3d46fe6 100644 --- a/src/support/ctool.hpp +++ b/src/support/ctool.hpp @@ -71,8 +71,12 @@ protected: void free_members(void); const bool& read_ahead(void) const; const GTimeReference& time_reference(void) const; - GObservations get_observations(const bool& get_response = true); - void setup_observations(GObservations& obs); + + // Protected high-level setup methods + void setup_observations(GObservations& obs, const bool& response = true, + const bool& list = true, + const bool& cube = true); + void setup_models(GObservations& obs, const std::string& name = ""); // Protected methods that create objects from user parameters GEbounds create_ebounds(void); @@ -100,6 +104,7 @@ protected: const std::vector& edisp) const; void set_obs_response(GCTAObservation* obs); void set_obs_bounds(GObservations& obs); + GObservations get_observations(const bool& get_response = true); GSkyDir get_mean_pointing(const GObservations& obs); size_t get_current_rss(void); std::string get_obs_header(const GObservation* obs); diff --git a/test/test_ctobssim.py b/test/test_ctobssim.py index fe55cac..8e905c0 100755 --- a/test/test_ctobssim.py +++ b/test/test_ctobssim.py @@ -74,7 +74,8 @@ class Test(test): ' outevents="events.fits"'+ \ ' caldb="'+self._caldb+'" irf="'+self._irf+'" '+ \ ' ra=83.63 dec=22.01 rad=10.0'+ \ - ' tmin=0.0 tmax=1800.0 emin=0.1 emax=100.0' + ' tmin=0.0 tmax=1800.0 emin=0.1 emax=100.0'+ \ + ' logfile="ctobssim_cmd1.log" chatter=1' # Check if execution of wrong command fails self.test_assert(self._execute('command_that_does_not_exist') != 0, @@ -93,7 +94,8 @@ class Test(test): ' outevents="events.fits"'+ \ ' caldb="'+self._caldb+'" irf="'+self._irf+'" '+ \ ' ra=83.63 dec=22.01 rad=10.0'+ \ - ' tmin=0.0 tmax=1800.0 emin=0.1 emax=100.0' + ' tmin=0.0 tmax=1800.0 emin=0.1 emax=100.0'+ \ + ' logfile="ctobssim_cmd2.log" chatter=1' # Check if execution failed self.test_assert(self._execute(cmd) != 0, @@ -120,8 +122,11 @@ class Test(test): sim['tmax'] = 1800.0 sim['emin'] = 0.1 sim['emax'] = 100.0 + sim['logfile'] = 'ctobssim_py1.log' + sim['chatter'] = 2 # Run tool + sim.logFileOpen() sim.run() # Check content of observation @@ -146,8 +151,11 @@ class Test(test): sim = ctools.ctobssim(obs) sim['outevents'] = 'sim_events.xml' sim['inmodel'] = self._model + sim['logfile'] = 'ctobssim_py2.log' + sim['chatter'] = 3 # Run tool + sim.logFileOpen() sim.run() # Retrieve observation and check content @@ -182,10 +190,13 @@ class Test(test): sim['tmax'] = 1800.0 sim['emin'] = 0.1 sim['emax'] = 100.0 + sim['logfile'] = 'ctobssim_py3.log' + sim['chatter'] = 4 # Run ctbin tool self.test_try('Run ctobssim with invalid model file') try: + sim.logFileOpen() sim.run() self.test_try_failure() except: