Commit af5cca0dc6bf66fcfe27cf940b5cbef849eb1c45

Authored by Jürgen Knödlseder
2 parents 8624151e 34fb46eb

Merge branch 'devel' into hess

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 &quot;x$openmp_ok&quot; = &quot;xyes&quot; ; 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
... ... @@ -76,7 +76,7 @@ public:
76 76 GEnergy emax(int inx) const;
77 77 GEnergy emean(int inx) const;
78 78 GEnergy elogmean(int inx) const;
79   - bool isin(const GEnergy& eng) const;
  79 + bool contains(const GEnergy& eng) const;
80 80 std::string print(void) const;
81 81  
82 82  
... ...
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&amp; 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&amp; GLATEventCube::operator= (const GLATEventCube&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; ie, const int&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&lt;double&gt; 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
... ... @@ -66,7 +66,7 @@ public:
66 66 GEnergy emax(int inx) const;
67 67 GEnergy emean(int inx) const;
68 68 GEnergy elogmean(int inx) const;
69   - bool isin(const GEnergy& eng) const;
  69 + bool contains(const GEnergy& eng) const;
70 70 };
71 71  
72 72  
... ...
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&amp; 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&amp; 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&amp; 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&amp; 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&amp; ix, const int&amp; 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&amp; ix, const int&amp; iy, const int&amp; 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&amp; 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
... ... @@ -228,7 +228,7 @@ double GEnergy::TeV(void) const
228 228 double GEnergy::log10keV(void) const
229 229 {
230 230 // Return log10 energy
231   - return (log10keV()+3.0);
  231 + return (log10MeV()+3.0);
232 232 }
233 233  
234 234  
... ...
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&amp; GNodeArray::operator= (const GNodeArray&amp; 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&amp; GNodeArray::operator[](const int&amp; 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&amp; GNodeArray::operator[](const int&amp; 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&amp; GNodeArray::operator[](const int&amp; 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&amp; GNodeArray::operator[](const int&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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) {
... ...