Ejemplo n.º 1
0
/***********************************************************************//**
 * @brief Constructor
 *
 * @param[in] coeffs Vector of polynomial coefficients.
 ***************************************************************************/
GCTAModelRadialPolynom::GCTAModelRadialPolynom(const std::vector<double>& coeffs)
                                                          : GCTAModelRadial()
{
    // Initialise members
    init_members();

    // Assign coefficients
    for (int i = 0; i < coeffs.size(); ++i) {

        // Allocate parameter
        GModelPar par;

        // Set value
        par.real_value(coeffs[i]);

        // Set other attributes
        std::string name = "coeff"+str(i);
        par.name(name);
        par.unit("");
        par.free();
        par.scale(1.0);
        par.gradient(0.0);
        par.hasgrad(true);

        // Push coefficient on list
        m_coeffs.push_back(par);

    } // endfor: looped over coefficients

    // Update parameter mapping
    update_pars();

    // Return
    return;
}
Ejemplo n.º 2
0
/***********************************************************************//**
 * @brief Read instrument scales from XML element
 *
 * @param[in] xml XML source element.
 *
 * Reads the instrument scale factors from a tag with the following format
 *
 *      <scaling>
 *         <instrument name="LAT" scale="1.0" min="0.1" max="10.0" value="1.0" free="0"/>
 *         <instrument name="CTA" scale="1.0" min="0.1" max="10.0" value="0.5" free="0"/>
 *      </scaling>
 *
 * The instrument name is case sensitive, but any leading and trailing white
 * space will be removed.
 *
 * If no scaling tag is found, all instrument scale factors will be cleared.
 ***************************************************************************/
void GModel::read_scales(const GXmlElement& xml)
{
    // Clear any existing scales
    m_scales.clear();

    // Continue only if there is a <scaling> tag
    if (xml.elements("scaling") != 0) {

        // Get pointer on first instrument scale factors
        const GXmlElement* scales = xml.element("scaling", 0);

        // Determine number of scale factors
        int nscales = scales->elements("instrument");

        // Read all scale factors
        for (int i = 0; i < nscales; ++i) {
            const GXmlElement* par = scales->element("instrument", i);
            GModelPar scale;
            scale.read(*par);
            scale.name(gammalib::strip_whitespace(par->attribute("name")));
            m_scales.push_back(scale);
        }

    }

    // Return
    return;
}
Ejemplo n.º 3
0
/***********************************************************************//**
 * @brief Set model scale factor for a given instrument
 *
 * @param[in] par Model parameter for scaling.
 *
 * Sets the model parameter for a given instrument. The instrument name is
 * case sensitive, but any leading to trailing white space will be stripped.
 *
 * If the instrument is not yet defined it will be appended to the list of
 * instruments.
 ***************************************************************************/
void GModel::scale(const GModelPar& par)
{
    // String leading and trailing while space
    std::string instrument = gammalib::strip_whitespace(par.name());

    // Search for instrument and copy the model parameter if the instrument
    // has been found. Make sure that the instrument name is in upper case.
    bool found = false;
    for (int i = 0; i < m_scales.size(); ++i) {
        if (m_scales[i].name() == instrument) {
            found       = true;
            m_scales[i] = par;
            m_scales[i].name(instrument);
            break;
        }
    }

    // If instrument has not been found then append it now to the list
    // of instruments.
    if (!found) {
        m_scales.push_back(par);
        m_scales[m_scales.size()-1].name(instrument);
    }

    // Return
    return;
}
Ejemplo n.º 4
0
/***********************************************************************//**
 * @brief Returns model scale factor for a given instrument
 *
 * @param[in] instrument Instrument.
 *
 * Returns the model scale factor for a given @p instrument. The search is
 * case sensitive.
 *
 * If the @p instrument is not found, the method returns a scale factor of
 * unity.
 ***************************************************************************/
GModelPar GModel::scale(const std::string& instrument) const
{
    // Initialise unit scale factor
    GModelPar scale;
    scale.value(1.0);
    scale.name(instrument);
    scale.fix();

    // Search for instrument and recover scale factor if the instrument
    // has been found.
    for (int i = 0; i < m_scales.size(); ++i) {
        if (m_scales[i].name() == instrument) {
            scale = m_scales[i];
            break;
        }
    }

    // Return scale factor
    return scale;
}
Ejemplo n.º 5
0
/***********************************************************************//**
 * @brief Read model from XML element
 *
 * @param[in] xml XML element.
 *
 * @exception GException::invalid_value
 *            Model definition requires at least one node.
 *
 * Read the COMPTEL DRB fitting model from an XML element.
 *
 * The model is composed of nodes that define the normalization value as
 * function of Phibar value. The following XML file syntax is expected:
 *
 *     <source name="Background" type="DRBFitting" instrument="COM">
 *       <node>
 *         <parameter name="Phibar"        .../>
 *         <parameter name="Normalization" .../>
 *       </node>
 *       ...
 *       <node>
 *         <parameter name="Phibar"        .../>
 *         <parameter name="Normalization" .../>
 *       </node>
 *     </source>
 ***************************************************************************/
void GCOMModelDRBFitting::read(const GXmlElement& xml)
{
    // Free space for nodes
    m_phibars.clear();
    m_values.clear();

    // Get number of nodes from XML file
    int nodes = xml.elements("node");

    // Throw an error if there are no nodes
    if (nodes < 1) {
        std::string msg = "DRB fitting model requires at least one Phibar "
                          "node. Please correct XML format.";
        throw GException::invalid_value(G_READ, msg);
    }

    // Loop over all nodes
    for (int i = 0; i < nodes; ++i) {

        // Allocate node parameters
        GModelPar phibar;
        GModelPar normalization;
            
        // Get node
        const GXmlElement* node = xml.element("node", i);

        // Read Phibar parameter
        const GXmlElement* par = gammalib::xml_get_par(G_READ, *node, "Phibar");
        phibar.read(*par);

        // Read Normalization parameter
        par = gammalib::xml_get_par(G_READ, *node, "Normalization");
        normalization.read(*par);

        // Set parameter names
        std::string phibar_name        = "Phibar layer "+gammalib::str(i);
        std::string normalization_name = "Scale factor "+gammalib::str(i);

        // Set Phibar attributes
        phibar.name(phibar_name);
        phibar.unit("deg");
        phibar.has_grad(false);

        // Set normalization attributes
        normalization.name(normalization_name);
        normalization.unit("");
        normalization.has_grad(true);

        // Push node parameters on list
        m_phibars.push_back(phibar);
        m_values.push_back(normalization);

    } // endfor: looped over nodes

    // Set model name
    name(xml.attribute("name"));

    // Set instruments
    instruments(xml.attribute("instrument"));

    // Set observation identifiers
    ids(xml.attribute("id"));

    // Check flag if TS value should be computed
    bool tscalc = (xml.attribute("tscalc") == "1") ? true : false;

    // Set flag if TS value should be computed
    this->tscalc(tscalc);

    // Set pointers
    set_pointers();

    // Set evluation cache
    set_cache();

    // Return
    return;
}
Ejemplo n.º 6
0
/***********************************************************************//**
 * @brief Read model from XML element
 *
 * @param[in] xml XML element.
 *
 * @exception GException::model_invalid_parnum
 *            Invalid number of model parameters found in XML element.
 * @exception GException::model_invalid_parnames
 *            Invalid model parameter names found in XML element.
 *
 * Read the radial Polynom model information from an XML element. The XML
 * element is required to have at least one parameter. Parameters are named
 * "CoeffX", where "X" starts from "0".  
 *
 * @todo Implement a test of the coefficient boundaries.
 ***************************************************************************/
void GCTAModelRadialPolynom::read(const GXmlElement& xml)
{
    // Free space for coefficients
    m_coeffs.clear();

    // Get maximum number of coefficients from XML file
    int max_coeffs = xml.elements("parameter");

    // Throw an error if no parameters were found
    if (max_coeffs < 1) {
        std::string message = "Radial polynomial model requires at least"
                              " one coefficient.";
        throw GException::model_invalid_parnum(G_READ, xml, message);
    }

    // Verify XML file consistency and determine number of coefficients
    int ncoeffs = 0;
    std::vector<int> npar;
    npar.assign(max_coeffs, 0);
    for (int i = 0; i < max_coeffs; ++i) {

        // Get parameter element
        GXmlElement* par = static_cast<GXmlElement*>(xml.element("parameter", i));

        // Verify that parameter is indeed a coefficient
        if (par->attribute("name").compare(0,5,"Coeff") != 0) {
            throw GException::model_invalid_parnames(G_READ, xml, 
                  par->attribute("name"));
        }
        
        // Verify that parameter coefficient has index in valid range
        int index = -1;
        size_t nchars = par->attribute("name").length() - 5;
        if (nchars > 0) {
            index = toint(par->attribute("name").substr(5, nchars));
        }
        else {
            throw GException::model_invalid_parnames(G_READ, xml,
                  "Radial polynomial \"Coeff\" parameter has no index.");
        }
        if (index < 0) {
            throw GException::model_invalid_parnames(G_READ, xml,
                  "Radial polynomial \"Coeff\" parameter index < 0.");
        }
        if (index >= max_coeffs) {
            std::string message = "There are "+str(max_coeffs)+" parameters,"
                                  " hence polynomial coefficients are expected"
                                  " to run from 0 to "+str(max_coeffs-1)+", yet"
                                  " a coefficient with index "+str(index)+" was"
                                  " encountered.";
            throw GException::model_invalid_parnames(G_READ, xml, message);
        }

        // Increment parameter counter
        npar[index]++;
        
        // Update number of coefficients
        if (index+1 > ncoeffs) {
            ncoeffs = index + 1;
        }

    } // endfor: verified XML file consistency
    
    // Verify that the number of coefficients is between 1 and max_coeffs
    if (ncoeffs < 0 || ncoeffs > max_coeffs) {
        std::string message = "Radial polynomial model requires at between"
                              " 1 and "+str(max_coeffs)+" parameters.";
        throw GException::model_invalid_parnum(G_READ, xml, message);
    }

    // Verify that all parameters were found
    for (int i = 0; i < ncoeffs; ++i) {
        if (npar[i] == 0) {
            std::string message = "Parameter \"Coeff"+str(i)+"\" required,"
                                  " but not found in XML file.";
            throw GException::model_invalid_parnames(G_READ, xml, message);
        }
        else if (npar[i] > 1) {
            std::string message = "Multiple parameters \"Coeff"+str(i)+"\""
                                  " found in XML file.";
            throw GException::model_invalid_parnames(G_READ, xml, message);
        }
    }

    // Finally get all coefficients in order
    for (int i = 0; i < ncoeffs; ++i) {

        // Set parameter name
        std::string name = "Coeff"+str(i);

        // Get corresponding parameter element
        GXmlElement* par = NULL;
        for (int k = 0; k < ncoeffs; ++k) {
            GXmlElement* element = static_cast<GXmlElement*>(xml.element("parameter", k));
            if (element->attribute("name") == name) {
                par = element;
                break;
            }
        }

        // Make sure that we really have one (just a double check, this should
        // never fail)
        if (par == NULL) {
            std::string message = "Required parameter \""+name+"\" not found.";
            throw GException::model_invalid_parnames(G_READ, xml, message);
        }

        // Now read that parameter ...
        GModelPar coeff;
        coeff.read(*par);

        // ... set other attributes ...
        coeff.name(name);
        coeff.unit("");

        //TODO: Check parameter

        // ... and push it on the list
        m_coeffs.push_back(coeff);

    } // endfor: looped over all parameters

    // Update parameter mapping
    update_pars();

    // Return
    return;
}