GModel.hpp 15.8 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
/***************************************************************************
 *              GModel.hpp - Abstract virtual model base class             *
 * ----------------------------------------------------------------------- *
 *  copyright (C) 2009-2020 by Juergen Knoedlseder                         *
 * ----------------------------------------------------------------------- *
 *                                                                         *
 *  This program is free software: you can redistribute it and/or modify   *
 *  it under the terms of the GNU General Public License as published by   *
 *  the Free Software Foundation, either version 3 of the License, or      *
 *  (at your option) any later version.                                    *
 *                                                                         *
 *  This program is distributed in the hope that it will be useful,        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
 *  GNU General Public License for more details.                           *
 *                                                                         *
 *  You should have received a copy of the GNU General Public License      *
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
 *                                                                         *
 ***************************************************************************/
/**
 * @file GModel.hpp
 * @brief Abstract model base class interface definition
 * @author Juergen Knoedlseder
 */

#ifndef GMODEL_HPP
#define GMODEL_HPP

/* __ Includes ___________________________________________________________ */
#include <vector>
#include <string>
#include "GBase.hpp"
#include "GModelPar.hpp"
#include "GModelAssociations.hpp"
#include "GXmlElement.hpp"
#include "GEnergy.hpp"
#include "GTime.hpp"

/* __ Forward declarations _______________________________________________ */
class GVector;
class GMatrixSparse;
class GEvent;
class GObservation;


/***********************************************************************//**
 * @class GModel
 *
 * @brief Abstract model class
 *
 * This class implements a parametric model. The eval() method evaluates the
 * model for a given event and observation. If the gradients parameter is set
 * to true, the eval() method also computes analytical parameter gradients if
 * they exist.
 *
 * A model has the following attributes:
 * - @p name
 * - @p type
 * - @p instruments
 * - @p ids
 * - @p scales
 *
 * The model @p name is a text string that names the model. The name()
 * methods allow setting and retrieving the model name. The model handling
 * does not actual depend on the value of this text string.
 *
 * The model @p type is a text string that specifies the kind of the model.
 * Examples are @p PointSource, @p ExtendedSource or @p DiffuseSource for
 * sky models. The type() method allows retrieving the model type. The model
 * handling does not actual depend on the value of this text string.
 *
 * The model @p instruments is a list of text strings that specifies the
 * instruments to which the model applies. The is_valid() method will check
 * a given instrument name against that list to verify if the model applies
 * to an instrument. The instruments() method returns a comma separated
 * list of all instruments. Another instance of this method allows setting
 * the instrument list from a comma separated list. If the @p instruments
 * list is empty, the model applies to all instruments. 
 *
 * The model @p ids is a list of text strings that specifies the observation
 * identifiers to which the model applies. This allows specifying of models
 * for a specific list of observations. The is_valid() method will check
 * a given observation identifier against that list to verify if the model
 * applies. The ids() method returns a comma separated list of all
 * observation identifiers. Another instance of this method allows setting
 * the observation identifiers from a comma separated list. If the @p ids
 * list is empty, the model applies to all observation identifiers.
 *
 * The model @p scales is a list of model parameters that specify an
 * instrument dependent scaling factor. This allows to prescale a model for
 * a given instrument. The scale() methods allow to set and to retrieve the
 * scale factor for a specific instrument.
 *
 * As the class holds simply a collection of model parameters, it should
 * neither deal with allocation and deallocation, nor with cloning of
 * model parameters. This will be done by the classes that actually
 * implement the model parameters.
 ***************************************************************************/
class GModel : public GBase {

public:
    // Constructors and destructors
    GModel(void);
    explicit GModel(const GXmlElement& xml);
    GModel(const GModel& model);
    virtual ~GModel(void);

    // Operators
    virtual GModel&          operator=(const GModel& model);
    virtual GModelPar&       operator[](const int& index);
    virtual const GModelPar& operator[](const int& index) const;
    virtual GModelPar&       operator[](const std::string& name);
    virtual const GModelPar& operator[](const std::string& name) const;

    // Pure virtual methods
    virtual void        clear(void) = 0;
    virtual GModel*     clone(void) const = 0;
    virtual std::string classname(void) const = 0;
    virtual std::string type(void) const = 0;
    virtual bool        is_constant(void) const = 0;
    virtual double      eval(const GEvent& event,
                             const GObservation& obs,
                             const bool& gradients = false) const = 0;
    virtual GVector     eval(const GObservation& obs,
                             GMatrixSparse* gradients = NULL) const = 0;
    virtual double      npred(const GEnergy& obsEng, const GTime& obsTime,
                              const GObservation& obs) const = 0;
    virtual void        read(const GXmlElement& xml) = 0;
    virtual void        write(GXmlElement& xml) const = 0;
    virtual std::string print(const GChatter& chatter = NORMAL) const = 0;

    // Implemented methods
    int                       size(void) const;
    int                       scales(void) const;
    GModelPar&                at(const int& index);
    const GModelPar&          at(const int& index) const;
    bool                      has_par(const std::string& name) const;
    bool                      has_scales(void) const;
    const std::string&        name(void) const;
    void                      name(const std::string& name);
    const double&             ts(void) const;
    void                      ts(const double& ts);
    const bool&               tscalc(void) const;
    void                      tscalc(const bool& tscalc);
    const bool&               has_ts(void) const;
    std::string               instruments(void) const;
    void                      instruments(const std::string& instruments);
    GModelPar&                scale(const int& index);
    const GModelPar&          scale(const int& index) const;
    GModelPar                 scale(const std::string& instrument) const;
    void                      scale(const GModelPar& par);
    std::string               ids(void) const;
    void                      ids(const std::string& ids);
    bool                      is_valid(const std::string& instruments,
                                       const std::string& ids) const;
    const GModelAssociations& associations(void) const;
    void                      associations(const GModelAssociations& associations);
    const bool&               has_eval_indices(void) const;
    const std::vector<int>&   eval_indices(void) const;

protected:
    // Protected methods
    void         init_members(void);
    void         copy_members(const GModel& model);
    void         free_members(void);
    void         read_attributes(const GXmlElement& xml);
    void         write_attributes(GXmlElement& xml) const;
    std::string  print_attributes(void) const;
    void         read_scales(const GXmlElement& xml);
    void         write_scales(GXmlElement& xml) const;

    // Protected members
    std::string              m_name;         //!< Model name
    std::vector<std::string> m_instruments;  //!< Instruments to which model applies
    std::vector<GModelPar>   m_scales;       //!< Model instrument scale factors
    std::vector<std::string> m_ids;          //!< Identifiers to which model applies
    std::vector<GModelPar*>  m_pars;         //!< Pointers to all model parameters
    GModelAssociations       m_associations; //!< Model associations
    bool                     m_has_ts;       //!< Signals if TS is available
    bool                     m_has_tscalc;   //!< Signals if tscalc attribute is available
    bool                     m_tscalc;       //!< Signals if TS should be computed
    double                   m_ts;           //!< Test Statistic of the model

    // Protected members for efficient gradient access
    mutable bool             m_has_eval_inx; //!< Signal that parameter indices
                                             //!< updated by eval() method exist
    mutable std::vector<int> m_eval_inx;     //!< List of parameter indices updated
                                             //!< by eval() method
};


/***********************************************************************//**
 * @brief Returns reference to model parameter by index
 *
 * @param[in] index Parameter index [0,...,size()-1].
 * @return Reference to model parameter.
 *
 * Returns a reference to the model parameter of the specified @p index.
 ***************************************************************************/
inline
GModelPar& GModel::operator[](const int& index)
{
    // Return reference
    return *(m_pars[index]);
}


/***********************************************************************//**
 * @brief Returns reference to model parameter by index (const version)
 *
 * @param[in] index Parameter index [0,...,size()-1].
 * @return Const reference to model parameter.
 *
 * Returns a const reference to the model parameter of the specified
 ***************************************************************************/
inline
const GModelPar& GModel::operator[](const int& index) const
{
    // Return reference
    return *(m_pars[index]);
}


/***********************************************************************//**
 * @brief Return number of parameters in model
 *
 * @return Number of parameters in model.
 *
 * Returns the number of parameters in the model.
 ***************************************************************************/
inline
int GModel::size(void) const
{
    return (int)m_pars.size();
}


/***********************************************************************//**
 * @brief Return number of scale parameters in model
 *
 * @return Number of scale parameters in model.
 *
 * Returns the number of scale parameters in the model.
 ***************************************************************************/
inline
int GModel::scales(void) const
{
    return (int)m_scales.size();
}


/***********************************************************************//**
 * @brief Return parameter name
 *
 * @return Parameter name.
 *
 * Returns the parameter name.
 ***************************************************************************/
inline
const std::string& GModel::name(void) const
{
    return m_name;
}


/***********************************************************************//**
 * @brief Set parameter name
 *
 * @param[in] name Parameter name.
 *
 * Set the parameter name.
 ***************************************************************************/
inline
void GModel::name(const std::string& name)
{
    m_name = name;
    return;
}


/***********************************************************************//**
 * @brief Return Test Statistic value
 *
 * @return Test Statistic value.
 *
 * Returns the Test Statistic value. The Test Statistic value is twice the
 * difference between the log-likelihood of the null hypothesis and the
 * alternative hypothesis.
 ***************************************************************************/
inline
const double& GModel::ts(void) const
{
    return m_ts;
}


/***********************************************************************//**
 * @brief Set Test Statistic value
 *
 * @param[in] ts Test Statistic value.
 *
 * Set the Test Statistic value. The Test Statistic value is twice the
 * difference between the log-likelihood of the null hypothesis and the
 * alternative hypothesis.
 ***************************************************************************/
inline
void GModel::ts(const double& ts)
{
    m_ts     = ts;
    m_has_ts = true; //!< Signals that TS is now available
    return;
}


/***********************************************************************//**
 * @brief Return Test Statistic computation flag
 *
 * @return Test Statistic computation flag; true is Test Statistic should be
 *         computed.
 *
 * Returns the flag that signals whether Test Statistic values should be
 * computed.
 ***************************************************************************/
inline
const bool& GModel::tscalc(void) const
{
    return m_tscalc;
}


/***********************************************************************//**
 * @brief Set Test Statistic computation flag
 *
 * @param[in] tscalc Test Statistic computation flag.
 *
 * Set the flag that signals whether Test Statistic values should be
 * computed.
 ***************************************************************************/
inline
void GModel::tscalc(const bool& tscalc)
{
    m_tscalc     = tscalc;
    m_has_tscalc = true; //!< Signals that tscalc is now available
    return;
}


/***********************************************************************//**
 * @brief Signals that model has scales
 *
 * @return True if model has scale factors.
 ***************************************************************************/
inline
bool GModel::has_scales(void) const
{
    return (!m_scales.empty());
}


/***********************************************************************//**
 * @brief Signals that model has Test Statistics value
 *
 * @return True if model has TS value.
 ***************************************************************************/
inline
const bool& GModel::has_ts(void) const
{
    return m_has_ts;
}


/***********************************************************************//**
 * @brief Return model associations
 *
 * @return Model associations.
 *
 * Returns model associations.
 ***************************************************************************/
inline
const GModelAssociations& GModel::associations(void) const
{
    return m_associations;
}


/***********************************************************************//**
 * @brief Set model associations
 *
 * @param[in] associations Model associations.
 *
 * Set the model associations.
 ***************************************************************************/
inline
void GModel::associations(const GModelAssociations& associations)
{
    m_associations = associations;
    return;
}


/***********************************************************************//**
 * @brief Signals that parameter indices updated by eval() method were set
 *
 * @return True if parameter indices updated by eval() method were set.
 ***************************************************************************/
inline
const bool& GModel::has_eval_indices(void) const
{
    return m_has_eval_inx;
}


/***********************************************************************//**
 * @brief Return vector of parameter indices updated by eval() method
 *
 * @return Vector of parameter indices updated by eval() method.
 ***************************************************************************/
inline
const std::vector<int>& GModel::eval_indices(void) const
{
    return m_eval_inx;
}

#endif /* GMODEL_HPP */