Commit af5cca0dc6bf66fcfe27cf940b5cbef849eb1c45
Merge branch 'devel' into hess
Showing
24 changed files
with
912 additions
and
299 deletions
configure.ac
| ... | ... | @@ -659,8 +659,8 @@ if test "x$openmp_ok" = "xyes" ; then |
| 659 | 659 | # dynamically |
| 660 | 660 | if test "$OPENMP_CXXFLAGS" = "-fopenmp" -a "$ac_sys_system" = "Linux"; then |
| 661 | 661 | AC_MSG_CHECKING(whether we can dynamically load libgomp) |
| 662 | - SAVED_LDFLAGS=$LDFLAGS | |
| 663 | - LDFLAGS="$LDFLAGS -ldl" | |
| 662 | + SAVED_LIBS=$LIBS | |
| 663 | + LIBS="-ldl" | |
| 664 | 664 | AC_TRY_RUN(AC_LANG_PROGRAM([#include <dlfcn.h>], |
| 665 | 665 | [if (dlopen("libgomp.so.1", RTLD_NOW) == 0) return 1;]), |
| 666 | 666 | [AC_MSG_RESULT(yes)], |
| ... | ... | @@ -668,7 +668,7 @@ if test "x$openmp_ok" = "xyes" ; then |
| 668 | 668 | AC_MSG_RESULT(no) |
| 669 | 669 | AC_MSG_WARN([OpenMP detected but shared libgomp.so.1 library cannot be dlopen()ed.]) |
| 670 | 670 | AC_MSG_WARN([If you use a gcc 4.2.x compiler, this is a known feature. Try to use gcc >= 4.3.])]) |
| 671 | - LDFLAGS=$SAVED_LDFLAGS | |
| 671 | + LIBS=$SAVED_LIBS | |
| 672 | 672 | fi |
| 673 | 673 | |
| 674 | 674 | # Special Darwin test to see whether OpenMP compiles without adding the | ... | ... |
include/GEbounds.hpp
inst/cta/include/GCTAEventBin.hpp
| 1 | 1 | /*************************************************************************** |
| 2 | - * GCTAEventBin.hpp - CTA event bin class * | |
| 2 | + * GCTAEventBin.hpp - CTA event bin class * | |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2010 by Jurgen Knodlseder * | |
| 4 | + * copyright (C) 2010-2012 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -20,8 +20,8 @@ |
| 20 | 20 | ***************************************************************************/ |
| 21 | 21 | /** |
| 22 | 22 | * @file GCTAEventBin.hpp |
| 23 | - * @brief GCTAEventBin class interface definition. | |
| 24 | - * @author J. Knodlseder | |
| 23 | + * @brief CTA event bin class interface definition | |
| 24 | + * @author Juergen Knoedlseder | |
| 25 | 25 | */ |
| 26 | 26 | |
| 27 | 27 | #ifndef GCTAEVENTBIN_HPP |
| ... | ... | @@ -67,18 +67,18 @@ public: |
| 67 | 67 | virtual void clear(void); |
| 68 | 68 | virtual GCTAEventBin* clone(void) const; |
| 69 | 69 | virtual double size(void) const; |
| 70 | - virtual const GCTAInstDir& dir(void) const { return *m_dir; } | |
| 71 | - virtual const GEnergy& energy(void) const { return *m_energy; } | |
| 72 | - virtual const GTime& time(void) const { return *m_time; } | |
| 73 | - virtual double counts(void) const { return *m_counts; } | |
| 70 | + virtual const GCTAInstDir& dir(void) const; | |
| 71 | + virtual const GEnergy& energy(void) const; | |
| 72 | + virtual const GTime& time(void) const; | |
| 73 | + virtual double counts(void) const; | |
| 74 | 74 | virtual double error(void) const; |
| 75 | - virtual void counts(const double& counts) { *m_counts=counts; } | |
| 75 | + virtual void counts(const double& counts); | |
| 76 | 76 | virtual std::string print(void) const; |
| 77 | 77 | |
| 78 | 78 | // Other methods |
| 79 | - const double& omega(void) const { return *m_omega; } | |
| 80 | - const GEnergy& ewidth(void) const { return *m_ewidth; } | |
| 81 | - const double& ontime(void) const { return *m_ontime; } | |
| 79 | + const double& omega(void) const; | |
| 80 | + const GEnergy& ewidth(void) const; | |
| 81 | + const double& ontime(void) const; | |
| 82 | 82 | |
| 83 | 83 | protected: |
| 84 | 84 | // Protected methods | ... | ... |
inst/cta/include/GCTAException.hpp
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | * GCTAException.hpp - CTA exception handler * |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2010-2011 by Jurgen Knodlseder * | |
| 4 | + * copyright (C) 2010-2012 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | /** |
| 22 | 22 | * @file GCTAException.hpp |
| 23 | 23 | * @brief CTA exception handler interface definition. |
| 24 | - * @author J. Knodlseder | |
| 24 | + * @author Juergen Knoedlseder | |
| 25 | 25 | */ |
| 26 | 26 | |
| 27 | 27 | #ifndef GCTAEXCEPTION_HPP |
| ... | ... | @@ -65,6 +65,12 @@ public: |
| 65 | 65 | std::string message = ""); |
| 66 | 66 | }; |
| 67 | 67 | |
| 68 | + // Event bin exceptions | |
| 69 | + class no_member : public GCTAExceptionHandler { | |
| 70 | + public: | |
| 71 | + no_member(const std::string& origin, const std::string& message); | |
| 72 | + }; | |
| 73 | + | |
| 68 | 74 | // Observation exceptions |
| 69 | 75 | class no_response : public GCTAExceptionHandler { |
| 70 | 76 | public: | ... | ... |
inst/cta/src/GCTAEventBin.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | - * GCTAEventBin.cpp - CTA event bin class * | |
| 2 | + * GCTAEventBin.cpp - CTA event bin class * | |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2010 by Jurgen Knodlseder * | |
| 4 | + * copyright (C) 2010-2012 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -20,8 +20,8 @@ |
| 20 | 20 | ***************************************************************************/ |
| 21 | 21 | /** |
| 22 | 22 | * @file GCTAEventBin.cpp |
| 23 | - * @brief GCTAEventBin class implementation. | |
| 24 | - * @author J. Knodlseder | |
| 23 | + * @brief CTA event bin class implementation | |
| 24 | + * @author Juergen Knoedlseder | |
| 25 | 25 | */ |
| 26 | 26 | |
| 27 | 27 | /* __ Includes ___________________________________________________________ */ |
| ... | ... | @@ -31,9 +31,18 @@ |
| 31 | 31 | #include <string> |
| 32 | 32 | #include <cmath> |
| 33 | 33 | #include "GCTAEventBin.hpp" |
| 34 | +#include "GCTAException.hpp" | |
| 34 | 35 | #include "GTools.hpp" |
| 35 | 36 | |
| 36 | 37 | /* __ Method name definitions ____________________________________________ */ |
| 38 | +#define G_DIR "GCTAEventBin::dir()" | |
| 39 | +#define G_ENERGY "GCTAEventBin::energy()" | |
| 40 | +#define G_TIME "GCTAEventBin::time()" | |
| 41 | +#define G_COUNTS_GET "GCTAEventBin::counts()" | |
| 42 | +#define G_COUNTS_SET "GCTAEventBin::counts(double&)" | |
| 43 | +#define G_OMEGA "GCTAEventBin::omega()" | |
| 44 | +#define G_EWIDTH "GCTAEventBin::ewidth()" | |
| 45 | +#define G_ONTIME "GCTAEventBin::ontime()" | |
| 37 | 46 | |
| 38 | 47 | /* __ Macros _____________________________________________________________ */ |
| 39 | 48 | |
| ... | ... | @@ -185,8 +194,128 @@ double GCTAEventBin::size(void) const |
| 185 | 194 | |
| 186 | 195 | |
| 187 | 196 | /***********************************************************************//** |
| 197 | + * @brief Return instrument direction of event bin | |
| 198 | + * | |
| 199 | + * @return Instrument direction of event bin | |
| 200 | + * | |
| 201 | + * @exception GCTAException::no_member | |
| 202 | + * Invalid instrument direction pointer. | |
| 203 | + * | |
| 204 | + * Returns reference to the instrument direction of the event bin. | |
| 205 | + ***************************************************************************/ | |
| 206 | +const GCTAInstDir& GCTAEventBin::dir(void) const | |
| 207 | +{ | |
| 208 | + // Throw an exception if instrument direction pointer is not valid | |
| 209 | + if (m_dir == NULL) { | |
| 210 | + throw GCTAException::no_member(G_DIR, | |
| 211 | + "Invalid instrument direction pointer."); | |
| 212 | + } | |
| 213 | + | |
| 214 | + // Return instrument direction | |
| 215 | + return *m_dir; | |
| 216 | +} | |
| 217 | + | |
| 218 | + | |
| 219 | +/***********************************************************************//** | |
| 220 | + * @brief Return energy of event bin | |
| 221 | + * | |
| 222 | + * @return Energy of event bin | |
| 223 | + * | |
| 224 | + * @exception GCTAException::no_member | |
| 225 | + * Invalid energy pointer. | |
| 226 | + * | |
| 227 | + * Returns reference to the energy of the event bin. | |
| 228 | + ***************************************************************************/ | |
| 229 | +const GEnergy& GCTAEventBin::energy(void) const | |
| 230 | +{ | |
| 231 | + // Throw an exception if energy pointer is not valid | |
| 232 | + if (m_energy == NULL) { | |
| 233 | + throw GCTAException::no_member(G_ENERGY, | |
| 234 | + "Invalid energy pointer."); | |
| 235 | + } | |
| 236 | + | |
| 237 | + // Return energy | |
| 238 | + return *m_energy; | |
| 239 | +} | |
| 240 | + | |
| 241 | + | |
| 242 | +/***********************************************************************//** | |
| 243 | + * @brief Return time of event bin | |
| 244 | + * | |
| 245 | + * @return Time of event bin | |
| 246 | + * | |
| 247 | + * @exception GCTAException::no_member | |
| 248 | + * Invalid time pointer. | |
| 249 | + * | |
| 250 | + * Returns reference to the time of the event bin. | |
| 251 | + ***************************************************************************/ | |
| 252 | +const GTime& GCTAEventBin::time(void) const | |
| 253 | +{ | |
| 254 | + // Throw an exception if time pointer is not valid | |
| 255 | + if (m_time == NULL) { | |
| 256 | + throw GCTAException::no_member(G_TIME, | |
| 257 | + "Invalid time pointer."); | |
| 258 | + } | |
| 259 | + | |
| 260 | + // Return time | |
| 261 | + return *m_time; | |
| 262 | +} | |
| 263 | + | |
| 264 | + | |
| 265 | +/***********************************************************************//** | |
| 266 | + * @brief Return number of counts in event bin | |
| 267 | + * | |
| 268 | + * @return Number of counts in event bin | |
| 269 | + * | |
| 270 | + * @exception GCTAException::no_member | |
| 271 | + * Invalid counts pointer. | |
| 272 | + * | |
| 273 | + * Returns reference to the number of counts in the event bin. | |
| 274 | + ***************************************************************************/ | |
| 275 | +double GCTAEventBin::counts(void) const | |
| 276 | +{ | |
| 277 | + // Throw an exception if counts pointer is not valid | |
| 278 | + if (m_counts == NULL) { | |
| 279 | + throw GCTAException::no_member(G_COUNTS_GET, | |
| 280 | + "Invalid counts pointer."); | |
| 281 | + } | |
| 282 | + | |
| 283 | + // Return counts | |
| 284 | + return *m_counts; | |
| 285 | +} | |
| 286 | + | |
| 287 | + | |
| 288 | +/***********************************************************************//** | |
| 289 | + * @brief Set number of counts in event bin | |
| 290 | + * | |
| 291 | + * @param[in] counts Number of counts. | |
| 292 | + * | |
| 293 | + * @exception GCTAException::no_member | |
| 294 | + * Invalid counts pointer. | |
| 295 | + * | |
| 296 | + * Set the number of counts in the event bin. | |
| 297 | + ***************************************************************************/ | |
| 298 | +void GCTAEventBin::counts(const double& counts) | |
| 299 | +{ | |
| 300 | + // Throw an exception if counts pointer is not valid | |
| 301 | + if (m_counts == NULL) { | |
| 302 | + throw GCTAException::no_member(G_COUNTS_SET, | |
| 303 | + "Invalid counts pointer."); | |
| 304 | + } | |
| 305 | + | |
| 306 | + // Set number of counts in event bin | |
| 307 | + *m_counts = counts; | |
| 308 | + | |
| 309 | + // Return | |
| 310 | + return; | |
| 311 | +} | |
| 312 | + | |
| 313 | + | |
| 314 | +/***********************************************************************//** | |
| 188 | 315 | * @brief Return error in number of counts |
| 189 | 316 | * |
| 317 | + * @return Error in number of counts in event bin | |
| 318 | + * | |
| 190 | 319 | * Returns \f$\sqrt(counts+delta)\f$ as the uncertainty in the number of |
| 191 | 320 | * counts in the bin. Adding delta avoids uncertainties of 0 which will |
| 192 | 321 | * lead in the optimisation step to the exlusion of the corresponding bin. |
| ... | ... | @@ -206,6 +335,75 @@ double GCTAEventBin::error(void) const |
| 206 | 335 | |
| 207 | 336 | |
| 208 | 337 | /***********************************************************************//** |
| 338 | + * @brief Return solid angle of event bin | |
| 339 | + * | |
| 340 | + * @return Solid angle of event bin | |
| 341 | + * | |
| 342 | + * @exception GCTAException::no_member | |
| 343 | + * Invalid solid angle pointer. | |
| 344 | + * | |
| 345 | + * Returns reference to the solid angle of the event bin. | |
| 346 | + ***************************************************************************/ | |
| 347 | +const double& GCTAEventBin::omega(void) const | |
| 348 | +{ | |
| 349 | + // Throw an exception if solid angle pointer is not valid | |
| 350 | + if (m_omega == NULL) { | |
| 351 | + throw GCTAException::no_member(G_OMEGA, | |
| 352 | + "Invalid solid angle pointer."); | |
| 353 | + } | |
| 354 | + | |
| 355 | + // Return solid angle | |
| 356 | + return *m_omega; | |
| 357 | +} | |
| 358 | + | |
| 359 | + | |
| 360 | +/***********************************************************************//** | |
| 361 | + * @brief Return energy width of event bin | |
| 362 | + * | |
| 363 | + * @return Energy width of event bin | |
| 364 | + * | |
| 365 | + * @exception GCTAException::no_member | |
| 366 | + * Invalid energy width pointer. | |
| 367 | + * | |
| 368 | + * Returns reference to the energy width of the event bin. | |
| 369 | + ***************************************************************************/ | |
| 370 | +const GEnergy& GCTAEventBin::ewidth(void) const | |
| 371 | +{ | |
| 372 | + // Throw an exception if energy width pointer is not valid | |
| 373 | + if (m_ewidth == NULL) { | |
| 374 | + throw GCTAException::no_member(G_EWIDTH, | |
| 375 | + "Invalid energy width pointer."); | |
| 376 | + } | |
| 377 | + | |
| 378 | + // Return energy width | |
| 379 | + return *m_ewidth; | |
| 380 | +} | |
| 381 | + | |
| 382 | + | |
| 383 | +/***********************************************************************//** | |
| 384 | + * @brief Return ontime of event bin | |
| 385 | + * | |
| 386 | + * @return Ontime of event bin | |
| 387 | + * | |
| 388 | + * @exception GCTAException::no_member | |
| 389 | + * Invalid ontime pointer. | |
| 390 | + * | |
| 391 | + * Returns reference to the ontime of the event bin. | |
| 392 | + ***************************************************************************/ | |
| 393 | +const double& GCTAEventBin::ontime(void) const | |
| 394 | +{ | |
| 395 | + // Throw an exception if ontime pointer is not valid | |
| 396 | + if (m_ontime == NULL) { | |
| 397 | + throw GCTAException::no_member(G_ONTIME, | |
| 398 | + "Invalid ontime pointer."); | |
| 399 | + } | |
| 400 | + | |
| 401 | + // Return ontime | |
| 402 | + return *m_ontime; | |
| 403 | +} | |
| 404 | + | |
| 405 | + | |
| 406 | +/***********************************************************************//** | |
| 209 | 407 | * @brief Print event information |
| 210 | 408 | ***************************************************************************/ |
| 211 | 409 | std::string GCTAEventBin::print(void) const | ... | ... |
inst/cta/src/GCTAException.cpp
| ... | ... | @@ -61,6 +61,26 @@ GCTAException::file_open_error::file_open_error(std::string origin, |
| 61 | 61 | |
| 62 | 62 | |
| 63 | 63 | /***********************************************************************//** |
| 64 | + * @brief Member not set. | |
| 65 | + * | |
| 66 | + * @param[in] origin Name of method that has thrown the exception. | |
| 67 | + * @param[in] message Error message. | |
| 68 | + ***************************************************************************/ | |
| 69 | +GCTAException::no_member::no_member(const std::string& origin, | |
| 70 | + const std::string& message) | |
| 71 | +{ | |
| 72 | + // Set origin and message | |
| 73 | + m_origin = origin; | |
| 74 | + m_message = message; | |
| 75 | + | |
| 76 | + // Return | |
| 77 | + return; | |
| 78 | +} | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | +/***********************************************************************//** | |
| 64 | 84 | * @brief Pointing not set. |
| 65 | 85 | * |
| 66 | 86 | * @param[in] origin Name of method that has thrown the exception. | ... | ... |
inst/lat/include/GLATEventBin.hpp
| 1 | 1 | /*************************************************************************** |
| 2 | - * GLATEventBin.hpp - LAT event bin class * | |
| 2 | + * GLATEventBin.hpp - LAT event bin class * | |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2009-2011 by Jurgen Knodlseder * | |
| 4 | + * copyright (C) 2009-2012 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | /** |
| 22 | 22 | * @file GLATEventBin.hpp |
| 23 | 23 | * @brief Fermi-LAT event bin class interface definition |
| 24 | - * @author J. Knodlseder | |
| 24 | + * @author Juergen Knoedlseder | |
| 25 | 25 | */ |
| 26 | 26 | |
| 27 | 27 | #ifndef GLATEVENTBIN_HPP |
| ... | ... | @@ -62,18 +62,18 @@ public: |
| 62 | 62 | virtual void clear(void); |
| 63 | 63 | virtual GLATEventBin* clone(void) const; |
| 64 | 64 | virtual double size(void) const; |
| 65 | - virtual const GLATInstDir& dir(void) const { return *m_dir; } | |
| 66 | - virtual const GEnergy& energy(void) const { return *m_energy; } | |
| 67 | - virtual const GTime& time(void) const { return *m_time; } | |
| 68 | - virtual double counts(void) const { return *m_counts; } | |
| 65 | + virtual const GLATInstDir& dir(void) const; | |
| 66 | + virtual const GEnergy& energy(void) const; | |
| 67 | + virtual const GTime& time(void) const; | |
| 68 | + virtual double counts(void) const; | |
| 69 | 69 | virtual double error(void) const; |
| 70 | - virtual void counts(const double& counts) { *m_counts=counts; } | |
| 70 | + virtual void counts(const double& counts); | |
| 71 | 71 | virtual std::string print(void) const; |
| 72 | 72 | |
| 73 | 73 | // Other methods |
| 74 | - const double& omega(void) const { return *m_omega; } | |
| 75 | - const GEnergy& ewidth(void) const { return *m_ewidth; } | |
| 76 | - const double& ontime(void) const { return *m_ontime; } | |
| 74 | + const double& omega(void) const; | |
| 75 | + const GEnergy& ewidth(void) const; | |
| 76 | + const double& ontime(void) const; | |
| 77 | 77 | const int& index(void) const { return m_index; } |
| 78 | 78 | const int& ipix(void) const { return m_ipix; } |
| 79 | 79 | const int& ieng(void) const { return m_ieng; } | ... | ... |
inst/lat/include/GLATException.hpp
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | * GLATException.hpp - LAT exception handler * |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2010-2011 by Jurgen Knodlseder * | |
| 4 | + * copyright (C) 2010-2012 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | /** |
| 22 | 22 | * @file GLATException.hpp |
| 23 | 23 | * @brief LAT exception handler interface definition. |
| 24 | - * @author J. Knodlseder | |
| 24 | + * @author Juergen Knoedlseder | |
| 25 | 25 | */ |
| 26 | 26 | |
| 27 | 27 | #ifndef GLATEXCEPTION_HPP |
| ... | ... | @@ -64,6 +64,10 @@ public: |
| 64 | 64 | file_open_error(std::string origin, std::string filename, |
| 65 | 65 | std::string message = ""); |
| 66 | 66 | }; |
| 67 | + class no_member : public GLATExceptionHandler { | |
| 68 | + public: | |
| 69 | + no_member(const std::string& origin, const std::string& message); | |
| 70 | + }; | |
| 67 | 71 | class no_sky : public GLATExceptionHandler { |
| 68 | 72 | public: |
| 69 | 73 | no_sky(std::string origin, std::string message = ""); | ... | ... |
inst/lat/src/GLATAeff.cpp
| ... | ... | @@ -539,8 +539,8 @@ void GLATAeff::copy_members(const GLATAeff& aeff) |
| 539 | 539 | m_back = aeff.m_back; |
| 540 | 540 | |
| 541 | 541 | // Clone functors |
| 542 | - m_eff_func1 = aeff.m_eff_func1->clone(); | |
| 543 | - m_eff_func2 = aeff.m_eff_func2->clone(); | |
| 542 | + m_eff_func1 = (aeff.m_eff_func1 != NULL) ? aeff.m_eff_func1->clone() : NULL; | |
| 543 | + m_eff_func2 = (aeff.m_eff_func2 != NULL) ? aeff.m_eff_func2->clone() : NULL; | |
| 544 | 544 | |
| 545 | 545 | // Return |
| 546 | 546 | return; | ... | ... |
inst/lat/src/GLATEventBin.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | - * GLATEventBin.cpp - LAT event bin class * | |
| 2 | + * GLATEventBin.cpp - LAT event bin class * | |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2009-2010 by Jurgen Knodlseder * | |
| 4 | + * copyright (C) 2009-2012 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -20,8 +20,8 @@ |
| 20 | 20 | ***************************************************************************/ |
| 21 | 21 | /** |
| 22 | 22 | * @file GLATEventBin.cpp |
| 23 | - * @brief GLATEventBin class implementation. | |
| 24 | - * @author J. Knodlseder | |
| 23 | + * @brief Fermi-LAT event bin class implementation | |
| 24 | + * @author Juergen Knodlseder | |
| 25 | 25 | */ |
| 26 | 26 | |
| 27 | 27 | /* __ Includes ___________________________________________________________ */ |
| ... | ... | @@ -31,9 +31,18 @@ |
| 31 | 31 | #include <string> |
| 32 | 32 | #include <cmath> |
| 33 | 33 | #include "GLATEventBin.hpp" |
| 34 | +#include "GLATException.hpp" | |
| 34 | 35 | #include "GTools.hpp" |
| 35 | 36 | |
| 36 | 37 | /* __ Method name definitions ____________________________________________ */ |
| 38 | +#define G_DIR "GLATEventBin::dir()" | |
| 39 | +#define G_ENERGY "GLATEventBin::energy()" | |
| 40 | +#define G_TIME "GLATEventBin::time()" | |
| 41 | +#define G_COUNTS_GET "GLATEventBin::counts()" | |
| 42 | +#define G_COUNTS_SET "GLATEventBin::counts(double&)" | |
| 43 | +#define G_OMEGA "GLATEventBin::omega()" | |
| 44 | +#define G_EWIDTH "GLATEventBin::ewidth()" | |
| 45 | +#define G_ONTIME "GLATEventBin::ontime()" | |
| 37 | 46 | |
| 38 | 47 | /* __ Macros _____________________________________________________________ */ |
| 39 | 48 | |
| ... | ... | @@ -101,7 +110,8 @@ GLATEventBin::~GLATEventBin(void) |
| 101 | 110 | /***********************************************************************//** |
| 102 | 111 | * @brief Assignment operator |
| 103 | 112 | * |
| 104 | - * @param[in] bin Event bin which should be assigned. | |
| 113 | + * @param[in] bin LAT event bin. | |
| 114 | + * @return Lat event bin. | |
| 105 | 115 | ***************************************************************************/ |
| 106 | 116 | GLATEventBin& GLATEventBin::operator= (const GLATEventBin& bin) |
| 107 | 117 | { |
| ... | ... | @@ -157,7 +167,9 @@ void GLATEventBin::clear(void) |
| 157 | 167 | |
| 158 | 168 | /***********************************************************************//** |
| 159 | 169 | * @brief Clone instance |
| 160 | -***************************************************************************/ | |
| 170 | + * | |
| 171 | + * @return Deep copy of LAT event bin. | |
| 172 | + ***************************************************************************/ | |
| 161 | 173 | GLATEventBin* GLATEventBin::clone(void) const |
| 162 | 174 | { |
| 163 | 175 | return new GLATEventBin(*this); |
| ... | ... | @@ -167,6 +179,8 @@ GLATEventBin* GLATEventBin::clone(void) const |
| 167 | 179 | /***********************************************************************//** |
| 168 | 180 | * @brief Return size of event bin |
| 169 | 181 | * |
| 182 | + * @return Size of event bin in units of sr MeV s. | |
| 183 | + * | |
| 170 | 184 | * The size of the event bin (units sr MeV s) is given by |
| 171 | 185 | * \f[size = \Omega \times \Delta E \times \Delta T\f] |
| 172 | 186 | * where |
| ... | ... | @@ -185,8 +199,128 @@ double GLATEventBin::size(void) const |
| 185 | 199 | |
| 186 | 200 | |
| 187 | 201 | /***********************************************************************//** |
| 202 | + * @brief Return instrument direction of event bin | |
| 203 | + * | |
| 204 | + * @return Instrument direction of event bin. | |
| 205 | + * | |
| 206 | + * @exception GLATException::no_member | |
| 207 | + * Invalid instrument direction pointer. | |
| 208 | + * | |
| 209 | + * Returns reference to the instrument direction of the event bin. | |
| 210 | + ***************************************************************************/ | |
| 211 | +const GLATInstDir& GLATEventBin::dir(void) const | |
| 212 | +{ | |
| 213 | + // Throw an exception if instrument direction pointer is not valid | |
| 214 | + if (m_dir == NULL) { | |
| 215 | + throw GLATException::no_member(G_DIR, | |
| 216 | + "Invalid instrument direction pointer."); | |
| 217 | + } | |
| 218 | + | |
| 219 | + // Return instrument direction | |
| 220 | + return *m_dir; | |
| 221 | +} | |
| 222 | + | |
| 223 | + | |
| 224 | +/***********************************************************************//** | |
| 225 | + * @brief Return energy of event bin | |
| 226 | + * | |
| 227 | + * @return Energy of event bin. | |
| 228 | + * | |
| 229 | + * @exception GLATException::no_member | |
| 230 | + * Invalid energy pointer. | |
| 231 | + * | |
| 232 | + * Returns reference to the energy of the event bin. | |
| 233 | + ***************************************************************************/ | |
| 234 | +const GEnergy& GLATEventBin::energy(void) const | |
| 235 | +{ | |
| 236 | + // Throw an exception if energy pointer is not valid | |
| 237 | + if (m_energy == NULL) { | |
| 238 | + throw GLATException::no_member(G_ENERGY, | |
| 239 | + "Invalid energy pointer."); | |
| 240 | + } | |
| 241 | + | |
| 242 | + // Return energy | |
| 243 | + return *m_energy; | |
| 244 | +} | |
| 245 | + | |
| 246 | + | |
| 247 | +/***********************************************************************//** | |
| 248 | + * @brief Return time of event bin | |
| 249 | + * | |
| 250 | + * @return Time of event bin. | |
| 251 | + * | |
| 252 | + * @exception GLATException::no_member | |
| 253 | + * Invalid time pointer. | |
| 254 | + * | |
| 255 | + * Returns reference to the time of the event bin. | |
| 256 | + ***************************************************************************/ | |
| 257 | +const GTime& GLATEventBin::time(void) const | |
| 258 | +{ | |
| 259 | + // Throw an exception if time pointer is not valid | |
| 260 | + if (m_time == NULL) { | |
| 261 | + throw GLATException::no_member(G_TIME, | |
| 262 | + "Invalid time pointer."); | |
| 263 | + } | |
| 264 | + | |
| 265 | + // Return time | |
| 266 | + return *m_time; | |
| 267 | +} | |
| 268 | + | |
| 269 | + | |
| 270 | +/***********************************************************************//** | |
| 271 | + * @brief Return number of counts in event bin | |
| 272 | + * | |
| 273 | + * @return Number of counts in event bin. | |
| 274 | + * | |
| 275 | + * @exception GLATException::no_member | |
| 276 | + * Invalid counts pointer. | |
| 277 | + * | |
| 278 | + * Returns reference to the number of counts in the event bin. | |
| 279 | + ***************************************************************************/ | |
| 280 | +double GLATEventBin::counts(void) const | |
| 281 | +{ | |
| 282 | + // Throw an exception if counts pointer is not valid | |
| 283 | + if (m_counts == NULL) { | |
| 284 | + throw GLATException::no_member(G_COUNTS_GET, | |
| 285 | + "Invalid counts pointer."); | |
| 286 | + } | |
| 287 | + | |
| 288 | + // Return counts | |
| 289 | + return *m_counts; | |
| 290 | +} | |
| 291 | + | |
| 292 | + | |
| 293 | +/***********************************************************************//** | |
| 294 | + * @brief Set number of counts in event bin | |
| 295 | + * | |
| 296 | + * @param[in] counts Number of counts. | |
| 297 | + * | |
| 298 | + * @exception GLATException::no_member | |
| 299 | + * Invalid counts pointer. | |
| 300 | + * | |
| 301 | + * Set the number of counts in the event bin. | |
| 302 | + ***************************************************************************/ | |
| 303 | +void GLATEventBin::counts(const double& counts) | |
| 304 | +{ | |
| 305 | + // Throw an exception if counts pointer is not valid | |
| 306 | + if (m_counts == NULL) { | |
| 307 | + throw GLATException::no_member(G_COUNTS_SET, | |
| 308 | + "Invalid counts pointer."); | |
| 309 | + } | |
| 310 | + | |
| 311 | + // Set number of counts in event bin | |
| 312 | + *m_counts = counts; | |
| 313 | + | |
| 314 | + // Return | |
| 315 | + return; | |
| 316 | +} | |
| 317 | + | |
| 318 | + | |
| 319 | +/***********************************************************************//** | |
| 188 | 320 | * @brief Return error in number of counts |
| 189 | 321 | * |
| 322 | + * @return Error in number of counts in event bin. | |
| 323 | + * | |
| 190 | 324 | * Returns \f$\sqrt(counts+delta)\f$ as the uncertainty in the number of |
| 191 | 325 | * counts in the bin. Adding delta avoids uncertainties of 0 which will |
| 192 | 326 | * lead in the optimisation step to the exlusion of the corresponding bin. |
| ... | ... | @@ -206,7 +340,78 @@ double GLATEventBin::error(void) const |
| 206 | 340 | |
| 207 | 341 | |
| 208 | 342 | /***********************************************************************//** |
| 343 | + * @brief Return solid angle of event bin | |
| 344 | + * | |
| 345 | + * @return Solid angle of event bin. | |
| 346 | + * | |
| 347 | + * @exception GLATException::no_member | |
| 348 | + * Invalid solid angle pointer. | |
| 349 | + * | |
| 350 | + * Returns reference to the solid angle of the event bin. | |
| 351 | + ***************************************************************************/ | |
| 352 | +const double& GLATEventBin::omega(void) const | |
| 353 | +{ | |
| 354 | + // Throw an exception if solid angle pointer is not valid | |
| 355 | + if (m_omega == NULL) { | |
| 356 | + throw GLATException::no_member(G_OMEGA, | |
| 357 | + "Invalid solid angle pointer."); | |
| 358 | + } | |
| 359 | + | |
| 360 | + // Return solid angle | |
| 361 | + return *m_omega; | |
| 362 | +} | |
| 363 | + | |
| 364 | + | |
| 365 | +/***********************************************************************//** | |
| 366 | + * @brief Return energy width of event bin | |
| 367 | + * | |
| 368 | + * @return Energy width of event bin. | |
| 369 | + * | |
| 370 | + * @exception GLATException::no_member | |
| 371 | + * Invalid energy width pointer. | |
| 372 | + * | |
| 373 | + * Returns reference to the energy width of the event bin. | |
| 374 | + ***************************************************************************/ | |
| 375 | +const GEnergy& GLATEventBin::ewidth(void) const | |
| 376 | +{ | |
| 377 | + // Throw an exception if energy width pointer is not valid | |
| 378 | + if (m_ewidth == NULL) { | |
| 379 | + throw GLATException::no_member(G_EWIDTH, | |
| 380 | + "Invalid energy width pointer."); | |
| 381 | + } | |
| 382 | + | |
| 383 | + // Return energy width | |
| 384 | + return *m_ewidth; | |
| 385 | +} | |
| 386 | + | |
| 387 | + | |
| 388 | +/***********************************************************************//** | |
| 389 | + * @brief Return ontime of event bin | |
| 390 | + * | |
| 391 | + * @return Ontime of event bin. | |
| 392 | + * | |
| 393 | + * @exception GLATException::no_member | |
| 394 | + * Invalid ontime pointer. | |
| 395 | + * | |
| 396 | + * Returns reference to the ontime of the event bin. | |
| 397 | + ***************************************************************************/ | |
| 398 | +const double& GLATEventBin::ontime(void) const | |
| 399 | +{ | |
| 400 | + // Throw an exception if ontime pointer is not valid | |
| 401 | + if (m_ontime == NULL) { | |
| 402 | + throw GLATException::no_member(G_ONTIME, | |
| 403 | + "Invalid ontime pointer."); | |
| 404 | + } | |
| 405 | + | |
| 406 | + // Return ontime | |
| 407 | + return *m_ontime; | |
| 408 | +} | |
| 409 | + | |
| 410 | + | |
| 411 | +/***********************************************************************//** | |
| 209 | 412 | * @brief Print event information |
| 413 | + * | |
| 414 | + * @return String containing number of counts in event bin. | |
| 210 | 415 | ***************************************************************************/ |
| 211 | 416 | std::string GLATEventBin::print(void) const |
| 212 | 417 | { |
| ... | ... | @@ -283,10 +488,3 @@ void GLATEventBin::free_members(void) |
| 283 | 488 | // Return |
| 284 | 489 | return; |
| 285 | 490 | } |
| 286 | - | |
| 287 | - | |
| 288 | -/*========================================================================== | |
| 289 | - = = | |
| 290 | - = Friends = | |
| 291 | - = = | |
| 292 | - ==========================================================================*/ | ... | ... |
inst/lat/src/GLATEventCube.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | - * GLATEventCube.cpp - LAT event cube class * | |
| 2 | + * GLATEventCube.cpp - LAT event cube class * | |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | 4 | * copyright (C) 2009-2012 by Juergen Knoedlseder * |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | /** |
| 22 | 22 | * @file GLATEventCube.cpp |
| 23 | 23 | * @brief LAT event cube class implementation |
| 24 | - * @author J. Knoedlseder | |
| 24 | + * @author Juergen Knoedlseder | |
| 25 | 25 | */ |
| 26 | 26 | |
| 27 | 27 | /* __ Includes ___________________________________________________________ */ |
| ... | ... | @@ -111,6 +111,7 @@ GLATEventCube::~GLATEventCube(void) |
| 111 | 111 | * @brief Assignment operator |
| 112 | 112 | * |
| 113 | 113 | * @param[in] cube LAT event cube. |
| 114 | + * @return LAT event cube. | |
| 114 | 115 | ***************************************************************************/ |
| 115 | 116 | GLATEventCube& GLATEventCube::operator= (const GLATEventCube& cube) |
| 116 | 117 | { |
| ... | ... | @@ -140,6 +141,7 @@ GLATEventCube& GLATEventCube::operator= (const GLATEventCube& cube) |
| 140 | 141 | * @brief Event bin access operator |
| 141 | 142 | * |
| 142 | 143 | * @param[in] index Event index [0,...,size()-1]. |
| 144 | + * @return Pointer to event bin. | |
| 143 | 145 | * |
| 144 | 146 | * Returns pointer to an event bin. |
| 145 | 147 | ***************************************************************************/ |
| ... | ... | @@ -157,6 +159,7 @@ GLATEventBin* GLATEventCube::operator[](const int& index) |
| 157 | 159 | * @brief Event bin access operator (const version) |
| 158 | 160 | * |
| 159 | 161 | * @param[in] index Event index [0,...,size()-1]. |
| 162 | + * @return Pointer to event bin. | |
| 160 | 163 | * |
| 161 | 164 | * Returns pointer to an event bin. |
| 162 | 165 | ***************************************************************************/ |
| ... | ... | @@ -200,6 +203,8 @@ void GLATEventCube::clear(void) |
| 200 | 203 | |
| 201 | 204 | /***********************************************************************//** |
| 202 | 205 | * @brief Clone instance |
| 206 | + * | |
| 207 | + * @return Deep copy of LAT event cube. | |
| 203 | 208 | ***************************************************************************/ |
| 204 | 209 | GLATEventCube* GLATEventCube::clone(void) const |
| 205 | 210 | { |
| ... | ... | @@ -209,6 +214,8 @@ GLATEventCube* GLATEventCube::clone(void) const |
| 209 | 214 | |
| 210 | 215 | /***********************************************************************//** |
| 211 | 216 | * @brief Return number of bins in event cube |
| 217 | + * | |
| 218 | + * @return Number of bins in event cube. | |
| 212 | 219 | ***************************************************************************/ |
| 213 | 220 | int GLATEventCube::size(void) const |
| 214 | 221 | { |
| ... | ... | @@ -222,6 +229,8 @@ int GLATEventCube::size(void) const |
| 222 | 229 | |
| 223 | 230 | /***********************************************************************//** |
| 224 | 231 | * @brief Return dimension of event cube |
| 232 | + * | |
| 233 | + * @return Number of dimensions in event cube (either 2 or 3). | |
| 225 | 234 | ***************************************************************************/ |
| 226 | 235 | int GLATEventCube::dim(void) const |
| 227 | 236 | { |
| ... | ... | @@ -236,7 +245,8 @@ int GLATEventCube::dim(void) const |
| 236 | 245 | /***********************************************************************//** |
| 237 | 246 | * @brief Return number of bins in axis |
| 238 | 247 | * |
| 239 | - * @param[in] axis Axis. | |
| 248 | + * @param[in] axis Axis [0,...,dim()-1] | |
| 249 | + * @return Number of bins in specified axis | |
| 240 | 250 | * |
| 241 | 251 | * @exception GException::out_of_range |
| 242 | 252 | * Axis is out of range. |
| ... | ... | @@ -247,8 +257,9 @@ int GLATEventCube::naxis(int axis) const |
| 247 | 257 | { |
| 248 | 258 | // Optionally check if the axis is valid |
| 249 | 259 | #if defined(G_RANGE_CHECK) |
| 250 | - if (axis < 0 || axis >= dim()) | |
| 260 | + if (axis < 0 || axis >= dim()) { | |
| 251 | 261 | throw GException::out_of_range(G_NAXIS, axis, 0, dim()-1); |
| 262 | + } | |
| 252 | 263 | #endif |
| 253 | 264 | |
| 254 | 265 | // Set result |
| ... | ... | @@ -368,6 +379,8 @@ void GLATEventCube::write(GFits& file) const |
| 368 | 379 | |
| 369 | 380 | /***********************************************************************//** |
| 370 | 381 | * @brief Return number of events in cube |
| 382 | + * | |
| 383 | + * @return Total number of events in event cube. | |
| 371 | 384 | ***************************************************************************/ |
| 372 | 385 | int GLATEventCube::number(void) const |
| 373 | 386 | { |
| ... | ... | @@ -379,8 +392,9 @@ int GLATEventCube::number(void) const |
| 379 | 392 | |
| 380 | 393 | // Sum event cube |
| 381 | 394 | if (size() > 0 && pixels != NULL) { |
| 382 | - for (int i = 0; i < size(); ++i) | |
| 395 | + for (int i = 0; i < size(); ++i) { | |
| 383 | 396 | number += pixels[i]; |
| 397 | + } | |
| 384 | 398 | } |
| 385 | 399 | |
| 386 | 400 | // Return |
| ... | ... | @@ -406,6 +420,8 @@ void GLATEventCube::map(const GSkymap& map) |
| 406 | 420 | |
| 407 | 421 | /***********************************************************************//** |
| 408 | 422 | * @brief Print event cube information |
| 423 | + * | |
| 424 | + * @return String containing event cube information. | |
| 409 | 425 | ***************************************************************************/ |
| 410 | 426 | std::string GLATEventCube::print(void) const |
| 411 | 427 | { |
| ... | ... | @@ -419,17 +435,29 @@ std::string GLATEventCube::print(void) const |
| 419 | 435 | result.append(str(m_map.nx())+" x "+str(m_map.ny())); |
| 420 | 436 | result.append("\n"+parformat("Number of energy bins")+str(ebins())); |
| 421 | 437 | result.append("\n"+parformat("Number of events")+str(number())); |
| 438 | + | |
| 439 | + // Append time interval | |
| 422 | 440 | result.append("\n"+parformat("Time interval")); |
| 423 | - if (gti().size() > 0) | |
| 441 | + if (gti().size() > 0) { | |
| 424 | 442 | result.append(str(tstart().met())+" - "+str(tstop().met())); |
| 425 | - else | |
| 443 | + } | |
| 444 | + else { | |
| 426 | 445 | result.append("not defined"); |
| 446 | + } | |
| 447 | + | |
| 448 | + // Append energy range | |
| 427 | 449 | result.append("\n"+parformat("Energy range")); |
| 428 | - if (ebounds().size() > 0) | |
| 450 | + if (ebounds().size() > 0) { | |
| 429 | 451 | result.append(emin().print()+" - "+emax().print()); |
| 430 | - else | |
| 452 | + } | |
| 453 | + else { | |
| 431 | 454 | result.append("not defined"); |
| 432 | - result.append("\n"+m_map.wcs()->print()); | |
| 455 | + } | |
| 456 | + | |
| 457 | + // Append WCS | |
| 458 | + if (m_map.wcs() != NULL) { | |
| 459 | + result.append("\n"+m_map.wcs()->print()); | |
| 460 | + } | |
| 433 | 461 | |
| 434 | 462 | // Append source maps |
| 435 | 463 | result.append("\n"+parformat("Number of source maps")+str(m_srcmap.size())); |
| ... | ... | @@ -450,7 +478,8 @@ std::string GLATEventCube::print(void) const |
| 450 | 478 | /***********************************************************************//** |
| 451 | 479 | * @brief Return name of diffuse model |
| 452 | 480 | * |
| 453 | - * @param[in] index Diffuse model index (starting from 0). | |
| 481 | + * @param[in] index Diffuse model index [0,...,ndiffrsp()-1]. | |
| 482 | + * @return Name of diffuse model. | |
| 454 | 483 | * |
| 455 | 484 | * @exception GException::out_of_range |
| 456 | 485 | * Model index out of valid range. |
| ... | ... | @@ -461,8 +490,9 @@ std::string GLATEventCube::diffname(const int& index) const |
| 461 | 490 | { |
| 462 | 491 | // Optionally check if the index is valid |
| 463 | 492 | #if defined(G_RANGE_CHECK) |
| 464 | - if (index < 0 || index >= ndiffrsp()) | |
| 493 | + if (index < 0 || index >= ndiffrsp()) { | |
| 465 | 494 | throw GException::out_of_range(G_DIFFNAME, index, 0, ndiffrsp()-1); |
| 495 | + } | |
| 466 | 496 | #endif |
| 467 | 497 | |
| 468 | 498 | // Return |
| ... | ... | @@ -473,7 +503,8 @@ std::string GLATEventCube::diffname(const int& index) const |
| 473 | 503 | /***********************************************************************//** |
| 474 | 504 | * @brief Return diffuse response map |
| 475 | 505 | * |
| 476 | - * @param[in] index Diffuse model index (starting from 0). | |
| 506 | + * @param[in] index Diffuse model index [0,...,ndiffrsp()-1]. | |
| 507 | + * @return Pointer to diffuse response map. | |
| 477 | 508 | * |
| 478 | 509 | * @exception GException::out_of_range |
| 479 | 510 | * Model index out of valid range. |
| ... | ... | @@ -484,8 +515,9 @@ GSkymap* GLATEventCube::diffrsp(const int& index) const |
| 484 | 515 | { |
| 485 | 516 | // Optionally check if the index is valid |
| 486 | 517 | #if defined(G_RANGE_CHECK) |
| 487 | - if (index < 0 || index >= ndiffrsp()) | |
| 518 | + if (index < 0 || index >= ndiffrsp()) { | |
| 488 | 519 | throw GException::out_of_range(G_DIFFRSP, index, 0, ndiffrsp()-1); |
| 520 | + } | |
| 489 | 521 | #endif |
| 490 | 522 | |
| 491 | 523 | // Return |
| ... | ... | @@ -498,6 +530,7 @@ GSkymap* GLATEventCube::diffrsp(const int& index) const |
| 498 | 530 | * direction that fits spatially into the event cube |
| 499 | 531 | * |
| 500 | 532 | * @param[in] srcDir Source direction. |
| 533 | + * @return Maximum radius in degrees that fully fits into event cube. | |
| 501 | 534 | * |
| 502 | 535 | * By computing the sky directions of the event cube boundaries, the maximum |
| 503 | 536 | * radius is computed that fits fully within the event cube. This method is |
| ... | ... | @@ -513,8 +546,9 @@ double GLATEventCube::maxrad(const GSkyDir& srcDir) const |
| 513 | 546 | for (int ix = 0; ix < nx(); ++ix) { |
| 514 | 547 | GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); |
| 515 | 548 | double distance = m_map.xy2dir(pixel).dist_deg(srcDir); |
| 516 | - if (distance < radius) | |
| 549 | + if (distance < radius) { | |
| 517 | 550 | radius = distance; |
| 551 | + } | |
| 518 | 552 | } |
| 519 | 553 | |
| 520 | 554 | // Move along lower edge in longitude |
| ... | ... | @@ -522,8 +556,9 @@ double GLATEventCube::maxrad(const GSkyDir& srcDir) const |
| 522 | 556 | for (int ix = 0; ix < nx(); ++ix) { |
| 523 | 557 | GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); |
| 524 | 558 | double distance = m_map.xy2dir(pixel).dist_deg(srcDir); |
| 525 | - if (distance < radius) | |
| 559 | + if (distance < radius) { | |
| 526 | 560 | radius = distance; |
| 561 | + } | |
| 527 | 562 | } |
| 528 | 563 | |
| 529 | 564 | // Move along left edge in latitude |
| ... | ... | @@ -531,8 +566,9 @@ double GLATEventCube::maxrad(const GSkyDir& srcDir) const |
| 531 | 566 | for (int iy = 0; iy < ny(); ++iy) { |
| 532 | 567 | GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); |
| 533 | 568 | double distance = m_map.xy2dir(pixel).dist_deg(srcDir); |
| 534 | - if (distance < radius) | |
| 569 | + if (distance < radius) { | |
| 535 | 570 | radius = distance; |
| 571 | + } | |
| 536 | 572 | } |
| 537 | 573 | |
| 538 | 574 | // Move along right edge in latitude |
| ... | ... | @@ -540,8 +576,9 @@ double GLATEventCube::maxrad(const GSkyDir& srcDir) const |
| 540 | 576 | for (int iy = 0; iy < ny(); ++iy) { |
| 541 | 577 | GSkyPixel pixel = GSkyPixel(double(ix), double(iy)); |
| 542 | 578 | double distance = m_map.xy2dir(pixel).dist_deg(srcDir); |
| 543 | - if (distance < radius) | |
| 579 | + if (distance < radius) { | |
| 544 | 580 | radius = distance; |
| 581 | + } | |
| 545 | 582 | } |
| 546 | 583 | |
| 547 | 584 | // Return radius |
| ... | ... | @@ -664,18 +701,21 @@ void GLATEventCube::read_srcmap(const GFitsImage* hdu) |
| 664 | 701 | map->read(hdu); |
| 665 | 702 | |
| 666 | 703 | // Check that source map WCS is consistent with counts map WCS |
| 667 | - if (*(m_map.wcs()) != *(map->wcs())) | |
| 704 | + if (*(m_map.wcs()) != *(map->wcs())) { | |
| 668 | 705 | throw GLATException::wcs_incompatible(G_READ_SRCMAP, hdu->extname()); |
| 706 | + } | |
| 669 | 707 | |
| 670 | 708 | // Check that source map dimension is consistent with counts map |
| 671 | 709 | // dimension |
| 672 | 710 | if (m_map.nx() != map->nx() || |
| 673 | - m_map.ny() != map->ny()) | |
| 711 | + m_map.ny() != map->ny()) { | |
| 674 | 712 | throw GLATException::wcs_incompatible(G_READ_SRCMAP, hdu->extname()); |
| 713 | + } | |
| 675 | 714 | |
| 676 | 715 | // Check that source map has required number of energy bins |
| 677 | - if (m_map.nmaps()+1 != map->nmaps()) | |
| 716 | + if (m_map.nmaps()+1 != map->nmaps()) { | |
| 678 | 717 | throw GLATException::wcs_incompatible(G_READ_SRCMAP, hdu->extname()); |
| 718 | + } | |
| 679 | 719 | |
| 680 | 720 | // Append source map to list of maps |
| 681 | 721 | m_srcmap.push_back(map); |
| ... | ... | @@ -837,9 +877,10 @@ void GLATEventCube::set_energies(void) |
| 837 | 877 | void GLATEventCube::set_times(void) |
| 838 | 878 | { |
| 839 | 879 | // Throw an error if GTI is empty |
| 840 | - if (m_gti.size() < 1) | |
| 880 | + if (m_gti.size() < 1) { | |
| 841 | 881 | throw GLATException::no_gti(G_SET_TIMES, "Every LAT event cube needs" |
| 842 | 882 | " associated GTIs to allow the computation of the ontime."); |
| 883 | + } | |
| 843 | 884 | |
| 844 | 885 | // Compute mean time |
| 845 | 886 | m_time = 0.5 * (gti().tstart() + gti().tstop()); |
| ... | ... | @@ -874,17 +915,20 @@ void GLATEventCube::set_bin(const int& index) |
| 874 | 915 | { |
| 875 | 916 | // Optionally check if the index is valid |
| 876 | 917 | #if defined(G_RANGE_CHECK) |
| 877 | - if (index < 0 || index >= size()) | |
| 918 | + if (index < 0 || index >= size()) { | |
| 878 | 919 | throw GException::out_of_range(G_SET_BIN, index, 0, size()-1); |
| 920 | + } | |
| 879 | 921 | #endif |
| 880 | 922 | |
| 881 | 923 | // Check for the existence of energies and energy widths |
| 882 | - if (m_energies.size() != ebins() || m_ewidth.size() != ebins()) | |
| 924 | + if (m_energies.size() != ebins() || m_ewidth.size() != ebins()) { | |
| 883 | 925 | throw GLATException::no_energies(G_SET_BIN); |
| 926 | + } | |
| 884 | 927 | |
| 885 | 928 | // Check for the existence of sky directions and solid angles |
| 886 | - if (m_dirs.size() != npix() || m_omega.size() != npix()) | |
| 929 | + if (m_dirs.size() != npix() || m_omega.size() != npix()) { | |
| 887 | 930 | throw GLATException::no_dirs(G_SET_BIN); |
| 931 | + } | |
| 888 | 932 | |
| 889 | 933 | // Get pixel and energy bin indices. |
| 890 | 934 | m_bin.m_index = index; |
| ... | ... | @@ -904,10 +948,3 @@ void GLATEventCube::set_bin(const int& index) |
| 904 | 948 | // Return |
| 905 | 949 | return; |
| 906 | 950 | } |
| 907 | - | |
| 908 | - | |
| 909 | -/*========================================================================== | |
| 910 | - = = | |
| 911 | - = Friends = | |
| 912 | - = = | |
| 913 | - ==========================================================================*/ | ... | ... |
inst/lat/src/GLATException.cpp
| ... | ... | @@ -59,6 +59,24 @@ GLATException::file_open_error::file_open_error(std::string origin, |
| 59 | 59 | |
| 60 | 60 | |
| 61 | 61 | /***********************************************************************//** |
| 62 | + * @brief Member not set. | |
| 63 | + * | |
| 64 | + * @param[in] origin Name of method that has thrown the exception. | |
| 65 | + * @param[in] message Error message. | |
| 66 | + ***************************************************************************/ | |
| 67 | +GLATException::no_member::no_member(const std::string& origin, | |
| 68 | + const std::string& message) | |
| 69 | +{ | |
| 70 | + // Set origin and message | |
| 71 | + m_origin = origin; | |
| 72 | + m_message = message; | |
| 73 | + | |
| 74 | + // Return | |
| 75 | + return; | |
| 76 | +} | |
| 77 | + | |
| 78 | + | |
| 79 | +/***********************************************************************//** | |
| 62 | 80 | * @brief No sky pixels found. |
| 63 | 81 | * |
| 64 | 82 | * @param[in] origin Name of method that has thrown the exception. | ... | ... |
inst/lat/src/GLATResponseTable.cpp
| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | /** |
| 22 | 22 | * @file GLATResponseTable.cpp |
| 23 | 23 | * @brief Fermi/LAT response table class implementation |
| 24 | - * @author J. Knoedlseder | |
| 24 | + * @author Juergen Knoedlseder | |
| 25 | 25 | */ |
| 26 | 26 | |
| 27 | 27 | /* __ Includes ___________________________________________________________ */ |
| ... | ... | @@ -159,7 +159,7 @@ void GLATResponseTable::clear(void) |
| 159 | 159 | |
| 160 | 160 | /***********************************************************************//** |
| 161 | 161 | * @brief Clone instance |
| 162 | -***************************************************************************/ | |
| 162 | + ***************************************************************************/ | |
| 163 | 163 | GLATResponseTable* GLATResponseTable::clone(void) const |
| 164 | 164 | { |
| 165 | 165 | return new GLATResponseTable(*this); |
| ... | ... | @@ -290,9 +290,10 @@ int GLATResponseTable::index(const int& ie, const int& ic) const |
| 290 | 290 | // Optionally check if the index is valid |
| 291 | 291 | #if defined(G_RANGE_CHECK) |
| 292 | 292 | if (ie < 0 || ie >= m_energy_num || |
| 293 | - ic < 0 || ic >= m_ctheta_num) | |
| 293 | + ic < 0 || ic >= m_ctheta_num) { | |
| 294 | 294 | throw GException::out_of_range(G_INDEX, ie, ic, |
| 295 | 295 | m_energy_num-1, m_ctheta_num-1); |
| 296 | + } | |
| 296 | 297 | #endif |
| 297 | 298 | |
| 298 | 299 | // Compute index |
| ... | ... | @@ -323,8 +324,9 @@ double GLATResponseTable::energy(const int& ie) const |
| 323 | 324 | { |
| 324 | 325 | // Optionally check if the index is valid |
| 325 | 326 | #if defined(G_RANGE_CHECK) |
| 326 | - if (ie < 0 || ie >= m_energy_num) | |
| 327 | + if (ie < 0 || ie >= m_energy_num) { | |
| 327 | 328 | throw GException::out_of_range(G_ENERGY, ie, 0, m_energy_num-1); |
| 329 | + } | |
| 328 | 330 | #endif |
| 329 | 331 | |
| 330 | 332 | // Determine mean energy of bin |
| ... | ... | @@ -462,8 +464,9 @@ double GLATResponseTable::energy_lo(const int& inx) const |
| 462 | 464 | { |
| 463 | 465 | // Optionally check if the index is valid |
| 464 | 466 | #if defined(G_RANGE_CHECK) |
| 465 | - if (inx < 0 || inx >= m_energy_num) | |
| 467 | + if (inx < 0 || inx >= m_energy_num) { | |
| 466 | 468 | throw GException::out_of_range(G_ENERGY_LO, inx, 0, m_energy_num-1); |
| 469 | + } | |
| 467 | 470 | #endif |
| 468 | 471 | |
| 469 | 472 | // Return mean energy |
| ... | ... | @@ -483,8 +486,9 @@ double GLATResponseTable::energy_hi(const int& inx) const |
| 483 | 486 | { |
| 484 | 487 | // Optionally check if the index is valid |
| 485 | 488 | #if defined(G_RANGE_CHECK) |
| 486 | - if (inx < 0 || inx >= m_energy_num) | |
| 489 | + if (inx < 0 || inx >= m_energy_num) { | |
| 487 | 490 | throw GException::out_of_range(G_ENERGY_HI, inx, 0, m_energy_num-1); |
| 491 | + } | |
| 488 | 492 | #endif |
| 489 | 493 | |
| 490 | 494 | // Return mean energy |
| ... | ... | @@ -504,8 +508,9 @@ double GLATResponseTable::costheta_lo(const int& inx) const |
| 504 | 508 | { |
| 505 | 509 | // Optionally check if the index is valid |
| 506 | 510 | #if defined(G_RANGE_CHECK) |
| 507 | - if (inx < 0 || inx >= m_ctheta_num) | |
| 511 | + if (inx < 0 || inx >= m_ctheta_num) { | |
| 508 | 512 | throw GException::out_of_range(G_COSTHETA_LO, inx, 0, m_ctheta_num-1); |
| 513 | + } | |
| 509 | 514 | #endif |
| 510 | 515 | |
| 511 | 516 | // Return mean energy |
| ... | ... | @@ -525,8 +530,9 @@ double GLATResponseTable::costheta_hi(const int& inx) const |
| 525 | 530 | { |
| 526 | 531 | // Optionally check if the index is valid |
| 527 | 532 | #if defined(G_RANGE_CHECK) |
| 528 | - if (inx < 0 || inx >= m_ctheta_num) | |
| 533 | + if (inx < 0 || inx >= m_ctheta_num) { | |
| 529 | 534 | throw GException::out_of_range(G_COSTHETA_HI, inx, 0, m_ctheta_num-1); |
| 535 | + } | |
| 530 | 536 | #endif |
| 531 | 537 | |
| 532 | 538 | // Return mean energy |
| ... | ... | @@ -562,10 +568,12 @@ std::vector<double> GLATResponseTable::energies(void) const |
| 562 | 568 | std::vector<double> energies; |
| 563 | 569 | |
| 564 | 570 | // Push energies on vector |
| 565 | - energies.push_back(m_energy[m_logE.inx_left()]); | |
| 566 | - energies.push_back(m_energy[m_logE.inx_left()]); | |
| 567 | - energies.push_back(m_energy[m_logE.inx_right()]); | |
| 568 | - energies.push_back(m_energy[m_logE.inx_right()]); | |
| 571 | + if (m_energy_num > 0) { | |
| 572 | + energies.push_back(m_energy[m_logE.inx_left()]); | |
| 573 | + energies.push_back(m_energy[m_logE.inx_left()]); | |
| 574 | + energies.push_back(m_energy[m_logE.inx_right()]); | |
| 575 | + energies.push_back(m_energy[m_logE.inx_right()]); | |
| 576 | + } | |
| 569 | 577 | |
| 570 | 578 | // Return vector |
| 571 | 579 | return energies; | ... | ... |
pyext/GEbounds.i
src/fits/GFits.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | - * GFits.cpp - FITS file access class * | |
| 2 | + * GFits.cpp - FITS file access class * | |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | 4 | * copyright (C) 2008-2012 by Juergen Knoedlseder * |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| ... | ... | @@ -348,10 +348,13 @@ void GFits::open(const std::string& filename, bool create) |
| 348 | 348 | * @exception GException::fits_file_exist |
| 349 | 349 | * Attemting to overwrite an existing file without having specified |
| 350 | 350 | * clobber=true. |
| 351 | + * @exception GException::fits_file_not_open | |
| 352 | + * FITS file needs to be opened before saving. | |
| 353 | + * | |
| 354 | + * Saves all HDUs of an open FITS file to disk. After saving, the FITS file | |
| 355 | + * remains open. Invoke the close() method if explicit closing is needed. | |
| 356 | + * Note that de-allocation of the GFits object also closes the FITS file. | |
| 351 | 357 | * |
| 352 | - * Saves all HDUs to the FITS file by looping over the HDU's save() method. | |
| 353 | - * Saving does not mean that the FITS file is closed. Call the close() | |
| 354 | - * method if explicit closing is needed (de-allocation also closes the file). | |
| 355 | 358 | * In the special case that no first HDU exists an empty primary image is |
| 356 | 359 | * created. |
| 357 | 360 | ***************************************************************************/ |
| ... | ... | @@ -368,6 +371,12 @@ void GFits::save(bool clobber) |
| 368 | 371 | throw GException::fits_file_exist(G_SAVE, m_filename); |
| 369 | 372 | } |
| 370 | 373 | |
| 374 | + // If no FITS file has been opened then throw an error | |
| 375 | + if (m_fitsfile == NULL) { | |
| 376 | + throw GException::fits_file_not_open(G_SAVE, | |
| 377 | + "Either open FITS file before saving or use saveto() method."); | |
| 378 | + } | |
| 379 | + | |
| 371 | 380 | // If no HDUs exist then save an empty primary image. |
| 372 | 381 | if (size() == 0) { |
| 373 | 382 | int status = 0; |
| ... | ... | @@ -537,28 +546,33 @@ void GFits::append(const GFitsHDU& hdu) |
| 537 | 546 | // Clone FITS HDU |
| 538 | 547 | GFitsHDU* ptr = hdu.clone(); |
| 539 | 548 | |
| 540 | - // If FITS file exists then connect cloned HDU to FITS file | |
| 541 | - if (m_fitsfile != NULL) { | |
| 542 | - __fitsfile fptr = *(FPTR(m_fitsfile)); | |
| 543 | - fptr.HDUposition = n_hdu; | |
| 544 | - ptr->connect(&fptr); | |
| 545 | - } | |
| 546 | - else { | |
| 547 | - ptr->extno(n_hdu); | |
| 548 | - } | |
| 549 | + // Append HDU if it's valid | |
| 550 | + if (ptr != NULL) { | |
| 549 | 551 | |
| 550 | - // Debug information | |
| 551 | - #if DEBUG | |
| 552 | - std::cout << "Append HDU (extno=" << n_hdu << ")." << std::endl; | |
| 553 | - #endif | |
| 552 | + // If FITS file exists then connect cloned HDU to FITS file | |
| 553 | + if (m_fitsfile != NULL) { | |
| 554 | + __fitsfile fptr = *(FPTR(m_fitsfile)); | |
| 555 | + fptr.HDUposition = n_hdu; | |
| 556 | + ptr->connect(&fptr); | |
| 557 | + } | |
| 558 | + else { | |
| 559 | + ptr->extno(n_hdu); | |
| 560 | + } | |
| 554 | 561 | |
| 555 | - // Push back HDU | |
| 556 | - m_hdu.push_back(ptr); | |
| 562 | + // Debug information | |
| 563 | + #if DEBUG | |
| 564 | + std::cout << "Append HDU (extno=" << n_hdu << ")." << std::endl; | |
| 565 | + #endif | |
| 557 | 566 | |
| 558 | - // Debug trailer | |
| 559 | - #if DEBUG | |
| 560 | - std::cout << "<-- GFits::append" << std::endl; | |
| 561 | - #endif | |
| 567 | + // Push back HDU | |
| 568 | + m_hdu.push_back(ptr); | |
| 569 | + | |
| 570 | + // Debug trailer | |
| 571 | + #if DEBUG | |
| 572 | + std::cout << "<-- GFits::append" << std::endl; | |
| 573 | + #endif | |
| 574 | + | |
| 575 | + } // endif: HDU was valid | |
| 562 | 576 | |
| 563 | 577 | // Return |
| 564 | 578 | return; | ... | ... |
src/fits/GFitsHDU.cpp
| ... | ... | @@ -358,6 +358,8 @@ void GFitsHDU::connect(void* vptr) |
| 358 | 358 | /***********************************************************************//** |
| 359 | 359 | * @brief Move FITS file pointer to HDU |
| 360 | 360 | * |
| 361 | + * @exception GException::fits_file_not_open | |
| 362 | + * No FITS file has been opened. | |
| 361 | 363 | * @exception GException::fits_hdu_not_found |
| 362 | 364 | * Requested HDU not found. |
| 363 | 365 | * |
| ... | ... | @@ -366,6 +368,12 @@ void GFitsHDU::connect(void* vptr) |
| 366 | 368 | ***************************************************************************/ |
| 367 | 369 | void GFitsHDU::move_to_hdu(void) |
| 368 | 370 | { |
| 371 | + // Throw an exception if FITS file is not open | |
| 372 | + if (FPTR(m_fitsfile)->Fptr == NULL) { | |
| 373 | + throw GException::fits_file_not_open(G_MOVE_TO_HDU, | |
| 374 | + "Open file before moving file pointer to HDU."); | |
| 375 | + } | |
| 376 | + | |
| 369 | 377 | // Move to HDU |
| 370 | 378 | int status = 0; |
| 371 | 379 | status = __ffmahd(FPTR(m_fitsfile), m_hdunum+1, NULL, &status); |
| ... | ... | @@ -382,13 +390,23 @@ void GFitsHDU::move_to_hdu(void) |
| 382 | 390 | /***********************************************************************//** |
| 383 | 391 | * @brief Get HDU type from FITS file |
| 384 | 392 | * |
| 393 | + * @exception GException::fits_file_not_open | |
| 394 | + * No FITS file has been opened. | |
| 385 | 395 | * @exception GException::fits_hdu_not_found |
| 386 | 396 | * Requested HDU not found. |
| 387 | 397 | ***************************************************************************/ |
| 388 | 398 | GFitsHDU::HDUType GFitsHDU::get_hdu_type(void) const |
| 389 | 399 | { |
| 400 | + // Initialise HDU type | |
| 401 | + int type = 0; | |
| 402 | + | |
| 403 | + // Throw an exception if FITS file is not open | |
| 404 | + if (FPTR(m_fitsfile)->Fptr == NULL) { | |
| 405 | + throw GException::fits_file_not_open(G_GET_HDU_TYPE, | |
| 406 | + "Open file before requesting HDU type."); | |
| 407 | + } | |
| 408 | + | |
| 390 | 409 | // Get HDU type |
| 391 | - int type = 0; | |
| 392 | 410 | int status = 0; |
| 393 | 411 | status = __ffghdt(FPTR(m_fitsfile), &type, &status); |
| 394 | 412 | if (status != 0) { | ... | ... |
src/fits/GFitsImage.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | - * GFitsImage.cpp - FITS image class * | |
| 2 | + * GFitsImage.cpp - FITS image class * | |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | 4 | * copyright (C) 2008-2012 by Juergen Knoedlseder * |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| ... | ... | @@ -371,8 +371,9 @@ int GFitsImage::naxes(int axis) const |
| 371 | 371 | { |
| 372 | 372 | // Check if axis is within the range |
| 373 | 373 | #if defined(G_RANGE_CHECK) |
| 374 | - if (axis < 0 || axis >= m_naxis) | |
| 374 | + if (axis < 0 || axis >= m_naxis) { | |
| 375 | 375 | throw GException::out_of_range(G_NAXES, axis, 0, m_naxis-1); |
| 376 | + } | |
| 376 | 377 | #endif |
| 377 | 378 | |
| 378 | 379 | // Get axis dimension |
| ... | ... | @@ -448,9 +449,10 @@ std::string GFitsImage::print(void) const |
| 448 | 449 | result.append(parformat("Image type")+typecode(type())+"\n"); |
| 449 | 450 | result.append(parformat("Number of dimensions")+str(naxis())+"\n"); |
| 450 | 451 | result.append(parformat("Number of image pixels")+str(size())); |
| 451 | - for (int i = 0; i < naxis(); ++i) | |
| 452 | + for (int i = 0; i < naxis(); ++i) { | |
| 452 | 453 | result.append("\n"+parformat("Number of bins in "+str(i)) + |
| 453 | 454 | str(naxes(i))); |
| 455 | + } | |
| 454 | 456 | |
| 455 | 457 | // Append header information |
| 456 | 458 | result.append(+"\n"+m_header.print()); |
| ... | ... | @@ -577,6 +579,9 @@ void GFitsImage::init_image_header(void) |
| 577 | 579 | * |
| 578 | 580 | * @param[in] vptr FITS file void pointer. |
| 579 | 581 | * |
| 582 | + * @exception GException::fits_error | |
| 583 | + * FITS error. | |
| 584 | + * | |
| 580 | 585 | * Open FITS image in FITS file. Opening means connecting the FITS file |
| 581 | 586 | * pointer to the image and reading the image and axes dimensions. |
| 582 | 587 | ***************************************************************************/ |
| ... | ... | @@ -585,8 +590,9 @@ void GFitsImage::open_image(void* vptr) |
| 585 | 590 | // Move to HDU |
| 586 | 591 | int status = 0; |
| 587 | 592 | status = __ffmahd(FPTR(vptr), (FPTR(vptr)->HDUposition)+1, NULL, &status); |
| 588 | - if (status != 0) | |
| 593 | + if (status != 0) { | |
| 589 | 594 | throw GException::fits_error(G_OPEN_IMAGE, status); |
| 595 | + } | |
| 590 | 596 | |
| 591 | 597 | // Save the FITS file pointer and the HDU number |
| 592 | 598 | FPTR_COPY(m_fitsfile, vptr); |
| ... | ... | @@ -594,8 +600,9 @@ void GFitsImage::open_image(void* vptr) |
| 594 | 600 | |
| 595 | 601 | // Get the image dimensions |
| 596 | 602 | status = __ffgidm(FPTR(m_fitsfile), &m_naxis, &status); |
| 597 | - if (status != 0) | |
| 603 | + if (status != 0) { | |
| 598 | 604 | throw GException::fits_error(G_OPEN_IMAGE, status); |
| 605 | + } | |
| 599 | 606 | |
| 600 | 607 | // Reset number of image pixels |
| 601 | 608 | m_num_pixels = 0; |
| ... | ... | @@ -609,13 +616,15 @@ void GFitsImage::open_image(void* vptr) |
| 609 | 616 | |
| 610 | 617 | // Get the axes dimensions |
| 611 | 618 | status = __ffgisz(FPTR(m_fitsfile), m_naxis, m_naxes, &status); |
| 612 | - if (status != 0) | |
| 619 | + if (status != 0) { | |
| 613 | 620 | throw GException::fits_error(G_OPEN_IMAGE, status); |
| 621 | + } | |
| 614 | 622 | |
| 615 | 623 | // Calculate number of image pixels |
| 616 | 624 | m_num_pixels = 1; |
| 617 | - for (int i = 0; i < m_naxis; ++i) | |
| 625 | + for (int i = 0; i < m_naxis; ++i) { | |
| 618 | 626 | m_num_pixels *= m_naxes[i]; |
| 627 | + } | |
| 619 | 628 | |
| 620 | 629 | } // endif: there is an image |
| 621 | 630 | |
| ... | ... | @@ -632,6 +641,9 @@ void GFitsImage::open_image(void* vptr) |
| 632 | 641 | * @param[in] nulval Pointer to pixel nul value. |
| 633 | 642 | * @param[out] anynul Number of nul values encountered during loading. |
| 634 | 643 | * |
| 644 | + * @exception GException::fits_error | |
| 645 | + * FITS error. | |
| 646 | + * | |
| 635 | 647 | * Load image pixels from FITS file. |
| 636 | 648 | ***************************************************************************/ |
| 637 | 649 | void GFitsImage::load_image(int datatype, const void* pixels, |
| ... | ... | @@ -656,8 +668,9 @@ void GFitsImage::load_image(int datatype, const void* pixels, |
| 656 | 668 | delete [] fpixel; |
| 657 | 669 | delete [] lpixel; |
| 658 | 670 | delete [] inc; |
| 659 | - if (status != 0) | |
| 671 | + if (status != 0) { | |
| 660 | 672 | throw GException::fits_error(G_LOAD_IMAGE, status); |
| 673 | + } | |
| 661 | 674 | } |
| 662 | 675 | |
| 663 | 676 | // Return |
| ... | ... | @@ -671,12 +684,23 @@ void GFitsImage::load_image(int datatype, const void* pixels, |
| 671 | 684 | * @param[in] datatype Datatype of pixels to be saved |
| 672 | 685 | * @param[in] pixels Pixel array to be saved |
| 673 | 686 | * |
| 687 | + * @exception GException::fits_file_not_open | |
| 688 | + * No FITS file has been opened. | |
| 689 | + * @exception GException::fits_error | |
| 690 | + * FITS error. | |
| 691 | + * | |
| 674 | 692 | * Save image pixels into FITS file. In case that the HDU does not exist it |
| 675 | 693 | * is created. In case that the pixel array is empty no data are saved; all |
| 676 | 694 | * image pixels will be empty in this case. |
| 677 | 695 | ***************************************************************************/ |
| 678 | 696 | void GFitsImage::save_image(int datatype, const void* pixels) |
| 679 | 697 | { |
| 698 | + // Throw an exception if FITS file is not open | |
| 699 | + if (FPTR(m_fitsfile)->Fptr == NULL) { | |
| 700 | + throw GException::fits_file_not_open(G_SAVE_IMAGE, | |
| 701 | + "Open file before saving the image."); | |
| 702 | + } | |
| 703 | + | |
| 680 | 704 | // Move to HDU. We use here an explicit cfitsio moveto function since we |
| 681 | 705 | // want to recover the error code ... |
| 682 | 706 | int status = 0; |
| ... | ... | @@ -686,23 +710,27 @@ void GFitsImage::save_image(int datatype, const void* pixels) |
| 686 | 710 | if (status == 107) { |
| 687 | 711 | status = 0; |
| 688 | 712 | status = __ffcrim(FPTR(m_fitsfile), m_bitpix, m_naxis, m_naxes, &status); |
| 689 | - if (status != 0) | |
| 713 | + if (status != 0) { | |
| 690 | 714 | throw GException::fits_error(G_SAVE_IMAGE, status); |
| 715 | + } | |
| 691 | 716 | } |
| 692 | - else if (status != 0) | |
| 717 | + else if (status != 0) { | |
| 693 | 718 | throw GException::fits_error(G_SAVE_IMAGE, status); |
| 719 | + } | |
| 694 | 720 | |
| 695 | 721 | // If HDU seems to be empty then create it now. This is only needed for the |
| 696 | 722 | // primary HDU, since __ffmahd gives no error if the primary HDU is empty. |
| 697 | 723 | // By checking the number of keywords in the HDU we detect an empty HDU ... |
| 698 | 724 | int num = 0; |
| 699 | 725 | status = __ffghsp(FPTR(m_fitsfile), &num, NULL, &status); |
| 700 | - if (status != 0) | |
| 726 | + if (status != 0) { | |
| 701 | 727 | throw GException::fits_error(G_SAVE_IMAGE, status); |
| 728 | + } | |
| 702 | 729 | if (num == 0) { |
| 703 | 730 | status = __ffcrim(FPTR(m_fitsfile), m_bitpix, m_naxis, m_naxes, &status); |
| 704 | - if (status != 0) | |
| 731 | + if (status != 0) { | |
| 705 | 732 | throw GException::fits_error(G_SAVE_IMAGE, status); |
| 733 | + } | |
| 706 | 734 | } |
| 707 | 735 | |
| 708 | 736 | // Save the image pixels (if there are some ...) |
| ... | ... | @@ -717,8 +745,9 @@ void GFitsImage::save_image(int datatype, const void* pixels) |
| 717 | 745 | (void*)pixels, &status); |
| 718 | 746 | delete [] fpixel; |
| 719 | 747 | delete [] lpixel; |
| 720 | - if (status != 0) | |
| 748 | + if (status != 0) { | |
| 721 | 749 | throw GException::fits_error(G_SAVE_IMAGE, status); |
| 750 | + } | |
| 722 | 751 | } |
| 723 | 752 | |
| 724 | 753 | // Return |
| ... | ... | @@ -749,8 +778,9 @@ void GFitsImage::fetch_data(void) |
| 749 | 778 | init_data(); |
| 750 | 779 | |
| 751 | 780 | // If a FITS file is attached then load pixels from FITS file. |
| 752 | - if (FPTR(m_fitsfile)->Fptr != NULL) | |
| 781 | + if (FPTR(m_fitsfile)->Fptr != NULL) { | |
| 753 | 782 | load_image(type(), ptr_data(), ptr_nulval(), &m_anynul); |
| 783 | + } | |
| 754 | 784 | |
| 755 | 785 | } // endif: there were pixels available |
| 756 | 786 | |
| ... | ... | @@ -771,8 +801,9 @@ int GFitsImage::offset(const int& ix) const |
| 771 | 801 | { |
| 772 | 802 | // Check if axis is within the range |
| 773 | 803 | #if defined(G_RANGE_CHECK) |
| 774 | - if (ix < 0 || ix >= m_num_pixels) | |
| 804 | + if (ix < 0 || ix >= m_num_pixels) { | |
| 775 | 805 | throw GException::out_of_range(G_OFFSET_1D, ix, 0, m_num_pixels-1); |
| 806 | + } | |
| 776 | 807 | #endif |
| 777 | 808 | |
| 778 | 809 | // Return index |
| ... | ... | @@ -797,15 +828,18 @@ int GFitsImage::offset(const int& ix) const |
| 797 | 828 | int GFitsImage::offset(const int& ix, const int& iy) const |
| 798 | 829 | { |
| 799 | 830 | // Operator is only valid for 2D images |
| 800 | - if (m_naxis < 2) | |
| 831 | + if (m_naxis < 2) { | |
| 801 | 832 | throw GException::fits_wrong_image_operator(G_OFFSET_2D, m_naxis, 2); |
| 833 | + } | |
| 802 | 834 | |
| 803 | 835 | // Check if axis is within the range |
| 804 | 836 | #if defined(G_RANGE_CHECK) |
| 805 | - if (ix < 0 || ix >= m_naxes[0]) | |
| 837 | + if (ix < 0 || ix >= m_naxes[0]) { | |
| 806 | 838 | throw GException::out_of_range(G_OFFSET_2D, ix, 0, m_naxes[0]-1); |
| 807 | - if (iy < 0 || iy >= m_naxes[1]) | |
| 839 | + } | |
| 840 | + if (iy < 0 || iy >= m_naxes[1]) { | |
| 808 | 841 | throw GException::out_of_range(G_OFFSET_2D, iy, 0, m_naxes[1]-1); |
| 842 | + } | |
| 809 | 843 | #endif |
| 810 | 844 | |
| 811 | 845 | // Return offset |
| ... | ... | @@ -831,17 +865,21 @@ int GFitsImage::offset(const int& ix, const int& iy) const |
| 831 | 865 | int GFitsImage::offset(const int& ix, const int& iy, const int& iz) const |
| 832 | 866 | { |
| 833 | 867 | // Operator is only valid for 3D images |
| 834 | - if (m_naxis < 3) | |
| 868 | + if (m_naxis < 3) { | |
| 835 | 869 | throw GException::fits_wrong_image_operator(G_OFFSET_3D, m_naxis, 3); |
| 870 | + } | |
| 836 | 871 | |
| 837 | 872 | // Check if axis is within the range |
| 838 | 873 | #if defined(G_RANGE_CHECK) |
| 839 | - if (ix < 0 || ix >= m_naxes[0]) | |
| 874 | + if (ix < 0 || ix >= m_naxes[0]) { | |
| 840 | 875 | throw GException::out_of_range(G_OFFSET_3D, ix, 0, m_naxes[0]-1); |
| 841 | - if (iy < 0 || iy >= m_naxes[1]) | |
| 876 | + } | |
| 877 | + if (iy < 0 || iy >= m_naxes[1]) { | |
| 842 | 878 | throw GException::out_of_range(G_OFFSET_3D, iy, 0, m_naxes[1]-1); |
| 843 | - if (iz < 0 || iz >= m_naxes[2]) | |
| 879 | + } | |
| 880 | + if (iz < 0 || iz >= m_naxes[2]) { | |
| 844 | 881 | throw GException::out_of_range(G_OFFSET_3D, iz, 0, m_naxes[2]-1); |
| 882 | + } | |
| 845 | 883 | #endif |
| 846 | 884 | |
| 847 | 885 | // Return offset |
| ... | ... | @@ -869,19 +907,24 @@ int GFitsImage::offset(const int& ix, const int& iy, const int& iz, |
| 869 | 907 | const int& it) const |
| 870 | 908 | { |
| 871 | 909 | // Operator is only valid for 4D images |
| 872 | - if (m_naxis < 4) | |
| 910 | + if (m_naxis < 4) { | |
| 873 | 911 | throw GException::fits_wrong_image_operator(G_OFFSET_4D, m_naxis, 4); |
| 912 | + } | |
| 874 | 913 | |
| 875 | 914 | // Check if axis is within the range |
| 876 | 915 | #if defined(G_RANGE_CHECK) |
| 877 | - if (ix < 0 || ix >= m_naxes[0]) | |
| 916 | + if (ix < 0 || ix >= m_naxes[0]) { | |
| 878 | 917 | throw GException::out_of_range(G_OFFSET_4D, ix, 0, m_naxes[0]-1); |
| 879 | - if (iy < 0 || iy >= m_naxes[1]) | |
| 918 | + } | |
| 919 | + if (iy < 0 || iy >= m_naxes[1]) { | |
| 880 | 920 | throw GException::out_of_range(G_OFFSET_4D, iy, 0, m_naxes[1]-1); |
| 881 | - if (iz < 0 || iz >= m_naxes[2]) | |
| 921 | + } | |
| 922 | + if (iz < 0 || iz >= m_naxes[2]) { | |
| 882 | 923 | throw GException::out_of_range(G_OFFSET_4D, iz, 0, m_naxes[2]-1); |
| 883 | - if (it < 0 || it >= m_naxes[3]) | |
| 924 | + } | |
| 925 | + if (it < 0 || it >= m_naxes[3]) { | |
| 884 | 926 | throw GException::out_of_range(G_OFFSET_4D, it, 0, m_naxes[3]-1); |
| 927 | + } | |
| 885 | 928 | #endif |
| 886 | 929 | |
| 887 | 930 | // Return offset |
| ... | ... | @@ -929,8 +972,9 @@ void GFitsImage::copy_members(const GFitsImage& image) |
| 929 | 972 | m_naxes = NULL; |
| 930 | 973 | if (image.m_naxes != NULL && m_naxis > 0) { |
| 931 | 974 | m_naxes = new long[m_naxis]; |
| 932 | - for (int i = 0; i < m_naxis; ++i) | |
| 975 | + for (int i = 0; i < m_naxis; ++i) { | |
| 933 | 976 | m_naxes[i] = image.m_naxes[i]; |
| 977 | + } | |
| 934 | 978 | } |
| 935 | 979 | |
| 936 | 980 | // Return | ... | ... |
src/model/GModels.cpp
| ... | ... | @@ -312,8 +312,13 @@ GModels* GModels::clone(void) const |
| 312 | 312 | ***************************************************************************/ |
| 313 | 313 | void GModels::append(const GModel& model) |
| 314 | 314 | { |
| 315 | - // Append model | |
| 316 | - m_models.push_back(model.clone()); | |
| 315 | + // Make deep copy of model | |
| 316 | + GModel* model_copy = model.clone(); | |
| 317 | + | |
| 318 | + // If copy is valid, append it to the container | |
| 319 | + if (model_copy != NULL) { | |
| 320 | + m_models.push_back(model_copy); | |
| 321 | + } | |
| 317 | 322 | |
| 318 | 323 | // Set parameter pointers |
| 319 | 324 | set_pointers(); | ... | ... |
src/obs/GEbounds.cpp
| ... | ... | @@ -578,7 +578,7 @@ GEnergy GEbounds::elogmean(int inx) const |
| 578 | 578 | * |
| 579 | 579 | * @param[in] eng Energy to be tested. |
| 580 | 580 | ***************************************************************************/ |
| 581 | -bool GEbounds::isin(const GEnergy& eng) const | |
| 581 | +bool GEbounds::contains(const GEnergy& eng) const | |
| 582 | 582 | { |
| 583 | 583 | // Initialise test |
| 584 | 584 | bool found = false; | ... | ... |
src/obs/GEnergy.cpp
src/opt/GOptimizerLM.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | - * GOptimizerLM.cpp - Levenberg Marquardt optimizer * | |
| 2 | + * GOptimizerLM.cpp - Levenberg Marquardt optimizer * | |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2009-2011 by Jurgen Knodlseder * | |
| 4 | + * copyright (C) 2009-2012 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | /** |
| 22 | 22 | * @file GOptimizerLM.cpp |
| 23 | 23 | * @brief Levenberg-Marquardt optimizer class implementation |
| 24 | - * @author J. Knodlseder | |
| 24 | + * @author Juergen Knoedlseder | |
| 25 | 25 | */ |
| 26 | 26 | |
| 27 | 27 | /* __ Includes ___________________________________________________________ */ |
| ... | ... | @@ -948,108 +948,108 @@ double GOptimizerLM::step_size(GVector* grad, GOptimizerPars* pars) |
| 948 | 948 | ***************************************************************************/ |
| 949 | 949 | void GOptimizerLM::errors(GOptimizerFunction* fct, GOptimizerPars* pars) |
| 950 | 950 | { |
| 951 | - // Get number of parameters | |
| 952 | - int npars = pars->npars(); | |
| 951 | + // Continue only if pointers are valid | |
| 952 | + if (fct != NULL && pars != NULL) { | |
| 953 | 953 | |
| 954 | - // Perform final parameter evaluation | |
| 955 | - fct->eval(*pars); | |
| 954 | + // Get number of parameters | |
| 955 | + int npars = pars->npars(); | |
| 956 | 956 | |
| 957 | - // Fetch sparse matrix pointer. We have to do this after the eval() | |
| 958 | - // method since eval() will allocate new memory for the covariance | |
| 959 | - // matrix! | |
| 960 | - GSparseMatrix* covar = fct->covar(); | |
| 957 | + // Perform final parameter evaluation | |
| 958 | + fct->eval(*pars); | |
| 961 | 959 | |
| 962 | - // Save best fitting value | |
| 963 | - m_value = *(fct->value()); | |
| 960 | + // Fetch sparse matrix pointer. We have to do this after the eval() | |
| 961 | + // method since eval() will allocate new memory for the covariance | |
| 962 | + // matrix! | |
| 963 | + GSparseMatrix* covar = fct->covar(); | |
| 964 | 964 | |
| 965 | - // Save covariance matrix | |
| 966 | - GSparseMatrix save_covar = GSparseMatrix(*covar); | |
| 965 | + // Save best fitting value | |
| 966 | + m_value = *(fct->value()); | |
| 967 | 967 | |
| 968 | - // Signal no diagonal element loading | |
| 969 | - bool diag_loaded = false; | |
| 968 | + // Save covariance matrix | |
| 969 | + GSparseMatrix save_covar = GSparseMatrix(*covar); | |
| 970 | 970 | |
| 971 | - // Loop over error computation (maximum 2 turns) | |
| 972 | - for (int i = 0; i < 2; ++i) { | |
| 971 | + // Signal no diagonal element loading | |
| 972 | + bool diag_loaded = false; | |
| 973 | 973 | |
| 974 | - // Solve: covar * X = unit | |
| 975 | - try { | |
| 976 | - covar->cholesky_decompose(1); | |
| 977 | - GVector unit(npars); | |
| 978 | - for (int ipar = 0; ipar < npars; ++ipar) { | |
| 979 | - unit[ipar] = 1.0; | |
| 980 | - GVector x = covar->cholesky_solver(unit,1); | |
| 981 | - if (x[ipar] >= 0.0) | |
| 982 | - pars->par(ipar).error(sqrt(x[ipar])); | |
| 983 | - else { | |
| 984 | - pars->par(ipar).error(0.0); | |
| 985 | - m_status = G_LM_BAD_ERRORS; | |
| 974 | + // Loop over error computation (maximum 2 turns) | |
| 975 | + for (int i = 0; i < 2; ++i) { | |
| 976 | + | |
| 977 | + // Solve: covar * X = unit | |
| 978 | + try { | |
| 979 | + covar->cholesky_decompose(1); | |
| 980 | + GVector unit(npars); | |
| 981 | + for (int ipar = 0; ipar < npars; ++ipar) { | |
| 982 | + unit[ipar] = 1.0; | |
| 983 | + GVector x = covar->cholesky_solver(unit,1); | |
| 984 | + if (x[ipar] >= 0.0) { | |
| 985 | + pars->par(ipar).error(sqrt(x[ipar])); | |
| 986 | + } | |
| 987 | + else { | |
| 988 | + pars->par(ipar).error(0.0); | |
| 989 | + m_status = G_LM_BAD_ERRORS; | |
| 990 | + } | |
| 991 | + unit[ipar] = 0.0; | |
| 986 | 992 | } |
| 987 | - unit[ipar] = 0.0; | |
| 988 | - } | |
| 989 | - } | |
| 990 | - catch (GException::matrix_zero &e) { | |
| 991 | - m_status = G_LM_SINGULAR; | |
| 992 | - if (m_logger != NULL) { | |
| 993 | - *m_logger << "GOptimizerLM::terminate: " | |
| 994 | - << "All curvature matrix elements are zero." | |
| 995 | - << std::endl; | |
| 996 | 993 | } |
| 997 | - break; | |
| 998 | - } | |
| 999 | - catch (GException::matrix_not_pos_definite &e) { | |
| 1000 | - | |
| 1001 | - // Load diagonal if this has not yet been tried | |
| 1002 | - if (!diag_loaded) { | |
| 1003 | - | |
| 1004 | - // Flag errors as inaccurate | |
| 1005 | - m_status = G_LM_BAD_ERRORS; | |
| 994 | + catch (GException::matrix_zero &e) { | |
| 995 | + m_status = G_LM_SINGULAR; | |
| 1006 | 996 | if (m_logger != NULL) { |
| 1007 | - *m_logger << "Non-Positive definite curvature matrix encountered." | |
| 1008 | - << std::endl; | |
| 1009 | - *m_logger << "Load diagonal elements with 1e-10." | |
| 1010 | - << " Fit errors may be inaccurate." | |
| 997 | + *m_logger << "GOptimizerLM::terminate: " | |
| 998 | + << "All curvature matrix elements are zero." | |
| 1011 | 999 | << std::endl; |
| 1012 | 1000 | } |
| 1001 | + break; | |
| 1002 | + } | |
| 1003 | + catch (GException::matrix_not_pos_definite &e) { | |
| 1013 | 1004 | |
| 1014 | - // Try now with diagonal loaded matrix | |
| 1015 | - *covar = save_covar; | |
| 1016 | - for (int ipar = 0; ipar < npars; ++ipar) | |
| 1017 | - (*covar)(ipar,ipar) += 1.0e-10; | |
| 1005 | + // Load diagonal if this has not yet been tried | |
| 1006 | + if (!diag_loaded) { | |
| 1018 | 1007 | |
| 1019 | - // Signal loading | |
| 1020 | - diag_loaded = true; | |
| 1008 | + // Flag errors as inaccurate | |
| 1009 | + m_status = G_LM_BAD_ERRORS; | |
| 1010 | + if (m_logger != NULL) { | |
| 1011 | + *m_logger << "Non-Positive definite curvature matrix encountered." | |
| 1012 | + << std::endl; | |
| 1013 | + *m_logger << "Load diagonal elements with 1e-10." | |
| 1014 | + << " Fit errors may be inaccurate." | |
| 1015 | + << std::endl; | |
| 1016 | + } | |
| 1021 | 1017 | |
| 1022 | - // Try again | |
| 1023 | - continue; | |
| 1018 | + // Try now with diagonal loaded matrix | |
| 1019 | + *covar = save_covar; | |
| 1020 | + for (int ipar = 0; ipar < npars; ++ipar) { | |
| 1021 | + (*covar)(ipar,ipar) += 1.0e-10; | |
| 1022 | + } | |
| 1024 | 1023 | |
| 1025 | - } // endif: diagonal has not yet been loaded | |
| 1024 | + // Signal loading | |
| 1025 | + diag_loaded = true; | |
| 1026 | 1026 | |
| 1027 | - // ... otherwise signal an error | |
| 1028 | - else { | |
| 1029 | - m_status = G_LM_NOT_POSTIVE_DEFINITE; | |
| 1030 | - if (m_logger != NULL) { | |
| 1031 | - *m_logger << "Non-Positive definite curvature matrix encountered," | |
| 1032 | - << " even after diagonal loading." << std::endl; | |
| 1027 | + // Try again | |
| 1028 | + continue; | |
| 1029 | + | |
| 1030 | + } // endif: diagonal has not yet been loaded | |
| 1031 | + | |
| 1032 | + // ... otherwise signal an error | |
| 1033 | + else { | |
| 1034 | + m_status = G_LM_NOT_POSTIVE_DEFINITE; | |
| 1035 | + if (m_logger != NULL) { | |
| 1036 | + *m_logger << "Non-Positive definite curvature matrix encountered," | |
| 1037 | + << " even after diagonal loading." << std::endl; | |
| 1038 | + } | |
| 1039 | + break; | |
| 1033 | 1040 | } |
| 1034 | - break; | |
| 1035 | 1041 | } |
| 1036 | - } | |
| 1037 | - catch (std::exception &e) { | |
| 1038 | - throw; | |
| 1039 | - } | |
| 1042 | + catch (std::exception &e) { | |
| 1043 | + throw; | |
| 1044 | + } | |
| 1040 | 1045 | |
| 1041 | - // If no error occured then break now | |
| 1042 | - break; | |
| 1046 | + // If no error occured then break now | |
| 1047 | + break; | |
| 1048 | + | |
| 1049 | + } // endfor: looped over error computation | |
| 1043 | 1050 | |
| 1044 | - } // endfor: looped over error computation | |
| 1051 | + } // endif: pointers were valid | |
| 1045 | 1052 | |
| 1046 | 1053 | // Return |
| 1047 | 1054 | return; |
| 1048 | 1055 | } |
| 1049 | - | |
| 1050 | - | |
| 1051 | -/*========================================================================== | |
| 1052 | - = = | |
| 1053 | - = Friends = | |
| 1054 | - = = | |
| 1055 | - ==========================================================================*/ | ... | ... |
src/sky/GException_sky.cpp
| ... | ... | @@ -255,7 +255,7 @@ GException::wcs_hpx_bad_ordering::wcs_hpx_bad_ordering(std::string origin, |
| 255 | 255 | * @brief Singular matrix encountered |
| 256 | 256 | * |
| 257 | 257 | * @param[in] origin Method that throws the error. |
| 258 | - * @param[in] naxis Number of matrix axes. | |
| 258 | + * @param[in] naxis Matrix size (naxis*naxis). | |
| 259 | 259 | * @param[in] mat Matrix (stored in vector). |
| 260 | 260 | ***************************************************************************/ |
| 261 | 261 | GException::wcs_singular_matrix::wcs_singular_matrix(std::string origin, |
| ... | ... | @@ -266,13 +266,20 @@ GException::wcs_singular_matrix::wcs_singular_matrix(std::string |
| 266 | 266 | m_origin = origin; |
| 267 | 267 | m_message = "Singular matrix encountered: mat=["; |
| 268 | 268 | for (int i = 0, ij = 0; i < naxis; ++i) { |
| 269 | - if (i > 0) | |
| 269 | + if (i > 0) { | |
| 270 | 270 | m_message += ","; |
| 271 | + } | |
| 271 | 272 | m_message += "["; |
| 272 | 273 | for (int j = 0; j < naxis; ++j, ++ij) { |
| 273 | - if (j > 0) | |
| 274 | + if (j > 0) { | |
| 274 | 275 | m_message += ","; |
| 275 | - m_message += str(mat[ij]); | |
| 276 | + } | |
| 277 | + if (ij < mat.size()) { | |
| 278 | + m_message += str(mat[ij]); | |
| 279 | + } | |
| 280 | + else { | |
| 281 | + m_message += " ... "; | |
| 282 | + } | |
| 276 | 283 | } |
| 277 | 284 | m_message += "]"; |
| 278 | 285 | } | ... | ... |
src/support/GNodeArray.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | - * GNodeArray.cpp - Array of nodes class * | |
| 2 | + * GNodeArray.cpp - Array of nodes class * | |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | 4 | * copyright (C) 2008-2012 by Juergen Knoedlseder * |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| ... | ... | @@ -35,7 +35,9 @@ |
| 35 | 35 | |
| 36 | 36 | /* __ Method name definitions ____________________________________________ */ |
| 37 | 37 | #define G_ACCESS "GNodeArray::operator[](int)" |
| 38 | -#define G_INTERPOLATE "GNodeArray::interpolate(std::vector<double>&, double&" | |
| 38 | +#define G_INTERPOLATE "GNodeArray::interpolate(double&,std::vector<double>&)" | |
| 39 | +#define G_SET_VALUE "GNodeArray::set_value(double&)" | |
| 40 | +#define G_SETUP "GNodeArray::setup()" | |
| 39 | 41 | |
| 40 | 42 | /* __ Macros _____________________________________________________________ */ |
| 41 | 43 | |
| ... | ... | @@ -166,7 +168,8 @@ GNodeArray::~GNodeArray(void) |
| 166 | 168 | /***********************************************************************//** |
| 167 | 169 | * @brief Assignment operator |
| 168 | 170 | * |
| 169 | - * @param[in] array Instance that should be assigned. | |
| 171 | + * @param[in] array Node array. | |
| 172 | + * @return Node array. | |
| 170 | 173 | ***************************************************************************/ |
| 171 | 174 | GNodeArray& GNodeArray::operator= (const GNodeArray& array) |
| 172 | 175 | { |
| ... | ... | @@ -193,6 +196,7 @@ GNodeArray& GNodeArray::operator= (const GNodeArray& array) |
| 193 | 196 | * @brief Node access operator |
| 194 | 197 | * |
| 195 | 198 | * @param[in] index Node index [0,...,size()-1]. |
| 199 | + * @return Node value. | |
| 196 | 200 | * |
| 197 | 201 | * @exception GException::out_of_range |
| 198 | 202 | * Node index is out of range. |
| ... | ... | @@ -201,8 +205,9 @@ double& GNodeArray::operator[](const int& index) |
| 201 | 205 | { |
| 202 | 206 | // Compile option: raise an exception if index is out of range |
| 203 | 207 | #if defined(G_RANGE_CHECK) |
| 204 | - if (index < 0 || index >= size()) | |
| 208 | + if (index < 0 || index >= size()) { | |
| 205 | 209 | throw GException::out_of_range(G_ACCESS, index, size()-1); |
| 210 | + } | |
| 206 | 211 | #endif |
| 207 | 212 | |
| 208 | 213 | // Return node |
| ... | ... | @@ -214,6 +219,7 @@ double& GNodeArray::operator[](const int& index) |
| 214 | 219 | * @brief Node access operator (const version) |
| 215 | 220 | * |
| 216 | 221 | * @param[in] index Node index [0,...,size()-1]. |
| 222 | + * @return Node value. | |
| 217 | 223 | * |
| 218 | 224 | * @exception GException::out_of_range |
| 219 | 225 | * Node index is out of range. |
| ... | ... | @@ -222,8 +228,9 @@ const double& GNodeArray::operator[](const int& index) const |
| 222 | 228 | { |
| 223 | 229 | // Compile option: raise an exception if index is out of range |
| 224 | 230 | #if defined(G_RANGE_CHECK) |
| 225 | - if (index < 0 || index >= size()) | |
| 231 | + if (index < 0 || index >= size()) { | |
| 226 | 232 | throw GException::out_of_range(G_ACCESS, index, size()-1); |
| 233 | + } | |
| 227 | 234 | #endif |
| 228 | 235 | |
| 229 | 236 | // Return node |
| ... | ... | @@ -239,7 +246,7 @@ const double& GNodeArray::operator[](const int& index) const |
| 239 | 246 | |
| 240 | 247 | /***********************************************************************//** |
| 241 | 248 | * @brief Clear instance |
| 242 | -***************************************************************************/ | |
| 249 | + ***************************************************************************/ | |
| 243 | 250 | void GNodeArray::clear(void) |
| 244 | 251 | { |
| 245 | 252 | // Free class members |
| ... | ... | @@ -255,7 +262,9 @@ void GNodeArray::clear(void) |
| 255 | 262 | |
| 256 | 263 | /***********************************************************************//** |
| 257 | 264 | * @brief Clone instance |
| 258 | -***************************************************************************/ | |
| 265 | + * | |
| 266 | + * @return Deep copy of node array. | |
| 267 | + ***************************************************************************/ | |
| 259 | 268 | GNodeArray* GNodeArray::clone(void) const |
| 260 | 269 | { |
| 261 | 270 | return new GNodeArray(*this); |
| ... | ... | @@ -267,6 +276,8 @@ GNodeArray* GNodeArray::clone(void) const |
| 267 | 276 | * |
| 268 | 277 | * @param[in] num Number of nodes |
| 269 | 278 | * @param[in] array Node values \f$x_i\f$. |
| 279 | + * | |
| 280 | + * Setup node array from an array of double precision values. | |
| 270 | 281 | ***************************************************************************/ |
| 271 | 282 | void GNodeArray::nodes(const int& num, const double* array) |
| 272 | 283 | { |
| ... | ... | @@ -277,8 +288,9 @@ void GNodeArray::nodes(const int& num, const double* array) |
| 277 | 288 | init_members(); |
| 278 | 289 | |
| 279 | 290 | // Set node values |
| 280 | - for (int i = 0; i < num; ++i) | |
| 291 | + for (int i = 0; i < num; ++i) { | |
| 281 | 292 | m_node.push_back(array[i]); |
| 293 | + } | |
| 282 | 294 | |
| 283 | 295 | // Setup node distances and linear array handling |
| 284 | 296 | setup(); |
| ... | ... | @@ -292,6 +304,8 @@ void GNodeArray::nodes(const int& num, const double* array) |
| 292 | 304 | * @brief Set node array from vector |
| 293 | 305 | * |
| 294 | 306 | * @param[in] vector Vector from which node array will be built. |
| 307 | + * | |
| 308 | + * Setup node array from a vector of values. | |
| 295 | 309 | ***************************************************************************/ |
| 296 | 310 | void GNodeArray::nodes(const GVector& vector) |
| 297 | 311 | { |
| ... | ... | @@ -302,8 +316,9 @@ void GNodeArray::nodes(const GVector& vector) |
| 302 | 316 | init_members(); |
| 303 | 317 | |
| 304 | 318 | // Set node values |
| 305 | - for (int i = 0; i < vector.size(); ++i) | |
| 319 | + for (int i = 0; i < vector.size(); ++i) { | |
| 306 | 320 | m_node.push_back(vector[i]); |
| 321 | + } | |
| 307 | 322 | |
| 308 | 323 | // Setup node distances and linear array handling |
| 309 | 324 | setup(); |
| ... | ... | @@ -317,6 +332,8 @@ void GNodeArray::nodes(const GVector& vector) |
| 317 | 332 | * @brief Set node array from vector |
| 318 | 333 | * |
| 319 | 334 | * @param[in] vector Vector from which node array will be built. |
| 335 | + * | |
| 336 | + * Setup node array from a vector of double precision values. | |
| 320 | 337 | ***************************************************************************/ |
| 321 | 338 | void GNodeArray::nodes(const std::vector<double>& vector) |
| 322 | 339 | { |
| ... | ... | @@ -373,13 +390,15 @@ double GNodeArray::interpolate(const double& value, |
| 373 | 390 | const std::vector<double>& vector) const |
| 374 | 391 | { |
| 375 | 392 | // Throw exception if there are not enough nodes |
| 376 | - if (m_node.size() < 2) | |
| 393 | + if (m_node.size() < 2) { | |
| 377 | 394 | throw GException::not_enough_nodes(G_INTERPOLATE, m_node.size()); |
| 395 | + } | |
| 378 | 396 | |
| 379 | 397 | // Throw exception if vectors have not the same size |
| 380 | - if (m_node.size() != vector.size()) | |
| 398 | + if (m_node.size() != vector.size()) { | |
| 381 | 399 | throw GException::vector_mismatch(G_INTERPOLATE, m_node.size(), |
| 382 | 400 | vector.size()); |
| 401 | + } | |
| 383 | 402 | |
| 384 | 403 | // Set interpolation value (circumvent const correctness) |
| 385 | 404 | const_cast<GNodeArray*>(this)->set_value(value); |
| ... | ... | @@ -398,6 +417,9 @@ double GNodeArray::interpolate(const double& value, |
| 398 | 417 | * |
| 399 | 418 | * @param[in] value Value for which the interpolation should be done. |
| 400 | 419 | * |
| 420 | + * @exception GException::not_enough_nodes | |
| 421 | + * At least two nodes are required for setting up the factors | |
| 422 | + * | |
| 401 | 423 | * Set the indices that bound the specified value and the corresponding |
| 402 | 424 | * weighting factors for linear interpolation. If the array has a linear |
| 403 | 425 | * form (i.e. the nodes are equidistant), an analytic formula is used to |
| ... | ... | @@ -408,55 +430,60 @@ void GNodeArray::set_value(const double& value) |
| 408 | 430 | { |
| 409 | 431 | // Get number of nodes |
| 410 | 432 | int nodes = m_node.size(); |
| 433 | + | |
| 434 | + // Throw an exception if less than 2 nodes are available | |
| 435 | + if (nodes < 2) { | |
| 436 | + throw GException::not_enough_nodes(G_SET_VALUE, nodes); | |
| 437 | + } | |
| 411 | 438 | |
| 412 | - // Continue only if we have at least 2 nodes | |
| 413 | - if (nodes > 1) { | |
| 414 | - | |
| 415 | - // If array is linear then get left index from analytic formula | |
| 416 | - if (m_is_linear) { | |
| 439 | + // If array is linear then get left index from analytic formula | |
| 440 | + if (m_is_linear) { | |
| 417 | 441 | |
| 418 | - // Set left index | |
| 419 | - m_inx_left = int(m_linear_slope * value + m_linear_offset); | |
| 442 | + // Set left index | |
| 443 | + m_inx_left = int(m_linear_slope * value + m_linear_offset); | |
| 444 | + | |
| 445 | + // Keep index in valid range | |
| 446 | + if (m_inx_left < 0) m_inx_left = 0; | |
| 447 | + else if (m_inx_left >= nodes-1) m_inx_left = nodes - 2; | |
| 420 | 448 | |
| 421 | - // Keep index in valid range | |
| 422 | - if (m_inx_left < 0) m_inx_left = 0; | |
| 423 | - else if (m_inx_left >= nodes-1) m_inx_left = nodes - 2; | |
| 449 | + } // endif: array is linear | |
| 424 | 450 | |
| 425 | - } // endif: array is linear | |
| 451 | + // ... otherwise search the relevant indices by bisection | |
| 452 | + else { | |
| 453 | + | |
| 454 | + // Set left index if value is before first node | |
| 455 | + if (value < m_node[0]) { | |
| 456 | + m_inx_left = 0; | |
| 457 | + } | |
| 426 | 458 | |
| 427 | - // ... otherwise search the relevant indices by bisection | |
| 459 | + // Set left index if value is after last node | |
| 460 | + else if (value > m_node[nodes-1]) { | |
| 461 | + m_inx_left = nodes - 2; | |
| 462 | + } | |
| 463 | + | |
| 464 | + // Set left index by bisection | |
| 428 | 465 | else { |
| 429 | - // Set left index if value is before first node | |
| 430 | - if (value < m_node[0]) | |
| 431 | - m_inx_left = 0; | |
| 432 | - | |
| 433 | - // Set left index if value is after last node | |
| 434 | - else if (value > m_node[nodes-1]) | |
| 435 | - m_inx_left = nodes - 2; | |
| 436 | - | |
| 437 | - // Set left index by bisection | |
| 438 | - else { | |
| 439 | - int low = 0; | |
| 440 | - int high = nodes - 1; | |
| 441 | - while ((high - low) > 1) { | |
| 442 | - int mid = (low+high) / 2; | |
| 443 | - if (m_node[mid] > value) | |
| 444 | - high = mid; | |
| 445 | - else if (m_node[mid] <= value) | |
| 446 | - low = mid; | |
| 466 | + int low = 0; | |
| 467 | + int high = nodes - 1; | |
| 468 | + while ((high - low) > 1) { | |
| 469 | + int mid = (low+high) / 2; | |
| 470 | + if (m_node[mid] > value) { | |
| 471 | + high = mid; | |
| 447 | 472 | } |
| 448 | - m_inx_left = low; | |
| 449 | - } // endelse: did bisection | |
| 450 | - } | |
| 473 | + else if (m_node[mid] <= value) { | |
| 474 | + low = mid; | |
| 475 | + } | |
| 476 | + } | |
| 477 | + m_inx_left = low; | |
| 478 | + } // endelse: did bisection | |
| 479 | + } | |
| 451 | 480 | |
| 452 | - // Set right index | |
| 453 | - m_inx_right = m_inx_left + 1; | |
| 481 | + // Set right index | |
| 482 | + m_inx_right = m_inx_left + 1; | |
| 454 | 483 | |
| 455 | - // Set weighting factors | |
| 456 | - m_wgt_right = (value - m_node[m_inx_left]) / m_step[m_inx_left]; | |
| 457 | - m_wgt_left = 1.0 - m_wgt_right; | |
| 458 | - | |
| 459 | - } // endif: there were at least 2 nodes | |
| 484 | + // Set weighting factors | |
| 485 | + m_wgt_right = (value - m_node[m_inx_left]) / m_step[m_inx_left]; | |
| 486 | + m_wgt_left = 1.0 - m_wgt_right; | |
| 460 | 487 | |
| 461 | 488 | // Return |
| 462 | 489 | return; |
| ... | ... | @@ -493,7 +520,9 @@ std::string GNodeArray::print(void) const |
| 493 | 520 | for (int i = 0; i < size(); ++i) { |
| 494 | 521 | result.append("\n"+parformat("Node "+str(i))); |
| 495 | 522 | result.append(str(m_node[i])); |
| 496 | - result.append(" (delta="+str(m_step[i])+")"); | |
| 523 | + if (i < m_step.size()) { | |
| 524 | + result.append(" (delta="+str(m_step[i])+")"); | |
| 525 | + } | |
| 497 | 526 | } |
| 498 | 527 | |
| 499 | 528 | // Return result |
| ... | ... | @@ -515,7 +544,7 @@ void GNodeArray::init_members(void) |
| 515 | 544 | // Initialise members |
| 516 | 545 | m_node.clear(); |
| 517 | 546 | m_step.clear(); |
| 518 | - m_is_linear = 0; | |
| 547 | + m_is_linear = false; | |
| 519 | 548 | m_linear_slope = 0.0; |
| 520 | 549 | m_linear_offset = 0.0; |
| 521 | 550 | m_inx_left = 0; |
| ... | ... | @@ -563,6 +592,11 @@ void GNodeArray::free_members(void) |
| 563 | 592 | |
| 564 | 593 | /***********************************************************************//** |
| 565 | 594 | * @brief Compute distance array and linear slope/offset |
| 595 | + * | |
| 596 | + * Precomputes values for fast interpolation. The precomputation requires | |
| 597 | + * at least 2 nodes to be present in the node array. If less then two | |
| 598 | + * nodes are present, the distance vector m_step will be empty and no | |
| 599 | + * computation is done. | |
| 566 | 600 | ***************************************************************************/ |
| 567 | 601 | void GNodeArray::setup(void) |
| 568 | 602 | { |
| ... | ... | @@ -571,13 +605,14 @@ void GNodeArray::setup(void) |
| 571 | 605 | |
| 572 | 606 | // Get number of nodes |
| 573 | 607 | int nodes = m_node.size(); |
| 574 | - | |
| 575 | - // Continue only if we have nodes at least 2 nodes | |
| 608 | + | |
| 609 | + // Continue only if there are at least 2 nodes | |
| 576 | 610 | if (nodes > 1) { |
| 577 | - | |
| 611 | + | |
| 578 | 612 | // Setup distance array between subsequent nodes |
| 579 | - for (int i = 0; i < nodes-1; ++i) | |
| 613 | + for (int i = 0; i < nodes-1; ++i) { | |
| 580 | 614 | m_step.push_back(m_node[i+1] - m_node[i]); |
| 615 | + } | |
| 581 | 616 | |
| 582 | 617 | // Evaluate linear slope and offset |
| 583 | 618 | m_linear_slope = double(nodes-1) / (m_node[nodes-1] - m_node[0]); |
| ... | ... | @@ -592,9 +627,10 @@ void GNodeArray::setup(void) |
| 592 | 627 | break; |
| 593 | 628 | } |
| 594 | 629 | } |
| 595 | - | |
| 596 | - } // endif: there were at least 2 nodes | |
| 630 | + | |
| 631 | + } // endif: there were at least two nodes | |
| 597 | 632 | |
| 598 | 633 | // Return |
| 599 | 634 | return; |
| 600 | 635 | } |
| 636 | + | ... | ... |
test/test_GSky.cpp
| ... | ... | @@ -258,8 +258,8 @@ void TestGSky::test_GWcslib(void) |
| 258 | 258 | try { |
| 259 | 259 | |
| 260 | 260 | // Allocate projection CEL and GAL |
| 261 | - GWcslib *cel = (GWcslib*)registry.alloc(registry.code(i)); | |
| 262 | - GWcslib *gal = (GWcslib*)registry.alloc(registry.code(i)); | |
| 261 | + GWcslib *cel = dynamic_cast<GWcslib*>(registry.alloc(registry.code(i))); | |
| 262 | + GWcslib *gal = dynamic_cast<GWcslib*>(registry.alloc(registry.code(i))); | |
| 263 | 263 | |
| 264 | 264 | // Throw an error if allocation failed |
| 265 | 265 | if (cel == NULL || gal == NULL) { | ... | ... |