/***********************************************************************//**
 * @brief Write model into XML element
 *
 * @param[in] xml XML element into which model information is written.
 *
 * @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.
 *
 * Write the elliptical disk model information into an XML element. The XML
 * element will have the format 
 *
 *     <spatialModel type="DiskFunction">
 *       <parameter name="RA"          scale="1.0" value="83.6331" min="-360" max="360" free="1"/>
 *       <parameter name="DEC"         scale="1.0" value="22.0145" min="-90"  max="90"  free="1"/>
 *       <parameter name="PA"          scale="1.0" value="45.0"    min="-360"  max="360" free="1"/>
 *       <parameter name="MinorRadius" scale="1.0" value="0.5"     min="0.001" max="10"  free="1"/>
 *       <parameter name="MajorRadius" scale="1.0" value="2.0"     min="0.001" max="10"  free="1"/>
 *     </spatialModel>
 *
 ***************************************************************************/
void GModelSpatialEllipticalDisk::write(GXmlElement& xml) const
{
    // Write disk location
    GModelSpatialElliptical::write(xml);

    // If XML element has 3 nodes (which should be the location and PA nodes)
    // then append 2 parameter nodes
    if (xml.elements() == 3) {
        xml.append(GXmlElement("parameter name=\"MinorRadius\""));
        xml.append(GXmlElement("parameter name=\"MajorRadius\""));
    }

    // Determine number of parameter nodes in XML element
    int npars = xml.elements("parameter");

    // Verify that XML element has exactly 5 parameters
    if (xml.elements() != 5 || npars != 5) {
        throw GException::model_invalid_parnum(G_WRITE, xml,
              "Elliptical Disk model requires exactly 5 parameters.");
    }

    // Set or update model parameter attributes
    int npar[2] = {0, 0};
    for (int i = 0; i < npars; ++i) {

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

        // Handle semiminor radius
        if (par->attribute("name") == "MinorRadius") {

        	// Write parameter
            m_semiminor.write(*par);

            // Increment parameter counter
            npar[0]++;
        }

        // Handle semimajor radius
        else if (par->attribute("name") == "MajorRadius") {

        	// Write parameter
            m_semimajor.write(*par);

            // Increment parameter counter
            npar[1]++;
        }

    } // endfor: looped over all parameters

    // Check of all required parameters are present
    if (npar[0] != 1 || npar[1] != 1) {
        throw GException::model_invalid_parnames(G_WRITE, xml,
              "Elliptical disk model requires \"MinorRadius\" and"
              " \"MajorRadius\" parameters.");
    }

    // Return
    return;
}
Exemplo n.º 2
0
/***********************************************************************//**
 * @brief Write response information into XML element
 *
 * @param[in] xml XML element.
 *
 * Writes response information into an XML element. The Exposure, Psf
 * and background cubes are specified using
 *
 *      <observation name="..." id="..." instrument="...">
 *        ...
 *        <parameter name="ExposureCube" file="..."/>
 *        <parameter name="PsfCube"      file="..."/>
 *        <parameter name="BkgCube"      file="..."/>
 *      </observation>
 *
 ***************************************************************************/
void GCTAResponseCube::write(GXmlElement& xml) const
{
    // Add exposure cube filename
    std::string filename = gammalib::strip_whitespace(m_exposure.filename());
    if (!(filename.empty())) {
        GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, "ExposureCube");
        par->attribute("file", filename);
    }

    // Add PSF cube filename
    filename = gammalib::strip_whitespace(m_psf.filename());
    if (!(filename.empty())) {
        GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, "PsfCube");
        par->attribute("file", filename);
    }

    // Add background cube filename
    filename = gammalib::strip_whitespace(m_background.filename());
    if (!(filename.empty())) {
        GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, "BkgCube");
        par->attribute("file", filename);
    }

    // Return
    return;
}
Exemplo n.º 3
0
/***********************************************************************//**
 * @brief Write model into XML element
 *
 * @param[in] xml XML element into which model information is written.
 *
 * @exception GException::model_invalid_spatial
 *            Existing XML element is not of requested type.
 * @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.
 *
 * Writes the elliptical source location and position angle information into
 * an XML element in the following format
 *
 *     <spatialModel type="...">
 *       <parameter name="RA"  scale="1" value="83.63" min="-360" max="360" free="1"/>
 *       <parameter name="DEC" scale="1" value="22.01" min="-90"  max="90"  free="1"/>
 *       <parameter name="PA"  scale="1" value="45.0"  min="-360" max="360" free="1"/>
 *       ...
 *     </spatialModel>
 *
 * @todo The case that an existing spatial XML element with "GLON" and "GLAT"
 *       as coordinates is not supported.
 ***************************************************************************/
void GModelSpatialElliptical::write(GXmlElement& xml) const
{
    // Set model type
    if (xml.attribute("type") == "") {
        xml.attribute("type", type());
    }

    // Verify model type
    if (xml.attribute("type") != type()) {
        throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"),
              "Elliptical model is not of type \""+type()+"\".");
    }

    // Get or create parameters
    GXmlElement* ra  = gammalib::xml_need_par(G_WRITE, xml, m_ra.name());
    GXmlElement* dec = gammalib::xml_need_par(G_WRITE, xml, m_dec.name());
    GXmlElement* pa  = gammalib::xml_need_par(G_WRITE, xml, m_posangle.name());

    // Write parameters
    m_ra.write(*ra);
    m_dec.write(*dec);
    m_posangle.write(*pa);

    // Return
    return;
}
Exemplo n.º 4
0
/***********************************************************************//**
 * @brief Write model into XML element
 *
 * @param[in] xml XML element.
 *
 * @exception GException::model_invalid_spectral
 *            Existing XML element is not of the expected type.
 *
 * Writes the spectral information into an XML element.
 ***************************************************************************/
void GModelSpectralSmoothBrokenPlaw::write(GXmlElement& xml) const
{
    // Set model type
    if (xml.attribute("type") == "") {
        xml.attribute("type", type());
    }
    
    // Verify model type
    if (xml.attribute("type") != type()) {
        throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"),
                          "Spectral model is not of type \""+type()+"\".");
    }
    
    // Get XML parameters
    GXmlElement* norm        = gammalib::xml_need_par(G_WRITE, xml, m_norm.name());
    GXmlElement* index1      = gammalib::xml_need_par(G_WRITE, xml, m_index1.name());
    GXmlElement* index2      = gammalib::xml_need_par(G_WRITE, xml, m_index2.name());
    GXmlElement* pivot       = gammalib::xml_need_par(G_WRITE, xml, m_pivot.name());
    GXmlElement* breakenergy = gammalib::xml_need_par(G_WRITE, xml, m_breakenergy.name());
    GXmlElement* beta        = gammalib::xml_need_par(G_WRITE, xml, m_beta.name());
    
    // Write parameters
    m_norm.write(*norm);
    m_index1.write(*index1);
    m_pivot.write(*pivot);
    m_index2.write(*index2);
    m_breakenergy.write(*breakenergy);
    m_beta.write(*beta);
    
    // Return
    return;
}
Exemplo n.º 5
0
/***********************************************************************//**
 * @brief Read model from XML element
 *
 * @param[in] xml XML element containing power law model information.
 *
 * @exception GException::model_invalid_parnum
 *            Invalid number of model parameters found in XML element.
 * @exception GException::model_invalid_parnames
 *            Invalid model parameter name found in XML element.
 *
 * Read the function information from an XML element and load the nodes
 * from the associated file. The XML element is required to have an
 * attribute "file" that specifies the function nodes and a parameter
 * named "Normalization".
 ***************************************************************************/
void GModelSpectralFunc::read(const GXmlElement& xml)
{
    // Verify that XML element has exactly 1 parameter
    if (xml.elements() != 1 || xml.elements("parameter") != 1) {
        throw GException::model_invalid_parnum(G_READ, xml,
              "Spectral function requires exactly 1 parameter.");
    }

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

    // Get value
    if (par->attribute("name") == "Normalization") {
        m_norm.read(*par);
    }
    else {
        throw GException::model_invalid_parnames(G_READ, xml,
                          "Require \"Normalization\" parameter.");
    }

    // Load nodes from file
    load_nodes(xml.attribute("file"));

    // Return
    return;
}
Exemplo n.º 6
0
/***********************************************************************//**
 * @brief Write model into XML element
 *
 * @param[in] xml XML element.
 *
 * @exception GExpection::invalid_value
 *            Invalid XML format encountered.
 *
 * Writes the temporal information into an XML element in the format
 *
 *     <temporalModel type="LightCurve" file="..">
 *       <parameter name="Normalization" scale="1" value="1" min="0.1" max="10" free="1"/>
 *     </temporalModel>
 ***************************************************************************/
void GModelTemporalLightCurve::write(GXmlElement& xml) const
{
    // Set model type
    if (xml.attribute("type") == "") {
        xml.attribute("type", type());
    }

    // Verify model type
    if (xml.attribute("type") != type()) {
        std::string msg = "Temporal model of type "+xml.attribute("type")+
                          " encountered while \""+type()+"\" was expected.";
        throw GException::invalid_value(G_WRITE, msg);
    }

    // Get XML parameters
    GXmlElement* norm  = gammalib::xml_need_par(G_WRITE, xml, m_norm.name());

    // Write parameters
    m_norm.write(*norm);

    // Set file attribute
    xml.attribute("file", gammalib::xml_file_reduce(xml, m_filename));

    // Return
    return;
}
Exemplo n.º 7
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 map cube information from an XML element. The XML element is
 * required to have 1 parameter named either "Normalization" or "Value".
 ***************************************************************************/
void GModelSpatialCube::read(const GXmlElement& xml)
{
    // Verify that XML element has exactly 1 parameters
    if (xml.elements() != 1 || xml.elements("parameter") != 1) {
        throw GException::model_invalid_parnum(G_READ, xml,
              "Map cube spatial model requires exactly 1 parameter.");
    }

    // Get pointer on model parameter
    GXmlElement* par = static_cast<GXmlElement*>(xml.element("parameter", 0));

    // Get value
    if (par->attribute("name") == "Normalization" ||
        par->attribute("name") == "Value") {
        m_value.read(*par);
    }
    else {
        throw GException::model_invalid_parnames(G_READ, xml,
              "Map cube spatial model requires either \"Value\" or"
              " \"Normalization\" parameter.");
    }

    // Load map cube from file
    load_cube(xml.attribute("file"));

    // Return
    return;
}
Exemplo n.º 8
0
/***********************************************************************//**
 * @brief Read sky model from XML element
 *
 * @param[in] xml XML element.
 ***************************************************************************/
void GModelSky::read(const GXmlElement& xml)
{
    // Clear sky model
    clear();

    // Get pointers on spectrum and spatial model
    GXmlElement* spec = static_cast<GXmlElement*>(xml.element("spectrum", 0));
    GXmlElement* spat = static_cast<GXmlElement*>(xml.element("spatialModel", 0));

    // Allocate constant
    GModelTemporalConst temporal;

    // Clone spatial and spectral models
    m_spatial  = xml_spatial(*spat);
    m_spectral = xml_spectral(*spec);
    m_temporal = temporal.clone();

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

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

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

    // Set parameter pointers
    set_pointers();

    // Return
    return;
}
Exemplo n.º 9
0
/***********************************************************************//**
 * @brief Write CTA instrument background model into XML element
 *
 * @param[in] xml XML element.
 *
 * Write CTA instrument background model information into an XML element.
 * The XML element will have the following structure
 *
 *     <source name="..." type="..." instrument="...">
 *       <spectrum type="...">
 *         ...
 *       </spectrum>
 *     </source>
 *
 * If the model contains a non-constant temporal model, the temporal
 * component will also be written following the syntax
 *
 *     <source name="..." type="..." instrument="...">
 *       <spectrum type="...">
 *         ...
 *       </spectrum>
 *       <temporalModel type="...">
 *         ...
 *       </temporalModel>
 *     </source>
 *
 * If no temporal component is found a constant model is assumed.
 ***************************************************************************/
void GCTAModelIrfBackground::write(GXmlElement& xml) const
{
    // Initialise pointer on source
    GXmlElement* src = NULL;

    // Search corresponding source
    int n = xml.elements("source");
    for (int k = 0; k < n; ++k) {
        GXmlElement* element = xml.element("source", k);
        if (element->attribute("name") == name()) {
            src = element;
            break;
        }
    }

    // If we have a temporal model that is either not a constant, or a
    // constant with a normalization value that differs from 1.0 then
    // write the temporal component into the XML element. This logic
    // assures compatibility with the Fermi/LAT format as this format
    // does not handle temporal components.
    bool write_temporal = ((m_temporal != NULL) &&
                           (m_temporal->type() != "Constant" ||
                            (*m_temporal)[0].value() != 1.0));

    // If no source with corresponding name was found then append one
    if (src == NULL) {
        src = xml.append("source");
        if (spectral() != NULL) src->append(GXmlElement("spectrum"));
        if (write_temporal)     src->append(GXmlElement("temporalModel"));
    }

    // Set model type, name and optionally instruments
    src->attribute("name", name());
    src->attribute("type", type());
    if (instruments().length() > 0) {
        src->attribute("instrument", instruments());
    }
    std::string identifiers = ids();
    if (identifiers.length() > 0) {
        src->attribute("id", identifiers);
    }

    // Write spectral model
    if (spectral() != NULL) {
        GXmlElement* spec = src->element("spectrum", 0);
        spectral()->write(*spec);
    }

    // Optionally write temporal model
    if (write_temporal) {
        if (dynamic_cast<GModelTemporalConst*>(temporal()) == NULL) {
            GXmlElement* temp = src->element("temporalModel", 0);
            temporal()->write(*temp);
        }
    }

    // Return
    return;
}
Exemplo n.º 10
0
/***********************************************************************//**
 * @brief Write model into XML element
 *
 * @param[in] xml XML element.
 *
 * @todo Document method.
 ***************************************************************************/
void GCTAModelBackground::write(GXmlElement& xml) const
{
    // Initialise pointer on source
    GXmlElement* src = NULL;

    // Search corresponding source
    int n = xml.elements("source");
    for (int k = 0; k < n; ++k) {
        GXmlElement* element = xml.element("source", k);
        if (element->attribute("name") == name()) {
            src = element;
            break;
        }
    }

    // If no source with corresponding name was found then append one
    if (src == NULL) {
        src = xml.append("source");
        if (spectral() != NULL) src->append(GXmlElement("spectrum"));
        if (spatial()  != NULL) src->append(GXmlElement("spatialModel"));
        //if (temporal() != NULL) src->append(GXmlElement("temporalModel"));
    }

    // Set model type, name and optionally instruments
    src->attribute("name", name());
    src->attribute("type", type());
    if (instruments().length() > 0) {
        src->attribute("instrument", instruments());
    }
    std::string identifiers = ids();
    if (identifiers.length() > 0) {
        src->attribute("id", identifiers);
    }

    // Write spectral model
    if (spectral() != NULL) {
        GXmlElement* spec = src->element("spectrum", 0);
        spectral()->write(*spec);
    }

    // Write spatial model
    if (spatial() != NULL) {
        GXmlElement* spat = src->element("spatialModel", 0);
        spatial()->write(*spat);
    }

    // Write temporal model
    /*
    if (temporal() != NULL) {
        if (dynamic_cast<GModelTemporalConst*>(temporal()) == NULL) {
            GXmlElement* temp = src->element("temporalModel", 0);
            temporal()->write(*temp);
        }
    }
    */

    // Return
    return;
}
Exemplo n.º 11
0
/***********************************************************************//**
 * @brief Read observations from XML document
 *
 * @param[in] xml XML document.
 *
 * @exception GException::invalid_instrument
 *            Invalid instrument encountered.
 *
 * Reads observations from the first observation list that is found in the
 * XML document. The decoding of the instrument specific observation
 * definition is done within the observation's read() method.
 *
 * @todo Observation names and IDs are not verified so far for uniqueness.
 *       This would be required to achieve an unambiguous update of parameters
 *       in an already existing XML file when using the write method.
 ***************************************************************************/
void GObservations::read(const GXml& xml)
{
    // Get pointer on observation library
    GXmlElement* lib = xml.element("observation_list", 0);

    // Loop over all observations
    int n = lib->elements("observation");
    for (int i = 0; i < n; ++i) {

        // Get pointer on observation
        GXmlElement* obs = static_cast<GXmlElement*>(lib->element("observation", i));

        // Get attributes
        std::string name       = obs->attribute("name");
        std::string id         = obs->attribute("id");
        std::string instrument = obs->attribute("instrument");

        // Get model
        GObservationRegistry registry;
        GObservation*        ptr = registry.alloc(instrument);

        // If observation is valid then read its definition from XML file
        if (ptr != NULL) {

            // Read definition
            ptr->read(*obs);

            // Set attributes
            ptr->name(name);
            ptr->id(id);

        } // endif: observation was valid

        // ... otherwise throw an exception
        else {
            throw GException::invalid_instrument(G_READ, instrument);
        }

        // Append observation to container
        append(*ptr);

        // Free model (appending clones the observation)
        delete ptr;

    } // endfor: looped over all observations

    // Return
    return;
}
Exemplo n.º 12
0
/***********************************************************************//**
 * @brief Read model from XML element
 *
 * @param[in] xml XML element containing power law model information.
 *
 * @exception GException::model_invalid_parnum
 *            Invalid number of model parameters found in XML element.
 * @exception GException::model_invalid_parnames
 *            Invalid model parameter name found in XML element.
 *
 * Read the function information from an XML element and load the nodes
 * from the associated file. The XML element is required to have a parameter
 * named "Normalization" or "Value".
 ***************************************************************************/
void GModelSpectralConst::read(const GXmlElement& xml)
{
    // Verify that XML element has exactly 1 parameter
    if (xml.elements() != 1 || xml.elements("parameter") != 1) {
        throw GException::model_invalid_parnum(G_READ, xml,
              "Spectral constant requires exactly 1 parameter.");
    }

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

    // Get value
    if (par->attribute("name") == "Normalization" ||
        par->attribute("name") == "Value") {
        m_norm.read(*par);
    }
    else {
        throw GException::model_invalid_parnames(G_READ, xml,
                          "Spectral constant requires either"
                          " \"Normalization\" or \"Value\" parameter.");
    }

    // Return
    return;
}
Exemplo n.º 13
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 map cube information from an XML element. The XML element should
 * have either the format
 *
 *     <spatialModel type="MapCubeFunction" file="test_file.fits">
 *       <parameter name="Normalization" scale="1" value="1" min="0.1" max="10" free="0"/>
 *     </spatialModel>
 *
 * or alternatively
 *
 *     <spatialModel type="MapCubeFunction" file="test_file.fits">
 *       <parameter name="Value" scale="1" value="1" min="0.1" max="10" free="0"/>
 *     </spatialModel>
 *
 ***************************************************************************/
void GModelSpatialDiffuseCube::read(const GXmlElement& xml)
{
    // Clear model
    clear();

    // Verify that XML element has exactly 1 parameters
    if (xml.elements() != 1 || xml.elements("parameter") != 1) {
        throw GException::model_invalid_parnum(G_READ, xml,
              "Map cube spatial model requires exactly 1 parameter.");
    }

    // Get pointer on model parameter
    const GXmlElement* par = xml.element("parameter", 0);

    // Get value
    if (par->attribute("name") == "Normalization" ||
        par->attribute("name") == "Value") {
        m_value.read(*par);
    }
    else {
        throw GException::model_invalid_parnames(G_READ, xml,
              "Map cube spatial model requires either \"Value\" or"
              " \"Normalization\" parameter.");
    }

    // Save filename
    m_filename = xml.attribute("file");

    // Return
    return;
}
Exemplo n.º 14
0
/***********************************************************************//**
 * @brief Write model into XML element
 *
 * @param[in] xml Source library.
 ***************************************************************************/
void GModelSky::write(GXmlElement& xml) const
{
    // Initialise pointer on source
    GXmlElement* src = NULL;

    // Search corresponding source
    int n = xml.elements("source");
    for (int k = 0; k < n; ++k) {
        GXmlElement* element = static_cast<GXmlElement*>(xml.element("source", k));
        if (element->attribute("name") == name()) {
            src = element;
            break;
        }
    }

    // If no source with corresponding name was found then append one
    if (src == NULL) {
        src = new GXmlElement("source");
        src->attribute("name") = name();
        if (spectral() != NULL) src->append(new GXmlElement("spectrum"));
        if (spatial()  != NULL) src->append(new GXmlElement("spatialModel"));
        xml.append(src);
    }

    // Set model attributes
    src->attribute("name", name());
    src->attribute("type", type());
    std::string instruments = this->instruments();
    if (instruments.length() > 0) {
        src->attribute("instrument", instruments);
    }

    // Write spectral model
    if (spectral() != NULL) {
        GXmlElement* spec = static_cast<GXmlElement*>(src->element("spectrum", 0));
        spectral()->write(*spec);
    }

    // Write spatial model
    if (spatial() != NULL) {
        GXmlElement* spat = static_cast<GXmlElement*>(src->element("spatialModel", 0));
        spatial()->write(*spat);
    }

    // Return
    return;
}
Exemplo n.º 15
0
/***********************************************************************//**
 * @brief XML constructor
 *
 * @param[in] xml XML element.
 *
 * Construct model from XML element. The method extracts the "name",
 * "instrument" and "id" attributes from the model node.
 ***************************************************************************/
GModel::GModel(const GXmlElement& xml)
{
    // Initialise members
    init_members();

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

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

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

    // Return
    return;
}
Exemplo n.º 16
0
/***********************************************************************//**
 * @brief Read CTA instrument background model from XML element
 *
 * @param[in] xml XML element.
 *
 * Set up CTA instrument background model from the information provided by
 * an XML element. The XML element is expected to have the following
 * structure
 *
 *     <source name="..." type="..." instrument="...">
 *       <spectrum type="...">
 *         ...
 *       </spectrum>
 *     </source>
 *
 * Optionally, a temporal model may be provided using the following
 * syntax
 *
 *     <source name="..." type="..." instrument="...">
 *       <spectrum type="...">
 *         ...
 *       </spectrum>
 *       <temporalModel type="...">
 *         ...
 *       </temporalModel>
 *     </source>
 *
 * If no temporal component is found a constant model is assumed.
 ***************************************************************************/
void GCTAModelIrfBackground::read(const GXmlElement& xml)
{
    // Clear model
    clear();

    // Initialise XML elements
    const GXmlElement* spectral = NULL;
    const GXmlElement* temporal = NULL;

    // Get pointer on spectrum
    spectral = xml.element("spectrum", 0);

    // Extract spectral model
    m_spectral = xml_spectral(*spectral);

    // Optionally get temporal model
    if (xml.elements("temporalModel")) {
        temporal   = xml.element("temporalModel", 0);
        m_temporal = xml_temporal(*temporal);
    }
    else {
        GModelTemporalConst constant;
        m_temporal = constant.clone();
    }

    // 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 parameter pointers
    set_pointers();

    // Return
    return;
}
Exemplo n.º 17
0
/***********************************************************************//**
 * @brief Write model into XML element
 *
 * @param[in] xml XML element.
 *
 * @exception GException::model_invalid_spatial
 *            Existing XML element is not of type "MapCubeFunction"
 * @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.
 *
 * Write the map cube information into an XML element. The XML element has to
 * be of type "MapCubeFunction" and will have 1 parameter leaf named either
 * "Value" or "Normalization" (default).
 ***************************************************************************/
void GModelSpatialCube::write(GXmlElement& xml) const
{
    // Set model type
    if (xml.attribute("type") == "") {
        xml.attribute("type", "MapCubeFunction");
    }

    // Verify model type
    if (xml.attribute("type") != "MapCubeFunction") {
        throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"),
              "Spatial model is not of type \"MapCubeFunction\".");
    }

    // If XML element has 0 nodes then append parameter node. The name
    // of the node is "Normalization" as this is the Fermi-LAT standard.
    // We thus assure that the XML files will be compatible with
    // Fermi-LAT.
    if (xml.elements() == 0) {
        xml.append(new GXmlElement("parameter name=\"Normalization\""));
    }

    // Verify that XML element has exactly 1 parameter
    if (xml.elements() != 1 || xml.elements("parameter") != 1) {
        throw GException::model_invalid_parnum(G_WRITE, xml,
              "Map cube spatial model requires exactly 1 parameter.");
    }

    // Get pointers on model parameter
    GXmlElement* par = static_cast<GXmlElement*>(xml.element("parameter", 0));

    // Set or update parameter
    if (par->attribute("name") == "Normalization" ||
        par->attribute("name") == "Value") {
        m_value.write(*par);
    }
    else {
        throw GException::model_invalid_parnames(G_WRITE, xml,
              "Map cube spatial model requires either \"Value\" or"
              " \"Normalization\" parameter.");
    }

    // Return
    return;
}
Exemplo n.º 18
0
/***********************************************************************//**
 * @brief Read model from XML element
 *
 * @param[in] xml XML element.
 *
 * The model is composed of a spectrum component ('spectral'), a spatial
 * component ('spatialModel'), and, optionally, of a temporal component
 * ('lightcurve'). If no temporal component is found a constant model is
 * assumed.
 ***************************************************************************/
void GCTAModelBackground::read(const GXmlElement& xml)
{
    // Clear model
    clear();

    // Initialise XML elements
    const GXmlElement* spat = NULL;
    const GXmlElement* spec = NULL;
    const GXmlElement* temp = NULL;

    // Get pointers on spectrum and radial model
    spat = xml.element("spatialModel", 0);
    spec = xml.element("spectrum", 0);

    // Clone radial and spectral models
    m_spatial  = xml_spatial(*spat);
    m_spectral = xml_spectral(*spec);

    // Optionally get temporal model
    if (xml.elements("temporalModel")) {
        temp       = xml.element("temporalModel", 0);
        m_temporal = xml_temporal(*temp);
    }
    else {
        GModelTemporalConst temporal;
        m_temporal = temporal.clone();
    }

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

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

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

    // Set parameter pointers
    set_pointers();

    // Return
    return;
}
Exemplo n.º 19
0
/***********************************************************************//**
 * @brief Write Good Time Intervals into XML element
 *
 * @param[in] xml XML element.
 *
 * Writes Good Time Intervals into an XML element. The format of the Good
 * Time Intervals is
 *
 *     <parameter name="GoodTimeIntervals" tmin="..." tmax="..."/>
 *
 * The units of the @a tmin and @a tmax parameters are seconds.
 *
 * The method also writes the time reference as parameter in the @p xml
 * element.
 *
 * This method does nothing if the Good Time Intervals are empty.
 ***************************************************************************/
void GGti::write(GXmlElement& xml) const
{
    // Continue only if there are GTIs
    if (!is_empty()) {

        // Get parameter
        GXmlElement* par = gammalib::xml_need_par(G_WRITE_XML, xml, "GoodTimeIntervals");

        // Write time interval
        par->attribute("tmin", gammalib::str(tstart().convert(m_reference)));
        par->attribute("tmax", gammalib::str(tstop().convert(m_reference)));

        // Write time reference
        m_reference.write(xml);

    } // endif: GTIs were not empty

    // Return
    return;
}
Exemplo n.º 20
0
/***********************************************************************//**
 * @brief Write model into XML element
 *
 * @param[in] xml XML element into which model information is written.
 *
 * @exception GException::model_invalid_spectral
 *            Existing XML element is not of type "FileFunction"
 * @exception GException::model_invalid_parnum
 *            Invalid number of model parameters or nodes found in XML element.
 * @exception GException::model_invalid_parnames
 *            Invalid model parameter names found in XML element.
 *
 * Write the spectral function information into an XML element. The XML
 * element has to be of type "FileFunction" and will have 1 parameter leaf
 * named "Normalization". Note that the function nodes will not be written
 * since they will not be altered by any method.
 ***************************************************************************/
void GModelSpectralFunc::write(GXmlElement& xml) const
{
    // Set model type
    if (xml.attribute("type") == "") {
        xml.attribute("type", "FileFunction");
    }

    // Verify model type
    if (xml.attribute("type") != "FileFunction") {
        throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"),
              "Spectral model is not of type \"FileFunction\".");
    }

    // If XML element has 0 nodes then append 1 parameter node
    if (xml.elements() == 0) {
        xml.append(new GXmlElement("parameter name=\"Normalization\""));
    }

    // Verify that XML element has exactly 1 parameter
    if (xml.elements() != 1 || xml.elements("parameter") != 1) {
        throw GException::model_invalid_parnum(G_WRITE, xml,
              "Spectral function requires exactly 1 parameter.");
    }

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

    // Set parameyter
    if (par->attribute("name") == "Normalization") {
        m_norm.write(*par);
    }
    else {
        throw GException::model_invalid_parnames(G_WRITE, xml,
                          "Require \"Normalization\" parameter.");
    }

    // Return
    return;
}
Exemplo n.º 21
0
/***********************************************************************//**
 * @brief Write model into XML element
 *
 * @param[in] xml XML element into which model information is written.
 *
 * @exception GException::model_invalid_spatial
 *            Existing XML element is not of type 'GaussFunction'
 * @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.
 *
 * Writes the radial source location and position angle information into an
 * XML element in the following format
 *
 *     <spatialModel type="...">
 *       <parameter name="RA"  scale="1" value="83.63" min="-360" max="360" free="1"/>
 *       <parameter name="DEC" scale="1" value="22.01" min="-90"  max="90"  free="1"/>
 *       ...
 *     </spatialModel>
 *
 * @todo The case that an existing spatial XML element with "GLON" and "GLAT"
 *       as coordinates is not supported.
 ***************************************************************************/
void GModelSpatialRadial::write(GXmlElement& xml) const
{
    // Set model type
    if (xml.attribute("type") == "") {
        xml.attribute("type", type());
    }

    // Verify model type
    if (xml.attribute("type") != type()) {
        throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"),
              "Radial model is not of type \""+type()+"\".");
    }

    // If XML element has 0 nodes then append 2 parameter nodes
    if (xml.elements() == 0) {
        xml.append(GXmlElement("parameter name=\"RA\""));
        xml.append(GXmlElement("parameter name=\"DEC\""));
    }

    // Determine number of parameter nodes in XML element
    int npars = xml.elements("parameter");

    // Verify that XML element has at least 2 parameters
    if (xml.elements() < 2 || npars < 2) {
        throw GException::model_invalid_parnum(G_WRITE, xml,
              "Radial source model requires at least 2 parameters.");
    }

    // Set or update model parameter attributes
    int npar[2] = {0, 0};
    for (int i = 0; i < npars; ++i) {

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

        // Handle RA
        if (par->attribute("name") == "RA") {
            npar[0]++;
            m_ra.write(*par);
        }

        // Handle DEC
        else if (par->attribute("name") == "DEC") {
            npar[1]++;
            m_dec.write(*par);
        }

    } // endfor: looped over all parameters

    // Check of all required parameters are present
    if (npar[0] != 1 || npar[1] != 1) {
        throw GException::model_invalid_parnames(G_WRITE, xml,
              "Require \"RA\" and \"DEC\" parameters.");
    }

    // Return
    return;
}
Exemplo n.º 22
0
/***********************************************************************//**
 * @brief Write instrument scales into XML element
 *
 * @param[in] xml XML source element.
 *
 * @exception GException::model_invalid_parnum
 *            Invalid number of instrument tags found in XML element.
 *
 * If there are instrument scale factors then add a tag with the following
 * format to the XML element:
 *
 *      <scaling>
 *         <instrument name="LAT" scale="1" min="0.1" max="10" value="1.0" free="0"/>
 *         <instrument name="CTA" scale="1" min="0.1" max="10" value="0.5" free="0"/>
 *      </scaling>
 ***************************************************************************/
void GModel::write_scales(GXmlElement& xml) const
{
    // Continue only is scale factors are present
    if (!m_scales.empty()) {

        // Get number of instruments
        int num = m_scales.size();

        // Initialise scaling tag
        GXmlElement* scale = NULL;

        // If no <scaling> tag exists then add one now with the required
        // number of instruments ...
        if (xml.elements("scaling") == 0) {
            scale = xml.append("scaling");
            for (int i = 0; i < num; ++i) {
                scale->append(GXmlElement("instrument"));
            }
        }

        // ... otherwise get first tag
        else {
            scale = xml.element("scaling", 0);
        }

        // Verify that scaling tag  has the required number of instruments
        if (scale->elements() != num || scale->elements("instrument") != num) {
            throw GException::model_invalid_parnum(G_WRITE_SCALES, *scale,
                  "Instrument scaling needs "+gammalib::str(num)+" instrument tags.");
        }

        // Write all instruments
        for (int i = 0; i < num; ++i) {

            // Get instrument element
            GXmlElement* inst = scale->element("instrument", i);

            // Set instrument name
            inst->attribute("name", m_scales[i].name());

            // Write instrument scaling factor
            m_scales[i].write(*inst);

        } // endfor: looped over all instruments

    }

    // Return
    return;
}
Exemplo n.º 23
0
/***********************************************************************//**
 * @brief Read model from XML element
 *
 * @param[in] xml XML element.
 *
 * Reads the temporal information from an XML element. The XML element should
 * have the format
 *
 *     <temporalModel type="LightCurve" file="..">
 *       <parameter name="Normalization" scale="1" value="1" min="0.1" max="10" free="1"/>
 *     </temporalModel>
 ***************************************************************************/
void GModelTemporalLightCurve::read(const GXmlElement& xml)
{
    // Get parameter pointers
    const GXmlElement* norm  = gammalib::xml_get_par(G_READ, xml, m_norm.name());

    // Read parameters
    m_norm.read(*norm);

    // Load nodes from file
    load_nodes(gammalib::xml_file_expand(xml, xml.attribute("file")));

    // Return
    return;
}
Exemplo n.º 24
0
/***********************************************************************//**
 * @brief Write energy boundaries into XML element
 *
 * @param[in] xml XML element.
 *
 * Writes energy boundaries into an XML element. The format of the energy
 * boundaries is
 *
 *     <parameter name="EnergyBoundaries" emin="0.1" emax="10.0"/>
 *
 * The units of the @a emin and @a emax parameters are MeV.
 *
 * This method does nothing if the energy boundaries are empty.
 ***************************************************************************/
void GEbounds::write(GXmlElement& xml) const
{
    // Continue only if there are energy boundaries
    if (!is_empty()) {

        // Get parameter
        GXmlElement* par = gammalib::xml_need_par(G_WRITE_XML, xml,
                           "EnergyBoundaries");

        // Write attributes
        par->attribute("emin", gammalib::str(emin().MeV()));
        par->attribute("emax", gammalib::str(emax().MeV()));

    } // endif: energy boundaries were not empty

    // Return
    return;
}
Exemplo n.º 25
0
/***********************************************************************//**
 * @brief Write model into XML element
 *
 * @param[in] xml XML element into which model information is written.
 *
 * @exception GException::model_invalid_spatial
 *            Existing XML element is not of type 'GaussFunction'
 * @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.
 *
 * Writes the radial disk model information into an XML element. The XML
 * element will have the format 
 *
 *     <spatialModel type="RadialGaussian">
 *       <parameter name="RA"    scale="1.0" value="83.6331" min="-360" max="360" free="1"/>
 *       <parameter name="DEC"   scale="1.0" value="22.0145" min="-90"  max="90"  free="1"/>
 *       <parameter name="Sigma" scale="1.0" value="0.45"    min="0.01" max="10"  free="1"/>
 *     </spatialModel>
 *
 ***************************************************************************/
void GModelSpatialRadialGauss::write(GXmlElement& xml) const
{
    // Write Gaussian location
    GModelSpatialRadial::write(xml);

    // If XML element has 2 nodes (which should be the location nodes)
    // then append 1 parameter node
    if (xml.elements() == 2) {
        xml.append(GXmlElement("parameter name=\"Sigma\""));
    }

    // Determine number of parameter nodes in XML element
    int npars = xml.elements("parameter");

    // Verify that XML element has exactly 3 parameters
    if (xml.elements() != 3 || npars != 3) {
        throw GException::model_invalid_parnum(G_WRITE, xml,
              "Point source model requires exactly 3 parameters.");
    }

    // Set or update model parameter attributes
    int npar[1] = {0};
    for (int i = 0; i < npars; ++i) {

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

        // Handle Sigma
        if (par->attribute("name") == "Sigma") {
            m_sigma.write(*par);
            npar[0]++;
        }

    } // endfor: looped over all parameters

    // Check of all required parameters are present
    if (npar[0] != 1) {
        throw GException::model_invalid_parnames(G_WRITE, xml,
              "Require \"Sigma\" parameter.");
    }

    // Return
    return;
}
Exemplo n.º 26
0
/***********************************************************************//**
 * @brief Test XML element access
 **************************************************************************/
void TestGXml::test_GXml_access(void)
{
    // Test root document access
    GXml xml;
    xml.load(m_xml_file);
    test_value(xml.size(), 3, "Check number of child elements");

    // Test node access
    for (int i = 0; i < xml.size(); ++i) {
        GXmlNode* ptr = xml[i];
        test_assert(ptr != 0, "Check XML node access");
    }
    test_value(xml.elements(), 1, "Check number of child elements");

    // Test node access
    for (int i = 0; i < xml.elements(); ++i) {
        GXmlNode* ptr = xml.element(i);
        test_assert(ptr != 0, "Check XML element access");
    }
    test_value(xml.elements("source_library"), 1, "Check number of child elements");

    // Test element access
    for (int i = 0; i < xml.elements("source_library"); ++i) {
        GXmlElement* ptr = xml.element("source_library", i);
        test_value(ptr->name(), "source_library", "Check element name");
    }

    // Test hierarchy access
    GXmlElement* ptr = NULL;
    ptr = xml.element("source_library");
    test_value(ptr->name(), "source_library", "Check hierarchy level 1");
    ptr = xml.element("source_library > source");
    test_value(ptr->name(),  "source", "Check hierarchy level 2");
    ptr = xml.element("source_library > source > spectrum");
    test_value(ptr->name(), "spectrum", "Check hierarchy level 3");
    ptr = xml.element("source_library > source > spectrum > parameter[2]");
    test_value(ptr->name(), "parameter", "Check hierarchy level 4");
    test_value(ptr->attribute("name"), "PivotEnergy", "Check for attribute");

    // Return
    return;
}
Exemplo n.º 27
0
/***********************************************************************//**
 * @brief Write observation into XML element
 *
 * @param[in] xml XML element.
 *
 * @exception GException::xml_invalid_parnum
 *            Invalid number of parameters found in XML element.
 * @exception GException::xml_invalid_parnames
 *            Invalid parameter names found in XML element.
 *
 * Writes information for a multi-wavelength observation into an XML element.
 * The format of the XML element is
 *
 *     <observation name="..." id="..." instrument="MWL">
 *       <parameter name="Instrument" value="..."/>
 *       <parameter name="Data" file="..." [extno="..."] [extname="..."]/>
 *     </observation>
 ***************************************************************************/
void GMWLObservation::write(GXmlElement& xml) const
{
    // If XML element has 0 nodes then append 2 parameter nodes
    if (xml.elements() == 0) {
        xml.append(GXmlElement("parameter name=\"Instrument\""));
        xml.append(GXmlElement("parameter name=\"Data\""));
    }

    // Verify that XML element has exactly 2 parameters
    if (xml.elements() != 2 || xml.elements("parameter") != 2) {
        throw GException::xml_invalid_parnum(G_WRITE, xml,
              "MWL observation requires exactly 2 parameters.");
    }

    // Set or update parameter attributes
    int npar[] = {0, 0};
    for (int i = 0; i < 2; ++i) {

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

        // Handle Instrument
        if (par->attribute("name") == "Instrument") {
            npar[0]++;
            par->attribute("value", m_instrument);
        }

        // Handle Data
        else if (par->attribute("name") == "Data") {
            npar[1]++;
            par->attribute("file", m_filename);
            if (gammalib::strip_whitespace(m_extno).length() > 0) {
                par->attribute("extno", m_extno);
            }
            if (gammalib::strip_whitespace(m_extname).length() > 0) {
                par->attribute("extname", m_extname);
            }
        }

    } // endfor: looped over all parameters

    // Check of all required parameters are present
    if (npar[0] != 1 || npar[1] != 1)
        throw GException::xml_invalid_parnames(G_WRITE, xml,
              "Require \"Instrument\" and \"Data\" parameters.");

    // Return
    return;
}
Exemplo n.º 28
0
/***********************************************************************//**
 * @brief Write observations into XML document
 *
 * @param[in] xml XML document.
 *
 * Write observations into the first observation library that is found in the
 * XML document. In case that no observation library exists, one is added to
 * the document.
 ***************************************************************************/
void GObservations::write(GXml& xml) const
{
    // If there is no observation library then append one
    if (xml.elements("observation_list") == 0) {
        xml.append(new GXmlElement("observation_list title=\"observation list\""));
    }

    // Get pointer on observation library
    GXmlElement* lib = xml.element("observation_list", 0);

    // Write all observations into library
    for (int i = 0; i < size(); ++i) {
    
        // Initialise pointer on observation
        GXmlElement* obs = NULL;

        // Search corresponding observation
        int n = xml.elements("observation");
        for (int k = 0; k < n; ++k) {
            GXmlElement* element = static_cast<GXmlElement*>(xml.element("observation", k));
            if (element->attribute("name")       == m_obs[i]->name() &&
                element->attribute("id")         == m_obs[i]->id()   &&
                element->attribute("instrument") == m_obs[i]->instrument()) {
                obs = element;
                break;
            }
        }

        // If no observation with corresponding name, ID and instrument was found
        // then append one now
        if (obs == NULL) {
            obs = new GXmlElement("observation");
            obs->attribute("name", m_obs[i]->name());
            obs->attribute("id", m_obs[i]->id());
            obs->attribute("instrument", m_obs[i]->instrument());
            lib->append(obs);
        }
    
        // Write now observation
        m_obs[i]->write(*obs);

    } // endfor: looped over all observaitons

    // Return
    return;
}
Exemplo n.º 29
0
/***********************************************************************//**
 * @brief Write Test Suites into XML document
 *
 * @param[in] xml XML document.
 *
 * Write test suites into the XML document.
 ***************************************************************************/
void GTestSuites::write(GXml& xml) const
{
    // Append XML element for Test Suites
    GXmlElement* testsuites = xml.append("testsuites");

    // Set attributes
    testsuites->attribute("name", "GammaLib");
    /*
    testsuites->attribute("test",str(tests()));
    testsuites->attribute("errors",str(errors()));
    testsuites->attribute("failures",str(failures()));
    testsuites->attribute("time","0"); // not used
    testsuites->attribute("timestamp",str(timestamp()));
    */

    // Loop over all test suites in the container
    for (int i = 0; i < m_testsuites.size(); ++i) {

        // Get a pointer on the current test suite
        GTestSuite* testsuite = m_testsuites[i];

        // Append XML element for this test suite
        GXmlElement* element_testsuite = testsuites->append("testsuite");

        // Set attributes
        element_testsuite->attribute("disabled","");  // not used
        element_testsuite->attribute("errors",gammalib::str(testsuite->errors()));
        element_testsuite->attribute("failures",gammalib::str(testsuite->failures()));
        element_testsuite->attribute("hostname","");  // not used
        element_testsuite->attribute("id",gammalib::str(i));
        element_testsuite->attribute("name",testsuite->name()); 
        element_testsuite->attribute("package","");  // not used
        element_testsuite->attribute("skipped","");  // not used
        element_testsuite->attribute("tests",gammalib::str(testsuite->size()));
        element_testsuite->attribute("time",gammalib::str(testsuite->duration()));
        element_testsuite->attribute("timestamp",gammalib::str(testsuite->timestamp()));

        // Loop over all test cases in the test suite
        for (int j = 0; j < testsuite->size(); ++j) {

            // Reference to the current test case
            GTestCase& testcase = (*testsuite)[j];

            // Append XML element for this test case
            GXmlElement* element_testcase = element_testsuite->append("testcase");

            // Set attributes
            element_testcase->attribute("assertions",""); // not used
            element_testcase->attribute("classname",name());
            element_testcase->attribute("name",testcase.name());
            element_testcase->attribute("status","");  // not used
            element_testcase->attribute("time",gammalib::str(testcase.duration()));

            // If a failure or error occured then append the message to the
            // XML element.
            if (!testcase.has_passed()) {

                // Append XML element for the test case problem
                GXmlElement* element_testcase_problem = element_testcase->append("error");

                // Set attributes
                element_testcase_problem->attribute("message",testcase.message());
                element_testcase_problem->attribute("type",testcase.type());

                // Set tag name dependent on the type of problem
                if (testcase.kind() == GTestCase::ERROR_TEST) {
                    element_testcase_problem->name("error");
                }
                else {
                    element_testcase_problem->name("failure");
                }

            } // endif: failure or error occured

        } // endfor: looped over all test cases

    } // endfor: looped over all test suites

    // Return
    return;
}
Exemplo n.º 30
0
/***********************************************************************//**
 * @brief Write model into XML element
 *
 * @param[in] xml XML element.
 *
 * @exception GException::model_invalid_spatial
 *            Existing XML element is not of type 'ProfileFunction'
 * @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.
 *
 * Write the radial Profile model information into an XML element. The XML
 * element will have 3 parameter leafs named "Width", "Core" and "Tail".
 ***************************************************************************/
void GCTAModelRadialProfile::write(GXmlElement& xml) const
{
    // Set model type
    if (xml.attribute("type") == "") {
        xml.attribute("type", type());
    }

    // Verify model type
    if (xml.attribute("type") != type()) {
        throw GException::model_invalid_spatial(G_WRITE, xml.attribute("type"),
              "Radial Profile model is not of type \""+type()+"\".");
    }

    // If XML element has 0 nodes then append 3 parameter nodes
    if (xml.elements() == 0) {
        xml.append(new GXmlElement("parameter name=\"Width\""));
        xml.append(new GXmlElement("parameter name=\"Core\""));
        xml.append(new GXmlElement("parameter name=\"Tail\""));
    }

    // Verify that XML element has exactly 3 parameters
    if (xml.elements() != 3 || xml.elements("parameter") != 3) {
        throw GException::model_invalid_parnum(G_WRITE, xml,
              "Radial Profile model requires exactly 3 parameters.");
    }

    // Set or update model parameter attributes
    int npar[] = {0, 0, 0};
    for (int i = 0; i < 3; ++i) {

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

        // Handle prefactor
        if (par->attribute("name") == "Width") {
            m_width.write(*par);
            npar[0]++;
        }

        // Handle index
        else if (par->attribute("name") == "Core") {
            m_core.write(*par);
            npar[1]++;
        }

        // Handle pivot energy
        else if (par->attribute("name") == "Tail") {
            m_tail.write(*par);
            npar[2]++;
        }

    } // endfor: looped over all parameters

    // Check of all required parameters are present
    if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1) {
        throw GException::model_invalid_parnames(G_WRITE, xml,
              "Require \"Width\", \"Core\" and \"Tail\" parameters.");
    }

    // Return
    return;
}