00001 /*************************************************************************** 00002 * GModelPar.cpp - Model parameter class * 00003 * ----------------------------------------------------------------------- * 00004 * copyright (C) 2009-2016 by Juergen Knoedlseder * 00005 * ----------------------------------------------------------------------- * 00006 * * 00007 * This program is free software: you can redistribute it and/or modify * 00008 * it under the terms of the GNU General Public License as published by * 00009 * the Free Software Foundation, either version 3 of the License, or * 00010 * (at your option) any later version. * 00011 * * 00012 * This program is distributed in the hope that it will be useful, * 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00015 * GNU General Public License for more details. * 00016 * * 00017 * You should have received a copy of the GNU General Public License * 00018 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 00019 * * 00020 ***************************************************************************/ 00021 /** 00022 * @file GModelPar.cpp 00023 * @brief GModelPar class implementation. 00024 * @author Juergen Knoedlseder 00025 */ 00026 00027 /* __ Includes ___________________________________________________________ */ 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 #include "GException.hpp" 00032 #include "GModelPar.hpp" 00033 #include "GTools.hpp" 00034 00035 /* __ Method name definitions ____________________________________________ */ 00036 #define G_CONSTRUCT "GModelPar::GModelPar(std::string&, double&, double&)" 00037 #define G_FACTOR_VALUE "GModelPar::factor_value(double&)" 00038 #define G_FACTOR_MIN "GModelPar::factor_min(double&)" 00039 #define G_FACTOR_MAX "GModelPar::factor_max(double&)" 00040 #define G_SCALE "GModelPar::scale(double&)" 00041 #define G_READ "GModelPar::read(GXmlElement&)" 00042 00043 /* __ Macros _____________________________________________________________ */ 00044 00045 /* __ Coding definitions _________________________________________________ */ 00046 00047 /* __ Debug definitions __________________________________________________ */ 00048 00049 00050 /*========================================================================== 00051 = = 00052 = Constructors/destructors = 00053 = = 00054 ==========================================================================*/ 00055 00056 /***********************************************************************//** 00057 * @brief Void constructor 00058 ***************************************************************************/ 00059 GModelPar::GModelPar(void) : GOptimizerPar() 00060 { 00061 // Initialise members 00062 init_members(); 00063 00064 // Return 00065 return; 00066 } 00067 00068 00069 /***********************************************************************//** 00070 * @brief Parameter constructor 00071 * 00072 * @param[in] name Parameter name. 00073 * @param[in] value Parameter value. 00074 * 00075 * Constructs a parameter from a parameter @p name and a parameter @p value. 00076 * 00077 * The parameter is auto-scaled, which for a @p value that differs from zero 00078 * sets the scale factor to @p value and the @p factor_value to unity. For a 00079 * @p value of zero, the scale factor will be set to unity and the 00080 * @p factor_value will be set to @p value. 00081 ***************************************************************************/ 00082 GModelPar::GModelPar(const std::string& name, const double& value) : 00083 GOptimizerPar(name, value) 00084 { 00085 // Initialise members 00086 init_members(); 00087 00088 // Return 00089 return; 00090 } 00091 00092 00093 /***********************************************************************//** 00094 * @brief Parameter constructor 00095 * 00096 * @param[in] name Parameter name. 00097 * @param[in] factor Parameter value factor. 00098 * @param[in] scale Parameter scaling (non-zero value). 00099 * 00100 * @exception GException::invalid_argument 00101 * Sacle factor of 0 specified. 00102 * 00103 * Constructs a parameter from a parameter @p name, value @p factor 00104 * and @p scale factor. The @p scale factor needs to be a non-zero value. 00105 * If the @p scale factor is zero, an exception is thrown. 00106 ***************************************************************************/ 00107 GModelPar::GModelPar(const std::string& name, 00108 const double& factor, 00109 const double& scale) : 00110 GOptimizerPar(name, factor, scale) 00111 00112 { 00113 // Initialise members 00114 init_members(); 00115 00116 // Return 00117 return; 00118 } 00119 00120 00121 /***********************************************************************//** 00122 * @brief Copy constructor 00123 * 00124 * @param[in] par Model parameter. 00125 ***************************************************************************/ 00126 GModelPar::GModelPar(const GModelPar& par) : GOptimizerPar(par) 00127 { 00128 // Initialise members 00129 init_members(); 00130 00131 // Copy members 00132 copy_members(par); 00133 00134 // Return 00135 return; 00136 } 00137 00138 00139 /***********************************************************************//** 00140 * @brief Destructor 00141 ***************************************************************************/ 00142 GModelPar::~GModelPar(void) 00143 { 00144 // Free members 00145 free_members(); 00146 00147 // Return 00148 return; 00149 } 00150 00151 00152 /*========================================================================== 00153 = = 00154 = Operators = 00155 = = 00156 ==========================================================================*/ 00157 00158 /***********************************************************************//** 00159 * @brief Assignment operator 00160 * 00161 * @param[in] par Model parameter. 00162 * @return Model parameter. 00163 ***************************************************************************/ 00164 GModelPar& GModelPar::operator=(const GModelPar& par) 00165 { 00166 // Execute only if object is not identical 00167 if (this != &par) { 00168 00169 // Copy base class members 00170 this->GOptimizerPar::operator=(par); 00171 00172 // Free members 00173 free_members(); 00174 00175 // Initialise members 00176 init_members(); 00177 00178 // Copy members 00179 copy_members(par); 00180 00181 } // endif: object was not identical 00182 00183 // Return this object 00184 return *this; 00185 } 00186 00187 00188 /*========================================================================== 00189 = = 00190 = Public methods = 00191 = = 00192 ==========================================================================*/ 00193 00194 /***********************************************************************//** 00195 * @brief Clone model parameter 00196 * 00197 * @return Pointer to deep copy of model parameter. 00198 ***************************************************************************/ 00199 GModelPar* GModelPar::clone(void) const 00200 { 00201 // Clone model parameter 00202 return new GModelPar(*this); 00203 } 00204 00205 00206 /***********************************************************************//** 00207 * @brief Extract parameter attributes from XML element 00208 * 00209 * @param[in] xml XML element 00210 * 00211 * @exception GException::invalid_value 00212 * Invalid combination of parameter attributes encountered. 00213 * 00214 * Extracts the parameter attributes from an XML element of the form 00215 * 00216 * <parameter name=".." value=".." error=".." scale=".." min=".." max="..' free=".."> 00217 * 00218 * Each of the attributes are optional, with the following scheme for 00219 * assigning default values in case that the attribute was not found: 00220 * 00221 * @p name sets @p m_name (defaults to "Unknown") 00222 * @p value sets @p m_factor_value (defaults to 0.0) 00223 * @p error sets @p m_factor_error (defaults to 0.0) 00224 * @p scale sets @p m_scale (defaults to 1.0) 00225 * @p min sets @p m_factor_min (will remove_min() if not found) 00226 * @p max sets @p m_factor_max (will remove_max() if not found) 00227 * @p free sets @p m_free (papameter will be fixed if not found) 00228 ***************************************************************************/ 00229 void GModelPar::read(const GXmlElement& xml) 00230 { 00231 // Get name 00232 std::string arg = xml.attribute("name"); 00233 if (arg != "") { 00234 m_name = arg; 00235 } 00236 else { 00237 m_name = "Unknown"; 00238 } 00239 00240 // Get value 00241 arg = xml.attribute("value"); 00242 if (arg != "") { 00243 m_factor_value = gammalib::todouble(arg); 00244 } 00245 else { 00246 m_factor_value = 0.0; 00247 } 00248 00249 // Get error 00250 arg = xml.attribute("error"); 00251 if (arg != "") { 00252 m_factor_error = gammalib::todouble(arg); 00253 } 00254 else { 00255 m_factor_error = 0.0; 00256 } 00257 00258 // Get scale factor 00259 arg = xml.attribute("scale"); 00260 if (arg != "") { 00261 m_scale = gammalib::todouble(arg); 00262 } 00263 else { 00264 m_scale = 1.0; 00265 } 00266 00267 // Get min 00268 arg = xml.attribute("min"); 00269 if (arg != "") { 00270 m_factor_min = gammalib::todouble(arg); 00271 m_has_min = true; 00272 } 00273 else { 00274 remove_min(); 00275 } 00276 00277 // Get max 00278 arg = xml.attribute("max"); 00279 if (arg != "") { 00280 m_factor_max = gammalib::todouble(arg); 00281 m_has_max = true; 00282 } 00283 else { 00284 remove_max(); 00285 } 00286 00287 // Get free 00288 if (xml.attribute("free") == "1" || 00289 gammalib::tolower(xml.attribute("free")) == "true") { 00290 free(); 00291 } 00292 else { 00293 fix(); 00294 } 00295 00296 // If there is a minimum and maximum, make sure that the maximum is 00297 // not smaller than the minimum 00298 if (m_has_min && m_has_max) { 00299 if (m_factor_min > m_factor_max) { 00300 std::string msg = "The model parameter \""+m_name+ 00301 "\" in the XML document has a minimum boundary "+ 00302 gammalib::str(m_factor_min)+ 00303 " that is larger than the maximum boundary "+ 00304 gammalib::str(m_factor_max)+".\n"+xml.print(); 00305 throw GException::invalid_value(G_READ, msg); 00306 } 00307 } 00308 00309 // If there is a minimum, make sure that the value is not below it 00310 if (m_has_min && m_factor_value < m_factor_min) { 00311 std::string msg = "The model parameter \""+m_name+ 00312 "\" in the XML document has a value "+ 00313 gammalib::str(m_factor_value)+ 00314 " that is smaller than the minimum boundary "+ 00315 gammalib::str(m_factor_min)+".\n"+xml.print(); 00316 throw GException::invalid_value(G_READ, msg); 00317 } 00318 00319 // If there is a maximum, make sure that the value is not above it 00320 if (m_has_max && m_factor_value > m_factor_max) { 00321 std::string msg = "The model parameter \""+m_name+ 00322 "\" in the XML document has a value "+ 00323 gammalib::str(m_factor_value)+ 00324 " that is larger than the maximum boundary "+ 00325 gammalib::str(m_factor_max)+".\n"+xml.print(); 00326 throw GException::invalid_value(G_READ, msg); 00327 } 00328 00329 // Return 00330 return; 00331 } 00332 00333 00334 /***********************************************************************//** 00335 * @brief Set or update parameter attributes in XML element 00336 * 00337 * @param[in] xml XML element. 00338 * 00339 * Sets or updates the parameter attributes in an XML element of the form 00340 * 00341 * <parameter name=".." value=".." error=".." scale=".." min=".." max="..' free=".."> 00342 * 00343 * The following attributes will be set: 00344 * 00345 * @p name 00346 * @p value 00347 * @p error (only in case that the parameter is free) 00348 * @p scale 00349 * @p min (only in case that a minimum exists) 00350 * @p max (only in case that a maximum exists) 00351 * @p free 00352 ***************************************************************************/ 00353 void GModelPar::write(GXmlElement& xml) const 00354 { 00355 // Set name 00356 xml.attribute("name", m_name); 00357 00358 // Set value 00359 xml.attribute("value", gammalib::str(m_factor_value)); 00360 00361 // Set error (only if parameter is free) 00362 if (is_free()) { 00363 xml.attribute("error", gammalib::str(m_factor_error)); 00364 } 00365 00366 // Set scale 00367 xml.attribute("scale", gammalib::str(m_scale)); 00368 00369 // Set minimum 00370 if (has_min()) { 00371 xml.attribute("min", gammalib::str(m_factor_min)); 00372 } 00373 00374 // Set maximum 00375 if (has_max()) { 00376 xml.attribute("max", gammalib::str(m_factor_max)); 00377 } 00378 00379 // Set free/fix flag 00380 if (is_free()) { 00381 xml.attribute("free", "1"); 00382 } 00383 else { 00384 xml.attribute("free", "0"); 00385 } 00386 00387 // Return 00388 return; 00389 } 00390 00391 00392 /*========================================================================== 00393 = = 00394 = Private methods = 00395 = = 00396 ==========================================================================*/ 00397 00398 /***********************************************************************//** 00399 * @brief Initialise class members 00400 ***************************************************************************/ 00401 void GModelPar::init_members(void) 00402 { 00403 // Return 00404 return; 00405 } 00406 00407 00408 /***********************************************************************//** 00409 * @brief Copy class members 00410 * 00411 * @param[in] par Model parameter. 00412 ***************************************************************************/ 00413 void GModelPar::copy_members(const GModelPar& par) 00414 { 00415 // Return 00416 return; 00417 } 00418 00419 00420 /***********************************************************************//** 00421 * @brief Delete class members 00422 ***************************************************************************/ 00423 void GModelPar::free_members(void) 00424 { 00425 // Return 00426 return; 00427 }