/***********************************************************************//** * @brief Constructor * * @param[in] coeffs Vector of polynomial coefficients. ***************************************************************************/ GCTAModelRadialPolynom::GCTAModelRadialPolynom(const std::vector<double>& coeffs) : GCTAModelRadial() { // Initialise members init_members(); // Assign coefficients for (int i = 0; i < coeffs.size(); ++i) { // Allocate parameter GModelPar par; // Set value par.real_value(coeffs[i]); // Set other attributes std::string name = "coeff"+str(i); par.name(name); par.unit(""); par.free(); par.scale(1.0); par.gradient(0.0); par.hasgrad(true); // Push coefficient on list m_coeffs.push_back(par); } // endfor: looped over coefficients // Update parameter mapping update_pars(); // Return return; }
/***********************************************************************//** * @brief Read model from XML element * * @param[in] xml XML element. * * @exception GException::invalid_value * Model definition requires at least one node. * * Read the COMPTEL DRB fitting model from an XML element. * * The model is composed of nodes that define the normalization value as * function of Phibar value. The following XML file syntax is expected: * * <source name="Background" type="DRBFitting" instrument="COM"> * <node> * <parameter name="Phibar" .../> * <parameter name="Normalization" .../> * </node> * ... * <node> * <parameter name="Phibar" .../> * <parameter name="Normalization" .../> * </node> * </source> ***************************************************************************/ void GCOMModelDRBFitting::read(const GXmlElement& xml) { // Free space for nodes m_phibars.clear(); m_values.clear(); // Get number of nodes from XML file int nodes = xml.elements("node"); // Throw an error if there are no nodes if (nodes < 1) { std::string msg = "DRB fitting model requires at least one Phibar " "node. Please correct XML format."; throw GException::invalid_value(G_READ, msg); } // Loop over all nodes for (int i = 0; i < nodes; ++i) { // Allocate node parameters GModelPar phibar; GModelPar normalization; // Get node const GXmlElement* node = xml.element("node", i); // Read Phibar parameter const GXmlElement* par = gammalib::xml_get_par(G_READ, *node, "Phibar"); phibar.read(*par); // Read Normalization parameter par = gammalib::xml_get_par(G_READ, *node, "Normalization"); normalization.read(*par); // Set parameter names std::string phibar_name = "Phibar layer "+gammalib::str(i); std::string normalization_name = "Scale factor "+gammalib::str(i); // Set Phibar attributes phibar.name(phibar_name); phibar.unit("deg"); phibar.has_grad(false); // Set normalization attributes normalization.name(normalization_name); normalization.unit(""); normalization.has_grad(true); // Push node parameters on list m_phibars.push_back(phibar); m_values.push_back(normalization); } // endfor: looped over nodes // Set model name name(xml.attribute("name")); // Set instruments instruments(xml.attribute("instrument")); // Set observation identifiers ids(xml.attribute("id")); // Check flag if TS value should be computed bool tscalc = (xml.attribute("tscalc") == "1") ? true : false; // Set flag if TS value should be computed this->tscalc(tscalc); // Set pointers set_pointers(); // Set evluation cache set_cache(); // Return return; }
/***********************************************************************//** * @brief Read model from XML element * * @param[in] xml XML element. * * @exception GException::model_invalid_parnum * Invalid number of model parameters found in XML element. * @exception GException::model_invalid_parnames * Invalid model parameter names found in XML element. * * Read the radial Polynom model information from an XML element. The XML * element is required to have at least one parameter. Parameters are named * "CoeffX", where "X" starts from "0". * * @todo Implement a test of the coefficient boundaries. ***************************************************************************/ void GCTAModelRadialPolynom::read(const GXmlElement& xml) { // Free space for coefficients m_coeffs.clear(); // Get maximum number of coefficients from XML file int max_coeffs = xml.elements("parameter"); // Throw an error if no parameters were found if (max_coeffs < 1) { std::string message = "Radial polynomial model requires at least" " one coefficient."; throw GException::model_invalid_parnum(G_READ, xml, message); } // Verify XML file consistency and determine number of coefficients int ncoeffs = 0; std::vector<int> npar; npar.assign(max_coeffs, 0); for (int i = 0; i < max_coeffs; ++i) { // Get parameter element GXmlElement* par = static_cast<GXmlElement*>(xml.element("parameter", i)); // Verify that parameter is indeed a coefficient if (par->attribute("name").compare(0,5,"Coeff") != 0) { throw GException::model_invalid_parnames(G_READ, xml, par->attribute("name")); } // Verify that parameter coefficient has index in valid range int index = -1; size_t nchars = par->attribute("name").length() - 5; if (nchars > 0) { index = toint(par->attribute("name").substr(5, nchars)); } else { throw GException::model_invalid_parnames(G_READ, xml, "Radial polynomial \"Coeff\" parameter has no index."); } if (index < 0) { throw GException::model_invalid_parnames(G_READ, xml, "Radial polynomial \"Coeff\" parameter index < 0."); } if (index >= max_coeffs) { std::string message = "There are "+str(max_coeffs)+" parameters," " hence polynomial coefficients are expected" " to run from 0 to "+str(max_coeffs-1)+", yet" " a coefficient with index "+str(index)+" was" " encountered."; throw GException::model_invalid_parnames(G_READ, xml, message); } // Increment parameter counter npar[index]++; // Update number of coefficients if (index+1 > ncoeffs) { ncoeffs = index + 1; } } // endfor: verified XML file consistency // Verify that the number of coefficients is between 1 and max_coeffs if (ncoeffs < 0 || ncoeffs > max_coeffs) { std::string message = "Radial polynomial model requires at between" " 1 and "+str(max_coeffs)+" parameters."; throw GException::model_invalid_parnum(G_READ, xml, message); } // Verify that all parameters were found for (int i = 0; i < ncoeffs; ++i) { if (npar[i] == 0) { std::string message = "Parameter \"Coeff"+str(i)+"\" required," " but not found in XML file."; throw GException::model_invalid_parnames(G_READ, xml, message); } else if (npar[i] > 1) { std::string message = "Multiple parameters \"Coeff"+str(i)+"\"" " found in XML file."; throw GException::model_invalid_parnames(G_READ, xml, message); } } // Finally get all coefficients in order for (int i = 0; i < ncoeffs; ++i) { // Set parameter name std::string name = "Coeff"+str(i); // Get corresponding parameter element GXmlElement* par = NULL; for (int k = 0; k < ncoeffs; ++k) { GXmlElement* element = static_cast<GXmlElement*>(xml.element("parameter", k)); if (element->attribute("name") == name) { par = element; break; } } // Make sure that we really have one (just a double check, this should // never fail) if (par == NULL) { std::string message = "Required parameter \""+name+"\" not found."; throw GException::model_invalid_parnames(G_READ, xml, message); } // Now read that parameter ... GModelPar coeff; coeff.read(*par); // ... set other attributes ... coeff.name(name); coeff.unit(""); //TODO: Check parameter // ... and push it on the list m_coeffs.push_back(coeff); } // endfor: looped over all parameters // Update parameter mapping update_pars(); // Return return; }