/***********************************************************************//** * @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; }
/***********************************************************************//** * @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; }
/***********************************************************************//** * @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; }
/***********************************************************************//** * @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; }
/***********************************************************************//** * @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; }
/***********************************************************************//** * @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; }
/***********************************************************************//** * @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 will * 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> * * The latter format is the default for newly written XML elements. ***************************************************************************/ void GModelSpatialDiffuseCube::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(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 = 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."); } // Set filename xml.attribute("file", m_filename); // Return return; }
/***********************************************************************//** * @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. Please refer to the read() method for more information * about the structure of the XML document. ***************************************************************************/ void GCTAOnOffObservations::write(GXml& xml) const { // If there is no observation library then append one if (xml.elements("observation_list") == 0) { xml.append(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 = 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 = lib->append("observation"); obs->attribute("name", m_obs[i]->name()); obs->attribute("id", m_obs[i]->id()); obs->attribute("instrument", m_obs[i]->instrument()); } // Write now observation m_obs[i]->write(*obs); } // endfor: looped over all observaitons // Return return; }
/***********************************************************************//** * @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; }
/***********************************************************************//** * @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. * * Writes the spectral information into an XML element. The format of the XML * element is * * <spectrum type="FileFunction" file=".."> * <parameter name="Normalization" scale=".." value=".." min=".." max=".." free=".."/> * </spectrum> * * 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(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 = xml.element("parameter", 0); // Set parameter if (par->attribute("name") == "Normalization") { m_norm.write(*par); } else { throw GException::model_invalid_parnames(G_WRITE, xml, "Require \"Normalization\" parameter."); } // Set file attribute //xml.attribute("file", m_filename.url()); xml.attribute("file", gammalib::xml_file_reduce(xml, m_filename)); // Return return; }
/***********************************************************************//** * @brief Write observation into XML element * * @param[in] xml XML element. * * @exception GException::no_list * No valid CTA event list or event cube found. * @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 LAT observation into an XML element. The expected * format of the XML element is * * <observation name="..." id="..." instrument="LAT"> * <parameter name="FT1" file="..."/> * <parameter name="FT2" file="..."/> * <parameter name="LiveTimeCube" file="..."/> * <parameter name="IRF" file="..."/> * </observation> * * for an unbinned observation and * * <observation name="..." id="..." instrument="LAT"> * <parameter name="CountsMap" file="..."/> * <parameter name="ExposureMap" file="..."/> * <parameter name="LiveTimeCube" file="..."/> * <parameter name="IRF" value="..."/> * </observation> * * for a binned observation. * * @todo We should create a special exception that informs that there is * neither a valid LAT event list nor a valid LAT counts map in this * observations. ***************************************************************************/ void GLATObservation::write(GXmlElement& xml) const { // Determine if we deal with a binned or unbinned observation const GLATEventList* list = dynamic_cast<const GLATEventList*>(m_events); const GLATEventCube* cube = dynamic_cast<const GLATEventCube*>(m_events); if (list == NULL && cube == NULL) { throw GException::no_list(G_WRITE); } // Set event list flag bool is_list = (list != NULL); // If XML element has 0 nodes then append 4 parameter nodes if (xml.elements() == 0) { if (is_list) { xml.append(GXmlElement("parameter name=\"FT1\"")); xml.append(GXmlElement("parameter name=\"FT2\"")); xml.append(GXmlElement("parameter name=\"LiveTimeCube\"")); xml.append(GXmlElement("parameter name=\"IRF\"")); } else { xml.append(GXmlElement("parameter name=\"CountsMap\"")); xml.append(GXmlElement("parameter name=\"ExposureMap\"")); xml.append(GXmlElement("parameter name=\"LiveTimeCube\"")); xml.append(GXmlElement("parameter name=\"IRF\"")); } } // Verify that XML element has exactly 4 parameters if (xml.elements() != 4 || xml.elements("parameter") != 4) { throw GException::xml_invalid_parnum(G_WRITE, xml, "LAT observation requires exactly 4 parameters."); } // Set or update parameter attributes int npar[] = {0, 0, 0, 0}; for (int i = 0; i < 4; ++i) { // Get parameter element GXmlElement* par = xml.element("parameter", i); // Handle FT1 if (par->attribute("name") == "FT1") { par->attribute("file", m_ft1file); npar[0]++; } // Handle CountsMap else if (par->attribute("name") == "CountsMap") { par->attribute("file", m_cntfile); npar[0]++; } // Handle FT2 else if (par->attribute("name") == "FT2") { par->attribute("file", m_ft2file); npar[1]++; } // Handle ExposureMap else if (par->attribute("name") == "ExposureMap") { par->attribute("file", m_expfile); npar[1]++; } // Handle LiveTimeCube else if (par->attribute("name") == "LiveTimeCube") { par->attribute("file", m_ltfile); npar[2]++; } // Handle IRF else if (par->attribute("name") == "IRF") { std::string irfname = ""; irfname = m_response.rspname(); par->attribute("value", irfname); npar[3]++; } } // endfor: looped over all parameters // Verify that all required parameters are present if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1 || npar[3] != 1) { throw GException::xml_invalid_parnames(G_READ, xml, "Require either \"FT1\", \"FT2\", \"LiveTimeCube\", and \"IRF\"" " or \"CountsMap\", \"ExposureMap\", \"LiveTimeCube\", and" " \"IRF\" parameters."); } // Return return; }
/***********************************************************************//** * @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(GXmlElement("parameter name=\"Width\"")); xml.append(GXmlElement("parameter name=\"Core\"")); xml.append(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 = 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; }
/***********************************************************************//** * @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 "ExpCutoff" * @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. * * Writes the spectral information into an XML element. The format of the XML * element is * * <spectrum type="ExpCutoff"> * <parameter name="Prefactor" scale=".." value=".." min=".." max=".." free=".."/> * <parameter name="Index" scale=".." value=".." min=".." max=".." free=".."/> * <parameter name="Cutoff" scale=".." value=".." min=".." max=".." free=".."/> * <parameter name="Scale" scale=".." value=".." min=".." max=".." free=".."/> * </spectrum> ***************************************************************************/ void GModelSpectralExpPlaw::write(GXmlElement& xml) const { // Set model type if (xml.attribute("type") == "") { xml.attribute("type", "ExpCutoff"); } // Verify model type if (xml.attribute("type") != "ExpCutoff") { throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), "Spectral model is not of type \"ExpCutoff\"."); } // If XML element has 0 nodes then append 4 parameter nodes if (xml.elements() == 0) { xml.append(GXmlElement("parameter name=\"Prefactor\"")); xml.append(GXmlElement("parameter name=\"Index\"")); xml.append(GXmlElement("parameter name=\"Cutoff\"")); xml.append(GXmlElement("parameter name=\"Scale\"")); } // Verify that XML element has exactly 4 parameters if (xml.elements() != 4 || xml.elements("parameter") != 4) { throw GException::model_invalid_parnum(G_WRITE, xml, "Power law model requires exactly 4 parameters."); } // Set or update model parameter attributes int npar[] = {0, 0, 0, 0}; for (int i = 0; i < 4; ++i) { // Get parameter element GXmlElement* par = xml.element("parameter", i); // Handle prefactor if (par->attribute("name") == "Prefactor") { npar[0]++; m_norm.write(*par); } // Handle index else if (par->attribute("name") == "Index") { npar[1]++; m_index.write(*par); } // Handle index else if (par->attribute("name") == "Cutoff") { npar[2]++; m_ecut.write(*par); } // Handle pivot energy else if (par->attribute("name") == "Scale") { m_pivot.write(*par); npar[3]++; } } // endfor: looped over all parameters // Check of all required parameters are present if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1 || npar[3] != 1) { throw GException::model_invalid_parnames(G_WRITE, xml, "Require \"Prefactor\", \"Index\", \"Cutoff\" and \"Scale\"" " parameters."); } // Return return; }
/***********************************************************************//** * @brief Write model into XML element * * @param[in] xml XML element. * * @exception GException::model_invalid_spectral * Existing XML element is not of required type * @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 COMPTEL DRB fitting model into 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::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. // Set also the type and the instrument. if (src == NULL) { src = xml.append("source"); src->attribute("name", name()); src->attribute("type", type()); if (instruments().length() > 0) { src->attribute("instrument", instruments()); } } // Verify model type if (src->attribute("type") != type()) { std::string msg = "Invalid model type \""+src->attribute("type")+"\" " "found in XML file. Model type \""+type()+"\" " "expected."; throw GException::invalid_value(G_WRITE, msg); } // Determine number of nodes int nodes = m_phibars.size(); // If XML element has 0 nodes then append nodes if (src->elements() == 0) { for (int i = 0; i < nodes; ++i) { src->append(GXmlElement("node")); } } // Verify that XML element has the required number of nodes if (src->elements() != nodes || src->elements("node") != nodes) { std::string msg = "Invalid number of nodes "+ gammalib::str(src->elements("node"))+ " found in XML file, but model requires exactly "+ gammalib::str(nodes)+" nodes."; throw GException::invalid_value(G_WRITE, msg); } // Loop over all nodes for (int i = 0; i < nodes; ++i) { // Get node GXmlElement* node = src->element("node", i); // Write Phibar parameter GXmlElement* par = gammalib::xml_need_par(G_WRITE, *node, "Phibar"); m_phibars[i].write(*par); // Write Normalization parameter par = gammalib::xml_need_par(G_WRITE, *node, "Normalization"); m_values[i].write(*par); } // endfor: looped over nodes // Return return; }
/***********************************************************************//** * @brief Test XML constructors **************************************************************************/ void TestGXml::test_GXml_construct(void) { // Test void constructor test_try("Test void constructor"); try { GXml xml; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test load constructor test_try("Test load constructor"); try { GXml xml(m_xml_file); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test copy constructor test_try("Test copy constructor"); try { GXml xml1(m_xml_file); GXml xml2 = xml1; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test XML file creation test_try("Test XML file creation"); try { GXml xml; xml.append(GXmlComment("This is a comment.")); xml.append(GXmlElement("source_library")); GXmlElement* lib = xml.element("source_library", 0); lib->append(GXmlElement("source name=\"LMC\" type=\"DiffuseSource\"")); GXmlNode* src = lib->element("source", 0); src->append(GXmlElement("spectrum type=\"PLSuperExpCutoff\"")); GXmlNode* spec = src->element("spectrum", 0); spec->append(GXmlElement("parameter free=\"1\" max=\"1000\" min=\"1e-07\"" " name=\"Prefactor\" scale=\"1e-07\"" " value=\"0.02754520844\"")); spec->append(GXmlElement("parameter free=\"1\" max=\"5\" min=\"-5\"" " name=\"Index1\" scale=\"1\" value=\"-2.0458781\"")); GXmlElement* par = spec->element("parameter", 0); par->attribute("value", "1.01"); par->attribute("error", "3.145"); par = spec->element("parameter", 1); par->attribute("value", "-2.100"); par->attribute("error", "9.876"); src->append(GXmlElement("spatialModel file=\"LMC.fits\" type=\"SpatialMap\"")); GXmlNode* spat = src->element("spatialModel", 0); spat->append(GXmlElement("parameter free=\"0\" max=\"1000\" min=\"0.001\"" " name=\"Prefactor\" scale=\"1\" value=\"1\"")); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Return return; }
/***********************************************************************//** * @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 "Gaussian" * @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. * * Writes the spectral information into an XML element. The format of the XML * element is * * <spectrum type="Gaussian"> * <parameter name="Normalization" scale=".." value=".." min=".." max=".." free=".."/> * <parameter name="Mean" scale=".." value=".." min=".." max=".." free=".."/> * <parameter name="Sigma" scale=".." value=".." min=".." max=".." free=".."/> * </spectrum> ***************************************************************************/ void GModelSpectralGauss::write(GXmlElement& xml) const { // Set model type if (xml.attribute("type") == "") { xml.attribute("type", "Gaussian"); } // Verify model type if (xml.attribute("type") != "Gaussian") { throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), "Spectral model is not of type \"Gaussian\"."); } // If XML element has 0 nodes then append 3 parameter nodes if (xml.elements() == 0) { xml.append(GXmlElement("parameter name=\"Normalization\"")); xml.append(GXmlElement("parameter name=\"Mean\"")); xml.append(GXmlElement("parameter name=\"Sigma\"")); } // Verify that XML element has exactly 3 parameters if (xml.elements() != 3 || xml.elements("parameter") != 3) { throw GException::model_invalid_parnum(G_WRITE, xml, "Power law 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 = xml.element("parameter", i); // Handle normalization if (par->attribute("name") == "Normalization") { npar[0]++; m_norm.write(*par); } // Handle mean else if (par->attribute("name") == "Mean") { npar[1]++; m_mean.write(*par); } // Handle sigma else if (par->attribute("name") == "Sigma") { npar[2]++; m_sigma.write(*par); } } // 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 \"Normalization\", \"Mean\" and \"Sigma\"" " parameters."); } // Return return; }
/***********************************************************************//** * @brief Write model into XML element * * @param[in] xml XML element. * * @exception GException::model_invalid_spectral * Existing XML element is not of type "PowerLaw2" * @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. * * Writes the spectral information into an XML element. The format of the XML * element is * * <spectrum type="PowerLaw2"> * <parameter name="Integral" scale=".." value=".." min=".." max=".." free=".."/> * <parameter name="Index" scale=".." value=".." min=".." max=".." free=".."/> * <parameter name="LowerLimit" scale=".." value=".." min=".." max=".." free=".."/> * <parameter name="UpperLimit" scale=".." value=".." min=".." max=".." free=".."/> * </spectrum> ***************************************************************************/ void GModelSpectralPlaw2::write(GXmlElement& xml) const { // Set model type if (xml.attribute("type") == "") { xml.attribute("type", "PowerLaw2"); } // Verify model type if (xml.attribute("type") != "PowerLaw2") { throw GException::model_invalid_spectral(G_WRITE, xml.attribute("type"), "Spectral model is not of type \"PowerLaw2\"."); } // If XML element has 0 nodes then append 4 parameter nodes if (xml.elements() == 0) { xml.append(GXmlElement("parameter name=\"Integral\"")); xml.append(GXmlElement("parameter name=\"Index\"")); xml.append(GXmlElement("parameter name=\"LowerLimit\"")); xml.append(GXmlElement("parameter name=\"UpperLimit\"")); } // Verify that XML element has exactly 4 parameters if (xml.elements() != 4 || xml.elements("parameter") != 4) { throw GException::model_invalid_parnum(G_WRITE, xml, "Power law 2 spectral model requires exactly 4 parameters."); } // Set or update model parameter attributes int npar[] = {0, 0, 0, 0}; for (int i = 0; i < 4; ++i) { // Get parameter element GXmlElement* par = xml.element("parameter", i); // Handle prefactor if (par->attribute("name") == "Integral") { npar[0]++; m_integral.write(*par); } // Handle index else if (par->attribute("name") == "Index") { npar[1]++; m_index.write(*par); } // Handle lower limit else if (par->attribute("name") == "LowerLimit") { m_emin.write(*par); npar[2]++; } // Handle lower limit else if (par->attribute("name") == "UpperLimit") { m_emax.write(*par); npar[3]++; } } // endfor: looped over all parameters // Check of all required parameters are present if (npar[0] != 1 || npar[1] != 1 || npar[2] != 1 || npar[3] != 1) { throw GException::model_invalid_parnames(G_WRITE, xml, "Power law 2 spectral model requires \"Integral\", \"Index\"," " \"LowerLimit\" and \"UpperLimit\" parameters."); } // Return return; }