src/model/GModels.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                   GModels.cpp - Model container class                   *
00003  * ----------------------------------------------------------------------- *
00004  *  copyright (C) 2009-2016 by Juergen Knoedlseder                         *
00005  * ----------------------------------------------------------------------- *
00006  *                                                                         *
00007  *  This program is free software: you can redistribute it and/or modify   *
00008  *  it under the terms of the GNU General Public License as published by   *
00009  *  the Free Software Foundation, either version 3 of the License, or      *
00010  *  (at your option) any later version.                                    *
00011  *                                                                         *
00012  *  This program is distributed in the hope that it will be useful,        *
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
00015  *  GNU General Public License for more details.                           *
00016  *                                                                         *
00017  *  You should have received a copy of the GNU General Public License      *
00018  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
00019  *                                                                         *
00020  ***************************************************************************/
00021 /**
00022  * @file GModels.cpp
00023  * @brief Model container class implementation
00024  * @author Juergen Knoedlseder
00025  */
00026 
00027 /* __ Includes ___________________________________________________________ */
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 #include "GTools.hpp"
00032 #include "GException.hpp"
00033 #include "GFilename.hpp"
00034 #include "GModels.hpp"
00035 #include "GModel.hpp"
00036 #include "GModelRegistry.hpp"
00037 #include "GObservation.hpp"
00038 #include "GXml.hpp"
00039 #include "GXmlElement.hpp"
00040 
00041 /* __ Method name definitions ____________________________________________ */
00042 #define G_ACCESS                          "GModels::operator[](std::string&)"
00043 #define G_AT                                              "GModels::at(int&)"
00044 #define G_SET1                                  "GModels::set(int&, GModel&)"
00045 #define G_SET2                          "GModels::set(std::string&, GModel&)"
00046 #define G_APPEND                                   "GModels::append(GModel&)"
00047 #define G_INSERT1                            "GModels::insert(int&, GModel&)"
00048 #define G_INSERT2                    "GModels::insert(std::string&, GModel&)"
00049 #define G_REMOVE1                                     "GModels::remove(int&)"
00050 #define G_REMOVE2                             "GModels::remove(std::string&)"
00051 #define G_EXTEND                                  "GModels::extend(GModels&)"
00052 #define G_READ                                         "GModels::read(GXml&)"
00053 
00054 /* __ Macros _____________________________________________________________ */
00055 
00056 /* __ Coding definitions _________________________________________________ */
00057 
00058 /* __ Debug definitions __________________________________________________ */
00059 
00060 
00061 /*==========================================================================
00062  =                                                                         =
00063  =                         Constructors/destructors                        =
00064  =                                                                         =
00065  ==========================================================================*/
00066 
00067 /***********************************************************************//**
00068  * @brief Void constructor
00069  ***************************************************************************/
00070 GModels::GModels(void)
00071 {
00072     // Initialise members
00073     init_members();
00074 
00075     // Return
00076     return;
00077 }
00078 
00079 
00080 /***********************************************************************//**
00081  * @brief Copy constructor
00082  *
00083  * @param[in] models Model container.
00084  ***************************************************************************/
00085 GModels::GModels(const GModels& models)
00086 {
00087     // Initialise members
00088     init_members();
00089 
00090     // Copy members
00091     copy_members(models);
00092 
00093     // Return
00094     return;
00095 }
00096 
00097 
00098 /***********************************************************************//**
00099  * @brief Load constructor
00100  *
00101  * @param[in] filename XML filename.
00102  *
00103  * Constructs model container from an XML file. See the read() method for
00104  * more information about the expected structure of the XML file.
00105  ***************************************************************************/
00106 GModels::GModels(const GFilename& filename)
00107 {
00108     // Initialise members
00109     init_members();
00110 
00111     // Load XML file
00112     load(filename);
00113 
00114     // Return
00115     return;
00116 }
00117 
00118 
00119 /***********************************************************************//**
00120  * @brief Destructor
00121  ***************************************************************************/
00122 GModels::~GModels(void)
00123 {
00124     // Free members
00125     free_members();
00126 
00127     // Return
00128     return;
00129 }
00130 
00131 
00132 /*==========================================================================
00133  =                                                                         =
00134  =                               Operators                                 =
00135  =                                                                         =
00136  ==========================================================================*/
00137 
00138 /***********************************************************************//**
00139  * @brief Assignment operator
00140  *
00141  * @param[in] models Model container.
00142  * @return Model container.
00143  ***************************************************************************/
00144 GModels& GModels::operator=(const GModels& models)
00145 {
00146     // Execute only if object is not identical
00147     if (this != &models) {
00148 
00149         // Free members
00150         free_members();
00151 
00152         // Initialise members
00153         init_members();
00154 
00155         // Copy members
00156         copy_members(models);
00157 
00158     } // endif: object was not identical
00159 
00160     // Return
00161     return *this;
00162 }
00163 
00164 
00165 /***********************************************************************//**
00166  * @brief Return pointer to model
00167  *
00168  * @param[in] name Model name.
00169  *
00170  * @exception GException::model_not_found
00171  *            Model with specified name not found in container.
00172  *
00173  * Returns a pointer to the model with the specified @p name.
00174  ***************************************************************************/
00175 GModel* GModels::operator[](const std::string& name)
00176 {
00177     // Get model index
00178     int index = get_index(name);
00179 
00180     // Throw exception if model name was not found
00181     if (index == -1) {
00182         throw GException::model_not_found(G_ACCESS, name);
00183     }
00184 
00185     // Return pointer
00186     return m_models[index];
00187 }
00188 
00189 
00190 /***********************************************************************//**
00191  * @brief Return pointer to model (const version)
00192  *
00193  * @param[in] name Model name.
00194  *
00195  * @exception GException::model_not_found
00196  *            Model with specified name not found in container.
00197  *
00198  * Returns a const pointer to the model with the specified @p name.
00199  ***************************************************************************/
00200 const GModel* GModels::operator[](const std::string& name) const
00201 {
00202     // Get model index
00203     int index = get_index(name);
00204 
00205     // Throw exception if model name was not found
00206     if (index == -1) {
00207         throw GException::model_not_found(G_ACCESS, name);
00208     }
00209 
00210     // Return pointer
00211     return m_models[index];
00212 }
00213 
00214 
00215 /*==========================================================================
00216  =                                                                         =
00217  =                            Public methods                               =
00218  =                                                                         =
00219  ==========================================================================*/
00220 
00221 /***********************************************************************//**
00222  * @brief Clear object
00223  *
00224  * Removes all models from the container.
00225  ***************************************************************************/
00226 void GModels::clear(void)
00227 {
00228     // Free class members (base and derived classes, derived class first)
00229     free_members();
00230 
00231     // Initialise members
00232     init_members();
00233 
00234     // Return
00235     return;
00236 }
00237 
00238 
00239 /***********************************************************************//**
00240  * @brief Clone instance
00241  *
00242  * @return Pointer to deep copy of model container
00243  *
00244  * Makes a deep copy of the model container instance.
00245  ***************************************************************************/
00246 GModels* GModels::clone(void) const
00247 {
00248     return new GModels(*this);
00249 }
00250 
00251 
00252 /***********************************************************************//**
00253  * @brief Return pointer to model
00254  *
00255  * @param[in] index Model index [0,...,size()-1].
00256  *
00257  * @exception GException::out_of_range
00258  *            Model index is out of range.
00259  *
00260  * Returns a pointer to the model with the specified @p index.
00261  ***************************************************************************/
00262 GModel* GModels::at(const int& index)
00263 {
00264     // Compile option: raise an exception if index is out of range
00265     #if defined(G_RANGE_CHECK)
00266     if (index < 0 || index >= size()) {
00267         throw GException::out_of_range(G_AT, "Model index", index, size());
00268     }
00269     #endif
00270 
00271     // Return pointer
00272     return m_models[index];
00273 }
00274 
00275 
00276 /***********************************************************************//**
00277  * @brief Return pointer to model (const version)
00278  *
00279  * @param[in] index Model index [0,...,size()-1].
00280  *
00281  * @exception GException::out_of_range
00282  *            Model index is out of range.
00283  *
00284  * Returns a const pointer to the model with the specified @p index.
00285  ***************************************************************************/
00286 const GModel* GModels::at(const int& index) const
00287 {
00288     // Compile option: raise an exception if index is out of range
00289     #if defined(G_RANGE_CHECK)
00290     if (index < 0 || index >= size()) {
00291         throw GException::out_of_range(G_AT, "Model index", index, size());
00292     }
00293     #endif
00294 
00295     // Return pointer
00296     return m_models[index];
00297 }
00298 
00299 
00300 /***********************************************************************//**
00301  * @brief Set model in container
00302  *
00303  * @param[in] index Model index [0,...,size()-1].
00304  * @param[in] model Model.
00305  * @return Pointer to deep copy of model.
00306  *
00307  * @exception GException::out_of_range
00308  *            Model index is out of range.
00309  * @exception GException::invalid_value
00310  *            Name of model exists already in container.
00311  *
00312  * Set model in the container. A deep copy of the model will be made.
00313  ***************************************************************************/
00314 GModel* GModels::set(const int& index, const GModel& model)
00315 {
00316     // Compile option: raise exception if index is out of range
00317     #if defined(G_RANGE_CHECK)
00318     if (index < 0 || index >= size()) {
00319         throw GException::out_of_range(G_SET1, index, 0, size()-1);
00320     }
00321     #endif
00322 
00323     // Check if a model with specified name does not yet exist
00324     int inx = get_index(model.name());
00325     if (inx != -1 && inx != index) {
00326         std::string msg =
00327             "Attempt to set model with name \""+model.name()+"\" in model"
00328             " container at index "+gammalib::str(index)+", but a model with"
00329             " the same name exists already at index "+gammalib::str(inx)+
00330             " in the container.\n"
00331             "Every model in the model container needs a unique name.";
00332         throw GException::invalid_value(G_SET1, msg);
00333     }
00334 
00335     // Delete any existing model
00336     if (m_models[index] != NULL) delete m_models[index];
00337 
00338     // Assign new model by cloning
00339     m_models[index] = model.clone();
00340 
00341     // Return pointer to model
00342     return m_models[index];
00343 }
00344 
00345 
00346 /***********************************************************************//**
00347  * @brief Set model in container
00348  *
00349  * @param[in] name Model name.
00350  * @param[in] model Model pointer.
00351  * @return Pointer to deep copy of model.
00352  *
00353  * @exception GException::model_not_found
00354  *            Model with specified name not found in container.
00355  * @exception GException::invalid_value
00356  *            Name of model exists already in container.
00357  *
00358  * Set model in the container. A deep copy of the model will be made.
00359  ***************************************************************************/
00360 GModel* GModels::set(const std::string& name, const GModel& model)
00361 {
00362     // Get parameter index
00363     int index = get_index(name);
00364 
00365     // Throw exception if parameter name was not found
00366     if (index == -1) {
00367         throw GException::model_not_found(G_SET2, name);
00368     }
00369 
00370     // Check if a model with specified name does not yet exist
00371     int inx = get_index(model.name());
00372     if (inx != -1 && inx != index) {
00373         std::string msg =
00374             "Attempt to set model with name \""+model.name()+"\" in model"
00375             " container at index "+gammalib::str(index)+", but a model with"
00376             " the same name exists already at index "+gammalib::str(inx)+
00377             " in the container.\n"
00378             "Every model in the model container needs a unique name.";
00379         throw GException::invalid_value(G_SET2, msg);
00380     }
00381 
00382     // Delete any existing model
00383     if (m_models[index] != NULL) delete m_models[index];
00384 
00385     // Assign new model by cloning
00386     m_models[index] = model.clone();
00387 
00388     // Return pointer to model
00389     return m_models[index];
00390 }
00391 
00392 
00393 /***********************************************************************//**
00394  * @brief Append model to container
00395  *
00396  * @param[in] model Model.
00397  * @return Pointer to deep copy of model.
00398  *
00399  * @exception GException::invalid_value
00400  *            Name of model exists already in container.
00401  *
00402  * Appends model to the container by making a deep copy of the model and
00403  * storing its pointer.
00404  ***************************************************************************/
00405 GModel* GModels::append(const GModel& model)
00406 {
00407     // Check if a model with specified name does not yet exist
00408     int inx = get_index(model.name());
00409     if (inx != -1) {
00410         std::string msg = 
00411             "Attempt to append model with name \""+model.name()+"\" to model"
00412             " container, but a model with the same name exists already at"
00413             " index "+gammalib::str(inx)+" in the container.\n"
00414             "Every model in the model container needs a unique name.";
00415         throw GException::invalid_value(G_APPEND, msg);
00416     }
00417 
00418     // Create deep copy of model
00419     GModel* ptr = model.clone();
00420 
00421     // Append deep copy of model
00422     m_models.push_back(ptr);
00423 
00424     // Return pointer to model
00425     return ptr;
00426 }
00427 
00428 
00429 /***********************************************************************//**
00430  * @brief Insert model into container
00431  *
00432  * @param[in] index Model index [0,...,size()-1].
00433  * @param[in] model Model.
00434  * @return Pointer to deep copy of model.
00435  *
00436  * @exception GException::out_of_range
00437  *            Model index is out of range.
00438  * @exception GException::invalid_value
00439  *            Name of model exists already in container.
00440  *
00441  * Inserts a @p model into the container before the model with the specified
00442  * @p index.
00443  ***************************************************************************/
00444 GModel* GModels::insert(const int& index, const GModel& model)
00445 {
00446     // Compile option: raise exception if index is out of range
00447     #if defined(G_RANGE_CHECK)
00448     if (is_empty()) {
00449         if (index > 0) {
00450             throw GException::out_of_range(G_INSERT1, index, 0, size()-1);
00451         }
00452     }
00453     else {
00454         if (index < 0 || index >= size()) {
00455             throw GException::out_of_range(G_INSERT1, index, 0, size()-1);
00456         }
00457     }
00458     #endif
00459 
00460     // Check if a model with specified name does not yet exist
00461     int inx = get_index(model.name());
00462     if (inx != -1) {
00463         std::string msg =
00464             "Attempt to insert model with name \""+model.name()+"\" in model"
00465             " container before index "+gammalib::str(index)+", but a model"
00466             " with the same name exists already at index "+gammalib::str(inx)+
00467             " in the container.\n"
00468             "Every model in the model container needs a unique name.";
00469         throw GException::invalid_value(G_INSERT1, msg);
00470     }
00471 
00472     // Create deep copy of model
00473     GModel* ptr = model.clone();
00474 
00475     // Inserts deep copy of model
00476     m_models.insert(m_models.begin()+index, ptr);
00477 
00478     // Return pointer to model
00479     return ptr;
00480 }
00481 
00482 
00483 /***********************************************************************//**
00484  * @brief Insert model into container
00485  *
00486  * @param[in] name Model name.
00487  * @param[in] model Model.
00488  * @return Pointer to deep copy of model.
00489  *
00490  * @exception GException::model_not_found
00491  *            Model with specified name not found in container.
00492  * @exception GException::invalid_value
00493  *            Name of model exists already in container.
00494  *
00495  * Inserts a @p model into the container before the model with the specified
00496  * @p name.
00497  ***************************************************************************/
00498 GModel* GModels::insert(const std::string& name, const GModel& model)
00499 {
00500     // Get parameter index
00501     int index = get_index(name);
00502 
00503     // Throw exception if parameter name was not found
00504     if (index == -1) {
00505         throw GException::model_not_found(G_INSERT2, name);
00506     }
00507 
00508     // Check if a model with specified name does not yet exist
00509     int inx = get_index(model.name());
00510     if (inx != -1) {
00511         std::string msg =
00512             "Attempt to insert model with name \""+model.name()+"\" in model"
00513             " container before index "+gammalib::str(index)+", but a model"
00514             " with the same name exists already at index "+gammalib::str(inx)+
00515             " in the container.\n"
00516             "Every model in the model container needs a unique name.";
00517         throw GException::invalid_value(G_INSERT2, msg);
00518     }
00519 
00520     // Create deep copy of model
00521     GModel* ptr = model.clone();
00522 
00523     // Inserts deep copy of model
00524     m_models.insert(m_models.begin()+index, ptr);
00525 
00526     // Return pointer to model
00527     return ptr;
00528 }
00529 
00530 
00531 /***********************************************************************//**
00532  * @brief Remove model from container
00533  *
00534  * @param[in] index Model index [0,...,size()-1].
00535  *
00536  * @exception GException::out_of_range
00537  *            Model index is out of range.
00538  *
00539  * Remove model of specified @p index from container.
00540  ***************************************************************************/
00541 void GModels::remove(const int& index)
00542 {
00543     // Compile option: raise exception if index is out of range
00544     #if defined(G_RANGE_CHECK)
00545     if (index < 0 || index >= size()) {
00546         throw GException::out_of_range(G_REMOVE1, index, 0, size()-1);
00547     }
00548     #endif
00549 
00550     // Delete model
00551     delete m_models[index];
00552 
00553     // Erase model component from container
00554     m_models.erase(m_models.begin() + index);
00555 
00556     // Return
00557     return;
00558 }
00559 
00560 
00561 /***********************************************************************//**
00562  * @brief Remove model from container
00563  *
00564  * @param[in] name Model name.
00565  *
00566  * @exception GException::model_not_found
00567  *            Model with specified name not found in container.
00568  *
00569  * Remove model of specified @p name from container.
00570  ***************************************************************************/
00571 void GModels::remove(const std::string& name)
00572 {
00573     // Get parameter index
00574     int index = get_index(name);
00575 
00576     // Throw exception if parameter name was not found
00577     if (index == -1) {
00578         throw GException::model_not_found(G_REMOVE2, name);
00579     }
00580 
00581     // Delete model
00582     delete m_models[index];
00583 
00584     // Erase model component from container
00585     m_models.erase(m_models.begin() + index);
00586 
00587     // Return
00588     return;
00589 }
00590 
00591 
00592 /***********************************************************************//**
00593  * @brief Append model container
00594  *
00595  * @param[in] models Model container.
00596  *
00597  * Append model container to the container.
00598  ***************************************************************************/
00599 void GModels::extend(const GModels& models)
00600 {
00601     // Do nothing if model container is empty
00602     if (!models.is_empty()) {
00603 
00604         // Get size. Note that we extract the size first to avoid an
00605         // endless loop that arises when a container is appended to
00606         // itself.
00607         int num = models.size();
00608 
00609         // Reserve enough space
00610         reserve(size() + num);
00611 
00612         // Loop over all model components and append pointers to deep copies 
00613         for (int i = 0; i < num; ++i) {
00614 
00615             // Check if model name does not yet exist
00616             int inx = get_index(models[i]->name());
00617             if (inx != -1) {
00618                 std::string msg =
00619                     "Attempt to append model with name \""+models[i]->name()+
00620                     "\" to model container, but a model with the same name"
00621                     " exists already at index "+gammalib::str(inx)+" in the"
00622                     " container.\n"
00623                     "Every model in the model container needs a unique name.";
00624                 throw GException::invalid_value(G_EXTEND, msg);
00625             }
00626 
00627             // Append model to container
00628             m_models.push_back(models[i]->clone());
00629 
00630         } // endfor: looped over all models
00631 
00632     } // endif: model container was not empty
00633     
00634     // Return
00635     return;
00636 }
00637 
00638 
00639 /***********************************************************************//**
00640  * @brief Signals if model name exists
00641  *
00642  * @param[in] name Model name.
00643  * @return True if model with specified @p name exists.
00644  *
00645  * Searches all model names for a match with the specified @p name. If the
00646  * specified name has been found, true is returned.
00647  ***************************************************************************/
00648 bool GModels::contains(const std::string& name) const
00649 {
00650     // Get model index
00651     int index = get_index(name);
00652 
00653     // Return
00654     return (index != -1);
00655 }
00656 
00657 
00658 /***********************************************************************//**
00659  * @brief Load models from XML file
00660  *
00661  * @param[in] filename XML filename.
00662  *
00663  * Loads all models from an XML file. See the read() method for more
00664  * information about the expected structure of the XML file.
00665  ***************************************************************************/
00666 void GModels::load(const GFilename& filename)
00667 {
00668     // Clear any existing models
00669     clear();
00670 
00671     // Load XML document
00672     GXml xml(filename.url());
00673 
00674     // Read models from XML document
00675     read(xml);
00676 
00677     // Return
00678     return;
00679 }
00680 
00681 
00682 /***********************************************************************//**
00683  * @brief Save models into XML file
00684  *
00685  * @param[in] filename XML filename.
00686  *
00687  * Saves all models in the container into an XML file.
00688  ***************************************************************************/
00689 void GModels::save(const GFilename& filename) const
00690 {
00691     // Declare empty XML document
00692     GXml xml;
00693 
00694     // Write models into XML file
00695     write(xml);
00696 
00697     // Save XML document
00698     xml.save(filename);
00699 
00700     // Return
00701     return;
00702 }
00703 
00704 
00705 /***********************************************************************//**
00706  * @brief Read models from XML document
00707  *
00708  * @param[in] xml XML document.
00709  *
00710  * @exception GException::model_invalid
00711  *            Invalid model type encountered.
00712  *
00713  * Read models from the first source library found in the XML document. The
00714  * XML document is expected to have the following structure
00715  *
00716  *     <source_library title="source library">
00717  *       <source name="Source1" type="PointSource">
00718  *         ...
00719  *       </source>
00720  *       <source name="Source2" type="DiffuseSource">
00721  *         ...
00722  *       </source>
00723  *     </source_library>
00724  *
00725  * Each @p source tag will be interpreted as a model component.
00726  *
00727  * @todo Sources names are not verified so far for uniqueness. This would be
00728  *       required to achieve an unambiguous update of parameters in an already
00729  *       existing XML file when using the write method.
00730  ***************************************************************************/
00731 void GModels::read(const GXml& xml)
00732 {
00733     // Get pointer on source library
00734     const GXmlElement* lib = xml.element("source_library", 0);
00735 
00736     // Loop over all sources
00737     int n = lib->elements("source");
00738     for (int i = 0; i < n; ++i) {
00739 
00740         // Get pointer on source
00741         const GXmlElement* src = lib->element("source", i);
00742 
00743         // Get model type
00744         std::string type = src->attribute("type");
00745 
00746         // Get model
00747         GModelRegistry registry;
00748         GModel*        ptr = registry.alloc(type);
00749 
00750         // If model if valid then read model from XML file
00751         if (ptr != NULL) {
00752             ptr->read(*src);
00753         }
00754 
00755         // ... otherwise throw an exception
00756         else {
00757             throw GException::model_invalid(G_READ, type);
00758         }
00759 
00760         // Append model
00761         append(*ptr);
00762 
00763         // Free model (appending clones the model)
00764         delete ptr;
00765 
00766     } // endfor: looped over all sources
00767 
00768     // Return
00769     return;
00770 }
00771 
00772 
00773 /***********************************************************************//**
00774  * @brief Write models into XML document
00775  *
00776  * @param[in] xml XML document.
00777  *
00778  * Write models into the first source library that is found in the XML
00779  * document. In case that no source library exists, one is added to the
00780  * document.
00781  ***************************************************************************/
00782 void GModels::write(GXml& xml) const
00783 {
00784     // If there is no source library then append one
00785     if (xml.elements("source_library") == 0) {
00786         xml.append(GXmlElement("source_library title=\"source library\""));
00787     }
00788 
00789     // Get pointer on source library
00790     GXmlElement* lib = xml.element("source_library", 0);
00791 
00792     // Write all sources into library
00793     for (int i = 0; i < size(); ++i) {
00794         m_models[i]->write(*lib);
00795     }
00796 
00797     // Return
00798     return;
00799 }
00800 
00801 
00802 /***********************************************************************//**
00803  * @brief Return number of model parameters in container
00804  *
00805  * @return Number of model parameters in container.
00806  ***************************************************************************/
00807 int GModels::npars(void) const
00808 {
00809     // Initialise number of parameters
00810     int npars = 0;
00811 
00812     // Sum of number of parameters in model
00813     for (int i = 0; i < size(); ++i) {
00814         npars += m_models[i]->size();
00815     }
00816 
00817     // Return
00818     return npars;
00819 }
00820 
00821 
00822 /***********************************************************************//**
00823  * @brief Return optimizer parameter container
00824  *
00825  * @return Optimizer parameter container.
00826  *
00827  * Returns an optimizer parameter container that is built by extracting
00828  * all model pointers from the model and attaching them to the parameter
00829  * container. The optimizer parameter container will thus contains a flat
00830  * array of a model parameters.
00831  ***************************************************************************/
00832 GOptimizerPars GModels::pars(void) const
00833 {
00834     // Initialise parameter container
00835     GOptimizerPars pars;
00836 
00837     // Attach all parameters
00838     for (int i = 0; i < size(); ++i) {
00839         GModel* model = m_models[i];
00840         int     npars = model->size();
00841         for (int k = 0; k < npars; ++k) {
00842             pars.attach(&((*model)[k]));
00843         }
00844     }
00845 
00846     // Return
00847     return pars;
00848 }
00849 
00850 
00851 /***********************************************************************//**
00852  * @brief Evaluate sum of all models
00853  *
00854  * @param[in] event Observed event.
00855  * @param[in] obs Observation.
00856  * @param[in] gradients Compute gradients?
00857  * @return Value of models.
00858  *
00859  * Evaluates the sum of all models for the specified event and observation.
00860  * Only valid models are considered in this evaluation.
00861  *
00862  * If the @p gradients flag is true the method will also set the parameter
00863  * gradients of the model parameters.
00864  ***************************************************************************/
00865 double GModels::eval(const GEvent&       event,
00866                      const GObservation& obs,
00867                      const bool&         gradients) const
00868 {
00869     // Initialise function value
00870     double value = 0.0;
00871 
00872     // Evaluate function for all models
00873     for (int i = 0; i < size(); ++i) {
00874         if (m_models[i]->is_valid(obs.instrument(), obs.id())) {
00875             value += m_models[i]->eval(event, obs, gradients);
00876         }    
00877     }
00878 
00879     // Return
00880     return value;
00881 }
00882 
00883 
00884 /***********************************************************************//**
00885  * @brief Print models
00886  *
00887  * @param[in] chatter Chattiness (defaults to NORMAL).
00888  * @return String containing model container information.
00889  *
00890  * Prints all models into a string.
00891  ***************************************************************************/
00892 std::string GModels::print(const GChatter& chatter) const
00893 {
00894     // Initialise result string
00895     std::string result;
00896 
00897     // Continue only if chatter is not silent
00898     if (chatter != SILENT) {
00899 
00900         // Append header
00901         result.append("=== GModels ===");
00902 
00903         // Append information
00904         result.append("\n"+gammalib::parformat("Number of models"));
00905         result.append(gammalib::str(size()));
00906         result.append("\n"+gammalib::parformat("Number of parameters"));
00907         result.append(gammalib::str(npars()));
00908 
00909         // Append models
00910         for (int i = 0; i < size(); ++i) {
00911             result.append("\n"+m_models[i]->print(chatter));
00912         }
00913 
00914     } // endif: chatter was not silent
00915 
00916     // Return result
00917     return result;
00918 }
00919 
00920 
00921 /*==========================================================================
00922  =                                                                         =
00923  =                              Private methods                            =
00924  =                                                                         =
00925  ==========================================================================*/
00926 
00927 /***********************************************************************//**
00928  * @brief Initialise class members
00929  ***************************************************************************/
00930 void GModels::init_members(void)
00931 {
00932     // Initialise members
00933     m_models.clear();
00934 
00935     // Return
00936     return;
00937 }
00938 
00939 
00940 /***********************************************************************//**
00941  * @brief Copy class members
00942  *
00943  * @param[in] models Model container.
00944  *
00945  * Makes a copy of all class members. All models are deep copied, and the
00946  * linear pointer array for parameter access through the GOptimizerPars
00947  * base class is set.
00948  ***************************************************************************/
00949 void GModels::copy_members(const GModels& models)
00950 {
00951     // Copy models
00952     m_models.clear();
00953     for (int i = 0; i < models.m_models.size(); ++i) {
00954         m_models.push_back((models.m_models[i]->clone()));
00955     }
00956 
00957     // Return
00958     return;
00959 }
00960 
00961 
00962 /***********************************************************************//**
00963  * @brief Delete class members
00964  *
00965  * Deallocates all models. The method loops over the model container and
00966  * deallocates the memory that has been allocated before.
00967  ***************************************************************************/
00968 void GModels::free_members(void)
00969 {
00970     // Free models
00971     for (int i = 0; i < m_models.size(); ++i) {
00972         delete m_models[i];
00973         m_models[i] = NULL;
00974     }
00975 
00976     // Return
00977     return;
00978 }
00979 
00980 
00981 /***********************************************************************//**
00982  * @brief Return model index by name
00983  *
00984  * @param[in] name Model name.
00985  * @return Model index (-1 if model name has not been found)
00986  *
00987  * Returns model index based on the specified @p name. If no model with the
00988  * specified @p name is found the method returns -1.
00989  ***************************************************************************/
00990 int GModels::get_index(const std::string& name) const
00991 {
00992     // Initialise index
00993     int index = -1;
00994 
00995     // Search model with specified name
00996     for (int i = 0; i < size(); ++i) {
00997         if (m_models[i]->name() == name) {
00998             index = i;
00999             break;
01000         }
01001     }
01002 
01003     // Return index
01004     return index;
01005 }

Generated on Tue Jan 24 12:37:23 2017 for GammaLib by  doxygen 1.4.7