Commit bd6cc102b8bd76889d36ca1dbf04bda51bf00963

Authored by Jürgen Knödlseder
2 parents 4552f38d 2d8eadf1

Merge branch 'release'

Showing 113 changed files with 3099 additions and 1825 deletions

Too many changes.

To preserve performance only 100 of 113 files are displayed.

ChangeLog
  1 +2015-12-18 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu>
  2 +
  3 + * Version 1.0.0 released
  4 + =========================
  5 +
  6 + Ignore errors for El Capitan post processing (#1605)
  7 + Read only mandatory columns in GCTAEventList (#1600)
  8 + Remove extname arguments from classes (#1601)
  9 + Add GFilename class (#1599)
  10 + Check existence of files in CTA response loading (#1586)
  11 + GSkyMap::__getitem__ throw exception if out of bound (#1581)
  12 + Handle ~ in filenames (#1580)
  13 + Add GModel::has_ts() method (#1578)
  14 + Perform __init__.py creation only in build step (#1569)
  15 + Remove access by name methods from GSkyRegions (#1564)
  16 + Resolve Python test problem on El Capitan (#1563)
  17 +
  18 +
1 19 2015-10-28 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu>
2 20  
3 21 * Version 0.11.0 released
... ...
1   -New Features and Important Changes in GammaLib 0.11.0
  1 +New Features and Important Changes in GammaLib 1.0.0
2 2  
3 3 Author(s) : Juergen Knoedlseder
4 4  
5   -28 October 2015
  5 +18 December 2015
6 6  
7 7  
8 8 1. Introduction
... ... @@ -13,33 +13,32 @@ made since the last release of GammaLib.
13 13  
14 14 2. Public interface modifications
15 15 ---------------------------------
16   -The GOptimizerLM logger constructor now takes a pointer to a logger instead of
17   -a reference. This allows setting of a NULL pointer, disabling the logging of the
18   -optimizer.
19   -
20   -The GSkymap class has been renamed to GSkyMap to be consistent with the other
21   -classes in the sky module.
22   -
23   -The small angle approximation has been removed from GModelSpatialRadialShell.
  16 +Remove optional extname arguments from the following classes:
  17 +- GEbounds
  18 +- GEnergies
  19 +- GGti
  20 +- GNodeArray
  21 +- GCTAPointing
  22 +- GMWLObservation
  23 +- GMWLSpectrum
24 24  
25 25  
26 26 3. Configuration
27 27 -----------------
28   -None
  28 +The __init__.py file in the pyext/gammalib folder is now only created during
  29 +build but not during the install. This should avoid problems during installation
  30 +related to file access rights (#1569).
  31 +
  32 +A special post processing of the Python module libraries has been added for
  33 +Mac OS X 10.11 and higher (El Capitan). This post processing is a replacement for
  34 +setting DYLD_LIBRARY_PATH during unit testing since the environment variable is
  35 +ignored in certain circumstances by El Capitan. Any errors that occur during the
  36 +post processing will be ignored.
29 37  
30 38  
31 39 4. Application module
32 40 ---------------------
33   -GammaLib applications now only look for the application parameter file in the
34   -users pfiles directory if the PFILES environment variable has been not set. This
35   -assure that the PFILES environment variable will always take precedence over the
36   -users pfiles directory, and if the paramter file is missing in the directory
37   -pointed by the PFILES environment variable, it will be copied over from the
38   -syspfiles directory.
39   -
40   -The GApplication class now has a need_help() method that returns true is the
41   ---help option is specified on the command line. This allows the client to display
42   -any help information.
  41 +None
43 42  
44 43  
45 44 5. Base module
... ... @@ -59,35 +58,8 @@ None
59 58  
60 59 8. Model module
61 60 ---------------
62   -Implement a rejection method for Monte Carlo simulations of photons in
63   -GModelSpatialDiffuseMap and GModelSpatialDiffuseCube. This assures that the
64   -simulated photon distribution follows the intensity distribution of the skymap
65   -as obtained using the sky direction access operator.
66   -
67   -The algorithm used to draw random numbers in GModelSpatialDiffuseConst::mc()
68   -was wrong (sky directions were not distributed isotropically on the sky). This
69   -has now been fixed (#1480).
70   -
71   -The small angle approximation has been removed from GModelSpatialRadialShell
72   -as this complexifies the class and the approximation is not really needed.
73   -
74   -A GModelSpatialDiffuseMap::set_mc_cone method has been introduced to handle
75   -correctly Monte Carlo simulations for unnormalized diffuse maps. This method
76   -now computes the normalization for a map within the acceptance cone which is
77   -then returned by the GModelSpatialDiffuseMap::mc_norm method.
78   -
79   -The GModelSpatial::norm method has been renamed to GModelSpatial::mc_norm so that
80   -the usage of this method is now explicitly given by the method name.
81   -
82   -save() and write() methods have been added to GModelSpatialDiffuseCube that allow
83   -the saving of a diffuse cube spatial model to disk or into a FITS objects.
84   -
85   -The computations in GModelSpatialDiffuseCube were not precise enough to allow
86   -an accurate modelling of the simulated events. The eval() and eval_gradients()
87   -methods now use a log-log interpolation. Furthermore, the map is selected
88   -in mc() randomly based on the interpolation weights of th neighbouring maps.
89   -And some bugs related to the map indexing and maximum map value computation
90   -have been corrected.
  61 +Added GModel::has_ts() method that signals if a TS value has been computed
  62 +for a given model.
91 63  
92 64  
93 65 9. Numerics module
... ... @@ -97,49 +69,38 @@ None
97 69  
98 70 10. Observation module
99 71 ----------------------
100   -Integration in npred() is now done using a fixed number of Romberg iterations
101   -instead of using the integration precision. This will assure that the log-
102   -likelihood function is smooth.
103   -
104   -The number of integration iterations for the energy dispersion was changed from
105   -4 to 5 to make it compatible with the default integration order.
106   -
107   -An interval constructor and the set_lin() and set_log() methods have been added
108   -to the GEnergies class to allow quick creation of a linear or logarithmic series
109   -of energies.
  72 +None
110 73  
111 74  
112 75 11. Optimization module
113 76 -----------------------
114   -The gradient computation has been corrected. Instead of multiplying the gradient
115   -factor with the scale factor we have to divide the gradient factor by the scale
116   -factor.
117   -
118   -An logger() method has been added to GOptimizerLM to set the logger for an
119   -optimizer (before, a logger could only be set during construction).
  77 +None
120 78  
121 79  
122 80 12. Sky module
123 81 --------------
124   -Added the flux() method that provides estimates for the flux value of a pixel. The
125   -flux is defined as the intensity (computed by bilinear interpolation over the pixel)
126   -multiplied by the solid angle of the pixel.
  82 +Remove the following methods from GSkyRegions as we have not identified a use case
  83 +where this access is needed (#1564):
  84 +* set(std::string, GSkyRegion)
  85 +* insert(std::string, GSkyRegion)
  86 +* remove(std::string)
  87 +* operator[](std::string)
  88 +* contains(std::string)
  89 +* get_index(std::string)
127 90  
128   -The pixel containment check has been corrected. Before, the containment check returned
129   -true even if the pixel was by one beyond the skymap limits. On of the unwanted side
130   -effects in the sky map access operator was that pixels outside the valid sky map
131   -array were accessed, leading to unpredictable results at the edge of the images.
132   -This quite severe bug was now corrected.
133   -
134   -The GSkymap::operator/=(GSkymap) operator now sets all pixels to zero for which the
135   -nominator is zero. No exception is thrown any longer.
136   -
137   -Add +, -, * and / binary operators to the GSkymap class.
  91 +The Python extension GSkyMap::__getitem__ now checks the validity of the index and
  92 +map number and throws an out_of_range exception if the parameters are not valid.
  93 +This is required on some platforms to properly catch the end in iterations (#1581).
138 94  
139 95  
140 96 13. Support module
141 97 ------------------
142   -None
  98 +The gammalib::expand_env() function now handles ~, ~user, ~+ and ~- following the
  99 +logic implemented for the bash shell.
  100 +
  101 +The GFilename class has been added to deal with filenames in the future. This class
  102 +handles the decomposition of the string into a filename and an extension name in the
  103 +cfitsio style, allowing to specify the extension name, number and version.
143 104  
144 105  
145 106 14. XML module
... ... @@ -174,34 +135,11 @@ None
174 135  
175 136 20. CTA interface
176 137 -----------------
177   -All integrations are now done using a fixed number of Romberg iterations
178   -instead of using the integration precision. This will assure that the log-
179   -likelihood function is smooth.
180   -
181   -The number of integration iterations for the energy dispersion was changed from
182   -4 to 5 to make it compatible with the default integration order.
183   -
184   -An is_valid() method has been added to GCTARoi that returns true if the ROI
185   -has a positive radius. DS keywords are only written for a valid ROI into the
186   -event list file.
187   -
188   -The OBJECT attribute of an event file is now stored in to m_object member of
189   -GCTAObservation, and object() methods have been added to set and get the
190   -attribute value.
191   -
192   -The deadtime correction has been removed from GCTAModelCubeBackground as the
193   -background cube rates are already given per livetime. We formerly did the
194   -correction twice (#1503).
195   -
196   -The GCTAModelAeffBackground class has been added to generate a background model
197   -from the effective area information (#1525). The usage of this model is similar
198   -to that of the IRF background model. The model type in the XML file is
199   -"CTAAeffBackground".
200   -
201   -The precision for the IRF computation of radial shell models has been increased
202   -to reduce a bias in the fitting of the model for unbinned analysis (#1521). There
203   -is still a slight bias for the shell parameters in an unbinned analysis when the
204   -width of the shell becomes comparable to the angular resolution.
  138 +The IRF loaders now check the existence of the file before loading, and now throws
  139 +appropriate error messages in case that the files do not exist (#1586).
  140 +
  141 +Only manadatory columns are read by GCTAEventsList, while any other columns will only
  142 +be stored for back writing in a FITS file.
205 143  
206 144  
207 145 21. COMPTEL interface
... ...
1 1 GammaLib information
2 2 ====================
3   -Version: 0.11.0 (28 October 2015)
  3 +Version: 1.0.0 (18 December 2015)
4 4 Author: Juergen Knoedlseder (jurgen.knodlseder@irap.omp.eu)
5 5  
6 6  
... ... @@ -41,8 +41,7 @@ data analysis framework that enables simultaneous multi-mission analysis.
41 41  
42 42 Web sites
43 43 =========
44   -http://cta.irap.omp.eu/gammalib/ - for documentation
45   -https://sourceforge.net/projects/gammalib/ - for downloads
  44 +http://cta.irap.omp.eu/gammalib/ - for end users
46 45 https://cta-redmine.irap.omp.eu/projects/gammalib - for developers
47 46  
48 47  
... ... @@ -181,7 +180,7 @@ If everything works successfully you should see
181 180 or
182 181  
183 182 ============================================================================
184   -Testsuite summary for gammalib 0.11.0
  183 +Testsuite summary for gammalib 1.0.0
185 184 ============================================================================
186 185 # TOTAL: 20
187 186 # PASS: 20
... ...
configure.ac
... ... @@ -29,7 +29,7 @@
29 29 #############################################################################
30 30 # Initialisation #
31 31 #############################################################################
32   -AC_INIT([gammalib], [0.11.0], [jurgen.knodlseder@irap.omp.eu], [gammalib])
  32 +AC_INIT([gammalib], [1.0.0], [jurgen.knodlseder@irap.omp.eu], [gammalib])
33 33 AC_CONFIG_SRCDIR([src/support/GTools.cpp])
34 34 AC_CONFIG_MACRO_DIR([m4])
35 35 AM_INIT_AUTOMAKE([gnu no-dependencies -Wno-portability subdir-objects])
... ... @@ -39,13 +39,23 @@ AC_CONFIG_HEADER([config.h])
39 39  
40 40  
41 41 #############################################################################
42   -# Library versioning #
  42 +# Library versioning (current:revision:age) #
43 43 # ------------------------------------------------------------------------- #
44   -# See the libtool manual for an explanation. Currently, library versioning #
45   -# is not yet used for GammaLib as we're still in the development cycle. #
46   -# Users have to make sure that they link against the correct library. #
47   -#############################################################################
48   -GAMMALIB_LT_VERSION="0:0:0"
  44 +# Here are a set of rules to update your library version information: #
  45 +# 1. Update the version information only immediately before a public #
  46 +# release of your software. More frequent updates are unnecessary, #
  47 +# and only guarantee that the current interface number gets larger #
  48 +# faster. #
  49 +# 2. If the library source code has changed at all since the last update, #
  50 +# then increment revision. #
  51 +# 3. If any interfaces have been added, removed, or changed since the last #
  52 +# update, increment current, and set revision to 0. #
  53 +# 4. If any interfaces have been added since the last public release, then #
  54 +# increment age. #
  55 +# 5. If any interfaces have been removed or changed since the last public #
  56 +# release, then set age to 0. #
  57 +#############################################################################
  58 +GAMMALIB_LT_VERSION="1:0:0"
49 59 AC_SUBST(GAMMALIB_LT_VERSION)
50 60  
51 61  
... ... @@ -90,18 +100,42 @@ AC_CANONICAL_HOST
90 100 # #
91 101 # A special kluge was added for Mac OS X >=10.7. As Apple switched to clang #
92 102 # we search from this version on for the clang compiler. #
  103 +# #
  104 +# We also signal whether Mac OS X >=10.11 (El Capitan). #
93 105 #############################################################################
  106 +# Set default Mac OS X version flags
  107 +osx_lion=no
  108 +osx_el_capitan=no
  109 +
94 110 # Set default compiler lists
95 111 cxx_list="g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++"
96 112 cc_list="gcc cc cl.exe clang"
97 113  
98   -# Check if we have Mac OS X >= 10.7
  114 +# Check if we have Mac OS X >= 10.7 and >= 10.11
99 115 if test `uname -s` = "Darwin"; then
100   - if test `sw_vers -productVersion | sed 's/\(10\.[[0-9]]*\).*/\1/'` '>' 10.6; then
  116 + version=`sw_vers -productVersion | sed 's/\(10\.[[0-9]]*\).*/\1/' | sed -e 's/\.//g'`
  117 + if [ test $version -ge 107 ]; then
101 118 cxx_list="clang++ g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC"
102 119 cc_list="clang gcc cc cl.exe"
  120 + osx_lion=yes
  121 + fi
  122 + if [ test $version -ge 1011 ]; then
  123 + osx_el_capitan=yes
103 124 fi
104 125 fi
  126 +AC_MSG_CHECKING([for Mac OS X >= 10.7])
  127 +if [test "x$osx_lion" = "xyes"]; then
  128 + AC_MSG_RESULT(yes)
  129 +else
  130 + AC_MSG_RESULT(no)
  131 +fi
  132 +AC_MSG_CHECKING([for Mac OS X >= 10.11])
  133 +if [test "x$osx_el_capitan" = "xyes"]; then
  134 + AC_MSG_RESULT(yes)
  135 +else
  136 + AC_MSG_RESULT(no)
  137 +fi
  138 +AM_CONDITIONAL(IS_ELCAPITAN, test "x$osx_el_capitan" = "xyes")
105 139  
106 140 # Our language is C++
107 141 AC_LANG(C++)
... ...
dev/release_gammalib.sh
... ... @@ -8,13 +8,11 @@ makelatex=&quot;no&quot;
8 8  
9 9 echo "Checkout latest GammaLib"
10 10 rm -rf gammalib
11   -git clone -b release https://cta-git.irap.omp.eu/gammalib
12   -#git clone -b devel https://cta-git.irap.omp.eu/gammalib
  11 +git clone -b release https://cta-gitlab.irap.omp.eu/gammalib/gammalib.git
13 12 rm -rf gammalib/.git
14 13  
15 14 # Extract version number
16 15 version=`cat gammalib/configure.ac | grep 'AC_INIT' | awk -F"[" '{print $3}' | sed 's/],//' | sed 's/\./ /g'`
17   -#version=`printf "%2.2d-%2.2d-%2.2d" $version`
18 16 version=`printf "%d.%d.%d" $version`
19 17 echo "GammaLib version: "$version
20 18  
... ...
doc/Doxyfile
... ... @@ -32,7 +32,7 @@ PROJECT_NAME = GammaLib
32 32 # This could be handy for archiving the generated documentation or
33 33 # if some version control system is used.
34 34  
35   -PROJECT_NUMBER = 0.11.0
  35 +PROJECT_NUMBER = 1.0.0
36 36  
37 37 # Using the PROJECT_BRIEF tag one can provide an optional one line description
38 38 # for a project that appears at the top of each page and should give viewer
... ...
doc/source/coding/design.rst
... ... @@ -18,9 +18,11 @@ file:
18 18 #include <config.h>
19 19 #endif
20 20  
21   -Note that **the ``config.h`` file should not be included in header files**,
22   -since header files are used by the outside world without any knowledge
23   -about ``config.h``.
  21 +.. warning::
  22 +
  23 + **The config.h file should never be included in header files.**
  24 + The header files are used by the outside world without any knowledge
  25 + about ``config.h``.
24 26  
25 27 One of the most commonly used configuration options used throughout
26 28 GammaLib is related to range checking. Range checks are usually
... ... @@ -305,11 +307,13 @@ following guidelines should be respected as far as possible:
305 307 - Avoid as far as possible methods that are only defined in the derived
306 308 class.
307 309  
308   -Also note that **for a derived class, ``init_members()``,
309   -``copy_members(const &A a)`` and ``free_members()`` should only act on derived
310   -class members but not on base class members**. Any exception from this
311   -rule needs very careful documentation since it can easily be the source
312   -of memory leaks.
  310 +.. warning::
  311 +
  312 + **For a derived class, init_members(), copy_members(const &A a) and
  313 + free_members() should only act on derived class members but not on base
  314 + class members**. Any exception to this rule needs very careful
  315 + documentation since it can easily be the source of memory leaks.
  316 +
313 317  
314 318 Method naming conventions
315 319 ^^^^^^^^^^^^^^^^^^^^^^^^^
... ...
doc/source/coding/rules.rst
... ... @@ -8,7 +8,7 @@ C++ rules
8 8 ---------
9 9  
10 10 All GammaLib C++ code must be compatible with ISO standard C++98.
11   -Do not use C++11 features.
  11 +Do not use C++11 features
12 12 (see `here <http://en.wikipedia.org/wiki/C%2B%2B#Standardization>`__
13 13 if you don't know what C++98 and C++11 is and note that C++03 is
14 14 just a minor correction of C++98).
... ... @@ -189,16 +189,12 @@ Code semantics
189 189  
190 190 >>> import gammalib
191 191 >>> energy = gammalib.GEnergy(10, 'TeV')
192   - >>> import numpy as np
193   - >>> import matplotlib.pyplot as plt
194 192  
195 193 In interactive sessions (`IPython <http://ipython.org/>`_ is recommended) to save
196 194 typing you can use ``import *`` to import everything into your local namespace::
197 195  
198 196 >>> from gammalib import *
199 197 >>> energy = GEnergy(10, 'TeV')
200   - >>> from numpy import *
201   - >>> from matplotlib.pyplot import *
202 198  
203 199 Using ``import *`` in Python scripts is not recommended. Some reason are given in
204 200 `this section <http://docs.python.org/3/howto/doanddont.html#from-module-import>`__
... ...
doc/source/conf.py
... ... @@ -55,9 +55,10 @@ copyright = u&#39;2006-2015, GammaLib developers&#39;
55 55 # built documents.
56 56 #
57 57 # The short X.Y version.
58   -version = '0.11'
  58 +version = '1.0'
  59 +
59 60 # The full version, including alpha/beta/rc tags.
60   -release = '0.11.0'
  61 +release = '1.0.0'
61 62  
62 63 # The language for content autogenerated by Sphinx. Refer to documentation
63 64 # for a list of supported languages.
... ...
doc/source/download.rst
... ... @@ -14,10 +14,11 @@ Releases
14 14 --------
15 15  
16 16 The latest GammaLib release is
17   -`gammalib-0.11.0 <http://cta.irap.omp.eu/ctools/releases/gammalib/gammalib-0.11.0.tar.gz>`_
18   -(1 November 2015).
  17 +`gammalib-1.0.0 <http://cta.irap.omp.eu/ctools/releases/gammalib/gammalib-1.0.0.tar.gz>`_
  18 +(18 December 2015).
19 19  
20 20 To download an older release, click on the corresponding release number:
  21 +`0.11.0 <http://cta.irap.omp.eu/ctools/releases/gammalib/gammalib-0.11.0.tar.gz>`_
21 22 `0.10.0 <http://cta.irap.omp.eu/ctools/releases/gammalib/gammalib-0.10.0.tar.gz>`_
22 23 `0.9.1 <http://cta.irap.omp.eu/ctools/releases/gammalib/gammalib-00-09-01.tar.gz>`_
23 24 `0.9.0 <http://cta.irap.omp.eu/ctools/releases/gammalib/gammalib-00-09-00.tar.gz>`_
... ...
doc/source/installation.rst
... ... @@ -5,8 +5,8 @@ Installation
5 5  
6 6 .. note ::
7 7  
8   - These installation instructions apply to gammalib-0.11.0 and
9   - later. gammalib-0.11.0 has been built, installed and tested
  8 + These installation instructions apply to gammalib-1.0.0 and
  9 + later. gammalib-1.0.0 has been built, installed and tested
10 10 successfully on Debian, Ubuntu, Mandriva, OpenSUSE, Scientific Linux,
11 11 CentOS, Mac OS X, FreeBSD, and OpenSolaris (using gcc), so
12 12 hopefully it also installs on your distribution. In case you encounter
... ... @@ -51,7 +51,7 @@ shared library by typing ::
51 51  
52 52 GammaLib can also benefit from the presence of the readline library that
53 53 provides line-editing and history capabilities for text input (GammaLib
54   -offers however also full functionality without having readline
  54 +offers however full functionality without having readline
55 55 installed). readline (which depends on ncurses) is available on most
56 56 system as a prebuilt library, so also here we recommend to use your
57 57 package manager to install the libraries if they are not already there.
... ... @@ -83,7 +83,7 @@ Building GammaLib
83 83 If you need the latest source code from the git repository that has not
84 84 yet been released you may also clone the gammalib git repository using ::
85 85  
86   - $ git clone https://cta-git.irap.omp.eu/gammalib
  86 + $ git clone https://cta-gitlab.irap.omp.eu/gammalib/gammalib.git
87 87  
88 88 In case you encounter an SSL certificat problem, type ::
89 89  
... ... @@ -95,7 +95,7 @@ Building GammaLib
95 95 $ git checkout devel
96 96 $ ./autogen.sh
97 97  
98   - This will make sure that you use the validated development trunk and
  98 + This will make sure that you use the development trunk. It also
99 99 creates the configuration file that is needed to configure
100 100 GammaLib before compilation. Continue then with the procedure below
101 101 starting with ``./configure``.
... ... @@ -122,19 +122,19 @@ source files and builds the C++ library and Python module. Type
122 122 ``./configure`` and not simply ``configure`` to ensure that the configuration
123 123 script in the current directory is used and not some other system-wide
124 124 configuration script. By default, the install directory is set to
125   -``/usr/local/gamma``. To change the install directory an optional
126   -``--prefix`` argument should be given, for example ::
  125 +``/usr/local/gamma``. To change the install directory, provide an optional
  126 +``--prefix`` argument, for example ::
127 127  
128 128 $ ./configure --prefix=/usr/local
129 129  
130 130 If cfitsio and/or readline is not installed in a standard location for
131   -libraries (such as ``/usr/lib`` or ``/usr/local/lib``), the appropriate
132   -location(s) can be specified using the ``LDFLAGS`` (for the library
  131 +libraries (such as ``/usr/lib`` or ``/usr/local/lib``), you can specify
  132 +the appropriate location(s) using the ``LDFLAGS`` (for the library
133 133 directory) and ``CPPFLAGS`` (for the include directory) options::
134 134  
135 135 $ ./configure LDFLAGS='-L/opt/local/lib' CPPFLAGS='-I/opt/local/include'
136 136  
137   -A full list of configuration options can be found using ::
  137 +You can find a full list of configuration options using ::
138 138  
139 139 $ ./configure --help
140 140  
... ...
doc/source/issues.rst
... ... @@ -7,7 +7,6 @@ Below you will find a list of known issues.
7 7  
8 8 - :ref:`Many (but not all) unit tests fail <issue_test_fail>`
9 9 - :ref:`Python module does not work <issue_python>`
10   -- :ref:`Python unit test fails on El Capitan <issue_elcapitan>`
11 10 - :ref:`Mac OS X <issue_macosx>`
12 11 - :ref:`Solaris <issue_solaris>`
13 12 - :ref:`OpenSolaris <issue_opensolaris>`
... ... @@ -73,16 +72,6 @@ Below you will find a list of known issues.
73 72 If the ``Python.h`` header file does not exist then install the Python
74 73 development package.
75 74  
76   -.. _issue_elcapitan:
77   -
78   -.. topic:: Python unit test fails on El Capitan
79   -
80   - On Mac OS X 10.11 (El Capitan) the Python unit tests fail when GammaLib
81   - is not installed due to the way the ``DYLD_LIBRARY_PATH`` environment
82   - variable is handled by the operating system. A (not very elegant)
83   - workaround is to install GammaLib before running the unit test using
84   - ``make check``.
85   -
86 75 .. _issue_macosx:
87 76  
88 77 .. topic:: Mac OS X
... ...
doc/source/user_manual/getting.rst
... ... @@ -148,15 +148,15 @@ from this site by selection the gammalib package from the table.
148 148 Alternatively, the code can be downloaded and unpacked from the UNIX prompt
149 149 using::
150 150  
151   - $ wget --no-check-certificate http://cta.irap.omp.eu/ctools/releases/gammalib/gammalib-0.11.0.tar.gz
152   - $ tar xfz gammalib-0.11.0.tar.gz
  151 + $ wget --no-check-certificate http://cta.irap.omp.eu/ctools/releases/gammalib/gammalib-1.0.0.tar.gz
  152 + $ tar xfz gammalib-1.0.0.tar.gz
153 153  
154 154 The GammaLib source code can also be cloned using git. This method is
155 155 recommended if you plan to contribute to the development of the GammaLib
156 156 library. Assuming that git is installed on your system, you may clone
157 157 GammaLib using::
158 158  
159   - $ git clone https://cta-git.irap.omp.eu/gammalib
  159 + $ git clone https://cta-gitlab.irap.omp.eu/gammalib/gammalib.git
160 160  
161 161 In case that you get:
162 162  
... ...
doc/source/user_manual/index.rst
... ... @@ -7,7 +7,6 @@ User Manual
7 7  
8 8 introduction
9 9 getting
10   - quickstart
11 10 modules/index
12 11 internals
13 12 manual/index
... ...
doc/source/user_manual/introduction.rst
... ... @@ -43,7 +43,7 @@ are:
43 43 * Issue tracker: https://cta-redmine.irap.omp.eu/projects/gammalib/issues
44 44 * Documentation: http://cta.irap.omp.eu/gammalib/
45 45  
46   -The present document applies to GammaLib version 0.11.
  46 +The present document applies to GammaLib version 1.0.
47 47  
48 48 GammaLib is designed to compile on any POSIX compliant platform. So far,
49 49 GammaLib has been successfully compiled and tested on Mac OS X, OpenBSD, OpenSolaris
... ...
doc/source/user_manual/modules/support.rst
... ... @@ -38,10 +38,17 @@ and a string storage, respectively. As most of the classes are unrelated,
38 38 they will be described individually in the following sections.
39 39  
40 40  
41   -Column Separated Value tables
  41 +Bilinear interpolation
  42 +~~~~~~~~~~~~~~~~~~~~~~
  43 +
  44 +The :doxy:`GBilinear` class handles bilinear interpolation of values in a
  45 +two-dimensional table.
  46 +
  47 +
  48 +Comma-Separated Value tables
42 49 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
43 50  
44   -The :doxy:`GCsv` class handles column separated value tables. Column separated
  51 +The :doxy:`GCsv` class handles comma-separated value tables. Comma-separated
45 52 value tables are ASCII files representing a table, where individual table
46 53 columns a separated by a specific character (for example a whitespace or a
47 54 comma).
... ... @@ -113,6 +120,37 @@ Runtime exceptions Usage
113 120 =============================== =====
114 121  
115 122  
  123 +Filename handling
  124 +~~~~~~~~~~~~~~~~~
  125 +
  126 +The :doxy:`GFilename` class handles file names in GammaLib, including
  127 +extensions for FITS files in the cfitsio format. The following file name
  128 +formats are supported ::
  129 +
  130 + myfile.fits
  131 + myfile.fits[EVENTS]
  132 + myfile.fits[EVENTS,2]
  133 + myfile.fits[3,2]
  134 +
  135 +The class decomposes the input string into the filename and the extension.
  136 +The filename can be access using the :doxy:`GFilename::filename`
  137 +method, the extension name using the :doxy:`GFilename::extname` method,
  138 +the extension number using the :doxy:`GFilename::extno` method and the
  139 +extension version using the :doxy:`GFilename::extver` method. The latter
  140 +three methods take an argument that specifies the default value that
  141 +should be used in case that no extension information is specified. Below
  142 +a usage example that extracts by default the ``EBOUNDS`` table from a
  143 +FITS file:
  144 +
  145 +.. code-block:: cpp
  146 + :linenos:
  147 +
  148 + GFits file;
  149 + GFilename fname(filename);
  150 + file.open(fname.filename());
  151 + const GFitsTable& table = *file.table(fname.extname("EBOUNDS"));
  152 +
  153 +
116 154 Linear interpolation
117 155 ~~~~~~~~~~~~~~~~~~~~
118 156  
... ... @@ -279,9 +317,11 @@ Function Description
279 317 ``gammalib::plaw_energy_flux`` Compute energy flux under a power law.
280 318 ``gammalib::elogmean`` Computes geometric mean of energy.
281 319 ``gammalib::file_exists`` Check whether a file exists.
  320 +``gammalib::file_exists_gzip`` Check whether a file (or a gzipped version of it) exists.
282 321 ``gammalib::dir_exists`` Check whether a directory exists.
283 322 ``gammalib::is_infinite`` Check whether a double precision value is infinite.
284 323 ``gammalib::is_notanumber`` Check whether a double precision value is not a number.
  324 +``gammalib::is_fits`` Check whether a file is a FITS file.
285 325 ``gammalib::contains`` Check whether a string contains a sub-string.
286 326 ``gammalib::warning`` Dump warning in console.
287 327 ``gammalib::xml2str`` Converts XML to string.
... ...
doc/source/user_manual/modules/uml_support.png

46.3 KB | W: | H:

176 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
doc/source/user_manual/quickstart.rst deleted
1   -Getting started with GammaLib
2   -=============================
3   -
4   -A quick GammaLib tutorial
5   --------------------------
6   -
7   -To be written ...
8   -
9   -
10   -Using GammaLib from Python
11   ---------------------------
12   -
13   -To be written ...
14   -
15   -
16   -Programming guidelines
17   -----------------------
18   -
19   -To be written ...
20   -
21   -
22   -Frequently asked questions
23   ---------------------------
24   -
25   -To be written ...
gammalib.pc.in
... ... @@ -6,7 +6,7 @@ includedir=${prefix}/include
6 6 Name: GammaLib
7 7 Description: Versatile toolbox for analysis of astronomical gamma-ray data
8 8 URL: http://cta.irap.omp.eu/gammalib/
9   -Version: 0.11.0
  9 +Version: 1.0.0
10 10 Requires:
11 11 Requires.private: @CFITSIO@
12 12 Conflicts:
... ...
include/GCsv.hpp
1 1 /***************************************************************************
2   - * GCsv.hpp - Column separated values table class *
  2 + * GCsv.hpp - Comma-separated values table class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2014 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2015 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -20,7 +20,7 @@
20 20 ***************************************************************************/
21 21 /**
22 22 * @file GCsv.hpp
23   - * @brief Column separated values table class definition
  23 + * @brief Comma-separated values table class definition
24 24 * @author Juergen Knoedlseder
25 25 */
26 26  
... ... @@ -36,10 +36,10 @@
36 36 /***********************************************************************//**
37 37 * @class GCsv
38 38 *
39   - * @brief Column separated values table class
  39 + * @brief Comma-separated values table class
40 40 *
41 41 * This class implements a table of std::string elements that is loaded
42   - * from a column separated value ASCII file. The column separation string
  42 + * from a comma-separated value ASCII file. The comma-separation string
43 43 * can be specified upon loading of the file (by default the class assumes
44 44 * that elements are separated by a white space).
45 45 *
... ...
include/GEbounds.hpp
... ... @@ -55,13 +55,12 @@ class GEbounds : public GContainer {
55 55 public:
56 56 // Constructors and destructors
57 57 GEbounds(void);
58   - GEbounds(const GEbounds& ebds);
  58 + explicit GEbounds(const std::string& filename);
59 59 explicit GEbounds(const GXmlElement& xml);
  60 + GEbounds(const GEbounds& ebds);
60 61 GEbounds(const GEnergy& emin, const GEnergy& emax);
61 62 GEbounds(const int& num, const GEnergy& emin, const GEnergy& emax,
62 63 const bool& log = true);
63   - GEbounds(const std::string& filename,
64   - const std::string& extname = "EBOUNDS");
65 64 virtual ~GEbounds(void);
66 65  
67 66 // Operators
... ... @@ -82,11 +81,9 @@ public:
82 81 void extend(const GEbounds& ebds);
83 82 void set_lin(const int& num, const GEnergy& emin, const GEnergy& emax);
84 83 void set_log(const int& num, const GEnergy& emin, const GEnergy& emax);
85   - void load(const std::string& filename,
86   - const std::string& extname = "EBOUNDS");
  84 + void load(const std::string& filename);
87 85 void save(const std::string& filename,
88 86 const bool& clobber = false,
89   - const std::string& extname = "EBOUNDS",
90 87 const std::string& unit = "keV") const;
91 88 void read(const GFitsTable& table);
92 89 void write(GFits& file,
... ...
include/GEnergies.hpp
... ... @@ -49,8 +49,7 @@ class GEnergies : public GContainer {
49 49 public:
50 50 // Constructors and destructors
51 51 GEnergies(void);
52   - GEnergies(const std::string& filename,
53   - const std::string& extname = "ENERGIES");
  52 + explicit GEnergies(const std::string& filename);
54 53 GEnergies(const GEnergies& energies);
55 54 GEnergies(const int& num, const GEnergy& emin, const GEnergy& emax,
56 55 const bool& log = true);
... ... @@ -78,11 +77,9 @@ public:
78 77 const GEnergy& emax);
79 78 void set_log(const int& num, const GEnergy& emin,
80 79 const GEnergy& emax);
81   - void load(const std::string& filename,
82   - const std::string& extname = "ENERGIES");
  80 + void load(const std::string& filename);
83 81 void save(const std::string& filename,
84   - const bool& clobber = false,
85   - const std::string& extname = "ENERGIES") const;
  82 + const bool& clobber = false) const;
86 83 void read(const GFitsTable& table);
87 84 void write(GFits& file,
88 85 const std::string& extname = "ENERGIES") const;
... ...
include/GFilename.hpp 0 → 100644
  1 +/***************************************************************************
  2 + * GFilename.hpp - Filename class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2015 by Juergen Knoedlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software: you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation, either version 3 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + * This program is distributed in the hope that it will be useful, *
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15 + * GNU General Public License for more details. *
  16 + * *
  17 + * You should have received a copy of the GNU General Public License *
  18 + * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  19 + * *
  20 + ***************************************************************************/
  21 +/**
  22 + * @file GFilename.hpp
  23 + * @brief Filename class interface definition
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +
  27 +#ifndef GFILENAME_HPP
  28 +#define GFILENAME_HPP
  29 +
  30 +/* __ Includes ___________________________________________________________ */
  31 +#include <string>
  32 +#include "GBase.hpp"
  33 +
  34 +
  35 +/***********************************************************************//**
  36 + * @class GFilename
  37 + *
  38 + * @brief Filename class
  39 + *
  40 + * This class handles filenames.
  41 + ***************************************************************************/
  42 +class GFilename : public GBase {
  43 +
  44 +public:
  45 + // Constructors and destructors
  46 + GFilename(void);
  47 + GFilename(const std::string& filename);
  48 + GFilename(const char* filename);
  49 + GFilename(const GFilename& filename);
  50 + virtual ~GFilename(void);
  51 +
  52 + // Operators
  53 + GFilename& operator=(const GFilename& filename);
  54 +
  55 + // Methods
  56 + void clear(void);
  57 + GFilename* clone(void) const;
  58 + std::string classname(void) const;
  59 + bool empty(void) const;
  60 + int size(void) const;
  61 + int length(void) const;
  62 + const std::string& filename(void) const;
  63 + std::string extname(const std::string& defaultname = "") const;
  64 + int extno(const int& defaultno = -1) const;
  65 + int extver(const int& defaultver = 0) const;
  66 + bool has_extname(void) const;
  67 + bool has_extno(void) const;
  68 + bool has_extver(void) const;
  69 + std::string print(const GChatter& chatter = NORMAL) const;
  70 +
  71 +protected:
  72 + // Protected methods
  73 + void init_members(void);
  74 + void copy_members(const GFilename& filename);
  75 + void free_members(void);
  76 + void set_filename(const std::string& filename);
  77 +
  78 + // Protected members
  79 + std::string m_filename; //!< Filename (with stripped extension info)
  80 + std::string m_extname; //!< Extension name ("": not set)
  81 + int m_extno; //!< Extension number (-1: not set)
  82 + int m_extver; //!< Extension version (0: not set)
  83 +};
  84 +
  85 +
  86 +/***********************************************************************//**
  87 + * @brief Return class name
  88 + *
  89 + * @return String containing the class name ("GFilename").
  90 + ***************************************************************************/
  91 +inline
  92 +std::string GFilename::classname(void) const
  93 +{
  94 + return ("GFilename");
  95 +}
  96 +
  97 +
  98 +/***********************************************************************//**
  99 + * @brief Signal if filename is empty
  100 + *
  101 + * @return True if filename is empty, false otherwise.
  102 + ***************************************************************************/
  103 +inline
  104 +bool GFilename::empty(void) const
  105 +{
  106 + return (m_filename.empty());
  107 +}
  108 +
  109 +
  110 +/***********************************************************************//**
  111 + * @brief Return size of filename
  112 + *
  113 + * @return Size of filename.
  114 + *
  115 + * The size of the file name is equal to its length.
  116 + ***************************************************************************/
  117 +inline
  118 +int GFilename::size(void) const
  119 +{
  120 + return (m_filename.size());
  121 +}
  122 +
  123 +
  124 +/***********************************************************************//**
  125 + * @brief Return length of filename
  126 + *
  127 + * @return Length of filename.
  128 + ***************************************************************************/
  129 +inline
  130 +int GFilename::length(void) const
  131 +{
  132 + return (m_filename.length());
  133 +}
  134 +
  135 +
  136 +/***********************************************************************//**
  137 + * @brief Return file name
  138 + *
  139 + * @return String containing file name.
  140 + ***************************************************************************/
  141 +inline
  142 +const std::string& GFilename::filename(void) const
  143 +{
  144 + return (m_filename);
  145 +}
  146 +
  147 +
  148 +/***********************************************************************//**
  149 + * @brief Signal if filename has an extension name
  150 + *
  151 + * @return True if filename has an extension name, false otherwise.
  152 + ***************************************************************************/
  153 +inline
  154 +bool GFilename::has_extname(void) const
  155 +{
  156 + return (!m_extname.empty());
  157 +}
  158 +
  159 +
  160 +/***********************************************************************//**
  161 + * @brief Signal if filename has an extension number
  162 + *
  163 + * @return True if filename has an extension number, false otherwise.
  164 + ***************************************************************************/
  165 +inline
  166 +bool GFilename::has_extno(void) const
  167 +{
  168 + return (m_extno >= 0);
  169 +}
  170 +
  171 +
  172 +/***********************************************************************//**
  173 + * @brief Signal if filename has an extension version
  174 + *
  175 + * @return True if filename has an extension version, false otherwise.
  176 + ***************************************************************************/
  177 +inline
  178 +bool GFilename::has_extver(void) const
  179 +{
  180 + return (m_extver > 0);
  181 +}
  182 +
  183 +#endif /* GFILENAME_HPP */
... ...
include/GGti.hpp
... ... @@ -58,6 +58,7 @@ class GGti : public GContainer {
58 58 public:
59 59 // Constructors and destructors
60 60 GGti(void);
  61 + explicit GGti(const std::string& filename);
61 62 GGti(const GGti& gti);
62 63 GGti(const GTime& tstart, const GTime& tstop);
63 64 explicit GGti(const GXmlElement& xml);
... ... @@ -81,11 +82,9 @@ public:
81 82 void remove(const int& index);
82 83 void reserve(const int& num);
83 84 void extend(const GGti& gti);
84   - void load(const std::string& filename,
85   - const std::string& extname = "GTI");
  85 + void load(const std::string& filename);
86 86 void save(const std::string& filename,
87   - const bool& clobber = false,
88   - const std::string& extname = "GTI") const;
  87 + const bool& clobber = false) const;
89 88 void read(const GFitsTable& table);
90 89 void write(GFits& file,
91 90 const std::string& extname = "GTI") const;
... ...
include/GModel.hpp
... ... @@ -139,6 +139,7 @@ public:
139 139 void ts(const double& ts);
140 140 const bool& tscalc(void) const;
141 141 void tscalc(const bool& tscalc);
  142 + const bool& has_ts(void) const;
142 143 std::string instruments(void) const;
143 144 void instruments(const std::string& instruments);
144 145 GModelPar scale(const std::string& instrument) const;
... ... @@ -314,7 +315,7 @@ void GModel::tscalc(const bool&amp; tscalc)
314 315 /***********************************************************************//**
315 316 * @brief Signals that model has scales
316 317 *
317   - * @return True is model has scale factors.
  318 + * @return True if model has scale factors.
318 319 ***************************************************************************/
319 320 inline
320 321 bool GModel::has_scales(void) const
... ... @@ -322,4 +323,16 @@ bool GModel::has_scales(void) const
322 323 return (!m_scales.empty());
323 324 }
324 325  
  326 +
  327 +/***********************************************************************//**
  328 + * @brief Signals that model has Test Statistics value
  329 + *
  330 + * @return True if model has TS value.
  331 + ***************************************************************************/
  332 +inline
  333 +const bool& GModel::has_ts(void) const
  334 +{
  335 + return m_has_ts;
  336 +}
  337 +
325 338 #endif /* GMODEL_HPP */
... ...
include/GNodeArray.hpp
... ... @@ -59,9 +59,10 @@ class GNodeArray : public GContainer {
59 59 public:
60 60 // Constructors and destructors
61 61 GNodeArray(void);
62   - GNodeArray(const int& num, const double* array);
  62 + explicit GNodeArray(const std::string& filename);
63 63 explicit GNodeArray(const GVector& vector);
64 64 explicit GNodeArray(const std::vector<double>& vector);
  65 + GNodeArray(const int& num, const double* array);
65 66 GNodeArray(const GNodeArray& array);
66 67 virtual ~GNodeArray(void);
67 68  
... ... @@ -93,10 +94,9 @@ public:
93 94 const int& inx_right(void) const;
94 95 const double& wgt_left(void) const;
95 96 const double& wgt_right(void) const;
96   - void load(const std::string& filename,
97   - const std::string& extname = "NODES");
98   - void save(const std::string& filename, const bool& clobber = false,
99   - const std::string& extname = "NODES") const;
  97 + void load(const std::string& filename);
  98 + void save(const std::string& filename,
  99 + const bool& clobber = false) const;
100 100 void read(const GFitsTable& table);
101 101 void write(GFits& file,
102 102 const std::string& extname = "NODES") const;
... ...
include/GSkyRegions.hpp
... ... @@ -63,8 +63,6 @@ public:
63 63 GSkyRegions& operator=(const GSkyRegions& regions);
64 64 GSkyRegion* operator[](const int& index);
65 65 const GSkyRegion* operator[](const int& index) const;
66   - GSkyRegion* operator[](const std::string& name);
67   - const GSkyRegion* operator[](const std::string& name) const;
68 66  
69 67 // Methods
70 68 void clear(void);
... ... @@ -75,15 +73,11 @@ public:
75 73 int size(void) const;
76 74 bool is_empty(void) const;
77 75 GSkyRegion* set(const int& index, const GSkyRegion& region);
78   - GSkyRegion* set(const std::string& name, const GSkyRegion& region);
79 76 GSkyRegion* append(const GSkyRegion& region);
80 77 GSkyRegion* insert(const int& index, const GSkyRegion& region);
81   - GSkyRegion* insert(const std::string& name, const GSkyRegion& region);
82 78 void remove(const int& index);
83   - void remove(const std::string& name);
84 79 void reserve(const int& num);
85 80 void extend(const GSkyRegions& regions);
86   - bool contains(const std::string& name) const;
87 81 bool contains(const GSkyDir& dir) const;
88 82 bool overlaps(const GSkyRegion& reg) const;
89 83 void load(const std::string& filename);
... ... @@ -96,7 +90,6 @@ protected:
96 90 void init_members(void);
97 91 void copy_members(const GSkyRegions& regions);
98 92 void free_members(void);
99   - int get_index(const std::string& name) const;
100 93  
101 94 // Protected members
102 95 mutable std::string m_filename; //!< Filename of origin
... ...
include/GTools.hpp
... ... @@ -96,6 +96,7 @@ namespace gammalib {
96 96 const double& gamma);
97 97 GEnergy elogmean(const GEnergy& a, const GEnergy& b);
98 98 bool file_exists(const std::string& filename);
  99 + bool file_exists_gzip(const std::string& filename);
99 100 bool dir_exists(const std::string& dirname);
100 101 bool is_infinite(const double& x);
101 102 bool is_notanumber(const double& x);
... ... @@ -135,7 +136,7 @@ namespace gammalib {
135 136 inline
136 137 bool gammalib::is_infinite(const double& x)
137 138 {
138   - return (x < -DBL_MAX || x > DBL_MAX);
  139 + return (x < -DBL_MAX || x > DBL_MAX);
139 140 }
140 141  
141 142  
... ... @@ -147,12 +148,12 @@ bool gammalib::is_infinite(const double&amp; x)
147 148 *
148 149 * Signals if the argument @p x is not a number.
149 150 *
150   - * This function is a very simple kludge. It may not work on all systems.
  151 + * This function is a very simple kluge. It may not work on all systems.
151 152 ***************************************************************************/
152 153 inline
153 154 bool gammalib::is_notanumber(const double& x)
154 155 {
155   - return (x != x);
  156 + return (x != x);
156 157 }
157 158  
158 159 #endif /* GTOOLS_HPP */
... ...
include/GVOHub.hpp
... ... @@ -108,11 +108,14 @@ protected:
108 108  
109 109 // Low-level methods
110 110 void create_samp_file(void) const;
  111 + void delete_samp_file(void) const;
  112 + int get_socket(void);
111 113 void post_samp_ok(const socklen_t& sock) const;
112 114 void post_samp_void(const socklen_t& sock) const;
113 115 void post_string(const std::string& content, const socklen_t& sock) const;
114 116 void notify(const std::string& url, const std::string& notification) const;
115 117 std::string random_string(const size_t& length) const;
  118 + std::string hub_url(void) const;
116 119  
117 120 // Protected structure
118 121 struct client {
... ... @@ -132,7 +135,6 @@ protected:
132 135  
133 136 // Protected members
134 137 std::string m_secret; //!< Secret Hub key
135   - std::string m_hub_url; //!< The XML-RPC endpoint for communication with the hub
136 138 std::string m_hub_host; //!< Hub host
137 139 std::string m_hub_port; //!< Hub port
138 140 std::string m_hub_path; //!< Hub path
... ...
include/GammaLib.hpp
... ... @@ -49,6 +49,7 @@
49 49 #include "GUrl.hpp"
50 50 #include "GUrlFile.hpp"
51 51 #include "GUrlString.hpp"
  52 +#include "GFilename.hpp"
52 53  
53 54 /* __ Linear algebra module ______________________________________________ */
54 55 #include "GVector.hpp"
... ...
include/Makefile.am
... ... @@ -13,6 +13,7 @@ pkginclude_HEADERS = GammaLib.hpp \
13 13 GUrl.hpp \
14 14 GUrlFile.hpp \
15 15 GUrlString.hpp \
  16 + GFilename.hpp \
16 17 GVector.hpp \
17 18 GMatrixBase.hpp \
18 19 GMatrix.hpp \
... ...
inst/cta/include/GCTAAeff2D.hpp
... ... @@ -75,8 +75,8 @@ public:
75 75 // Methods
76 76 const GCTAResponseTable& table(void) const;
77 77 void table(const GCTAResponseTable& table);
78   - void read(const GFits& file);
79   - void write(GFitsBinTable& hdu) const;
  78 + void read(const GFitsTable& table);
  79 + void write(GFitsBinTable& table) const;
80 80 void save(const std::string& filename,
81 81 const bool& clobber = false) const;
82 82  
... ...
inst/cta/include/GCTAAeffArf.hpp
... ... @@ -85,7 +85,7 @@ public:
85 85 const double& thetacut(void) const;
86 86 void scale(const double& scale);
87 87 const double& scale(void) const;
88   - void read(const GFitsTable& hdu);
  88 + void read(const GFitsTable& table);
89 89 void remove_thetacut(const GCTAResponseIrf& rsp);
90 90  
91 91 private:
... ...
inst/cta/include/GCTABackground3D.hpp
... ... @@ -75,8 +75,8 @@ public:
75 75 bool is_valid(void) const;
76 76 const GCTAResponseTable& table(void) const;
77 77 void table(const GCTAResponseTable& table);
78   - void read(const GFits& file);
79   - void write(GFitsBinTable& hdu) const;
  78 + void read(const GFitsTable& table);
  79 + void write(GFitsBinTable& table) const;
80 80 void save(const std::string& filename,
81 81 const bool& clobber = false) const;
82 82  
... ...
inst/cta/include/GCTAEdisp2D.hpp
... ... @@ -91,8 +91,8 @@ public:
91 91 // Methods
92 92 const GCTAResponseTable& table(void) const;
93 93 void table(const GCTAResponseTable& table);
94   - void read(const GFits& file);
95   - void write(GFitsBinTable& hdu) const;
  94 + void read(const GFitsTable& table);
  95 + void write(GFitsBinTable& table) const;
96 96 void save(const std::string& filename,
97 97 const bool& clobber = false) const;
98 98 private:
... ...
inst/cta/include/GCTAEventAtom.hpp
... ... @@ -72,10 +72,8 @@ public:
72 72 // Other methods
73 73 const int& index(void) const;
74 74 const unsigned long& event_id(void) const;
75   - const unsigned long& obs_id(void) const;
76 75 const float& phase(void) const;
77 76 void event_id(const unsigned long& id);
78   - void obs_id(const unsigned long& id);
79 77 void phase(const float& phase);
80 78  
81 79 protected:
... ... @@ -90,24 +88,6 @@ protected:
90 88 GEnergy m_energy; //!< Event energy
91 89 GTime m_time; //!< Event time
92 90 unsigned long m_event_id; //!< Event identifier
93   - unsigned long m_obs_id; //!< Observation identifier
94   - int m_multip; //!< Multiplicity
95   - char m_telmask; //!< Telescope mask
96   - float m_dir_err; //!< Error on event direction
97   - float m_alt; //!< Event altitude
98   - float m_az; //!< Event azimuth
99   - float m_corex; //!< Position on ground (m)
100   - float m_corey; //!< Position on ground (m)
101   - float m_core_err; //!< Error on core reconstruction
102   - float m_xmax; //!< Position of shower max (g/cm2)
103   - float m_xmax_err; //!< Error on shower max (g/cm2)
104   - float m_shwidth; //!< Shower width (m)
105   - float m_shlength; //!< Shower length (m)
106   - float m_energy_err; //!< Error on event energy (MeV)
107   - float m_hil_msw; //!< Hillas MSW
108   - float m_hil_msw_err; //!< Hillas MSW error
109   - float m_hil_msl; //!< Hillas MSL
110   - float m_hil_msl_err; //!< Hillas MSL error
111 91 float m_phase; //!< Optional phase
112 92 };
113 93  
... ... @@ -226,18 +206,6 @@ const unsigned long&amp; GCTAEventAtom::event_id(void) const
226 206  
227 207  
228 208 /***********************************************************************//**
229   - * @brief Return observation identifier
230   - *
231   - * @return Observation identifier.
232   - ***************************************************************************/
233   -inline
234   -const unsigned long& GCTAEventAtom::obs_id(void) const
235   -{
236   - return (m_obs_id);
237   -}
238   -
239   -
240   -/***********************************************************************//**
241 209 * @brief Return event phase
242 210 *
243 211 * @return Event phase.
... ... @@ -263,19 +231,6 @@ void GCTAEventAtom::event_id(const unsigned long&amp; id)
263 231  
264 232  
265 233 /***********************************************************************//**
266   - * @brief Set observation identifier
267   - *
268   - * @param[in] id Observation identifier.
269   - ***************************************************************************/
270   -inline
271   -void GCTAEventAtom::obs_id(const unsigned long& id)
272   -{
273   - m_obs_id = id;
274   - return;
275   -}
276   -
277   -
278   -/***********************************************************************//**
279 234 * @brief Set event phase
280 235 *
281 236 * @param[in] phase Event phase.
... ...
inst/cta/include/GCTAEventList.hpp
... ... @@ -88,19 +88,18 @@ protected:
88 88 void free_members(void);
89 89 virtual void set_energies(void) { return; }
90 90 virtual void set_times(void) { return; }
91   - void read_events(const GFitsTable& hdu);
92   - void read_events_v0(const GFitsTable& hdu);
93   - void read_events_v1(const GFitsTable& hdu);
94   - void read_events_hillas(const GFitsTable& hdu);
95   - void write_events(GFitsBinTable& hdu) const;
  91 + void read_events(const GFitsTable& table);
  92 + void write_events(GFitsBinTable& table) const;
96 93 void write_ds_keys(GFitsHDU& hdu) const;
97 94 int irf_cache_init(const std::string& name) const;
98 95 int irf_cache_index(const std::string& name) const;
99 96  
100 97 // Protected members
101   - GCTARoi m_roi; //!< Region of interest
102   - std::vector<GCTAEventAtom> m_events; //!< Events
103   - bool m_has_phase; //!< Signal presence of phase
  98 + GCTARoi m_roi; //!< Region of interest
  99 + std::vector<GCTAEventAtom> m_events; //!< Events
  100 + std::vector<GFitsTableCol*> m_columns; //!< Pointers to optional columns
  101 + bool m_has_phase; //!< Signal presence of phase
  102 + bool m_has_detxy; //!< Signal presence of detector coordinates
104 103  
105 104 // IRF cache for diffuse models
106 105 mutable std::vector<std::string> m_irf_names; //!< Model names
... ...
inst/cta/include/GCTAPointing.hpp
... ... @@ -61,8 +61,7 @@ public:
61 61 GCTAPointing(void);
62 62 explicit GCTAPointing(const GSkyDir& dir);
63 63 explicit GCTAPointing(const GXmlElement& xml);
64   - GCTAPointing(const std::string& filename,
65   - const std::string& extname = "POINTING");
  64 + explicit GCTAPointing(const std::string& filename);
66 65 GCTAPointing(const GCTAPointing& pnt);
67 66 virtual ~GCTAPointing(void);
68 67  
... ... @@ -83,8 +82,7 @@ public:
83 82 void zenith(const double& zenith);
84 83 void azimuth(const double& azimuth);
85 84 GHorizDir dir_horiz(const GTime& time) const;
86   - void load(const std::string& filename,
87   - const std::string& extname = "POINTING");
  85 + void load(const std::string& filename);
88 86 void read(const GFitsTable& table);
89 87 void read(const GXmlElement& xml);
90 88 void write(GXmlElement& xml) const;
... ...
inst/cta/include/GCTAPsf2D.hpp
... ... @@ -96,8 +96,8 @@ public:
96 96 // Methods
97 97 const GCTAResponseTable& table(void) const;
98 98 void table(const GCTAResponseTable& table);
99   - void read(const GFits& file);
100   - void write(GFitsBinTable& hdu) const;
  99 + void read(const GFitsTable& table);
  100 + void write(GFitsBinTable& table) const;
101 101 void save(const std::string& filename,
102 102 const bool& clobber = false) const;
103 103  
... ...
inst/cta/include/GCTAPsfKing.hpp
... ... @@ -94,8 +94,8 @@ public:
94 94 // Methods
95 95 const GCTAResponseTable& table(void) const;
96 96 void table(const GCTAResponseTable& table);
97   - void read(const GFits& file);
98   - void write(GFitsBinTable& hdu) const;
  97 + void read(const GFitsTable& table);
  98 + void write(GFitsBinTable& table) const;
99 99 void save(const std::string& filename,
100 100 const bool& clobber = false) const;
101 101  
... ...
inst/cta/pyext/GCTAAeff2D.i
... ... @@ -66,8 +66,8 @@ public:
66 66 // Methods
67 67 const GCTAResponseTable& table(void) const;
68 68 void table(const GCTAResponseTable& table);
69   - void read(const GFits& file);
70   - void write(GFitsBinTable& hdu) const;
  69 + void read(const GFitsTable& table);
  70 + void write(GFitsBinTable& table) const;
71 71 void save(const std::string& filename,
72 72 const bool& clobber = false) const;
73 73 };
... ...
inst/cta/pyext/GCTAAeffArf.i
... ... @@ -71,7 +71,7 @@ public:
71 71 const double& thetacut(void) const;
72 72 void scale(const double& scale);
73 73 const double& scale(void) const;
74   - void read(const GFitsTable& hdu);
  74 + void read(const GFitsTable& table);
75 75 void remove_thetacut(const GCTAResponseIrf& rsp);
76 76 };
77 77  
... ...
inst/cta/pyext/GCTABackground3D.i
... ... @@ -63,8 +63,8 @@ public:
63 63 bool is_valid(void) const;
64 64 const GCTAResponseTable& table(void) const;
65 65 void table(const GCTAResponseTable& table);
66   - void read(const GFits& file);
67   - void write(GFitsBinTable& hdu) const;
  66 + void read(const GFitsTable& table);
  67 + void write(GFitsBinTable& table) const;
68 68 void save(const std::string& filename,
69 69 const bool& clobber = false) const;
70 70 };
... ...
inst/cta/pyext/GCTAEdisp2D.i
... ... @@ -77,8 +77,8 @@ public:
77 77 // Methods
78 78 const GCTAResponseTable& table(void) const;
79 79 void table(const GCTAResponseTable& table);
80   - void read(const GFits& file);
81   - void write(GFitsBinTable& hdu) const;
  80 + void read(const GFitsTable& table);
  81 + void write(GFitsBinTable& table) const;
82 82 void save(const std::string& filename,
83 83 const bool& clobber = false) const;
84 84 };
... ...
inst/cta/pyext/GCTAEventAtom.i
... ... @@ -55,10 +55,8 @@ public:
55 55 // Other methods
56 56 const int& index(void) const;
57 57 const unsigned long& event_id(void) const;
58   - const unsigned long& obs_id(void) const;
59 58 const float& phase(void) const;
60 59 void event_id(const unsigned long& id);
61   - void obs_id(const unsigned long& id);
62 60 void phase(const float& phase);
63 61 };
64 62  
... ...
inst/cta/pyext/GCTAPointing.i
... ... @@ -40,8 +40,7 @@ public:
40 40 GCTAPointing(void);
41 41 explicit GCTAPointing(const GSkyDir& dir);
42 42 explicit GCTAPointing(const GXmlElement& xml);
43   - GCTAPointing(const std::string& filename,
44   - const std::string& extname = "POINTING");
  43 + explicit GCTAPointing(const std::string& filename);
45 44 GCTAPointing(const GCTAPointing& pnt);
46 45 virtual ~GCTAPointing(void);
47 46  
... ... @@ -59,8 +58,7 @@ public:
59 58 void zenith(const double& zenith);
60 59 void azimuth(const double& azimuth);
61 60 GHorizDir dir_horiz(const GTime& time) const;
62   - void load(const std::string& filename,
63   - const std::string& extname = "POINTING");
  61 + void load(const std::string& filename);
64 62 void read(const GFitsTable& table);
65 63 void read(const GXmlElement& xml);
66 64 void write(GXmlElement& xml) const;
... ...
inst/cta/pyext/GCTAPsf2D.i
... ... @@ -82,8 +82,8 @@ public:
82 82 // Methods
83 83 const GCTAResponseTable& table(void) const;
84 84 void table(const GCTAResponseTable& table);
85   - void read(const GFits& file);
86   - void write(GFitsBinTable& hdu) const;
  85 + void read(const GFitsTable& table);
  86 + void write(GFitsBinTable& table) const;
87 87 void save(const std::string& filename,
88 88 const bool& clobber = false) const;
89 89  
... ...
inst/cta/pyext/GCTAPsfKing.i
... ... @@ -81,6 +81,13 @@ public:
81 81 const double& zenith = 0.0,
82 82 const double& azimuth = 0.0,
83 83 const bool& etrue = true) const;
  84 + // Methods
  85 + const GCTAResponseTable& table(void) const;
  86 + void table(const GCTAResponseTable& table);
  87 + void read(const GFitsTable& table);
  88 + void write(GFitsBinTable& table) const;
  89 + void save(const std::string& filename,
  90 + const bool& clobber = false) const;
84 91 };
85 92  
86 93  
... ...
inst/cta/src/GCTAAeff2D.cpp
... ... @@ -30,13 +30,14 @@
30 30 #endif
31 31 #include "GTools.hpp"
32 32 #include "GException.hpp"
  33 +#include "GFilename.hpp"
33 34 #include "GFits.hpp"
34 35 #include "GFitsBinTable.hpp"
35 36 #include "GFitsTable.hpp"
36 37 #include "GCTAAeff2D.hpp"
37 38  
38 39 /* __ Method name definitions ____________________________________________ */
39   -#define G_READ "GCTAAeff2D::read(GFits&)"
  40 +#define G_READ "GCTAAeff2D::read(GFitsTable&)"
40 41  
41 42 /* __ Macros _____________________________________________________________ */
42 43  
... ... @@ -71,8 +72,7 @@ GCTAAeff2D::GCTAAeff2D(void) : GCTAAeff()
71 72 *
72 73 * @param[in] filename FITS file name.
73 74 *
74   - * Construct instance by loading the effective area information from a FITS
75   - * file.
  75 + * Constructs effective area from a FITS file.
76 76 ***************************************************************************/
77 77 GCTAAeff2D::GCTAAeff2D(const std::string& filename) : GCTAAeff()
78 78 {
... ... @@ -235,25 +235,23 @@ GCTAAeff2D* GCTAAeff2D::clone(void) const
235 235  
236 236  
237 237 /***********************************************************************//**
238   - * @brief Read effective area from FITS file
  238 + * @brief Read effective area from FITS table
239 239 *
240   - * @param[in] fits FITS file pointer.
  240 + * @param[in] table FITS table.
241 241 *
242 242 * @exception GException::invalid_value
243 243 * FITS file format differs from expectation.
244 244 *
245   - * Reads the effective area form the FITS file extension "EFFECTIVE AREA".
  245 + * Reads the effective area form the FITS @p table.
  246 + *
246 247 * The data are stored in m_aeff which is of type GCTAResponseTable. The
247 248 * energy axis will be set to log10, the offset angle axis to radians.
248 249 ***************************************************************************/
249   -void GCTAAeff2D::read(const GFits& fits)
  250 +void GCTAAeff2D::read(const GFitsTable& table)
250 251 {
251 252 // Clear response table
252 253 m_aeff.clear();
253 254  
254   - // Get effective area table
255   - const GFitsTable& table = *fits.table("EFFECTIVE AREA");
256   -
257 255 // Read effective area table
258 256 m_aeff.read(table);
259 257  
... ... @@ -289,23 +287,25 @@ void GCTAAeff2D::read(const GFits&amp; fits)
289 287  
290 288  
291 289 /***********************************************************************//**
292   - * @brief Write CTA effective area table into FITS binary table object.
  290 + * @brief Write effective area into FITS binary table
  291 + *
  292 + * @param[in] table FITS binary table.
293 293 *
294   - * @param[in] hdu FITS binary table.
  294 + * Writes effective area into the FITS binary @p table.
295 295 *
296   - * @todo Add necessary keywords.
  296 + * @todo Add keywords.
297 297 ***************************************************************************/
298   -void GCTAAeff2D::write(GFitsBinTable& hdu) const
  298 +void GCTAAeff2D::write(GFitsBinTable& table) const
299 299 {
300 300 // Create a copy of the response table
301   - GCTAResponseTable table(m_aeff);
  301 + GCTAResponseTable aeff(m_aeff);
302 302  
303 303 // Convert area from cm2 to m2
304   - table.scale(0, 1.0e-4);
305   - table.scale(1, 1.0e-4);
  304 + aeff.scale(0, 1.0e-4);
  305 + aeff.scale(1, 1.0e-4);
306 306  
307 307 // Write response table
308   - table.write(hdu);
  308 + aeff.write(table);
309 309  
310 310 // Return
311 311 return;
... ... @@ -315,20 +315,32 @@ void GCTAAeff2D::write(GFitsBinTable&amp; hdu) const
315 315 /***********************************************************************//**
316 316 * @brief Load effective area from FITS file
317 317 *
318   - * @param[in] filename FITS file.
  318 + * @param[in] filename FITS file name.
  319 + *
  320 + * Loads the effective area from a FITS file.
319 321 *
320   - * This method loads the effective area information from a FITS file.
  322 + * If no extension name is provided, the effective area will be loaded from
  323 + * the "EFFECTIVE AREA" extension.
321 324 ***************************************************************************/
322 325 void GCTAAeff2D::load(const std::string& filename)
323 326 {
  327 + // Create file name
  328 + GFilename fname(filename);
  329 +
  330 + // Allocate FITS file
  331 + GFits file;
  332 +
324 333 // Open FITS file
325   - GFits fits(filename);
  334 + file.open(fname.filename());
  335 +
  336 + // Get effective area table
  337 + const GFitsTable& table = *file.table(fname.extname("EFFECTIVE AREA"));
326 338  
327   - // Read effective area from file
328   - read(fits);
  339 + // Read effective area from table
  340 + read(table);
329 341  
330 342 // Close FITS file
331   - fits.close();
  343 + file.close();
332 344  
333 345 // Store filename
334 346 m_filename = filename;
... ... @@ -339,18 +351,24 @@ void GCTAAeff2D::load(const std::string&amp; filename)
339 351  
340 352  
341 353 /***********************************************************************//**
342   - * @brief Save effectiva area table into FITS file
  354 + * @brief Save effectiva area into FITS file
343 355 *
344   - * @param[in] filename Effective area table FITS file name.
345   - * @param[in] clobber Overwrite existing file? (true=yes)
  356 + * @param[in] filename FITS file name.
  357 + * @param[in] clobber Overwrite existing file? (default: false)
  358 + *
  359 + * Save the effectiva area into a FITS file.
346 360 *
347   - * Save the effectiva area table into a FITS file.
  361 + * If no extension name is provided, the effective area will be saved into
  362 + * the "EFFECTIVE AREA" extension.
348 363 ***************************************************************************/
349 364 void GCTAAeff2D::save(const std::string& filename, const bool& clobber) const
350 365 {
  366 + // Create file name
  367 + GFilename fname(filename);
  368 +
351 369 // Create binary table
352 370 GFitsBinTable table;
353   - table.extname("EFFECTIVE AREA");
  371 + table.extname(fname.extname("EFFECTIVE AREA"));
354 372  
355 373 // Write the Effective area table
356 374 write(table);
... ... @@ -358,7 +376,7 @@ void GCTAAeff2D::save(const std::string&amp; filename, const bool&amp; clobber) const
358 376 // Create FITS file, append table, and write into the file
359 377 GFits fits;
360 378 fits.append(table);
361   - fits.saveto(filename, clobber);
  379 + fits.saveto(fname.filename(), clobber);
362 380  
363 381 // Return
364 382 return;
... ...
inst/cta/src/GCTAAeffArf.cpp
... ... @@ -31,6 +31,7 @@
31 31 #include "GTools.hpp"
32 32 #include "GMath.hpp"
33 33 #include "GIntegral.hpp"
  34 +#include "GFilename.hpp"
34 35 #include "GFitsTable.hpp"
35 36 #include "GFitsTableCol.hpp"
36 37 #include "GCTAAeffArf.hpp"
... ... @@ -74,8 +75,7 @@ GCTAAeffArf::GCTAAeffArf(void) : GCTAAeff()
74 75 *
75 76 * @param[in] filename ARF FITS file name.
76 77 *
77   - * Construct instance by loading the effective area information from an
78   - * ARF FITS file.
  78 + * Constructs effective area from an ARF FITS file.
79 79 ***************************************************************************/
80 80 GCTAAeffArf::GCTAAeffArf(const std::string& filename) : GCTAAeff()
81 81 {
... ... @@ -238,25 +238,33 @@ GCTAAeffArf* GCTAAeffArf::clone(void) const
238 238  
239 239  
240 240 /***********************************************************************//**
241   - * @brief Load effective area from performance table
  241 + * @brief Load effective area from ARF FITS file
242 242 *
243   - * @param[in] filename Performance table file name.
  243 + * @param[in] filename ARF FITS file name.
  244 + *
  245 + * Loads the effective area from an ARF FITS file.
244 246 *
245   - * This method loads the effective area information from an ASCII
246   - * performance table.
  247 + * If no extension name is provided, the effective area will be loaded from
  248 + * the "SPECRESP" extension.
247 249 ***************************************************************************/
248 250 void GCTAAeffArf::load(const std::string& filename)
249 251 {
250   - // Open ARF FITS file
251   - GFits file(filename);
  252 + // Create file name
  253 + GFilename fname(filename);
  254 +
  255 + // Allocate FITS file
  256 + GFits file;
  257 +
  258 + // Open FITS file
  259 + file.open(fname.filename());
252 260  
253 261 // Get ARF table
254   - const GFitsTable& table = *file.table("SPECRESP");
  262 + const GFitsTable& table = *file.table(fname.extname("SPECRESP"));
255 263  
256   - // Read ARF
  264 + // Read ARF from table
257 265 read(table);
258 266  
259   - // Close ARF FITS file
  267 + // Close FITS file
260 268 file.close();
261 269  
262 270 // Store filename
... ... @@ -270,11 +278,12 @@ void GCTAAeffArf::load(const std::string&amp; filename)
270 278 /***********************************************************************//**
271 279 * @brief Read CTA ARF vector
272 280 *
273   - * @param[in] hdu FITS table.
  281 + * @param[in] table FITS table.
  282 + *
  283 + * Reads a CTA ARF vector from the FITS @p table.
274 284 *
275   - * This method reads a CTA ARF vector from the FITS HDU. Note that the
276   - * energies are converted to TeV and the effective area is converted to cm2.
277   - * Conversion is done based on the units provided for the energy and
  285 + * The energies are converted to TeV and the effective area is converted to
  286 + * cm2. Conversion is done based on the units provided for the energy and
278 287 * effective area columns. Units that are recognized are 'keV', 'MeV', 'GeV',
279 288 * 'TeV', 'm^2', 'm2', 'cm^2' and 'cm^2' (case independent).
280 289 *
... ... @@ -282,16 +291,16 @@ void GCTAAeffArf::load(const std::string&amp; filename)
282 291 * For appropriate theta angle assignment, we would need this
283 292 * information in the response header.
284 293 ***************************************************************************/
285   -void GCTAAeffArf::read(const GFitsTable& hdu)
  294 +void GCTAAeffArf::read(const GFitsTable& table)
286 295 {
287 296 // Clear arrays
288 297 m_logE.clear();
289 298 m_aeff.clear();
290 299  
291 300 // Get pointers to table columns
292   - const GFitsTableCol* energy_lo = hdu["ENERG_LO"];
293   - const GFitsTableCol* energy_hi = hdu["ENERG_HI"];
294   - const GFitsTableCol* specresp = hdu["SPECRESP"];
  301 + const GFitsTableCol* energy_lo = table["ENERG_LO"];
  302 + const GFitsTableCol* energy_hi = table["ENERG_HI"];
  303 + const GFitsTableCol* specresp = table["SPECRESP"];
295 304  
296 305 // Determine unit conversion factors (default: TeV and cm^2)
297 306 std::string u_energy_lo = gammalib::tolower(gammalib::strip_whitespace(energy_lo->unit()));
... ...
inst/cta/src/GCTABackground3D.cpp
... ... @@ -30,13 +30,14 @@
30 30 #endif
31 31 #include "GTools.hpp"
32 32 #include "GException.hpp"
  33 +#include "GFilename.hpp"
33 34 #include "GMath.hpp"
34 35 #include "GFits.hpp"
35 36 #include "GFitsBinTable.hpp"
36 37 #include "GCTABackground3D.hpp"
37 38  
38 39 /* __ Method name definitions ____________________________________________ */
39   -#define G_READ "GCTABackground3D::read(GFits&)"
  40 +#define G_READ "GCTABackground3D::read(GFitsTable&)"
40 41 #define G_MC "GCTABackground3D::mc(GEnergy&, GTime&, GRan&)"
41 42 #define G_INIT_MC_CACHE "GCTABackground3D::init_mc_cache()"
42 43  
... ... @@ -76,7 +77,7 @@ GCTABackground3D::GCTABackground3D(void) : GCTABackground()
76 77 *
77 78 * @param[in] filename FITS file name.
78 79 *
79   - * Construct instance by loading the background information from a FITS file.
  80 + * Constructs background from a FITS file.
80 81 ***************************************************************************/
81 82 GCTABackground3D::GCTABackground3D(const std::string& filename) :
82 83 GCTABackground()
... ... @@ -303,26 +304,24 @@ GCTABackground3D* GCTABackground3D::clone(void) const
303 304  
304 305  
305 306 /***********************************************************************//**
306   - * @brief Read background from FITS file
  307 + * @brief Read background from FITS table
307 308 *
308   - * @param[in] fits FITS file pointer.
  309 + * @param[in] table FITS table.
309 310 *
310 311 * @exception GException::invalid_value
311 312 * FITS file format differs from expectation.
312 313 *
313   - * Reads the background from the FITS file extension "BACKGROUND". The data
314   - * are stored in m_background which is of type GCTAResponseTable. The DETX
315   - * and DETY axes will be set to radians, the energy axis will be set to
316   - * log10.
  314 + * Reads the background from the FITS @p table.
  315 + *
  316 + * The data are stored in m_background which is of type GCTAResponseTable.
  317 + * The DETX and DETY axes will be set to radians, the energy axis will be set
  318 + * to log10.
317 319 ***************************************************************************/
318   -void GCTABackground3D::read(const GFits& fits)
  320 +void GCTABackground3D::read(const GFitsTable& table)
319 321 {
320 322 // Clear response table
321 323 m_background.clear();
322 324  
323   - // Get background table
324   - const GFitsTable& table = *fits.table("BACKGROUND");
325   -
326 325 // Read background table
327 326 m_background.read(table);
328 327  
... ... @@ -361,16 +360,18 @@ void GCTABackground3D::read(const GFits&amp; fits)
361 360 }
362 361  
363 362 /***********************************************************************//**
364   - * @brief Write CTA background table into FITS binary table object.
  363 + * @brief Write background into FITS table
365 364 *
366   - * @param[in] hdu FITS binary table.
  365 + * @param[in] table FITS binary table.
  366 + *
  367 + * Writes background into a FITS binary @p table.
367 368 *
368 369 * @todo Add necessary keywords.
369 370 ***************************************************************************/
370   -void GCTABackground3D::write(GFitsBinTable& hdu) const
  371 +void GCTABackground3D::write(GFitsBinTable& table) const
371 372 {
372 373 // Write background table
373   - m_background.write(hdu);
  374 + m_background.write(table);
374 375  
375 376 // Return
376 377 return;
... ... @@ -380,20 +381,32 @@ void GCTABackground3D::write(GFitsBinTable&amp; hdu) const
380 381 /***********************************************************************//**
381 382 * @brief Load background from FITS file
382 383 *
383   - * @param[in] filename FITS file.
  384 + * @param[in] filename FITS file name.
  385 + *
  386 + * Loads the background from a FITS file.
384 387 *
385   - * This method loads the background information from a FITS file.
  388 + * If no extension name is provided, the background will be loaded from the
  389 + * "BACKGROUND" extension.
386 390 ***************************************************************************/
387 391 void GCTABackground3D::load(const std::string& filename)
388 392 {
  393 + // Create file name
  394 + GFilename fname(filename);
  395 +
  396 + // Allocate FITS file
  397 + GFits file;
  398 +
389 399 // Open FITS file
390   - GFits fits(filename);
  400 + file.open(fname.filename());
  401 +
  402 + // Get background table
  403 + const GFitsTable& table = *file.table(fname.extname("BACKGROUND"));
391 404  
392   - // Read background from file
393   - read(fits);
  405 + // Read effective area from table
  406 + read(table);
394 407  
395 408 // Close FITS file
396   - fits.close();
  409 + file.close();
397 410  
398 411 // Store filename
399 412 m_filename = filename;
... ... @@ -404,18 +417,24 @@ void GCTABackground3D::load(const std::string&amp; filename)
404 417  
405 418  
406 419 /***********************************************************************//**
407   - * @brief Save background table into FITS file
  420 + * @brief Save background into FITS file
408 421 *
409 422 * @param[in] filename background table FITS file name.
410   - * @param[in] clobber Overwrite existing file? (true=yes)
  423 + * @param[in] clobber Overwrite existing file? (default: false)
  424 + *
  425 + * Save the background into a FITS file.
411 426 *
412   - * Save the background table into a FITS file.
  427 + * If no extension name is provided, the background will be saved into the
  428 + * "BACKGROUND" extension.
413 429 ***************************************************************************/
414 430 void GCTABackground3D::save(const std::string& filename, const bool& clobber) const
415 431 {
  432 + // Create file name
  433 + GFilename fname(filename);
  434 +
416 435 // Create binary table
417 436 GFitsBinTable table;
418   - table.extname("BACKGROUND");
  437 + table.extname(fname.extname("BACKGROUND"));
419 438  
420 439 // Write the background table
421 440 write(table);
... ... @@ -423,7 +442,7 @@ void GCTABackground3D::save(const std::string&amp; filename, const bool&amp; clobber) co
423 442 // Create FITS file, append table, and write into the file
424 443 GFits fits;
425 444 fits.append(table);
426   - fits.saveto(filename, clobber);
  445 + fits.saveto(fname.filename(), clobber);
427 446  
428 447 // Return
429 448 return;
... ...
inst/cta/src/GCTAEdisp2D.cpp
... ... @@ -33,6 +33,7 @@
33 33 #include "GTools.hpp"
34 34 #include "GMath.hpp"
35 35 #include "GIntegral.hpp"
  36 +#include "GFilename.hpp"
36 37 #include "GFits.hpp"
37 38 #include "GFitsTable.hpp"
38 39 #include "GFitsBinTable.hpp"
... ... @@ -73,8 +74,7 @@ GCTAEdisp2D::GCTAEdisp2D(void) : GCTAEdisp()
73 74 *
74 75 * @param[in] filename FITS file name.
75 76 *
76   - * Construct instance by loading the energy dispersion information from a
77   - * FITS file.
  77 + * Constructs energy dispersion from a FITS file.
78 78 ***************************************************************************/
79 79 GCTAEdisp2D::GCTAEdisp2D(const std::string& filename) : GCTAEdisp()
80 80 {
... ... @@ -232,20 +232,32 @@ GCTAEdisp2D* GCTAEdisp2D::clone(void) const
232 232 /***********************************************************************//**
233 233 * @brief Load energy dispersion from FITS file
234 234 *
235   - * @param[in] filename FITS file.
  235 + * @param[in] filename FITS file name.
  236 + *
  237 + * Loads the energy dispersion from a FITS file.
236 238 *
237   - * This method loads the energy dispersion information from a FITS file.
  239 + * If no extension name is provided, the energy dispersion will be loaded
  240 + * from the "ENERGY DISPERSION" extension.
238 241 ***************************************************************************/
239 242 void GCTAEdisp2D::load(const std::string& filename)
240 243 {
  244 + // Create file name
  245 + GFilename fname(filename);
  246 +
  247 + // Allocate FITS file
  248 + GFits file;
  249 +
241 250 // Open FITS file
242   - GFits fits(filename);
  251 + file.open(fname.filename());
243 252  
244   - // Read energy dispersion from file
245   - read(fits);
  253 + // Get energy dispersion table
  254 + const GFitsTable& table = *file.table(fname.extname("ENERGY DISPERSION"));
  255 +
  256 + // Read energy dispersion from table
  257 + read(table);
246 258  
247 259 // Close FITS file
248   - fits.close();
  260 + file.close();
249 261  
250 262 // Store filename
251 263 m_filename = filename;
... ... @@ -256,26 +268,22 @@ void GCTAEdisp2D::load(const std::string&amp; filename)
256 268  
257 269  
258 270 /***********************************************************************//**
259   - * @brief Read energy dispersion from FITS file
  271 + * @brief Read energy dispersion from FITS table
  272 + *
  273 + * @param[in] table FITS table.
260 274 *
261   - * @param[in] fits FITS file pointer.
  275 + * Reads the energy dispersion form the FITS @p table.
262 276 *
263   - * Reads the energy dispersion form the FITS file extension
264   - * "ENERGY DISPERSION". The data are stored in m_edisp which is of type
265   - * GCTAResponseTable. The energy axis will be set to log10, the offset
266   - * angle axis to radians.
  277 + * The data are stored in m_edisp which is of type GCTAResponseTable. The
  278 + * energy axis will be set to log10, the offset angle axis to radians.
267 279 *
268   - * The method assures that the energy dispersion information is properly
269   - * normalised.
  280 + * The method assures that the energy dispersion is properly normalised.
270 281 ***************************************************************************/
271   -void GCTAEdisp2D::read(const GFits& fits)
  282 +void GCTAEdisp2D::read(const GFitsTable& table)
272 283 {
273 284 // Clear response table
274 285 m_edisp.clear();
275 286  
276   - // Get energy dispersion table
277   - const GFitsTable& table = *fits.table("ENERGY DISPERSION");
278   -
279 287 // Read energy dispersion table
280 288 m_edisp.read(table);
281 289  
... ... @@ -373,16 +381,18 @@ void GCTAEdisp2D::read(const GFits&amp; fits)
373 381  
374 382  
375 383 /***********************************************************************//**
376   - * @brief Write CTA energy dispersion table into FITS binary table object.
  384 + * @brief Write energy dispersion into FITS binary table
  385 + *
  386 + * @param[in] table FITS binary table.
377 387 *
378   - * @param[in] hdu FITS binary table.
  388 + * Writes the energy dispersion into the FITS binary @p table.
379 389 *
380   - * @todo Add necessary keywords.
  390 + * @todo Add keywords.
381 391 ***************************************************************************/
382   -void GCTAEdisp2D::write(GFitsBinTable& hdu) const
  392 +void GCTAEdisp2D::write(GFitsBinTable& table) const
383 393 {
384 394 // Write background table
385   - m_edisp.write(hdu);
  395 + m_edisp.write(table);
386 396  
387 397 // Return
388 398 return;
... ... @@ -392,24 +402,30 @@ void GCTAEdisp2D::write(GFitsBinTable&amp; hdu) const
392 402 /***********************************************************************//**
393 403 * @brief Save energy dispersion table into FITS file
394 404 *
395   - * @param[in] filename Energy dispersion table FITS file name.
396   - * @param[in] clobber Overwrite existing file? (true=yes)
  405 + * @param[in] filename FITS file name.
  406 + * @param[in] clobber Overwrite existing file? (default: false)
  407 + *
  408 + * Save the energy dispersion table into FITS file.
397 409 *
398   - * Save the energy dispersion table into a FITS file.
  410 + * If no extension name is provided, the energy dispersion will be saved into
  411 + * the "ENERGY DISPERSION" extension.
399 412 ***************************************************************************/
400 413 void GCTAEdisp2D::save(const std::string& filename, const bool& clobber) const
401 414 {
  415 + // Create file name
  416 + GFilename fname(filename);
  417 +
402 418 // Create binary table
403 419 GFitsBinTable table;
404   - table.extname("ENERGY DISPERSION");
  420 + table.extname(fname.extname("ENERGY DISPERSION"));
405 421  
406   - // Write the Energy dispersion table
  422 + // Write the energy dispersion table
407 423 write(table);
408 424  
409 425 // Create FITS file, append table, and write into the file
410 426 GFits fits;
411 427 fits.append(table);
412   - fits.saveto(filename, clobber);
  428 + fits.saveto(fname.filename(), clobber);
413 429  
414 430 // Return
415 431 return;
... ...
inst/cta/src/GCTAEventAtom.cpp
... ... @@ -207,27 +207,9 @@ void GCTAEventAtom::init_members(void)
207 207 m_dir.clear();
208 208 m_time.clear();
209 209 m_energy.clear();
210   - m_index = 0;
211   - m_event_id = 0;
212   - m_obs_id = 0;
213   - m_multip = 0;
214   - m_telmask = 0;
215   - m_dir_err = 0.0;
216   - m_alt = 0.0;
217   - m_az = 0.0;
218   - m_corex = 0.0;
219   - m_corey = 0.0;
220   - m_core_err = 0.0;
221   - m_xmax = 0.0;
222   - m_xmax_err = 0.0;
223   - m_shwidth = 0.0;
224   - m_shlength = 0.0;
225   - m_energy_err = 0.0;
226   - m_hil_msw = 0.0;
227   - m_hil_msw_err = 0.0;
228   - m_hil_msl = 0.0;
229   - m_hil_msl_err = 0.0;
230   - m_phase = 0.0;
  210 + m_index = 0;
  211 + m_event_id = 0;
  212 + m_phase = 0.0;
231 213  
232 214 // Return
233 215 return;
... ... @@ -242,30 +224,12 @@ void GCTAEventAtom::init_members(void)
242 224 void GCTAEventAtom::copy_members(const GCTAEventAtom& atom)
243 225 {
244 226 // Copy members
245   - m_dir = atom.m_dir;
246   - m_time = atom.m_time;
247   - m_energy = atom.m_energy;
248   - m_index = atom.m_index;
249   - m_event_id = atom.m_event_id;
250   - m_obs_id = atom.m_obs_id;
251   - m_multip = atom.m_multip;
252   - m_telmask = atom.m_telmask;
253   - m_dir_err = atom.m_dir_err;
254   - m_alt = atom.m_alt;
255   - m_az = atom.m_az;
256   - m_corex = atom.m_corex;
257   - m_corey = atom.m_corey;
258   - m_core_err = atom.m_core_err;
259   - m_xmax = atom.m_xmax;
260   - m_xmax_err = atom.m_xmax_err;
261   - m_shwidth = atom.m_shwidth;
262   - m_shlength = atom.m_shlength;
263   - m_energy_err = atom.m_energy_err;
264   - m_hil_msw = atom.m_hil_msw;
265   - m_hil_msw_err = atom.m_hil_msw_err;
266   - m_hil_msl = atom.m_hil_msl;
267   - m_hil_msl_err = atom.m_hil_msl_err;
268   - m_phase = atom.m_phase;
  227 + m_dir = atom.m_dir;
  228 + m_time = atom.m_time;
  229 + m_energy = atom.m_energy;
  230 + m_index = atom.m_index;
  231 + m_event_id = atom.m_event_id;
  232 + m_phase = atom.m_phase;
269 233  
270 234 // Return
271 235 return;
... ...
inst/cta/src/GCTAEventCube.cpp
... ... @@ -436,8 +436,11 @@ int GCTAEventCube::number(void) const
436 436  
437 437 // Sum event cube
438 438 if (size() > 0 && pixels != NULL) {
439   - for (int i = 0; i < size(); ++i)
440   - number += pixels[i];
  439 + for (int i = 0; i < size(); ++i) {
  440 + if (pixels[i] > 0.0) {
  441 + number += pixels[i];
  442 + }
  443 + }
441 444 }
442 445  
443 446 // Return
... ...
inst/cta/src/GCTAEventList.cpp
... ... @@ -572,7 +572,9 @@ void GCTAEventList::init_members(void)
572 572 // Initialise members
573 573 m_roi.clear();
574 574 m_events.clear();
  575 + m_columns.clear();
575 576 m_has_phase = false;
  577 + m_has_detxy = true;
576 578  
577 579 // Initialise cache
578 580 m_irf_names.clear();
... ... @@ -594,11 +596,18 @@ void GCTAEventList::copy_members(const GCTAEventList&amp; list)
594 596 m_roi = list.m_roi;
595 597 m_events = list.m_events;
596 598 m_has_phase = list.m_has_phase;
  599 + m_has_detxy = list.m_has_detxy;
597 600  
598 601 // Copy cache
599 602 m_irf_names = list.m_irf_names;
600 603 m_irf_values = list.m_irf_values;
601 604  
  605 + // Copy column pointers
  606 + m_columns.clear();
  607 + for (int i = 0; i < list.m_columns.size(); ++i) {
  608 + m_columns.push_back((list.m_columns[i]->clone()));
  609 + }
  610 +
602 611 // Return
603 612 return;
604 613 }
... ... @@ -609,6 +618,12 @@ void GCTAEventList::copy_members(const GCTAEventList&amp; list)
609 618 ***************************************************************************/
610 619 void GCTAEventList::free_members(void)
611 620 {
  621 + // Free columns
  622 + for (int i = 0; i < m_columns.size(); ++i) {
  623 + delete m_columns[i];
  624 + m_columns[i] = NULL;
  625 + }
  626 +
612 627 // Return
613 628 return;
614 629 }
... ... @@ -619,52 +634,26 @@ void GCTAEventList::free_members(void)
619 634 *
620 635 * @param[in] table FITS table.
621 636 *
622   - * This method reads the CTA event list from a FITS table HDU into memory.
623   - * Depending on the columns existing in the file, it either selects v0 or
624   - * v1 of the event list reader.
625   - ***************************************************************************/
626   -void GCTAEventList::read_events(const GFitsTable& table)
627   -{
628   - // Clear existing events
629   - m_events.clear();
630   -
631   - // Extract number of events in FITS file
632   - int num = table.integer("NAXIS2");
633   -
634   - // Continue only if there are events
635   - if (num > 0) {
636   -
637   - // Read events for v1
638   - if (table.contains("SHWIDTH") && table.contains("SHLENGTH")) {
639   - read_events_v1(table);
640   - }
641   -
642   - // ... otherwise read events for v0
643   - else {
644   - read_events_v0(table);
645   - }
646   -
647   - // Read (optional) Hillas parameters
648   - read_events_hillas(table);
649   -
650   - } // endif: there were events
651   -
652   - // Return
653   - return;
654   -}
655   -
656   -
657   -/***********************************************************************//**
658   - * @brief Read CTA events from FITS table (version 0)
  637 + * This method reads the CTA event list from a FITS table into memory.
  638 + * The following columns are mandatory in the FITS table:
659 639 *
660   - * @param[in] table FITS table.
  640 + * - EVENT_ID
  641 + * - TIME
  642 + * - RA
  643 + * - DEC
  644 + * - ENERGY
  645 + *
  646 + * Optionally, the
661 647 *
662   - * This method reads the CTA event list from a FITS table HDU into memory.
663   - * It is a minimal event reader that is compliant with the initial data
664   - * format distributed by Karl Kosack. Information that is not present in
665   - * that format is set to 0.
  648 + * - DETX
  649 + * - DETY
  650 + * - PHASE
  651 + *
  652 + * columns are read. Any other columns present in the FITS table will also be
  653 + * read, and written into the FITS table when the write_events() method is
  654 + * called.
666 655 ***************************************************************************/
667   -void GCTAEventList::read_events_v0(const GFitsTable& table)
  656 +void GCTAEventList::read_events(const GFitsTable& table)
668 657 {
669 658 // Clear existing events
670 659 m_events.clear();
... ... @@ -679,120 +668,25 @@ void GCTAEventList::read_events_v0(const GFitsTable&amp; table)
679 668 m_events.reserve(num);
680 669  
681 670 // Get column pointers
682   - const GFitsTableCol* ptr_eid = table["EVENT_ID"];
683   - const GFitsTableCol* ptr_time = table["TIME"];
684   - const GFitsTableCol* ptr_multip = table["MULTIP"];
685   - const GFitsTableCol* ptr_ra = table["RA"];
686   - const GFitsTableCol* ptr_dec = table["DEC"];
687   - const GFitsTableCol* ptr_dir_err = table["DIR_ERR"];
688   - const GFitsTableCol* ptr_detx = table["DETX"];
689   - const GFitsTableCol* ptr_dety = table["DETY"];
690   - const GFitsTableCol* ptr_alt = table["ALT"];
691   - const GFitsTableCol* ptr_az = table["AZ"];
692   - const GFitsTableCol* ptr_corex = table["COREX"];
693   - const GFitsTableCol* ptr_corey = table["COREY"];
694   - const GFitsTableCol* ptr_core_err = table["CORE_ERR"];
695   - const GFitsTableCol* ptr_xmax = table["XMAX"];
696   - const GFitsTableCol* ptr_xmax_err = table["XMAX_ERR"];
697   - const GFitsTableCol* ptr_energy = table["ENERGY"];
698   - const GFitsTableCol* ptr_energy_err = table["ENERGY_ERR"];
699   -
700   - // Check for phase column
701   - const GFitsTableCol* ptr_phase;
702   - if (table.contains("PHASE")) {
703   - m_has_phase = true;
704   - ptr_phase = table["PHASE"];
  671 + const GFitsTableCol* ptr_eid = table["EVENT_ID"];
  672 + const GFitsTableCol* ptr_time = table["TIME"];
  673 + const GFitsTableCol* ptr_ra = table["RA"];
  674 + const GFitsTableCol* ptr_dec = table["DEC"];
  675 + const GFitsTableCol* ptr_energy = table["ENERGY"];
  676 +
  677 + // Check for DETX and DETY columns
  678 + const GFitsTableCol* ptr_detx;
  679 + const GFitsTableCol* ptr_dety;
  680 + if (table.contains("DETX") && table.contains("DETY")) {
  681 + m_has_detxy = true;
  682 + ptr_detx = table["DETX"];
  683 + ptr_dety = table["DETY"];
705 684 }
706 685 else {
707   - m_has_phase = false;
708   - }
709   -
710   - // Copy data from columns into GCTAEventAtom objects
711   - GCTAEventAtom event;
712   - for (int i = 0; i < num; ++i) {
713   - event.m_index = i;
714   - event.m_time.set(ptr_time->real(i), m_gti.reference());
715   - event.m_dir.dir().radec_deg(ptr_ra->real(i), ptr_dec->real(i));
716   - event.m_dir.detx(ptr_detx->real(i)*gammalib::deg2rad);
717   - event.m_dir.dety(ptr_dety->real(i)*gammalib::deg2rad);
718   - event.m_energy.TeV(ptr_energy->real(i));
719   - event.m_event_id = ptr_eid->integer(i);
720   - event.m_obs_id = 0;
721   - event.m_multip = ptr_multip->integer(i);
722   - event.m_telmask = 0;
723   - event.m_dir_err = ptr_dir_err->real(i);
724   - event.m_alt = ptr_alt->real(i);
725   - event.m_az = ptr_az->real(i);
726   - event.m_corex = ptr_corex->real(i);
727   - event.m_corey = ptr_corey->real(i);
728   - event.m_core_err = ptr_core_err->real(i);
729   - event.m_xmax = ptr_xmax->real(i);
730   - event.m_xmax_err = ptr_xmax_err->real(i);
731   - event.m_shwidth = 0.0;
732   - event.m_shlength = 0.0;
733   - event.m_energy_err = ptr_energy_err->real(i);
734   -
735   - // Set pulse phase if available
736   - if (m_has_phase) {
737   - event.m_phase = ptr_phase->real(i);
738   - }
739   -
740   - m_events.push_back(event);
  686 + m_has_detxy = false;
741 687 }
742 688  
743   - } // endif: there were events
744   -
745   - // Return
746   - return;
747   -}
748   -
749   -
750   -/***********************************************************************//**
751   - * @brief Read CTA events from FITS table (version 1)
752   - *
753   - * @param[in] table FITS table.
754   - *
755   - * This method reads the CTA event list from a FITS table HDU into memory.
756   - *
757   - * @todo Implement agreed column format
758   - ***************************************************************************/
759   -void GCTAEventList::read_events_v1(const GFitsTable& table)
760   -{
761   - // Clear existing events
762   - m_events.clear();
763   -
764   - // Extract number of events in FITS file
765   - int num = table.nrows();
766   -
767   - // If there are events then load them
768   - if (num > 0) {
769   -
770   - // Reserve data
771   - m_events.reserve(num);
772   -
773   - // Get column pointers
774   - const GFitsTableCol* ptr_eid = table["EVENT_ID"];
775   - const GFitsTableCol* ptr_oid = table["OBS_ID"];
776   - const GFitsTableCol* ptr_time = table["TIME"];
777   - const GFitsTableCol* ptr_multip = table["MULTIP"];
778   - const GFitsTableCol* ptr_ra = table["RA"];
779   - const GFitsTableCol* ptr_dec = table["DEC"];
780   - const GFitsTableCol* ptr_dir_err = table["DIR_ERR"];
781   - const GFitsTableCol* ptr_detx = table["DETX"];
782   - const GFitsTableCol* ptr_dety = table["DETY"];
783   - const GFitsTableCol* ptr_alt = table["ALT"];
784   - const GFitsTableCol* ptr_az = table["AZ"];
785   - const GFitsTableCol* ptr_corex = table["COREX"];
786   - const GFitsTableCol* ptr_corey = table["COREY"];
787   - const GFitsTableCol* ptr_core_err = table["CORE_ERR"];
788   - const GFitsTableCol* ptr_xmax = table["XMAX"];
789   - const GFitsTableCol* ptr_xmax_err = table["XMAX_ERR"];
790   - const GFitsTableCol* ptr_shw = table["SHWIDTH"];
791   - const GFitsTableCol* ptr_shl = table["SHLENGTH"];
792   - const GFitsTableCol* ptr_energy = table["ENERGY"];
793   - const GFitsTableCol* ptr_energy_err = table["ENERGY_ERR"];
794   -
795   - // Check for phase column
  689 + // Check for PHASE column
796 690 const GFitsTableCol* ptr_phase;
797 691 if (table.contains("PHASE")) {
798 692 m_has_phase = true;
... ... @@ -805,98 +699,57 @@ void GCTAEventList::read_events_v1(const GFitsTable&amp; table)
805 699 // Copy data from columns into GCTAEventAtom objects
806 700 GCTAEventAtom event;
807 701 for (int i = 0; i < num; ++i) {
808   - event.m_index = i;
  702 +
  703 + // Set mandatory information
809 704 event.m_time.set(ptr_time->real(i), m_gti.reference());
810 705 event.m_dir.dir().radec_deg(ptr_ra->real(i), ptr_dec->real(i));
811   - event.m_dir.detx(ptr_detx->real(i)*gammalib::deg2rad);
812   - event.m_dir.dety(ptr_dety->real(i)*gammalib::deg2rad);
813 706 event.m_energy.TeV(ptr_energy->real(i));
814   - event.m_event_id = ptr_eid->integer(i);
815   - event.m_obs_id = ptr_oid->integer(i);
816   - event.m_multip = ptr_multip->integer(i);
817   - event.m_telmask = 0;
818   - event.m_dir_err = ptr_dir_err->real(i);
819   - event.m_alt = ptr_alt->real(i);
820   - event.m_az = ptr_az->real(i);
821   - event.m_corex = ptr_corex->real(i);
822   - event.m_corey = ptr_corey->real(i);
823   - event.m_core_err = ptr_core_err->real(i);
824   - event.m_xmax = ptr_xmax->real(i);
825   - event.m_xmax_err = ptr_xmax_err->real(i);
826   - event.m_shwidth = ptr_shw->real(i);
827   - event.m_shlength = ptr_shl->real(i);
828   - event.m_energy_err = ptr_energy_err->real(i);
829   -
830   - // Set phase if available
  707 + event.m_event_id = ptr_eid->integer(i);
  708 + event.m_index = i;
  709 +
  710 + // If available, set detector coordinates in radians
  711 + if (m_has_detxy) {
  712 + event.m_dir.detx(ptr_detx->real(i)*gammalib::deg2rad);
  713 + event.m_dir.dety(ptr_dety->real(i)*gammalib::deg2rad);
  714 + }
  715 +
  716 + // If available, set pulse phase
831 717 if (m_has_phase) {
832 718 event.m_phase = ptr_phase->real(i);
833 719 }
834 720  
  721 + // Append event
835 722 m_events.push_back(event);
836   - }
837 723  
838   - } // endif: there were events
  724 + } // endfor: looped over all events
839 725  
840   - // Return
841   - return;
842   -}
  726 + // Loop over table and find optional columns
  727 + for (int i = 0; i < table.ncols(); ++i) {
843 728  
  729 + // Get column pointer
  730 + const GFitsTableCol* col = table[i];
844 731  
845   -/***********************************************************************//**
846   - * @brief Read Hillas information for CTA events from FITS table
847   - *
848   - * @param[in] table FITS table.
849   - *
850   - * This method reads the Hillas reconstruction information for CTA events
851   - * from an EVENTS file. It searches for the columns HIL_MSW, HIL_MSW_ERR,
852   - * HIL_MSL, and HIL_MSL_ERR in the FITS table and extracts the relevant
853   - * columns from the FITS file. If a column is not found, no action is
854   - * performed.
855   - *
856   - * @todo Verify consistency of event list size
857   - ***************************************************************************/
858   -void GCTAEventList::read_events_hillas(const GFitsTable& table)
859   -{
860   - // Extract number of events in FITS file
861   - int num = table.nrows();
  732 + // Get column name
  733 + const std::string name = col->name();
862 734  
863   - //TODO: Make sure that dimension is consistent with existing event
864   - // list
865   -
866   - // Continue only if there are events
867   - if (num > 0) {
868   -
869   - // HIL_MSW
870   - if (table.contains("HIL_MSW")) {
871   - const GFitsTableCol* ptr = table["HIL_MSW"];
872   - for (int i = 0; i < num; ++i) {
873   - m_events[i].m_hil_msw = ptr->real(i);
874   - }
875   - }
876   -
877   - // HIL_MSW_ERR
878   - if (table.contains("HIL_MSW_ERR")) {
879   - const GFitsTableCol* ptr = table["HIL_MSW_ERR"];
880   - for (int i = 0; i < num; ++i) {
881   - m_events[i].m_hil_msw_err = ptr->real(i);
  735 + // If column was mandatory or optional then skip it ...
  736 + if (name == "EVENT_ID" ||
  737 + name == "TIME" ||
  738 + name == "RA" ||
  739 + name == "DEC" ||
  740 + name == "ENERGY" ||
  741 + name == "DETX" ||
  742 + name == "DETY" ||
  743 + name == "PHASE") {
  744 + continue;
882 745 }
883   - }
884 746  
885   - // HIL_MSL
886   - if (table.contains("HIL_MSL")) {
887   - const GFitsTableCol* ptr = table["HIL_MSL"];
888   - for (int i = 0; i < num; ++i) {
889   - m_events[i].m_hil_msl = ptr->real(i);
  747 + // ... otherwise keep a copy
  748 + else {
  749 + m_columns.push_back(col->clone());
890 750 }
891   - }
892 751  
893   - // HIL_MSL_ERR
894   - if (table.contains("HIL_MSL_ERR")) {
895   - const GFitsTableCol* ptr = table["HIL_MSL_ERR"];
896   - for (int i = 0; i < num; ++i) {
897   - m_events[i].m_hil_msl_err = ptr->real(i);
898   - }
899   - }
  752 + } // endfor: loop over optional columns
900 753  
901 754 } // endif: there were events
902 755  
... ... @@ -908,12 +761,26 @@ void GCTAEventList::read_events_hillas(const GFitsTable&amp; table)
908 761 /***********************************************************************//**
909 762 * @brief Write CTA events into FITS table
910 763 *
911   - * @param[in] hdu FITS table HDU.
  764 + * @param[in] hdu FITS binary table.
912 765 *
913   - * Write the CTA event list into FITS table.
  766 + * Write the CTA event list into a FITS binary table.
914 767 *
915   - * @todo The TELMASK column is allocated with a dummy length of 100.
916   - * @todo Implement agreed column format
  768 + * The following mandatory columns will be written into the FITS table:
  769 + *
  770 + * - EVENT_ID
  771 + * - TIME
  772 + * - RA
  773 + * - DEC
  774 + * - ENERGY
  775 + *
  776 + * If available, also the
  777 + *
  778 + * - DETX
  779 + * - DETY
  780 + * - PHASE
  781 + *
  782 + * columns are written. Any other columns that were read by the read_events()
  783 + * method will be also written into the table.
917 784 ***************************************************************************/
918 785 void GCTAEventList::write_events(GFitsBinTable& hdu) const
919 786 {
... ... @@ -923,109 +790,55 @@ void GCTAEventList::write_events(GFitsBinTable&amp; hdu) const
923 790 // If there are events then write them now
924 791 if (size() > 0) {
925 792  
926   - // Allocate columns
927   - GFitsTableULongCol col_eid = GFitsTableULongCol("EVENT_ID", size());
928   - GFitsTableULongCol col_oid = GFitsTableULongCol("OBS_ID", size());
929   - GFitsTableDoubleCol col_time = GFitsTableDoubleCol("TIME", size());
930   - GFitsTableDoubleCol col_live = GFitsTableDoubleCol("TLIVE", size());
931   - GFitsTableShortCol col_multip = GFitsTableShortCol("MULTIP", size());
932   - GFitsTableBitCol col_telmask = GFitsTableBitCol("TELMASK", size(), 100);
933   - GFitsTableFloatCol col_ra = GFitsTableFloatCol("RA", size());
934   - GFitsTableFloatCol col_dec = GFitsTableFloatCol("DEC", size());
935   - GFitsTableFloatCol col_direrr = GFitsTableFloatCol("DIR_ERR", size());
936   - GFitsTableFloatCol col_detx = GFitsTableFloatCol("DETX", size());
937   - GFitsTableFloatCol col_dety = GFitsTableFloatCol("DETY", size());
938   - GFitsTableFloatCol col_alt = GFitsTableFloatCol("ALT", size());
939   - GFitsTableFloatCol col_az = GFitsTableFloatCol("AZ", size());
940   - GFitsTableFloatCol col_corex = GFitsTableFloatCol("COREX", size());
941   - GFitsTableFloatCol col_corey = GFitsTableFloatCol("COREY", size());
942   - GFitsTableFloatCol col_core_err = GFitsTableFloatCol("CORE_ERR", size());
943   - GFitsTableFloatCol col_xmax = GFitsTableFloatCol("XMAX", size());
944   - GFitsTableFloatCol col_xmax_err = GFitsTableFloatCol("XMAX_ERR", size());
945   - GFitsTableFloatCol col_shw = GFitsTableFloatCol("SHWIDTH", size());
946   - GFitsTableFloatCol col_shl = GFitsTableFloatCol("SHLENGTH", size());
947   - GFitsTableFloatCol col_energy = GFitsTableFloatCol("ENERGY", size());
948   - GFitsTableFloatCol col_energy_err = GFitsTableFloatCol("ENERGY_ERR", size());
949   - GFitsTableFloatCol col_hil_msw = GFitsTableFloatCol("HIL_MSW", size());
950   - GFitsTableFloatCol col_hil_msw_err = GFitsTableFloatCol("HIL_MSW_ERR", size());
951   - GFitsTableFloatCol col_hil_msl = GFitsTableFloatCol("HIL_MSL", size());
952   - GFitsTableFloatCol col_hil_msl_err = GFitsTableFloatCol("HIL_MSL_ERR", size());
953   -
954   - // Create phase column if required
955   - GFitsTableFloatCol col_phase;
956   - if (m_has_phase) {
957   - col_phase = GFitsTableFloatCol("PHASE", size());
958   - }
  793 + // Allocate mandatory columns
  794 + GFitsTableULongCol col_eid = GFitsTableULongCol("EVENT_ID", size());
  795 + GFitsTableDoubleCol col_time = GFitsTableDoubleCol("TIME", size());
  796 + GFitsTableFloatCol col_ra = GFitsTableFloatCol("RA", size());
  797 + GFitsTableFloatCol col_dec = GFitsTableFloatCol("DEC", size());
  798 + GFitsTableFloatCol col_energy = GFitsTableFloatCol("ENERGY", size());
959 799  
960   - // Fill columns
  800 + // Fill mandatory columns
961 801 for (int i = 0; i < size(); ++i) {
962   - col_eid(i) = m_events[i].m_event_id;
963   - col_oid(i) = m_events[i].m_obs_id;
964   - col_time(i) = m_events[i].time().convert(m_gti.reference());
965   - col_live(i) = 0.0;
966   - col_multip(i) = 0;
967   - //col_telmask
968   - col_ra(i) = m_events[i].dir().dir().ra_deg();
969   - col_dec(i) = m_events[i].dir().dir().dec_deg();
970   - col_direrr(i) = m_events[i].m_dir_err;
971   - col_detx(i) = m_events[i].dir().detx() * gammalib::rad2deg;
972   - col_dety(i) = m_events[i].dir().dety() * gammalib::rad2deg;
973   - col_alt(i) = m_events[i].m_alt;
974   - col_az(i) = m_events[i].m_az;
975   - col_corex(i) = m_events[i].m_corex;
976   - col_corey(i) = m_events[i].m_corey;
977   - col_core_err(i) = m_events[i].m_core_err;
978   - col_xmax(i) = m_events[i].m_xmax;
979   - col_xmax_err(i) = m_events[i].m_xmax_err;
980   - col_shw(i) = m_events[i].m_shwidth;
981   - col_shl(i) = m_events[i].m_shlength;
982   - col_energy(i) = m_events[i].energy().TeV();
983   - col_energy_err(i) = m_events[i].m_energy_err;
984   - col_hil_msw(i) = m_events[i].m_hil_msw;
985   - col_hil_msw_err(i) = m_events[i].m_hil_msw_err;
986   - col_hil_msl(i) = m_events[i].m_hil_msl;
987   - col_hil_msl_err(i) = m_events[i].m_hil_msl_err;
988   -
989   - // Optionally fill pulse phase column
990   - if (m_has_phase) {
991   - col_phase(i) = m_events[i].m_phase;
992   - }
993   -
994   - } // endfor: looped over rows
  802 + col_eid(i) = m_events[i].m_event_id;
  803 + col_time(i) = m_events[i].time().convert(m_gti.reference());
  804 + col_ra(i) = m_events[i].dir().dir().ra_deg();
  805 + col_dec(i) = m_events[i].dir().dir().dec_deg();
  806 + col_energy(i) = m_events[i].energy().TeV();
  807 + }
995 808  
996   - // Append columns to table
  809 + // Append mandatory columns to table
997 810 hdu.append(col_eid);
998   - hdu.append(col_oid);
999 811 hdu.append(col_time);
1000   - hdu.append(col_live);
1001   - hdu.append(col_multip);
1002   - hdu.append(col_telmask);
1003 812 hdu.append(col_ra);
1004 813 hdu.append(col_dec);
1005   - hdu.append(col_direrr);
1006   - hdu.append(col_detx);
1007   - hdu.append(col_dety);
1008   - hdu.append(col_alt);
1009   - hdu.append(col_az);
1010   - hdu.append(col_corex);
1011   - hdu.append(col_corey);
1012   - hdu.append(col_core_err);
1013   - hdu.append(col_xmax);
1014   - hdu.append(col_xmax_err);
1015   - hdu.append(col_shw);
1016   - hdu.append(col_shl);
1017 814 hdu.append(col_energy);
1018   - hdu.append(col_energy_err);
1019   - hdu.append(col_hil_msw);
1020   - hdu.append(col_hil_msw_err);
1021   - hdu.append(col_hil_msl);
1022   - hdu.append(col_hil_msl_err);
1023 815  
1024   - // Optionally write phase column
  816 + // If available, add detector coordinates in degrees
  817 + if (m_has_detxy) {
  818 + GFitsTableFloatCol col_detx = GFitsTableFloatCol("DETX", size());
  819 + GFitsTableFloatCol col_dety = GFitsTableFloatCol("DETY", size());
  820 + for (int i = 0; i < size(); ++i) {
  821 + col_detx(i) = m_events[i].dir().detx() * gammalib::rad2deg;
  822 + col_dety(i) = m_events[i].dir().dety() * gammalib::rad2deg;
  823 + }
  824 + hdu.append(col_detx);
  825 + hdu.append(col_dety);
  826 + }
  827 +
  828 + // If available, add event phase
1025 829 if (m_has_phase) {
  830 + GFitsTableFloatCol col_phase = GFitsTableFloatCol("PHASE", size());
  831 + for (int i = 0; i < size(); ++i) {
  832 + col_phase(i) = m_events[i].m_phase;
  833 + }
1026 834 hdu.append(col_phase);
1027 835 }
1028 836  
  837 + // Append other columns to table
  838 + for (int i = 0; i < m_columns.size(); ++i) {
  839 + hdu.append(*m_columns[i]);
  840 + }
  841 +
1029 842 } // endif: there were events to write
1030 843  
1031 844 // Return
... ...
inst/cta/src/GCTAPointing.cpp
... ... @@ -28,8 +28,9 @@
28 28 #ifdef HAVE_CONFIG_H
29 29 #include <config.h>
30 30 #endif
31   -#include "GCTAPointing.hpp"
32 31 #include "GTools.hpp"
  32 +#include "GFilename.hpp"
  33 +#include "GCTAPointing.hpp"
33 34 #include "GFits.hpp"
34 35 #include "GHorizDir.hpp"
35 36  
... ... @@ -107,21 +108,19 @@ GCTAPointing::GCTAPointing(const GXmlElement&amp; xml)
107 108  
108 109  
109 110 /***********************************************************************//**
110   - * @brief Pointing table constructor
  111 + * @brief FITS file constructor
111 112 *
112   - * @param[in] filename Pointing table file.
113   - * @param[in] extname Pointing extension name (defaults to "POINTING")
  113 + * @param[in] filename FITS file.
114 114 *
115   - * Construct CTA pointing from a pointing table file.
  115 + * Construct CTA pointing from a pointing table FITS file.
116 116 ***************************************************************************/
117   -GCTAPointing::GCTAPointing(const std::string& filename,
118   - const std::string& extname)
  117 +GCTAPointing::GCTAPointing(const std::string& filename)
119 118 {
120 119 // Initialise members
121 120 init_members();
122 121  
123 122 // Load pointing table
124   - load(filename, extname);
  123 + load(filename);
125 124  
126 125 // Return
127 126 return;
... ... @@ -400,24 +399,28 @@ GHorizDir GCTAPointing::dir_horiz(const GTime&amp; time) const
400 399  
401 400  
402 401 /************************************************************************
403   - * @brief Load pointing table from a pointing file
  402 + * @brief Load pointings from a FITS file
404 403 *
405   - * @param[in] filename Pointing table filename.
406   - * @param[in] extname Pointing extension name (defaults to "POINTING")
  404 + * @param[in] filename FITS file name.
  405 + *
  406 + * Loads pointings from a pointing table FITS file.
407 407 *
408   - * Loads a pointing table from a FITS file. See the read() method for
409   - * more information about the structure of the FITS file.
  408 + * If no extension name is provided, the pointing is are loaded from the
  409 + * "POINTING" extension.
410 410 ************************************************************************/
411   -void GCTAPointing::load(const std::string& filename, const std::string& extname)
  411 +void GCTAPointing::load(const std::string& filename)
412 412 {
  413 + // Create file name
  414 + GFilename fname(filename);
  415 +
413 416 // Allocate FITS file
414 417 GFits file;
415 418  
416 419 // Open FITS file
417   - file.open(filename);
  420 + file.open(fname.filename());
418 421  
419 422 // Get pointing table
420   - const GFitsTable& table = *file.table(extname);
  423 + const GFitsTable& table = *file.table(fname.extname("POINTING"));
421 424  
422 425 // Read pointing from table
423 426 read(table);
... ... @@ -431,7 +434,7 @@ void GCTAPointing::load(const std::string&amp; filename, const std::string&amp; extname)
431 434  
432 435  
433 436 /************************************************************************
434   - * @brief Load pointing table from a pointing file
  437 + * @brief Read pointings from a FITS table
435 438 *
436 439 * @param[in] filename Pointing table filename.
437 440 * @param[in] extname Pointing extension name (defaults to "POINTING")
... ...
inst/cta/src/GCTAPsf2D.cpp
... ... @@ -32,14 +32,14 @@
32 32 #include "GTools.hpp"
33 33 #include "GException.hpp"
34 34 #include "GMath.hpp"
  35 +#include "GFilename.hpp"
35 36 #include "GFits.hpp"
36 37 #include "GFitsBinTable.hpp"
37 38 #include "GCTAPsf2D.hpp"
38 39 #include "GCTAException.hpp"
39 40  
40 41 /* __ Method name definitions ____________________________________________ */
41   -#define G_READ "GCTAPsf2D::read(GFits&)"
42   -#define G_LOAD "GCTAPsf2D::load(std::string&)"
  42 +#define G_READ "GCTAPsf2D::read(GFitsTable&)"
43 43 #define G_CONTAINMENT_RADIUS "GCTAPsf2D::containment_radius(double&,"\
44 44 " double&, double&, double&, double&, double&, bool&)"
45 45  
... ... @@ -75,10 +75,9 @@ GCTAPsf2D::GCTAPsf2D(void) : GCTAPsf()
75 75 /***********************************************************************//**
76 76 * @brief File constructor
77 77 *
78   - * @param[in] filename PSF FITS file name.
  78 + * @param[in] filename FITS file name.
79 79 *
80   - * Construct instance by loading the point spread function information from
81   - * a PSF response table.
  80 + * Constructs point spread function from a FITS file.
82 81 ***************************************************************************/
83 82 GCTAPsf2D::GCTAPsf2D(const std::string& filename) : GCTAPsf()
84 83 {
... ... @@ -274,26 +273,24 @@ GCTAPsf2D* GCTAPsf2D::clone(void) const
274 273  
275 274  
276 275 /***********************************************************************//**
277   - * @brief Read PSF from FITS file
  276 + * @brief Read point spread function from FITS table
278 277 *
279   - * @param[in] fits FITS file pointer.
  278 + * @param[in] table FITS table.
280 279 *
281 280 * @exception GException::invalid_value
282 281 * FITS file format differs from expectation.
283 282 *
284   - * Reads the PSF from the FITS file extension "POINT SPREAD FUNCTION". The data
285   - * are stored in m_psf which is of type GCTAResponseTable.
286   - * The energy axis will be set to log10. The offset angle axis and
287   - * sigma parameter columns will be set to radians.
  283 + * Reads point spread function from the FITS @p table.
  284 + *
  285 + * The data are stored in m_psf which is of type GCTAResponseTable. The
  286 + * energy axis will be set to log10. The offset angle axis and sigma
  287 + * parameter columns will be set to radians.
288 288 ***************************************************************************/
289   -void GCTAPsf2D::read(const GFits& fits)
  289 +void GCTAPsf2D::read(const GFitsTable& table)
290 290 {
291 291 // Clear response table
292 292 m_psf.clear();
293 293  
294   - // Get PSF table
295   - const GFitsTable& table = *fits.table("POINT SPREAD FUNCTION");
296   -
297 294 // Read PSF table
298 295 m_psf.read(table);
299 296  
... ... @@ -330,24 +327,26 @@ void GCTAPsf2D::read(const GFits&amp; fits)
330 327  
331 328  
332 329 /***********************************************************************//**
333   - * @brief Write CTA PSF table into FITS binary table object.
  330 + * @brief Write point spread function into FITS binary table
334 331 *
335   - * @param[in] hdu FITS binary table.
  332 + * @param[in] table FITS binary table.
  333 + *
  334 + * Writes point spread function into FITS binary @p table.
336 335 *
337 336 * @todo Add necessary keywords.
338 337 ***************************************************************************/
339   -void GCTAPsf2D::write(GFitsBinTable& hdu) const
  338 +void GCTAPsf2D::write(GFitsBinTable& table) const
340 339 {
341 340 // Create a copy of the response table
342   - GCTAResponseTable table(m_psf);
  341 + GCTAResponseTable psf(m_psf);
343 342  
344 343 // Convert sigma parameters back to degrees
345   - table.scale(1, gammalib::rad2deg);
346   - table.scale(3, gammalib::rad2deg);
347   - table.scale(5, gammalib::rad2deg);
  344 + psf.scale(1, gammalib::rad2deg);
  345 + psf.scale(3, gammalib::rad2deg);
  346 + psf.scale(5, gammalib::rad2deg);
348 347  
349 348 // Write background table
350   - table.write(hdu);
  349 + psf.write(table);
351 350  
352 351 // Return
353 352 return;
... ... @@ -355,26 +354,34 @@ void GCTAPsf2D::write(GFitsBinTable&amp; hdu) const
355 354  
356 355  
357 356 /***********************************************************************//**
358   - * @brief Load point spread function from performance table
  357 + * @brief Load point spread function from FITS file
359 358 *
360   - * @param[in] filename Performance table file name.
  359 + * @param[in] filename FITS file name.
361 360 *
362   - * @exception GCTAExceptionHandler::file_open_error
363   - * File could not be opened for read access.
  361 + * Loads the point spread function from a FITS file.
364 362 *
365   - * This method loads the point spread function information from a PSF
366   - * response table.
  363 + * If no extension name is provided, the point spread function will be loaded
  364 + * from the "POINT SPREAD FUNCTION" extension.
367 365 ***************************************************************************/
368 366 void GCTAPsf2D::load(const std::string& filename)
369 367 {
370   - // Open PSF FITS file
371   - GFits fits(filename);
  368 + // Create file name
  369 + GFilename fname(filename);
  370 +
  371 + // Allocate FITS file
  372 + GFits file;
372 373  
373   - // Read fits file
374   - read(fits);
  374 + // Open FITS file
  375 + file.open(fname.filename());
375 376  
376   - // Close PSF FITS file
377   - fits.close();
  377 + // Get PSFa table
  378 + const GFitsTable& table = *file.table(fname.extname("POINT SPREAD FUNCTION"));
  379 +
  380 + // Read PSF from table
  381 + read(table);
  382 +
  383 + // Close FITS file
  384 + file.close();
378 385  
379 386 // Store filename
380 387 m_filename = filename;
... ... @@ -385,18 +392,24 @@ void GCTAPsf2D::load(const std::string&amp; filename)
385 392  
386 393  
387 394 /***********************************************************************//**
388   - * @brief Save PSF table into FITS file
  395 + * @brief Save point spread function table into FITS file
389 396 *
390   - * @param[in] filename PSF table FITS file name.
391   - * @param[in] clobber Overwrite existing file? (true=yes)
  397 + * @param[in] filename FITS file name.
  398 + * @param[in] clobber Overwrite existing file? (default: false)
392 399 *
393   - * Save the PSF table into a FITS file.
  400 + * Save the point spread function into a FITS file.
  401 + *
  402 + * If no extension name is provided, the point spread function will be saved
  403 + * into the "POINT SPREAD FUNCTION" extension.
394 404 ***************************************************************************/
395 405 void GCTAPsf2D::save(const std::string& filename, const bool& clobber) const
396 406 {
  407 + // Create file name
  408 + GFilename fname(filename);
  409 +
397 410 // Create binary table
398 411 GFitsBinTable table;
399   - table.extname("POINT SPREAD FUNCTION");
  412 + table.extname(fname.extname("POINT SPREAD FUNCTION"));
400 413  
401 414 // Write the PSF table
402 415 write(table);
... ... @@ -404,7 +417,7 @@ void GCTAPsf2D::save(const std::string&amp; filename, const bool&amp; clobber) const
404 417 // Create FITS file, append table, and write into the file
405 418 GFits fits;
406 419 fits.append(table);
407   - fits.saveto(filename, clobber);
  420 + fits.saveto(fname.filename(), clobber);
408 421  
409 422 // Return
410 423 return;
... ...
inst/cta/src/GCTAPsfKing.cpp
... ... @@ -32,13 +32,14 @@
32 32 #include "GTools.hpp"
33 33 #include "GException.hpp"
34 34 #include "GMath.hpp"
  35 +#include "GFilename.hpp"
35 36 #include "GFits.hpp"
36 37 #include "GFitsBinTable.hpp"
37 38 #include "GCTAPsfKing.hpp"
38 39 #include "GCTAException.hpp"
39 40  
40 41 /* __ Method name definitions ____________________________________________ */
41   -#define G_READ "GCTAPsfKing::read(GFits&)"
  42 +#define G_READ "GCTAPsfKing::read(GFitsTable&)"
42 43 #define G_CONTAINMENT_RADIUS "GCTAPsfKing::containment_radius(double&,"\
43 44 " double&, double&, double&, double&, double&, bool&)"
44 45 #define G_UPDATE "GCTAPsfKing::update(double&, double&)"
... ... @@ -80,8 +81,7 @@ GCTAPsfKing::GCTAPsfKing(void) : GCTAPsf()
80 81 *
81 82 * @param[in] filename PSF FITS file.
82 83 *
83   - * Construct instance by loading the point spread function information from
84   - * a FITS file that contains the PSF information in form of a column.
  84 + * Constructs point spread function from a FITS file.
85 85 ***************************************************************************/
86 86 GCTAPsfKing::GCTAPsfKing(const std::string& filename) : GCTAPsf()
87 87 {
... ... @@ -275,26 +275,24 @@ GCTAPsfKing* GCTAPsfKing::clone(void) const
275 275  
276 276  
277 277 /***********************************************************************//**
278   - * @brief Read PSF from FITS file
  278 + * @brief Read point spread function from FITS table
279 279 *
280   - * @param[in] fits FITS file pointer.
  280 + * @param[in] table FITS table.
281 281 *
282 282 * @exception GException::invalid_value
283 283 * FITS file format differs from expectation.
284 284 *
285   - * Reads the PSF from the FITS file extension "POINT SPREAD FUNCTION". The
286   - * data are stored in m_psf which is of type GCTAResponseTable.
287   - * The energy axis will be set to log10. The offset angle axis and
288   - * sigma parameter columns will be set to radians.
  285 + * Reads the point spread function from the FITS @p table.
  286 + *
  287 + * The data are stored in m_psf which is of type GCTAResponseTable. The
  288 + * energy axis will be set to log10. The offset angle axis and sigma
  289 + * parameter columns will be set to radians.
289 290 ***************************************************************************/
290   -void GCTAPsfKing::read(const GFits& fits)
  291 +void GCTAPsfKing::read(const GFitsTable& table)
291 292 {
292 293 // Clear response table
293 294 m_psf.clear();
294 295  
295   - // Get PSF table
296   - const GFitsTable& table = *fits.table("POINT SPREAD FUNCTION");
297   -
298 296 // Read PSF table
299 297 m_psf.read(table);
300 298  
... ... @@ -329,16 +327,18 @@ void GCTAPsfKing::read(const GFits&amp; fits)
329 327  
330 328  
331 329 /***********************************************************************//**
332   - * @brief Write CTA PSF table into FITS binary table object.
  330 + * @brief Write point spread function into FITS table
333 331 *
334   - * @param[in] hdu FITS binary table.
  332 + * @param[in] table FITS binary table.
335 333 *
336   - * @todo Add necessary keywords.
  334 + * Writes point spread function into a FITS binary @p table.
  335 + *
  336 + * @todo Add keywords.
337 337 ***************************************************************************/
338   -void GCTAPsfKing::write(GFitsBinTable& hdu) const
  338 +void GCTAPsfKing::write(GFitsBinTable& table) const
339 339 {
340 340 // Write background table
341   - m_psf.write(hdu);
  341 + m_psf.write(table);
342 342  
343 343 // Return
344 344 return;
... ... @@ -346,25 +346,33 @@ void GCTAPsfKing::write(GFitsBinTable&amp; hdu) const
346 346  
347 347  
348 348 /***********************************************************************//**
349   - * @brief Load point spread function from binary table
  349 + * @brief Load point spread function from FITS file
350 350 *
351   - * @param[in] filename Performance table file name.
  351 + * @param[in] filename FITS file name.
352 352 *
353   - * @exception GCTAExceptionHandler::file_open_error
354   - * File could not be opened for read access.
  353 + * Loads the point spread function from a FITS file.
355 354 *
356   - * This method loads the point spread function information from a PSF
357   - * response table.
  355 + * If no extension name is provided, the point spread function will be loaded
  356 + * from the "POINT SPREAD FUNCTION" extension.
358 357 ***************************************************************************/
359 358 void GCTAPsfKing::load(const std::string& filename)
360 359 {
361   - // Open PSF FITS file
362   - GFits file(filename);
  360 + // Create file name
  361 + GFilename fname(filename);
  362 +
  363 + // Allocate FITS file
  364 + GFits file;
363 365  
364   - // Read fits file
365   - read(file);
  366 + // Open FITS file
  367 + file.open(fname.filename());
366 368  
367   - // Close PSF FITS file
  369 + // Get PSFa table
  370 + const GFitsTable& table = *file.table(fname.extname("POINT SPREAD FUNCTION"));
  371 +
  372 + // Read PSF from table
  373 + read(table);
  374 +
  375 + // Close FITS file
368 376 file.close();
369 377  
370 378 // Store filename
... ... @@ -375,18 +383,24 @@ void GCTAPsfKing::load(const std::string&amp; filename)
375 383 }
376 384  
377 385 /***********************************************************************//**
378   - * @brief Save PSF table into FITS file
  386 + * @brief Save point spread function table into FITS file
379 387 *
380   - * @param[in] filename PSF table FITS file name.
381   - * @param[in] clobber Overwrite existing file? (true=yes)
  388 + * @param[in] filename FITS file name.
  389 + * @param[in] clobber Overwrite existing file? (default: false)
382 390 *
383   - * Save the PSF table into a FITS file.
  391 + * Save the point spread function into a FITS file.
  392 + *
  393 + * If no extension name is provided, the point spread function will be saved
  394 + * into the "POINT SPREAD FUNCTION" extension.
384 395 ***************************************************************************/
385 396 void GCTAPsfKing::save(const std::string& filename, const bool& clobber) const
386 397 {
  398 + // Create file name
  399 + GFilename fname(filename);
  400 +
387 401 // Create binary table
388 402 GFitsBinTable table;
389   - table.extname("POINT SPREAD FUNCTION");
  403 + table.extname(fname.extname("POINT SPREAD FUNCTION"));
390 404  
391 405 // Write the PSF table
392 406 write(table);
... ... @@ -394,7 +408,7 @@ void GCTAPsfKing::save(const std::string&amp; filename, const bool&amp; clobber) const
394 408 // Create FITS file, append table, and write into the file
395 409 GFits fits;
396 410 fits.append(table);
397   - fits.saveto(filename, clobber);
  411 + fits.saveto(fname.filename(), clobber);
398 412  
399 413 // Return
400 414 return;
... ...
inst/cta/src/GCTAPsfVector.cpp
... ... @@ -31,6 +31,7 @@
31 31 #include <cmath>
32 32 #include "GTools.hpp"
33 33 #include "GMath.hpp"
  34 +#include "GFilename.hpp"
34 35 #include "GFitsTable.hpp"
35 36 #include "GFitsTableCol.hpp"
36 37 #include "GCTAPsfVector.hpp"
... ... @@ -74,8 +75,7 @@ GCTAPsfVector::GCTAPsfVector(void) : GCTAPsf()
74 75 *
75 76 * @param[in] filename PSF FITS file.
76 77 *
77   - * Construct instance by loading the point spread function information from
78   - * a FITS file that contains the PSF information in form of a column.
  78 + * Constructs point spread function vector from a FITS file.
79 79 ***************************************************************************/
80 80 GCTAPsfVector::GCTAPsfVector(const std::string& filename) : GCTAPsf()
81 81 {
... ... @@ -247,25 +247,33 @@ GCTAPsfVector* GCTAPsfVector::clone(void) const
247 247  
248 248  
249 249 /***********************************************************************//**
250   - * @brief Load point spread function from performance table
  250 + * @brief Load point spread function from FITS file
251 251 *
252   - * @param[in] filename Performance table file name.
  252 + * @param[in] filename FITS file name.
253 253 *
254   - * This method loads the point spread function information from a FITS file
255   - * that contains the PSF width in a single column.
  254 + * Loads the point spread function from a FITS file.
  255 + *
  256 + * If no extension name is provided, the point spread function will be loaded
  257 + * from the "PSF" extension.
256 258 ***************************************************************************/
257 259 void GCTAPsfVector::load(const std::string& filename)
258 260 {
259   - // Open PSF FITS file
260   - GFits file(filename);
  261 + // Create file name
  262 + GFilename fname(filename);
  263 +
  264 + // Allocate FITS file
  265 + GFits file;
261 266  
262   - // Get PSF table
263   - const GFitsTable& table = *file.table(1);
  267 + // Open FITS file
  268 + file.open(fname.filename());
264 269  
265   - // Read PSF
  270 + // Get PSFa table
  271 + const GFitsTable& table = *file.table(fname.extname("PSF"));
  272 +
  273 + // Read PSF from table
266 274 read(table);
267 275  
268   - // Close PSF FITS file
  276 + // Close FITS file
269 277 file.close();
270 278  
271 279 // Store filename
... ... @@ -277,12 +285,13 @@ void GCTAPsfVector::load(const std::string&amp; filename)
277 285  
278 286  
279 287 /***********************************************************************//**
280   - * @brief Read CTA PSF vector
  288 + * @brief Read point spread function vector from FITS table
281 289 *
282 290 * @param[in] table FITS table.
283 291 *
284   - * This method reads a CTA PSF vector from the FITS HDU. Note that the
285   - * energies are converted to TeV. Conversion is done based on the units
  292 + * Reads a point spread function vector from the FITS @p table.
  293 + *
  294 + * The energies are converted to TeV. Conversion is done based on the units
286 295 * provided for the energy columns. Units that are recognized are 'keV',
287 296 * 'MeV', 'GeV', and 'TeV' (case independent).
288 297 *
... ...
inst/cta/src/GCTAResponseIrf.cpp
... ... @@ -34,6 +34,7 @@
34 34 #include "GFits.hpp"
35 35 #include "GTools.hpp"
36 36 #include "GMath.hpp"
  37 +#include "GFilename.hpp"
37 38 #include "GIntegral.hpp"
38 39 #include "GCaldb.hpp"
39 40 #include "GSource.hpp"
... ... @@ -70,14 +71,17 @@
70 71 #include "GCTABackground3D.hpp"
71 72  
72 73 /* __ Method name definitions ____________________________________________ */
73   -#define G_CALDB "GCTAResponseIrf::caldb(GCaldb&)"
74 74 #define G_IRF "GCTAResponseIrf::irf(GInstDir&, GEnergy&, GTime&, GSkyDir&,"\
75 75 " GEnergy&, GTime&, GObservation&)"
76   -#define G_NPRED "GCTAResponseIrf::npred(GSkyDir&, GEnergy&, GTime&,"\
77   - " GObservation&)"
78 76 #define G_MC "GCTAResponseIrf::mc(double&, GPhoton&, GObservation&, GRan&)"
79 77 #define G_READ "GCTAResponseIrf::read(GXmlElement&)"
80 78 #define G_WRITE "GCTAResponseIrf::write(GXmlElement&)"
  79 +#define G_LOAD_AEFF "GCTAResponseIrf::load_aeff(std::string&)"
  80 +#define G_LOAD_PSF "GCTAResponseIrf::load_psf(std::string&)"
  81 +#define G_LOAD_EDISP "GCTAResponseIrf::load_edisp(std::string&)"
  82 +#define G_LOAD_BACKGROUND "GCTAResponseIrf::load_background(std::string&)"
  83 +#define G_NIRF "GCTAResponseIrf::nirf(GPhoton&, GEnergy&, GTime&,"\
  84 + " GObservation&)"
81 85 #define G_IRF_RADIAL "GCTAResponseIrf::irf_radial(GEvent&, GSource&,"\
82 86 " GObservation&)"
83 87 #define G_IRF_ELLIPTICAL "GCTAResponseIrf::irf_elliptical(GEvent&, GSource&,"\
... ... @@ -96,8 +100,6 @@
96 100 " double&)"
97 101 #define G_PSF_DELTA_MAX "GCTAResponseIrf::psf_delta_max(double&, double&,"\
98 102 " double&, double&, double&)"
99   -#define G_EDISP "GCTAResponseIrf::edisp(double&, double&, double&, double&,"\
100   - " double&)"
101 103  
102 104 /* __ Macros _____________________________________________________________ */
103 105  
... ... @@ -1069,30 +1071,22 @@ void GCTAResponseIrf::load(const std::string&amp; rspname)
1069 1071 *
1070 1072 * @param[in] filename Effective area filename.
1071 1073 *
1072   - * This method allocates an effective area instance and load the effective
1073   - * area information from a response file. The following response file formats
1074   - * are supported:
1075   - *
1076   - * (1) A CTA performance table. This is an ASCII file which specifies the
1077   - * on-axis effective area as function of energy.
1078   - *
1079   - * (2) A ARF FITS file. This is a FITS file which stores the effective area
1080   - * in a vector.
1081   - *
1082   - * (3) A CTA response table. This is a FITS file which specifies the
1083   - * effective area as function of energy and offset angle.
  1074 + * @exception GException::file_error
  1075 + * File or extension not found.
1084 1076 *
1085   - * This method examines the file, and depending on the detected format,
1086   - * allocates the appropriate effective area class and loads the data.
  1077 + * Loads the effective area from a response file.
1087 1078 *
1088   - * First, the method checks whether the file is a FITS file or not. If the
1089   - * file is not a FITS file, it is assumed that the file is an ASCII
1090   - * performance table. If the file is a FITS file, the number of rows found
1091   - * in the table is used to distinguish between an ARF (multiple rows) and
1092   - * a CTA response table (single row).
  1079 + * If the file is a FITS file, the method will either use the extension name
  1080 + * specified with the filename, or if no extension name is given, search for
  1081 + * an "EFFECTIVE AREA" or "SPECRESP" extension in the file and open the
  1082 + * corresponding FITS table. If a column named "SPECRESP" is found in the
  1083 + * table, a GCTAAeffArf object will be allocated. Otherwise, a GCTAAeff2D
  1084 + * object will be allocated. In both cases, the method will extract the
  1085 + * optional "LO_THRES" and "HI_THRES" save energy thresholds from the FITS
  1086 + * file header.
1093 1087 *
1094   - * @todo Implement a method that checks if a file is a FITS file instead
1095   - * of using try-catch.
  1088 + * If the file is not a FITS file, it will be interpreted as a
  1089 + * GCTAAeffPerfTable performance table.
1096 1090 ***************************************************************************/
1097 1091 void GCTAResponseIrf::load_aeff(const std::string& filename)
1098 1092 {
... ... @@ -1100,68 +1094,93 @@ void GCTAResponseIrf::load_aeff(const std::string&amp; filename)
1100 1094 if (m_aeff != NULL) delete m_aeff;
1101 1095 m_aeff = NULL;
1102 1096  
1103   - // Try opening the file as a FITS file
1104   - try {
  1097 + // Initialise filename
  1098 + GFilename fname(filename);
  1099 +
  1100 + // Check for existence of file
  1101 + if (!gammalib::file_exists_gzip(fname.filename())) {
  1102 + std::string msg = "File \""+filename+"\" not found. Please specify "
  1103 + "a valid effective area response file.";
  1104 + throw GException::file_error(G_LOAD_AEFF, msg);
  1105 + }
  1106 +
  1107 + // If file is a FITS file ...
  1108 + if (gammalib::is_fits(filename)) {
1105 1109  
1106 1110 // Open FITS file
1107   - GFits file(filename);
  1111 + GFits file(fname.filename());
  1112 +
  1113 + // Get the extension name. If an extension name has been specified
  1114 + // then use this name, otherwise use either the "EFFECTIVE AREA"
  1115 + // or the "SPECRESP" extension.
  1116 + std::string extname = "";
  1117 + if (fname.has_extname()) {
  1118 + extname = fname.extname();
  1119 + }
  1120 + else {
  1121 + if (file.contains("EFFECTIVE AREA")) {
  1122 + extname = "EFFECTIVE AREA";
  1123 + }
  1124 + else if (file.contains("SPECRESP")) {
  1125 + extname = "SPECRESP";
  1126 + }
  1127 + }
1108 1128  
1109   - // If file contains an "EFFECTIVE AREA" extension then load it
1110   - // as CTA response table
1111   - if (file.contains("EFFECTIVE AREA")) {
  1129 + // Continue only if extension name is not empty
  1130 + if (!extname.empty()) {
1112 1131  
1113   - // Get HDU
1114   - const GFitsHDU* hdu = file.at("EFFECTIVE AREA");
  1132 + // Get FITS table
  1133 + const GFitsTable& table = *file.table(extname);
1115 1134  
1116 1135 // Read save energy thresholds if available
1117   - if (hdu->has_card("LO_THRES")) {
1118   - m_lo_save_thres = hdu->real("LO_THRES");
  1136 + if (table.has_card("LO_THRES")) {
  1137 + m_lo_save_thres = table.real("LO_THRES");
1119 1138 }
1120   - if (hdu->has_card("HI_THRES")) {
1121   - m_hi_save_thres = hdu->real("HI_THRES");
  1139 + if (table.has_card("HI_THRES")) {
  1140 + m_hi_save_thres = table.real("HI_THRES");
1122 1141 }
1123 1142  
1124   - // Close file
1125   - file.close();
  1143 + // Check for specific table column
  1144 + if (table.contains("SPECRESP")) {
1126 1145  
1127   - // Allocate Aeff from file
1128   - m_aeff = new GCTAAeff2D(filename);
1129   -
1130   - }
  1146 + // Close file
  1147 + file.close();
1131 1148  
1132   - // ... else if file contains a "SPECRESP" extension then load it
1133   - // as ARF
1134   - else if (file.contains("SPECRESP")) {
  1149 + // Allocate Aeff from file
  1150 + m_aeff = new GCTAAeffArf(filename);
1135 1151  
1136   - // Get HDU
1137   - const GFitsHDU* hdu = file.at("SPECRESP");
  1152 + } // endif: load as GCTAAeffArf
  1153 +
  1154 + else {
1138 1155  
1139   - // Read save energy thresholds if available
1140   - if (hdu->has_card("LO_THRES")) {
1141   - m_lo_save_thres = hdu->real("LO_THRES");
1142   - }
1143   - if (hdu->has_card("LO_THRES")) {
1144   - m_hi_save_thres = hdu->real("HI_THRES");
1145   - }
  1156 + // Close file
  1157 + file.close();
1146 1158  
1147   - // Close file
1148   - file.close();
  1159 + // Allocate Aeff from file
  1160 + m_aeff = new GCTAAeff2D(filename);
  1161 +
  1162 + } // endelse: load as GCTAAeff2D
1149 1163  
1150   - // Allocate Aeff from file
1151   - m_aeff = new GCTAAeffArf(filename);
  1164 + } // endif: extension name is not empty
1152 1165  
  1166 + // Signal that no extension was found
  1167 + else {
  1168 + std::string msg = "FITS file \""+filename+"\" does not "
  1169 + "contain a valid effective area table. "
  1170 + "Please specify a valid effective area "
  1171 + "response file.";
  1172 + throw GException::file_error(G_LOAD_AEFF, msg);
1153 1173 }
1154 1174  
1155   - }
  1175 + } // endif: file was FITS file
  1176 +
  1177 + // ... else try handling an ASCII performance table
  1178 + else {
1156 1179  
1157   - // If FITS file opening failed then assume that we have a performance
1158   - // table
1159   - catch (GException::fits_open_error &e) {
  1180 + // Allocate a performance table
1160 1181 m_aeff = new GCTAAeffPerfTable(filename);
1161   - }
1162 1182  
1163   - // Record Aeff file name
1164   - //m_xml_aeff = filename;
  1183 + } // endif: load as GCTAAeffPerfTable
1165 1184  
1166 1185 // Return
1167 1186 return;
... ... @@ -1173,25 +1192,22 @@ void GCTAResponseIrf::load_aeff(const std::string&amp; filename)
1173 1192 *
1174 1193 * @param[in] filename FITS file name.
1175 1194 *
1176   - * This method loads CTA PSF information from a FITS table. Two FITS file
1177   - * formats are supported by the method:
1178   - *
1179   - * (1) A PSF vector, stored in a format similar to an ARF vector. It is
1180   - * expected that this format is only a preliminary format that will
1181   - * disappear in the future (m_psf_version=-9).
  1195 + * @exception GException::file_error
  1196 + * File or extension not found.
1182 1197 *
1183   - * (2) A PSF response table, where PSF parameters are given as function of
1184   - * energy, offset angle, and eventually some other parameters. This format
1185   - * is expected to be the definitive response format for CTA
1186   - * (m_psf_version=-8).
  1198 + * Loads the point spead function from a response file.
1187 1199 *
1188   - * This method examines the FITS file, and depending on the detected format,
1189   - * calls the relevant methods. Detection is done by the number of rows that
1190   - * are found in the table. A single row means that we deal with a response
1191   - * table, while multiple rows mean that we deal with a response vector.
  1200 + * If the file is a FITS file, the method will either use the extension name
  1201 + * specified with the filename, or if no extension name is given, search for
  1202 + * a "POINT SPREAD FUNCTION" or "PSF" extension in the file and open the
  1203 + * corresponding FITS table. If columns named "GAMMA" and "SIGMA" are found
  1204 + * in the table, a GCTAPsfKing object will be allocated. If columns named
  1205 + * "SCALE", "SIGMA_1", "AMPL_2", "SIGMA_2", "AMPL_3" and "SIGMA_3" are found
  1206 + * in the table, a GCTAPsf2D object will be allocated. Otherwise, a
  1207 + * GCTAPsfVector object will be allocated.
1192 1208 *
1193   - * @todo Implement a method that checks if a file is a FITS file instead
1194   - * of using try-catch.
  1209 + * If the file is not a FITS file, it will be interpreted as a
  1210 + * GCTAPsfPerfTable performance table.
1195 1211 ***************************************************************************/
1196 1212 void GCTAResponseIrf::load_psf(const std::string& filename)
1197 1213 {
... ... @@ -1199,47 +1215,100 @@ void GCTAResponseIrf::load_psf(const std::string&amp; filename)
1199 1215 if (m_psf != NULL) delete m_psf;
1200 1216 m_psf = NULL;
1201 1217  
1202   - // Try opening the file as a FITS file
1203   - try {
  1218 + // Initialise filename
  1219 + GFilename fname(filename);
  1220 +
  1221 + // Check for existence of file
  1222 + if (!gammalib::file_exists_gzip(fname.filename())) {
  1223 + std::string msg = "File \""+filename+"\" not found. Please specify "
  1224 + "a valid point spread function response file.";
  1225 + throw GException::file_error(G_LOAD_PSF, msg);
  1226 + }
  1227 +
  1228 + // If file is a FITS file ...
  1229 + if (gammalib::is_fits(filename)) {
1204 1230  
1205 1231 // Open FITS file
1206   - GFits file(filename);
  1232 + GFits file(fname.filename());
  1233 +
  1234 + // Get the extension name. If an extension name has been specified
  1235 + // then use this name, otherwise use either the
  1236 + // "POINT SPREAD FUNCTION" or the "PSF" extension.
  1237 + std::string extname = "";
  1238 + if (fname.has_extname()) {
  1239 + extname = fname.extname();
  1240 + }
  1241 + else {
  1242 + if (file.contains("POINT SPREAD FUNCTION")) {
  1243 + extname = "POINT SPREAD FUNCTION";
  1244 + }
  1245 + else if (file.contains("PSF")) {
  1246 + extname = "PSF";
  1247 + }
  1248 + }
1207 1249  
1208   - // If file contains a "POINT SPREAD FUNCTION" extension then load it
1209   - // as either a King profile PSF or a 2D PSF
1210   - if (file.contains("POINT SPREAD FUNCTION")) {
1211   - const GFitsTable& table = *file.table("POINT SPREAD FUNCTION");
  1250 + // Continue only if extension name is not empty
  1251 + if (!extname.empty()) {
  1252 +
  1253 + // Get FITS table
  1254 + const GFitsTable& table = *file.table(extname);
  1255 +
  1256 + // Check for King profile specific table columns
1212 1257 if (table.contains("GAMMA") && table.contains("SIGMA")) {
  1258 +
  1259 + // Close FITS file
1213 1260 file.close();
  1261 +
  1262 + // Allocate King profile PSF
1214 1263 m_psf = new GCTAPsfKing(filename);
  1264 +
1215 1265 }
1216   - else if (table.contains("SCALE") && table.contains("SIGMA_1") &&
  1266 +
  1267 + // ... otherwise check for Gaussian profile specific table
  1268 + // columns
  1269 + else if (table.contains("SCALE") && table.contains("SIGMA_1") &&
1217 1270 table.contains("AMPL_2") && table.contains("SIGMA_2") &&
1218 1271 table.contains("AMPL_3") && table.contains("SIGMA_3")) {
  1272 +
  1273 + // Close FITS file
1219 1274 file.close();
  1275 +
  1276 + // Allocate Gaussian profile PSF
1220 1277 m_psf = new GCTAPsf2D(filename);
  1278 +
1221 1279 }
  1280 +
  1281 + // ... otherwise try opening as vector PSF
1222 1282 else {
  1283 +
  1284 + // Close FITS file
1223 1285 file.close();
  1286 +
  1287 + // Allocate vector PSF
  1288 + m_psf = new GCTAPsfVector(filename);
  1289 +
1224 1290 }
1225   - }
1226 1291  
1227   - // ... else load it has PSF vector
  1292 + } // endif: extension name is not empty
  1293 +
  1294 + // Signal that no extension was found
1228 1295 else {
1229   - file.close();
1230   - m_psf = new GCTAPsfVector(filename);
  1296 + std::string msg = "FITS file \""+filename+"\" does not "
  1297 + "contain a valid point spread function table. "
  1298 + "Please specify a valid point spread function "
  1299 + "response file.";
  1300 + throw GException::file_error(G_LOAD_PSF, msg);
1231 1301 }
1232 1302  
1233   - }
  1303 + } // endif: file was FITS file
1234 1304  
1235   - // If FITS file opening failed then assume that we have a performance
1236   - // table
1237   - catch (GException::fits_open_error &e) {
  1305 + // ... otherwise load file as a performance table
  1306 + else {
  1307 +
  1308 + // Allocate a performance table
1238 1309 m_psf = new GCTAPsfPerfTable(filename);
  1310 +
1239 1311 }
1240   -
1241   - // Record PSF filename
1242   - //m_xml_psf = filename;
1243 1312  
1244 1313 // Return
1245 1314 return;
... ... @@ -1250,6 +1319,21 @@ void GCTAResponseIrf::load_psf(const std::string&amp; filename)
1250 1319 * @brief Load energy dispersion information
1251 1320 *
1252 1321 * @param[in] filename Energy dispersion file name.
  1322 + *
  1323 + * @exception GException::file_error
  1324 + * File or extension not found.
  1325 + *
  1326 + * Loads the energy dispersion from a response file.
  1327 + *
  1328 + * If the file is a FITS file, the method will either use the extension name
  1329 + * specified with the filename, or if no extension name is given, search for
  1330 + * an "ENERGY DISPERSION" or "MATRIX" extension in the file and open the
  1331 + * corresponding FITS table. If columns named "MIGRA_LO" and "MIGRA_HI" are
  1332 + * found in the table, a GCTAEdisp2D object will be allocated. Otherwise, a
  1333 + * GCTAEdispRmf object will be allocated.
  1334 + *
  1335 + * If the file is not a FITS file, it will be interpreted as a
  1336 + * GCTAEdispPerfTable performance table.
1253 1337 ***************************************************************************/
1254 1338 void GCTAResponseIrf::load_edisp(const std::string& filename)
1255 1339 {
... ... @@ -1257,35 +1341,86 @@ void GCTAResponseIrf::load_edisp(const std::string&amp; filename)
1257 1341 if (m_edisp != NULL) delete m_edisp;
1258 1342 m_edisp = NULL;
1259 1343  
1260   - // Try opening the file as a FITS file
1261   - try {
  1344 + // Initialise filename
  1345 + GFilename fname(filename);
1262 1346  
1263   - // Open FITS file
1264   - GFits file(filename);
  1347 + // Check for existence of file
  1348 + if (!gammalib::file_exists_gzip(fname.filename())) {
  1349 + std::string msg = "File \""+filename+"\" not found. Please specify "
  1350 + "a valid energy dispersion response file.";
  1351 + throw GException::file_error(G_LOAD_EDISP, msg);
  1352 + }
1265 1353  
1266   - // If file contains an "ENERGY DISPERSION" extension then load it
1267   - // as CTA response table
1268   - if (file.contains("ENERGY DISPERSION")) {
1269   - file.close();
1270   - m_edisp = new GCTAEdisp2D(filename);
  1354 + // If file is a FITS file ...
  1355 + if (gammalib::is_fits(filename)) {
  1356 +
  1357 + // Open FITS file
  1358 + GFits file(fname.filename());
  1359 +
  1360 + // Get the extension name. If an extension name has been specified
  1361 + // then use this name, otherwise use either the "EFFECTIVE AREA"
  1362 + // or the "SPECRESP" extension.
  1363 + std::string extname = "";
  1364 + if (fname.has_extname()) {
  1365 + extname = fname.extname();
  1366 + }
  1367 + else {
  1368 + if (file.contains("ENERGY DISPERSION")) {
  1369 + extname = "ENERGY DISPERSION";
  1370 + }
  1371 + else if (file.contains("MATRIX")) {
  1372 + extname = "MATRIX";
  1373 + }
1271 1374 }
1272 1375  
1273   - // ... else load it as RMF
  1376 + // Continue only if extension name is not empty
  1377 + if (!extname.empty()) {
  1378 +
  1379 + // Get FITS table
  1380 + const GFitsTable& table = *file.table(extname);
  1381 +
  1382 + // Check for 2D migration matrix
  1383 + if (table.contains("MIGRA_LO") && table.contains("MIGRA_HI")) {
  1384 +
  1385 + // Close FITS file
  1386 + file.close();
  1387 +
  1388 + // Allocate 2D migration matrix
  1389 + m_edisp = new GCTAEdisp2D(filename);
  1390 +
  1391 + }
  1392 +
  1393 + // ... otherwise allocate RMF
  1394 + else {
  1395 +
  1396 + // Close FITS file
  1397 + file.close();
  1398 +
  1399 + // Allocate Gaussian profile PSF
  1400 + m_edisp = new GCTAEdispRmf(filename);
  1401 +
  1402 + }
  1403 +
  1404 + } // endif: extension name is not empty
  1405 +
  1406 + // Signal that no extension was found
1274 1407 else {
1275   - file.close();
1276   - m_edisp = new GCTAEdispRmf(filename);
  1408 + std::string msg = "FITS file \""+filename+"\" does not "
  1409 + "contain a valid energy dispersion table. "
  1410 + "Please specify a valid energy dispersion "
  1411 + "response file.";
  1412 + throw GException::file_error(G_LOAD_EDISP, msg);
1277 1413 }
1278 1414  
1279   - }
  1415 + } // endif: file was FITS file
1280 1416  
1281   - // If FITS file opening failed then assume that we have a performance
1282   - // table
1283   - catch (GException::fits_open_error &e) {
  1417 + // ... otherwise load file as a performance table
  1418 + else {
  1419 +
  1420 + // Allocate a performance table
1284 1421 m_edisp = new GCTAEdispPerfTable(filename);
1285   - }
1286 1422  
1287   - // Record energy dispersion filename
1288   - //m_xml_edisp = filename;
  1423 + }
1289 1424  
1290 1425 // Return
1291 1426 return;
... ... @@ -1296,6 +1431,17 @@ void GCTAResponseIrf::load_edisp(const std::string&amp; filename)
1296 1431 * @brief Load background model
1297 1432 *
1298 1433 * @param[in] filename Background model file name.
  1434 + *
  1435 + * @exception GException::file_error
  1436 + * File not found.
  1437 + *
  1438 + * Loads the background model from a response file.
  1439 + *
  1440 + * If the file is a FITS file the method allocates a GCTABackground3D
  1441 + * response and loads the information from the FITS file.
  1442 + *
  1443 + * If the file is not a FITS file it will be interpreted as a
  1444 + * GCTABackgroundPerfTable performance table.
1299 1445 ***************************************************************************/
1300 1446 void GCTAResponseIrf::load_background(const std::string& filename)
1301 1447 {
... ... @@ -1303,18 +1449,25 @@ void GCTAResponseIrf::load_background(const std::string&amp; filename)
1303 1449 if (m_background != NULL) delete m_background;
1304 1450 m_background = NULL;
1305 1451  
1306   - // Try opening the file as a FITS file
1307   - try {
1308   - // Load background as 3D background
  1452 + // Initialise filename
  1453 + GFilename fname(filename);
  1454 +
  1455 + // Check for existence of file
  1456 + if (!gammalib::file_exists_gzip(fname.filename())) {
  1457 + std::string msg = "File \""+filename+"\" not found. Please specify "
  1458 + "a valid background response file.";
  1459 + throw GException::file_error(G_LOAD_BACKGROUND, msg);
  1460 + }
  1461 +
  1462 + // If file is a FITS file than load background as 3D background
  1463 + if (gammalib::is_fits(filename)) {
1309 1464 m_background = new GCTABackground3D(filename);
1310 1465 }
1311   - catch (GException::fits_open_error &e) {
1312   - // Load background as performance table background
  1466 +
  1467 + // ... otherwise load background as performance table
  1468 + else {
1313 1469 m_background = new GCTABackgroundPerfTable(filename);
1314 1470 }
1315   -
1316   - // Record background filename
1317   - //m_xml_background = filename;
1318 1471  
1319 1472 // Return
1320 1473 return;
... ... @@ -1724,8 +1877,8 @@ double GCTAResponseIrf::nirf(const GPhoton&amp; photon,
1724 1877 const GObservation& obs) const
1725 1878 {
1726 1879 // Retrieve CTA observation, ROI and pointing
1727   - const GCTAObservation& cta = retrieve_obs(G_NPRED, obs);
1728   - const GCTARoi& roi = retrieve_roi(G_NPRED, obs);
  1880 + const GCTAObservation& cta = retrieve_obs(G_NIRF, obs);
  1881 + const GCTARoi& roi = retrieve_roi(G_NIRF, obs);
1729 1882 const GCTAPointing& pnt = cta.pointing();
1730 1883  
1731 1884 // Get photon attributes
... ...
inst/cta/test/test_CTA.py
... ... @@ -271,8 +271,8 @@ class Test(gammalib.GPythonTestSuite):
271 271 # Load 1DC CTA observation (ARF, PSF, RMF)
272 272 self.test_try("Test 1DC responses")
273 273 try:
274   - filname = self.caldb + "/../data/irf_1dc.xml"
275   - obs = gammalib.GObservations(filname)
  274 + filename = self.caldb + "/../data/irf_1dc.xml"
  275 + obs = gammalib.GObservations(filename)
276 276 self.test_try_success()
277 277 except:
278 278 self.test_try_failure("Unable to load 1DC responses.")
... ...
inst/mwl/include/GMWLObservation.hpp
1 1 /***************************************************************************
2 2 * GMWLObservation.hpp - Multi-wavelength observation class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2014 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2015 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -49,8 +49,6 @@ public:
49 49 // Constructors and destructors
50 50 GMWLObservation(void);
51 51 explicit GMWLObservation(const std::string& filename);
52   - explicit GMWLObservation(const std::string& filename, const int& extno);
53   - explicit GMWLObservation(const std::string& filename, const std::string& extname);
54 52 GMWLObservation(const GMWLObservation& obs);
55 53 virtual ~GMWLObservation(void);
56 54  
... ... @@ -73,8 +71,6 @@ public:
73 71  
74 72 // Other methods
75 73 void load(const std::string& filename);
76   - void load(const std::string& filename, const int& extno);
77   - void load(const std::string& filename, const std::string& extname);
78 74 const std::string& filename(void) const;
79 75 const std::string& extno(void) const;
80 76 const std::string& extname(void) const;
... ...
inst/mwl/include/GMWLSpectrum.hpp
... ... @@ -74,8 +74,6 @@ public:
74 74 virtual std::string print(const GChatter& chatter = NORMAL) const;
75 75  
76 76 // Other methods
77   - void load(const std::string& filename, const std::string& extname);
78   - void load(const std::string& filename, const int& extno);
79 77 void read(const GFits& file, const std::string& extname);
80 78 void read(const GFits& file, const int& extno);
81 79 const std::string& telescope(void) const;
... ...
inst/mwl/pyext/GMWLObservation.i
1 1 /***************************************************************************
2 2 * GMWLObservation.i - Multi-wavelength observation class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2014 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2015 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -39,12 +39,11 @@
39 39 * instrument. The spectral points are given in physical units.
40 40 ***************************************************************************/
41 41 class GMWLObservation : public GObservation {
  42 +
42 43 public:
43 44 // Constructors and destructors
44 45 GMWLObservation(void);
45 46 explicit GMWLObservation(const std::string& filename);
46   - explicit GMWLObservation(const std::string& filename, const int& extno);
47   - explicit GMWLObservation(const std::string& filename, const std::string& extname);
48 47 GMWLObservation(const GMWLObservation& obs);
49 48 virtual ~GMWLObservation(void);
50 49  
... ... @@ -63,8 +62,6 @@ public:
63 62  
64 63 // Other methods
65 64 void load(const std::string& filename);
66   - void load(const std::string& filename, const int& extno);
67   - void load(const std::string& filename, const std::string& extname);
68 65 const std::string& filename(void) const;
69 66 const std::string& extno(void) const;
70 67 const std::string& extname(void) const;
... ...
inst/mwl/pyext/GMWLSpectrum.i
... ... @@ -57,8 +57,6 @@ public:
57 57 virtual int number(void) const;
58 58  
59 59 // Other methods
60   - void load(const std::string& filename, const std::string& extname);
61   - void load(const std::string& filename, const int& extno);
62 60 void read(const GFits& file, const std::string& extname);
63 61 void read(const GFits& file, const int& extno);
64 62 const std::string& telescope(void) const;
... ...
inst/mwl/src/GMWLObservation.cpp
1 1 /***************************************************************************
2 2 * GMWLObservation.cpp - Multi-wavelength observation class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2013 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2015 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -28,8 +28,9 @@
28 28 #ifdef HAVE_CONFIG_H
29 29 #include <config.h>
30 30 #endif
31   -#include "GObservationRegistry.hpp"
32 31 #include "GTools.hpp"
  32 +#include "GFilename.hpp"
  33 +#include "GObservationRegistry.hpp"
33 34 #include "GException.hpp"
34 35 #include "GMWLObservation.hpp"
35 36 #include "GMWLSpectrum.hpp"
... ... @@ -93,50 +94,6 @@ GMWLObservation::GMWLObservation(const std::string&amp; filename) : GObservation()
93 94  
94 95  
95 96 /***********************************************************************//**
96   - * @brief File constructor
97   - *
98   - * @param[in] filename File name.
99   - * @param[in] extno FITS file extension number.
100   - *
101   - * Creates instance from file.
102   - ***************************************************************************/
103   -GMWLObservation::GMWLObservation(const std::string& filename,
104   - const int& extno) : GObservation()
105   -{
106   - // Initialise members
107   - init_members();
108   -
109   - // Load observation
110   - load(filename, extno);
111   -
112   - // Return
113   - return;
114   -}
115   -
116   -
117   -/***********************************************************************//**
118   - * @brief File constructor
119   - *
120   - * @param[in] filename File name.
121   - * @param[in] extname FITS file extension name.
122   - *
123   - * Creates instance from file.
124   - ***************************************************************************/
125   -GMWLObservation::GMWLObservation(const std::string& filename,
126   - const std::string& extname) : GObservation()
127   -{
128   - // Initialise members
129   - init_members();
130   -
131   - // Load observation
132   - load(filename, extname);
133   -
134   - // Return
135   - return;
136   -}
137   -
138   -
139   -/***********************************************************************//**
140 97 * @brief Copy constructor
141 98 *
142 99 * @param[in] obs Observation.
... ... @@ -336,11 +293,11 @@ void GMWLObservation::read(const GXmlElement&amp; xml)
336 293  
337 294 // Load file (this also stores the filename, extno and
338 295 // extname)
339   - if (gammalib::strip_whitespace(extno).length() > 0) {
340   - load(filename, gammalib::toint(extno));
  296 + if (!gammalib::strip_whitespace(extno).empty()) {
  297 + load(filename+"["+extno+"]");
341 298 }
342   - else if (gammalib::strip_whitespace(extname).length() > 0) {
343   - load(filename, extname);
  299 + else if (!gammalib::strip_whitespace(extname).empty()) {
  300 + load(filename+"["+extname+"]");
344 301 }
345 302 else {
346 303 load(filename);
... ... @@ -442,79 +399,32 @@ void GMWLObservation::load(const std::string&amp; filename)
442 399 // Clear observation
443 400 clear();
444 401  
445   - // Allocate spectrum
446   - GMWLSpectrum* spec = new GMWLSpectrum;
447   - m_events = spec;
448   -
449   - // Load spectrum
450   - spec->load(filename);
451   -
452   - // Set attributes
453   - name("Multi-wavelength observation");
454   - id(filename);
455   - m_filename = filename;
456   - m_instrument = spec->instrument();
457   -
458   - // Return
459   - return;
460   -}
461   -
462   -
463   -/***********************************************************************//**
464   - * @brief Load observation
465   - *
466   - * @param[in] filename File name.
467   - * @param[in] extno FITS extension number.
468   - ***************************************************************************/
469   -void GMWLObservation::load(const std::string& filename,
470   - const int& extno)
471   -{
472   - // Clear observation
473   - clear();
474   -
475   - // Allocate spectrum
476   - GMWLSpectrum* spec = new GMWLSpectrum;
477   - m_events = spec;
478   -
479   - // Load spectrum
480   - spec->load(filename, extno);
481   -
482   - // Set attributes
483   - name("Multi-wavelength observation");
484   - id(filename+"["+gammalib::str(extno)+"]");
485   - m_filename = filename;
486   - m_extno = gammalib::str(extno);
487   - m_instrument = spec->instrument();
488   -
489   - // Return
490   - return;
491   -}
492   -
493   -
494   -/***********************************************************************//**
495   - * @brief Load observation
496   - *
497   - * @param[in] filename File name.
498   - * @param[in] extname FITS extension name.
499   - ***************************************************************************/
500   -void GMWLObservation::load(const std::string& filename,
501   - const std::string& extname)
502   -{
503   - // Clear observation
504   - clear();
  402 + // Create file name
  403 + GFilename fname(filename);
505 404  
506 405 // Allocate spectrum
507 406 GMWLSpectrum* spec = new GMWLSpectrum;
508 407 m_events = spec;
509 408  
510 409 // Load spectrum
511   - spec->load(filename, extname);
  410 + if (fname.has_extno()) {
  411 + spec->load(filename);
  412 + m_extno = gammalib::str(fname.extno());
  413 + id(filename+"["+m_extno+"]");
  414 + }
  415 + else if (fname.has_extname()) {
  416 + spec->load(filename);
  417 + m_extname = fname.extname();
  418 + id(filename+"["+m_extname+"]");
  419 + }
  420 + else {
  421 + spec->load(filename);
  422 + id(filename);
  423 + }
512 424  
513 425 // Set attributes
514 426 name("Multi-wavelength observation");
515   - id(filename+"["+extname+"]");
516   - m_filename = filename;
517   - m_extname = extname;
  427 + m_filename = fname.filename();
518 428 m_instrument = spec->instrument();
519 429  
520 430 // Return
... ...
inst/mwl/src/GMWLSpectrum.cpp
1 1 /***************************************************************************
2 2 * GMWLSpectrum.cpp - Multi-wavelength spectrum class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2013 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2015 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -29,6 +29,7 @@
29 29 #include <config.h>
30 30 #endif
31 31 #include "GTools.hpp"
  32 +#include "GFilename.hpp"
32 33 #include "GFits.hpp"
33 34 #include "GFitsTable.hpp"
34 35 #include "GEnergy.hpp"
... ... @@ -259,70 +260,25 @@ GMWLSpectrum* GMWLSpectrum::clone(void) const
259 260 ***************************************************************************/
260 261 void GMWLSpectrum::load(const std::string& filename)
261 262 {
262   - // Clear object
263   - clear();
264   -
265   - // Open FITS file
266   - GFits file(filename);
267   -
268   - // Read spectrum
269   - read(file);
270   -
271   - // Close FITS file
272   - file.close();
273   -
274   - // Return
275   - return;
276   -}
277   -
278   -
279   -/***********************************************************************//**
280   - * @brief Load spectrum from FITS file
281   - *
282   - * @param[in] filename FITS file name.
283   - * @param[in] extname FITS extension name.
284   - *
285   - * This method loads a spectrum from the specified extension from a FITS
286   - * file.
287   - ***************************************************************************/
288   -void GMWLSpectrum::load(const std::string& filename, const std::string& extname)
289   -{
290   - // Clear object
291   - clear();
292   -
293   - // Open FITS file
294   - GFits file(filename);
295   -
296   - // Read spectrum from FITS file
297   - read(file, extname);
298   -
299   - // Close FITS file
300   - file.close();
301   -
302   - // Return
303   - return;
304   -}
  263 + // Create file name
  264 + GFilename fname(filename);
305 265  
306   -
307   -/***********************************************************************//**
308   - * @brief Load spectrum from FITS file
309   - *
310   - * @param[in] filename FITS file name.
311   - * @param[in] extno FITS extension number.
312   - *
313   - * This method loads a spectrum from the specified extension number from a
314   - * FITS file.
315   - ***************************************************************************/
316   -void GMWLSpectrum::load(const std::string& filename, const int& extno)
317   -{
318 266 // Clear object
319 267 clear();
320 268  
321 269 // Open FITS file
322   - GFits file(filename);
  270 + GFits file(fname.filename());
323 271  
324   - // Read spectrum from FITS file
325   - read(file, extno);
  272 + // Read spectrum
  273 + if (fname.has_extno()) {
  274 + read(file, fname.extno());
  275 + }
  276 + else if (fname.has_extname()) {
  277 + read(file, fname.extname());
  278 + }
  279 + else {
  280 + read(file);
  281 + }
326 282  
327 283 // Close FITS file
328 284 file.close();
... ... @@ -336,7 +292,7 @@ void GMWLSpectrum::load(const std::string&amp; filename, const int&amp; extno)
336 292 * @brief Save spectrum
337 293 *
338 294 * @param[in] filename File name.
339   - * @param[in] clobber Overwrite existing file (default=false).
  295 + * @param[in] clobber Overwrite existing file (default: false).
340 296 *
341 297 * @todo To be implemented.
342 298 ***************************************************************************/
... ...
inst/mwl/test/test_MWL.cpp
... ... @@ -191,9 +191,9 @@ void TestGMWL::test_optimizer(void)
191 191 test_try("Load multi-wavelength observations");
192 192 try {
193 193 obs.clear();
194   - GMWLObservation comptel(crab_fits, "COMPTEL");
195   - GMWLObservation lat(crab_fits, "LAT");
196   - GMWLObservation hess(crab_fits, "HESS");
  194 + GMWLObservation comptel(crab_fits+"[COMPTEL]");
  195 + GMWLObservation lat(crab_fits+"[LAT]");
  196 + GMWLObservation hess(crab_fits+"[HESS]");
197 197 obs.append(comptel);
198 198 obs.append(lat);
199 199 obs.append(hess);
... ...
inst/mwl/test/test_python.py
... ... @@ -2,8 +2,6 @@
2 2  
3 3 import gammalib
4 4 import math
5   -#from gammalib import *
6   -#from math import *
7 5 import os
8 6  
9 7  
... ... @@ -29,7 +27,7 @@ def extract_data(filename):
29 27  
30 28 # Load spectrum
31 29 spectrum = gammalib.GMWLSpectrum()
32   - spectrum.load(filename, extno)
  30 + spectrum.load(filename+"["+str(extno)+"]")
33 31  
34 32 # Add spectral points
35 33 x = []
... ... @@ -66,9 +64,9 @@ def fit_spectrum(filename, xmlname):
66 64 """
67 65 # Load observations
68 66 obs = gammalib.GObservations()
69   - comptel = gammalib.GMWLObservation(filename, "COMPTEL")
70   - lat = gammalib.GMWLObservation(filename, "LAT")
71   - hess = gammalib.GMWLObservation(filename, "HESS")
  67 + comptel = gammalib.GMWLObservation(filename+"[COMPTEL]")
  68 + lat = gammalib.GMWLObservation(filename+"[LAT]")
  69 + hess = gammalib.GMWLObservation(filename+"[HESS]")
72 70 obs.append(comptel)
73 71 obs.append(lat)
74 72 obs.append(hess)
... ...
pyext/GCsv.i
1 1 /***************************************************************************
2   - * GCsv.i - Column separated values table class *
  2 + * GCsv.i - Comma-separated values table class *
3 3 * ----------------------------------------------------------------------- *
4 4 * copyright (C) 2010-2015 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
... ... @@ -20,7 +20,7 @@
20 20 ***************************************************************************/
21 21 /**
22 22 * @file GCsv.hpp
23   - * @brief Column separated values table class definition
  23 + * @brief Comma-separated values table class definition
24 24 * @author Juergen Knoedlseder
25 25 */
26 26 %{
... ... @@ -80,7 +80,7 @@ static int csv_tuple(PyObject *input, int *ptr) {
80 80 /***********************************************************************//**
81 81 * @class GCsv
82 82 *
83   - * @brief Column separated values table class definition
  83 + * @brief Comma-separated values table class definition
84 84 ***************************************************************************/
85 85 class GCsv : public GBase {
86 86 public:
... ...
pyext/GEbounds.i
... ... @@ -39,13 +39,12 @@ class GEbounds : public GContainer {
39 39 public:
40 40 // Constructors and destructors
41 41 GEbounds(void);
42   - GEbounds(const GEbounds& ebds);
  42 + explicit GEbounds(const std::string& filename);
43 43 explicit GEbounds(const GXmlElement& xml);
  44 + GEbounds(const GEbounds& ebds);
44 45 GEbounds(const GEnergy& emin, const GEnergy& emax);
45 46 GEbounds(const int& num, const GEnergy& emin, const GEnergy& emax,
46 47 const bool& log = true);
47   - GEbounds(const std::string& filename,
48   - const std::string& extname = "EBOUNDS");
49 48 virtual ~GEbounds(void);
50 49  
51 50 // Methods
... ... @@ -63,11 +62,9 @@ public:
63 62 void extend(const GEbounds& ebds);
64 63 void set_lin(const int& num, const GEnergy& emin, const GEnergy& emax);
65 64 void set_log(const int& num, const GEnergy& emin, const GEnergy& emax);
66   - void load(const std::string& filename,
67   - const std::string& extname = "EBOUNDS");
  65 + void load(const std::string& filename);
68 66 void save(const std::string& filename,
69 67 const bool& clobber = false,
70   - const std::string& extname = "EBOUNDS",
71 68 const std::string& unit = "keV") const;
72 69 void read(const GFitsTable& table);
73 70 void write(GFits& file,
... ...
pyext/GEnergies.i
... ... @@ -41,8 +41,7 @@ class GEnergies : public GContainer {
41 41 public:
42 42 // Constructors and destructors
43 43 GEnergies(void);
44   - GEnergies(const std::string& filename,
45   - const std::string& extname = "ENERGIES");
  44 + explicit GEnergies(const std::string& filename);
46 45 GEnergies(const GEnergies& energies);
47 46 GEnergies(const int& num, const GEnergy& emin, const GEnergy& emax,
48 47 const bool& log = true);
... ... @@ -64,13 +63,12 @@ public:
64 63 const GEnergy& emax);
65 64 void set_log(const int& num, const GEnergy& emin,
66 65 const GEnergy& emax);
67   - void load(const std::string& filename,
68   - const std::string& extname = "ENERGIES");
  66 + void load(const std::string& filename);
69 67 void save(const std::string& filename,
70   - const bool& clobber = false,
71   - const std::string& extname = "ENERGIES") const;
  68 + const bool& clobber = false) const;
72 69 void read(const GFitsTable& table);
73   - void write(GFits& file, const std::string& extname = "ENERGIES") const;
  70 + void write(GFits& file,
  71 + const std::string& extname = "ENERGIES") const;
74 72 };
75 73  
76 74  
... ...
pyext/GFilename.i 0 → 100644
  1 +/***************************************************************************
  2 + * GFilename.i - Filename class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2015 by Juergen Knoedlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software: you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation, either version 3 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + * This program is distributed in the hope that it will be useful, *
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15 + * GNU General Public License for more details. *
  16 + * *
  17 + * You should have received a copy of the GNU General Public License *
  18 + * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  19 + * *
  20 + ***************************************************************************/
  21 +/**
  22 + * @file GFilename.i
  23 + * @brief Filename class interface definition
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +%{
  27 +/* Put headers and other declarations here that are needed for compilation */
  28 +#include "GFilename.hpp"
  29 +%}
  30 +
  31 +
  32 +/***********************************************************************//**
  33 + * @class GFilename
  34 + *
  35 + * @brief Filename class
  36 + ***************************************************************************/
  37 +class GFilename : public GBase {
  38 +
  39 +public:
  40 + // Constructors and destructors
  41 + GFilename(void);
  42 + GFilename(const std::string& filename);
  43 + GFilename(const GFilename& filename);
  44 + GFilename(const char* filename);
  45 + virtual ~GFilename(void);
  46 +
  47 + // Methods
  48 + void clear(void);
  49 + GFilename* clone(void) const;
  50 + std::string classname(void) const;
  51 + bool empty(void) const;
  52 + int size(void) const;
  53 + int length(void) const;
  54 + const std::string& filename(void) const;
  55 + std::string extname(const std::string& defaultname = "") const;
  56 + int extno(const int& defaultno = -1) const;
  57 + int extver(const int& defaultver = 0) const;
  58 + bool has_extname(void) const;
  59 + bool has_extno(void) const;
  60 + bool has_extver(void) const;
  61 +};
  62 +
  63 +
  64 +/***********************************************************************//**
  65 + * @brief GFilename class extension
  66 + ***************************************************************************/
  67 +%extend GFilename {
  68 + GFilename copy() {
  69 + return (*self);
  70 + }
  71 +};
... ...
pyext/GFitsTableBitCol.i
... ... @@ -71,16 +71,44 @@ public:
71 71 ***************************************************************************/
72 72 %extend GFitsTableBitCol {
73 73 bool __getitem__(int GFitsTableColInx[]) {
74   - if (GFitsTableColInx[0] == 1)
  74 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  75 + throw GException::out_of_range("__getitem__()", "Row index",
  76 + GFitsTableColInx[1], self->length());
  77 + }
  78 + if (GFitsTableColInx[0] == 1) {
75 79 return (*self)(GFitsTableColInx[1]);
76   - else
77   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  80 + }
  81 + else {
  82 + if (GFitsTableColInx[2] >= 0 &&
  83 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  84 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  85 + }
  86 + else {
  87 + throw GException::out_of_range("__getitem__()", "Column index",
  88 + GFitsTableColInx[2],
  89 + self->elements(GFitsTableColInx[1]));
  90 + }
  91 + }
78 92 }
79 93 void __setitem__(int GFitsTableColInx[], bool value) {
80   - if (GFitsTableColInx[0] == 1)
  94 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  95 + throw GException::out_of_range("__setitem__()", "Row index",
  96 + GFitsTableColInx[1], self->length());
  97 + }
  98 + if (GFitsTableColInx[0] == 1) {
81 99 (*self)(GFitsTableColInx[1]) = value;
82   - else
83   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  100 + }
  101 + else {
  102 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  103 + self->elements(GFitsTableColInx[1])) {
  104 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  105 + }
  106 + else {
  107 + throw GException::out_of_range("__setitem__()", "Column index",
  108 + GFitsTableColInx[2],
  109 + self->elements(GFitsTableColInx[1]));
  110 + }
  111 + }
84 112 }
85 113 GFitsTableBitCol copy() {
86 114 return (*self);
... ...
pyext/GFitsTableBoolCol.i
... ... @@ -71,16 +71,44 @@ public:
71 71 ***************************************************************************/
72 72 %extend GFitsTableBoolCol {
73 73 bool __getitem__(int GFitsTableColInx[]) {
74   - if (GFitsTableColInx[0] == 1)
  74 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  75 + throw GException::out_of_range("__getitem__()", "Row index",
  76 + GFitsTableColInx[1], self->length());
  77 + }
  78 + if (GFitsTableColInx[0] == 1) {
75 79 return (*self)(GFitsTableColInx[1]);
76   - else
77   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  80 + }
  81 + else {
  82 + if (GFitsTableColInx[2] >= 0 &&
  83 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  84 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  85 + }
  86 + else {
  87 + throw GException::out_of_range("__getitem__()", "Column index",
  88 + GFitsTableColInx[2],
  89 + self->elements(GFitsTableColInx[1]));
  90 + }
  91 + }
78 92 }
79 93 void __setitem__(int GFitsTableColInx[], bool value) {
80   - if (GFitsTableColInx[0] == 1)
  94 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  95 + throw GException::out_of_range("__setitem__()", "Row index",
  96 + GFitsTableColInx[1], self->length());
  97 + }
  98 + if (GFitsTableColInx[0] == 1) {
81 99 (*self)(GFitsTableColInx[1]) = value;
82   - else
83   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  100 + }
  101 + else {
  102 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  103 + self->elements(GFitsTableColInx[1])) {
  104 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  105 + }
  106 + else {
  107 + throw GException::out_of_range("__setitem__()", "Column index",
  108 + GFitsTableColInx[2],
  109 + self->elements(GFitsTableColInx[1]));
  110 + }
  111 + }
84 112 }
85 113 GFitsTableBoolCol copy() {
86 114 return (*self);
... ...
pyext/GFitsTableByteCol.i
... ... @@ -70,16 +70,44 @@ public:
70 70 ***************************************************************************/
71 71 %extend GFitsTableByteCol {
72 72 unsigned char __getitem__(int GFitsTableColInx[]) {
73   - if (GFitsTableColInx[0] == 1)
  73 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  74 + throw GException::out_of_range("__getitem__()", "Row index",
  75 + GFitsTableColInx[1], self->length());
  76 + }
  77 + if (GFitsTableColInx[0] == 1) {
74 78 return (*self)(GFitsTableColInx[1]);
75   - else
76   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  79 + }
  80 + else {
  81 + if (GFitsTableColInx[2] >= 0 &&
  82 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  83 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  84 + }
  85 + else {
  86 + throw GException::out_of_range("__getitem__()", "Column index",
  87 + GFitsTableColInx[2],
  88 + self->elements(GFitsTableColInx[1]));
  89 + }
  90 + }
77 91 }
78 92 void __setitem__(int GFitsTableColInx[], unsigned char value) {
79   - if (GFitsTableColInx[0] == 1)
  93 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  94 + throw GException::out_of_range("__setitem__()", "Row index",
  95 + GFitsTableColInx[1], self->length());
  96 + }
  97 + if (GFitsTableColInx[0] == 1) {
80 98 (*self)(GFitsTableColInx[1]) = value;
81   - else
82   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  99 + }
  100 + else {
  101 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  102 + self->elements(GFitsTableColInx[1])) {
  103 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  104 + }
  105 + else {
  106 + throw GException::out_of_range("__setitem__()", "Column index",
  107 + GFitsTableColInx[2],
  108 + self->elements(GFitsTableColInx[1]));
  109 + }
  110 + }
83 111 }
84 112 GFitsTableByteCol copy() {
85 113 return (*self);
... ...
pyext/GFitsTableCDoubleCol.i
... ... @@ -75,17 +75,45 @@ public:
75 75 %extend GFitsTableCDoubleCol {
76 76 /*
77 77 GFits::cdouble __getitem__(int GFitsTableColInx[]) {
78   - if (GFitsTableColInx[0] == 1)
  78 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  79 + throw GException::out_of_range("__getitem__()", "Row index",
  80 + GFitsTableColInx[1], self->length());
  81 + }
  82 + if (GFitsTableColInx[0] == 1) {
79 83 return (*self)(GFitsTableColInx[1]);
80   - else
81   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  84 + }
  85 + else {
  86 + if (GFitsTableColInx[2] >= 0 &&
  87 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  88 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  89 + }
  90 + else {
  91 + throw GException::out_of_range("__getitem__()", "Column index",
  92 + GFitsTableColInx[2],
  93 + self->elements(GFitsTableColInx[1]));
  94 + }
  95 + }
82 96 }
83 97 */
84 98 void __setitem__(int GFitsTableColInx[], GFits::cdouble value) {
85   - if (GFitsTableColInx[0] == 1)
  99 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  100 + throw GException::out_of_range("__setitem__()", "Row index",
  101 + GFitsTableColInx[1], self->length());
  102 + }
  103 + if (GFitsTableColInx[0] == 1) {
86 104 (*self)(GFitsTableColInx[1]) = value;
87   - else
88   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  105 + }
  106 + else {
  107 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  108 + self->elements(GFitsTableColInx[1])) {
  109 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  110 + }
  111 + else {
  112 + throw GException::out_of_range("__setitem__()", "Column index",
  113 + GFitsTableColInx[2],
  114 + self->elements(GFitsTableColInx[1]));
  115 + }
  116 + }
89 117 }
90 118 GFitsTableCDoubleCol copy() {
91 119 return (*self);
... ...
pyext/GFitsTableCFloatCol.i
... ... @@ -75,17 +75,45 @@ public:
75 75 %extend GFitsTableCFloatCol {
76 76 /*
77 77 GFits::cfloat __getitem__(int GFitsTableColInx[]) {
78   - if (GFitsTableColInx[0] == 1)
  78 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  79 + throw GException::out_of_range("__getitem__()", "Row index",
  80 + GFitsTableColInx[1], self->length());
  81 + }
  82 + if (GFitsTableColInx[0] == 1) {
79 83 return (*self)(GFitsTableColInx[1]);
80   - else
81   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  84 + }
  85 + else {
  86 + if (GFitsTableColInx[2] >= 0 &&
  87 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  88 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  89 + }
  90 + else {
  91 + throw GException::out_of_range("__getitem__()", "Column index",
  92 + GFitsTableColInx[2],
  93 + self->elements(GFitsTableColInx[1]));
  94 + }
  95 + }
82 96 }
83 97 */
84 98 void __setitem__(int GFitsTableColInx[], GFits::cfloat value) {
85   - if (GFitsTableColInx[0] == 1)
  99 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  100 + throw GException::out_of_range("__setitem__()", "Row index",
  101 + GFitsTableColInx[1], self->length());
  102 + }
  103 + if (GFitsTableColInx[0] == 1) {
86 104 (*self)(GFitsTableColInx[1]) = value;
87   - else
88   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  105 + }
  106 + else {
  107 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  108 + self->elements(GFitsTableColInx[1])) {
  109 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  110 + }
  111 + else {
  112 + throw GException::out_of_range("__setitem__()", "Column index",
  113 + GFitsTableColInx[2],
  114 + self->elements(GFitsTableColInx[1]));
  115 + }
  116 + }
89 117 }
90 118 GFitsTableCFloatCol copy() {
91 119 return (*self);
... ...
pyext/GFitsTableDoubleCol.i
... ... @@ -71,16 +71,44 @@ public:
71 71 ***************************************************************************/
72 72 %extend GFitsTableDoubleCol {
73 73 double __getitem__(int GFitsTableColInx[]) {
74   - if (GFitsTableColInx[0] == 1)
  74 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  75 + throw GException::out_of_range("__getitem__()", "Row index",
  76 + GFitsTableColInx[1], self->length());
  77 + }
  78 + if (GFitsTableColInx[0] == 1) {
75 79 return (*self)(GFitsTableColInx[1]);
76   - else
77   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  80 + }
  81 + else {
  82 + if (GFitsTableColInx[2] >= 0 &&
  83 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  84 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  85 + }
  86 + else {
  87 + throw GException::out_of_range("__getitem__()", "Column index",
  88 + GFitsTableColInx[2],
  89 + self->elements(GFitsTableColInx[1]));
  90 + }
  91 + }
78 92 }
79 93 void __setitem__(int GFitsTableColInx[], double value) {
80   - if (GFitsTableColInx[0] == 1)
  94 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  95 + throw GException::out_of_range("__setitem__()", "Row index",
  96 + GFitsTableColInx[1], self->length());
  97 + }
  98 + if (GFitsTableColInx[0] == 1) {
81 99 (*self)(GFitsTableColInx[1]) = value;
82   - else
83   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  100 + }
  101 + else {
  102 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  103 + self->elements(GFitsTableColInx[1])) {
  104 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  105 + }
  106 + else {
  107 + throw GException::out_of_range("__setitem__()", "Column index",
  108 + GFitsTableColInx[2],
  109 + self->elements(GFitsTableColInx[1]));
  110 + }
  111 + }
84 112 }
85 113 GFitsTableDoubleCol copy() {
86 114 return (*self);
... ...
pyext/GFitsTableFloatCol.i
... ... @@ -71,16 +71,44 @@ public:
71 71 ***************************************************************************/
72 72 %extend GFitsTableFloatCol {
73 73 float __getitem__(int GFitsTableColInx[]) {
74   - if (GFitsTableColInx[0] == 1)
  74 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  75 + throw GException::out_of_range("__getitem__()", "Row index",
  76 + GFitsTableColInx[1], self->length());
  77 + }
  78 + if (GFitsTableColInx[0] == 1) {
75 79 return (*self)(GFitsTableColInx[1]);
76   - else
77   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  80 + }
  81 + else {
  82 + if (GFitsTableColInx[2] >= 0 &&
  83 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  84 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  85 + }
  86 + else {
  87 + throw GException::out_of_range("__getitem__()", "Column index",
  88 + GFitsTableColInx[2],
  89 + self->elements(GFitsTableColInx[1]));
  90 + }
  91 + }
78 92 }
79 93 void __setitem__(int GFitsTableColInx[], float value) {
80   - if (GFitsTableColInx[0] == 1)
  94 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  95 + throw GException::out_of_range("__setitem__()", "Row index",
  96 + GFitsTableColInx[1], self->length());
  97 + }
  98 + if (GFitsTableColInx[0] == 1) {
81 99 (*self)(GFitsTableColInx[1]) = value;
82   - else
83   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  100 + }
  101 + else {
  102 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  103 + self->elements(GFitsTableColInx[1])) {
  104 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  105 + }
  106 + else {
  107 + throw GException::out_of_range("__setitem__()", "Column index",
  108 + GFitsTableColInx[2],
  109 + self->elements(GFitsTableColInx[1]));
  110 + }
  111 + }
84 112 }
85 113 GFitsTableFloatCol copy() {
86 114 return (*self);
... ...
pyext/GFitsTableLongCol.i
... ... @@ -71,16 +71,44 @@ public:
71 71 ***************************************************************************/
72 72 %extend GFitsTableLongCol {
73 73 long __getitem__(int GFitsTableColInx[]) {
74   - if (GFitsTableColInx[0] == 1)
  74 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  75 + throw GException::out_of_range("__getitem__()", "Row index",
  76 + GFitsTableColInx[1], self->length());
  77 + }
  78 + if (GFitsTableColInx[0] == 1) {
75 79 return (*self)(GFitsTableColInx[1]);
76   - else
77   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  80 + }
  81 + else {
  82 + if (GFitsTableColInx[2] >= 0 &&
  83 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  84 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  85 + }
  86 + else {
  87 + throw GException::out_of_range("__getitem__()", "Column index",
  88 + GFitsTableColInx[2],
  89 + self->elements(GFitsTableColInx[1]));
  90 + }
  91 + }
78 92 }
79 93 void __setitem__(int GFitsTableColInx[], long value) {
80   - if (GFitsTableColInx[0] == 1)
  94 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  95 + throw GException::out_of_range("__setitem__()", "Row index",
  96 + GFitsTableColInx[1], self->length());
  97 + }
  98 + if (GFitsTableColInx[0] == 1) {
81 99 (*self)(GFitsTableColInx[1]) = value;
82   - else
83   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  100 + }
  101 + else {
  102 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  103 + self->elements(GFitsTableColInx[1])) {
  104 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  105 + }
  106 + else {
  107 + throw GException::out_of_range("__setitem__()", "Column index",
  108 + GFitsTableColInx[2],
  109 + self->elements(GFitsTableColInx[1]));
  110 + }
  111 + }
84 112 }
85 113 GFitsTableLongCol copy() {
86 114 return (*self);
... ...
pyext/GFitsTableLongLongCol.i
... ... @@ -71,16 +71,44 @@ public:
71 71 ***************************************************************************/
72 72 %extend GFitsTableLongLongCol {
73 73 long long __getitem__(int GFitsTableColInx[]) {
74   - if (GFitsTableColInx[0] == 1)
  74 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  75 + throw GException::out_of_range("__getitem__()", "Row index",
  76 + GFitsTableColInx[1], self->length());
  77 + }
  78 + if (GFitsTableColInx[0] == 1) {
75 79 return (*self)(GFitsTableColInx[1]);
76   - else
77   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  80 + }
  81 + else {
  82 + if (GFitsTableColInx[2] >= 0 &&
  83 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  84 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  85 + }
  86 + else {
  87 + throw GException::out_of_range("__getitem__()", "Column index",
  88 + GFitsTableColInx[2],
  89 + self->elements(GFitsTableColInx[1]));
  90 + }
  91 + }
78 92 }
79 93 void __setitem__(int GFitsTableColInx[], long long value) {
80   - if (GFitsTableColInx[0] == 1)
  94 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  95 + throw GException::out_of_range("__setitem__()", "Row index",
  96 + GFitsTableColInx[1], self->length());
  97 + }
  98 + if (GFitsTableColInx[0] == 1) {
81 99 (*self)(GFitsTableColInx[1]) = value;
82   - else
83   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  100 + }
  101 + else {
  102 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  103 + self->elements(GFitsTableColInx[1])) {
  104 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  105 + }
  106 + else {
  107 + throw GException::out_of_range("__setitem__()", "Column index",
  108 + GFitsTableColInx[2],
  109 + self->elements(GFitsTableColInx[1]));
  110 + }
  111 + }
84 112 }
85 113 GFitsTableLongLongCol copy() {
86 114 return (*self);
... ...
pyext/GFitsTableShortCol.i
... ... @@ -71,16 +71,44 @@ public:
71 71 ***************************************************************************/
72 72 %extend GFitsTableShortCol {
73 73 short __getitem__(int GFitsTableColInx[]) {
74   - if (GFitsTableColInx[0] == 1)
  74 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  75 + throw GException::out_of_range("__getitem__()", "Row index",
  76 + GFitsTableColInx[1], self->length());
  77 + }
  78 + if (GFitsTableColInx[0] == 1) {
75 79 return (*self)(GFitsTableColInx[1]);
76   - else
77   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  80 + }
  81 + else {
  82 + if (GFitsTableColInx[2] >= 0 &&
  83 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  84 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  85 + }
  86 + else {
  87 + throw GException::out_of_range("__getitem__()", "Column index",
  88 + GFitsTableColInx[2],
  89 + self->elements(GFitsTableColInx[1]));
  90 + }
  91 + }
78 92 }
79 93 void __setitem__(int GFitsTableColInx[], short value) {
80   - if (GFitsTableColInx[0] == 1)
  94 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  95 + throw GException::out_of_range("__setitem__()", "Row index",
  96 + GFitsTableColInx[1], self->length());
  97 + }
  98 + if (GFitsTableColInx[0] == 1) {
81 99 (*self)(GFitsTableColInx[1]) = value;
82   - else
83   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  100 + }
  101 + else {
  102 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  103 + self->elements(GFitsTableColInx[1])) {
  104 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  105 + }
  106 + else {
  107 + throw GException::out_of_range("__setitem__()", "Column index",
  108 + GFitsTableColInx[2],
  109 + self->elements(GFitsTableColInx[1]));
  110 + }
  111 + }
84 112 }
85 113 GFitsTableShortCol copy() {
86 114 return (*self);
... ...
pyext/GFitsTableStringCol.i
... ... @@ -71,16 +71,44 @@ public:
71 71 ***************************************************************************/
72 72 %extend GFitsTableStringCol {
73 73 std::string __getitem__(int GFitsTableColInx[]) {
74   - if (GFitsTableColInx[0] == 1)
  74 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  75 + throw GException::out_of_range("__getitem__()", "Row index",
  76 + GFitsTableColInx[1], self->length());
  77 + }
  78 + if (GFitsTableColInx[0] == 1) {
75 79 return (*self)(GFitsTableColInx[1]);
76   - else
77   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  80 + }
  81 + else {
  82 + if (GFitsTableColInx[2] >= 0 &&
  83 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  84 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  85 + }
  86 + else {
  87 + throw GException::out_of_range("__getitem__()", "Column index",
  88 + GFitsTableColInx[2],
  89 + self->elements(GFitsTableColInx[1]));
  90 + }
  91 + }
78 92 }
79 93 void __setitem__(int GFitsTableColInx[], std::string value) {
80   - if (GFitsTableColInx[0] == 1)
  94 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  95 + throw GException::out_of_range("__setitem__()", "Row index",
  96 + GFitsTableColInx[1], self->length());
  97 + }
  98 + if (GFitsTableColInx[0] == 1) {
81 99 (*self)(GFitsTableColInx[1]) = value;
82   - else
83   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  100 + }
  101 + else {
  102 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  103 + self->elements(GFitsTableColInx[1])) {
  104 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  105 + }
  106 + else {
  107 + throw GException::out_of_range("__setitem__()", "Column index",
  108 + GFitsTableColInx[2],
  109 + self->elements(GFitsTableColInx[1]));
  110 + }
  111 + }
84 112 }
85 113 GFitsTableStringCol copy() {
86 114 return (*self);
... ...
pyext/GFitsTableULongCol.i
... ... @@ -71,16 +71,44 @@ public:
71 71 ***************************************************************************/
72 72 %extend GFitsTableULongCol {
73 73 unsigned long __getitem__(int GFitsTableColInx[]) {
74   - if (GFitsTableColInx[0] == 1)
  74 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  75 + throw GException::out_of_range("__getitem__()", "Row index",
  76 + GFitsTableColInx[1], self->length());
  77 + }
  78 + if (GFitsTableColInx[0] == 1) {
75 79 return (*self)(GFitsTableColInx[1]);
76   - else
77   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  80 + }
  81 + else {
  82 + if (GFitsTableColInx[2] >= 0 &&
  83 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  84 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  85 + }
  86 + else {
  87 + throw GException::out_of_range("__getitem__()", "Column index",
  88 + GFitsTableColInx[2],
  89 + self->elements(GFitsTableColInx[1]));
  90 + }
  91 + }
78 92 }
79 93 void __setitem__(int GFitsTableColInx[], unsigned long value) {
80   - if (GFitsTableColInx[0] == 1)
  94 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  95 + throw GException::out_of_range("__setitem__()", "Row index",
  96 + GFitsTableColInx[1], self->length());
  97 + }
  98 + if (GFitsTableColInx[0] == 1) {
81 99 (*self)(GFitsTableColInx[1]) = value;
82   - else
83   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  100 + }
  101 + else {
  102 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  103 + self->elements(GFitsTableColInx[1])) {
  104 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  105 + }
  106 + else {
  107 + throw GException::out_of_range("__setitem__()", "Column index",
  108 + GFitsTableColInx[2],
  109 + self->elements(GFitsTableColInx[1]));
  110 + }
  111 + }
84 112 }
85 113 GFitsTableULongCol copy() {
86 114 return (*self);
... ...
pyext/GFitsTableUShortCol.i
... ... @@ -71,16 +71,44 @@ public:
71 71 ***************************************************************************/
72 72 %extend GFitsTableUShortCol {
73 73 unsigned short __getitem__(int GFitsTableColInx[]) {
74   - if (GFitsTableColInx[0] == 1)
  74 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  75 + throw GException::out_of_range("__getitem__()", "Row index",
  76 + GFitsTableColInx[1], self->length());
  77 + }
  78 + if (GFitsTableColInx[0] == 1) {
75 79 return (*self)(GFitsTableColInx[1]);
76   - else
77   - return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  80 + }
  81 + else {
  82 + if (GFitsTableColInx[2] >= 0 &&
  83 + GFitsTableColInx[2] < self->elements(GFitsTableColInx[1])) {
  84 + return (*self)(GFitsTableColInx[1], GFitsTableColInx[2]);
  85 + }
  86 + else {
  87 + throw GException::out_of_range("__getitem__()", "Column index",
  88 + GFitsTableColInx[2],
  89 + self->elements(GFitsTableColInx[1]));
  90 + }
  91 + }
78 92 }
79 93 void __setitem__(int GFitsTableColInx[], unsigned short value) {
80   - if (GFitsTableColInx[0] == 1)
  94 + if (GFitsTableColInx[1] < 0 || GFitsTableColInx[1] >= self->length()) {
  95 + throw GException::out_of_range("__setitem__()", "Row index",
  96 + GFitsTableColInx[1], self->length());
  97 + }
  98 + if (GFitsTableColInx[0] == 1) {
81 99 (*self)(GFitsTableColInx[1]) = value;
82   - else
83   - (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  100 + }
  101 + else {
  102 + if (GFitsTableColInx[2] >= 0 && GFitsTableColInx[2] <
  103 + self->elements(GFitsTableColInx[1])) {
  104 + (*self)(GFitsTableColInx[1], GFitsTableColInx[2]) = value;
  105 + }
  106 + else {
  107 + throw GException::out_of_range("__setitem__()", "Column index",
  108 + GFitsTableColInx[2],
  109 + self->elements(GFitsTableColInx[1]));
  110 + }
  111 + }
84 112 }
85 113 GFitsTableUShortCol copy() {
86 114 return (*self);
... ...
pyext/GGti.i
... ... @@ -36,9 +36,11 @@
36 36 * @brief Good Time Interval class
37 37 ***************************************************************************/
38 38 class GGti : public GBase {
  39 +
39 40 public:
40 41 // Constructors and destructors
41 42 GGti(void);
  43 + explicit GGti(const std::string& filename);
42 44 GGti(const GGti& gti);
43 45 GGti(const GTime& tstart, const GTime& tstop);
44 46 explicit GGti(const GXmlElement& xml);
... ... @@ -59,11 +61,9 @@ public:
59 61 void remove(const int& index);
60 62 void reserve(const int& num);
61 63 void extend(const GGti& gti);
62   - void load(const std::string& filename,
63   - const std::string& extname = "GTI");
  64 + void load(const std::string& filename);
64 65 void save(const std::string& filename,
65   - const bool& clobber = false,
66   - const std::string& extname = "GTI") const;
  66 + const bool& clobber = false) const;
67 67 void read(const GFitsTable& table);
68 68 void write(GFits& file,
69 69 const std::string& extname = "GTI") const;
... ...
pyext/GModel.i
... ... @@ -72,6 +72,7 @@ public:
72 72 void ts(const double& ts);
73 73 const bool& tscalc(void) const;
74 74 void tscalc(const bool& tscalc);
  75 + const bool& has_ts(void) const;
75 76 GModelPar scale(const std::string& instrument) const;
76 77 void scale(const GModelPar& par);
77 78 std::string ids(void) const;
... ...
pyext/GNodeArray.i
... ... @@ -39,12 +39,14 @@ namespace std {
39 39 * @brief Node array class
40 40 ***************************************************************************/
41 41 class GNodeArray : public GContainer {
  42 +
42 43 public:
43 44 // Constructors and destructors
44 45 GNodeArray(void);
45   - GNodeArray(const int& num, const double* array);
  46 + explicit GNodeArray(const std::string& filename);
46 47 explicit GNodeArray(const GVector& vector);
47 48 explicit GNodeArray(const std::vector<double>& vector);
  49 + GNodeArray(const int& num, const double* array);
48 50 GNodeArray(const GNodeArray& array);
49 51 virtual ~GNodeArray(void);
50 52  
... ... @@ -70,10 +72,9 @@ public:
70 72 const int& inx_right(void) const;
71 73 const double& wgt_left(void) const;
72 74 const double& wgt_right(void) const;
73   - void load(const std::string& filename,
74   - const std::string& extname = "NODES");
75   - void save(const std::string& filename, const bool& clobber = false,
76   - const std::string& extname = "NODES") const;
  75 + void load(const std::string& filename);
  76 + void save(const std::string& filename,
  77 + const bool& clobber = false) const;
77 78 void read(const GFitsTable& table);
78 79 void write(GFits& file,
79 80 const std::string& extname = "NODES") const;
... ...
pyext/GSkyMap.i
... ... @@ -183,11 +183,21 @@ public:
183 183 ***************************************************************************/
184 184 %extend GSkyMap {
185 185 double __getitem__(int GSkyMapInx[]) {
  186 + if (GSkyMapInx[1] < 0 || GSkyMapInx[1] >= self->npix()) {
  187 + throw GException::out_of_range("__getitem__(int)", "Sky map index",
  188 + GSkyMapInx[1], self->npix());
  189 + }
186 190 if (GSkyMapInx[0] == 1) {
187 191 return (*self)(GSkyMapInx[1]);
188 192 }
189 193 else {
190   - return (*self)(GSkyMapInx[1], GSkyMapInx[2]);
  194 + if (GSkyMapInx[2] >= 0 && GSkyMapInx[2] < self->nmaps()) {
  195 + return (*self)(GSkyMapInx[1], GSkyMapInx[2]);
  196 + }
  197 + else {
  198 + throw GException::out_of_range("__getitem__(int)", "Sky map number",
  199 + GSkyMapInx[2], self->nmaps());
  200 + }
191 201 }
192 202 }
193 203 /*
... ... @@ -196,11 +206,21 @@ public:
196 206 }
197 207 */
198 208 void __setitem__(int GSkyMapInx[], double value) {
  209 + if (GSkyMapInx[1] < 0 || GSkyMapInx[1] >= self->npix()) {
  210 + throw GException::out_of_range("__setitem__(int)", "Sky map index",
  211 + GSkyMapInx[1], self->npix());
  212 + }
199 213 if (GSkyMapInx[0] == 1) {
200 214 (*self)(GSkyMapInx[1]) = value;
201 215 }
202 216 else {
203   - (*self)(GSkyMapInx[1], GSkyMapInx[2]) = value;
  217 + if (GSkyMapInx[2] >= 0 && GSkyMapInx[2] < self->nmaps()) {
  218 + (*self)(GSkyMapInx[1], GSkyMapInx[2]) = value;
  219 + }
  220 + else {
  221 + throw GException::out_of_range("__setitem__(int)", "Sky map number",
  222 + GSkyMapInx[2], self->nmaps());
  223 + }
204 224 }
205 225 }
206 226 /*
... ...
pyext/GSkyRegions.i
... ... @@ -50,15 +50,11 @@ public:
50 50 int size(void) const;
51 51 bool is_empty(void) const;
52 52 GSkyRegion* set(const int& index, const GSkyRegion& region);
53   - GSkyRegion* set(const std::string& name, const GSkyRegion& region);
54 53 GSkyRegion* append(const GSkyRegion& region);
55 54 GSkyRegion* insert(const int& index, const GSkyRegion& region);
56   - GSkyRegion* insert(const std::string& name, const GSkyRegion& region);
57 55 void remove(const int& index);
58   - void remove(const std::string& name);
59 56 void reserve(const int& num);
60 57 void extend(const GSkyRegions& regions);
61   - bool contains(const std::string& name) const;
62 58 void load(const std::string& filename);
63 59 void save(const std::string& filename) const;
64 60  
... ...
pyext/GTools.i
... ... @@ -63,6 +63,7 @@ namespace gammalib {
63 63 const double& gamma);
64 64 GEnergy elogmean(const GEnergy& a, const GEnergy& b);
65 65 bool file_exists(const std::string& filename);
  66 + bool file_exists_gzip(const std::string& filename);
66 67 bool dir_exists(const std::string& dirname);
67 68 bool is_infinite(const double& x);
68 69 bool is_notanumber(const double& x);
... ... @@ -84,4 +85,6 @@ namespace gammalib {
84 85 void xml_check_par(const std::string& origin,
85 86 const std::string& name,
86 87 const int& number);
  88 + int recv(int fd, char *buffer, int len, int flags,
  89 + int timeout);
87 90 }
... ...
pyext/Makefile.am
... ... @@ -51,7 +51,7 @@ INST_SWIG_TARGETS = $(MWL_SWIG_TARGETS) \
51 51 $(LAT_SWIG_TARGETS) \
52 52 $(COM_SWIG_TARGETS)
53 53  
54   -# Test scripts to be distributed in $(pyexecdir)/ctools/tests
  54 +# Test scripts to be distributed in $(pyexecdir)/gammalib/tests
55 55 testscripts = gammalib/tests/__init__.py \
56 56 ../test/test_python.py \
57 57 ../test/test_GApplication.py \
... ... @@ -139,6 +139,14 @@ all-local: build
139 139 # Build the gammalib extension module
140 140 build: $(BUILT_SOURCES)
141 141 @PYTHON_BUILD_PREFIX@ $(PYTHON) setup.py build_ext
  142 +if IS_ELCAPITAN
  143 + -for f in build/gammalib/_*.so; do \
  144 + echo "Post process module "$$f; \
  145 + install_name_tool -change $(libdir)/libgamma.1.dylib @rpath/libgamma.1.dylib $$f; \
  146 + install_name_tool -add_rpath $(libdir) $$f; \
  147 + install_name_tool -add_rpath $(abs_top_srcdir)/src/.libs $$f; \
  148 + done
  149 +endif
142 150  
143 151 # Do nothing for 'make check'
144 152 #check-local:
... ...
pyext/gammalib/support.i
... ... @@ -71,3 +71,4 @@
71 71 %include "GUrl.i"
72 72 %include "GUrlFile.i"
73 73 %include "GUrlString.i"
  74 +%include "GFilename.i"
... ...
pyext/setup.py.in
1 1 #############################################################################
2 2 # Disutils setup file for gammalib Python extension module #
3 3 # ------------------------------------------------------------------------- #
4   -# Copyright (C) 2011-2014 Juergen Knoedlseder #
  4 +# Copyright (C) 2011-2015 Juergen Knoedlseder #
5 5 # ------------------------------------------------------------------------- #
6 6 # #
7 7 # This program is free software: you can redistribute it and/or modify #
... ... @@ -139,6 +139,10 @@ else:
139 139 extra_compile_args = []
140 140 extra_link_args = []
141 141  
  142 +# Optionally add link flag for El Capitan post-processing of modules
  143 +if '@IS_ELCAPITAN_TRUE@' != '#':
  144 + extra_link_args.append('-headerpad_max_install_names')
  145 +
142 146 # Loop over all core modules
143 147 for module in core_modules:
144 148  
... ... @@ -225,19 +229,20 @@ for name in casts:
225 229 names += "'"+name+"'"
226 230 n_names += 1
227 231  
228   -# Create gammalib/__init__.py file
229   -file = open(pkg_name+'/__init__.py', 'w')
230   -file.write('# This file is created automatically by setup.py\n')
231   -file.write('# Please do not modify, unless you exactly know what you do.\n')
232   -file.write('__all__ = [')
233   -file.write(names)
234   -file.write(']\n')
235   -for module in all_modules:
236   - file.write('from gammalib.'+module+' import *\n')
237   -
238   -# Remove useless and annoying `*_swigregister` entries from the namespace
239   -# see https://cta-redmine.irap.omp.eu/issues/832
240   -file.write("""
  232 +# Create gammalib/__init__.py file (build only)
  233 +if is_build:
  234 + file = open(pkg_name+'/__init__.py', 'w')
  235 + file.write('# This file is created automatically by setup.py\n')
  236 + file.write('# Please do not modify, unless you exactly know what you do.\n')
  237 + file.write('__all__ = [')
  238 + file.write(names)
  239 + file.write(']\n')
  240 + for module in all_modules:
  241 + file.write('from gammalib.'+module+' import *\n')
  242 +
  243 + # Remove useless and annoying `*_swigregister` entries from the namespace
  244 + # see https://cta-redmine.irap.omp.eu/issues/832
  245 + file.write("""
241 246 bad_entries = [entry for entry in list(locals())
242 247 if entry.endswith('_swigregister')]
243 248 for entry in bad_entries:
... ... @@ -245,14 +250,19 @@ for entry in bad_entries:
245 250 del gammalib.gammalib
246 251 """)
247 252  
248   -# Add test function
249   -# see https://cta-redmine.irap.omp.eu/issues/1486
250   -file.write("""
  253 + # Add test function
  254 + # see https://cta-redmine.irap.omp.eu/issues/1486
  255 + file.write("""
251 256 def test():
252 257 from gammalib.tests import test_python
253 258 test_python.test(installed=True)
254 259 """)
255   -file.close()
  260 +
  261 + # Add version
  262 + file.write("\n__version__ = '@PACKAGE_VERSION@'\n")
  263 +
  264 + # Close file
  265 + file.close()
256 266  
257 267 # Set data files to install.
258 268 data_files=[('@prefix@/share/gammalib/swig', install_files)]
... ...
src/obs/GEbounds.cpp
... ... @@ -29,9 +29,9 @@
29 29 #include <config.h>
30 30 #endif
31 31 #include <cmath>
32   -//#include <iostream>
33 32 #include "GException.hpp"
34 33 #include "GTools.hpp"
  34 +#include "GFilename.hpp"
35 35 #include "GEbounds.hpp"
36 36 #include "GFits.hpp"
37 37 #include "GFitsTable.hpp"
... ... @@ -77,17 +77,19 @@ GEbounds::GEbounds(void)
77 77  
78 78  
79 79 /***********************************************************************//**
80   - * @brief Copy constructor
  80 + * @brief FITS file constructor
81 81 *
82   - * @param[in] ebds Energy boundaries.
  82 + * @param[in] filename FITS file name.
  83 + *
  84 + * Constructs energy boundaries from a FITS file.
83 85 ***************************************************************************/
84   -GEbounds::GEbounds(const GEbounds& ebds)
  86 +GEbounds::GEbounds(const std::string& filename)
85 87 {
86   - // Initialise class members for clean destruction
  88 + // Initialise members
87 89 init_members();
88 90  
89   - // Copy members
90   - copy_members(ebds);
  91 + // Load FITS file
  92 + load(filename);
91 93  
92 94 // Return
93 95 return;
... ... @@ -99,7 +101,7 @@ GEbounds::GEbounds(const GEbounds&amp; ebds)
99 101 *
100 102 * @param[in] xml XML element.
101 103 *
102   - * Constructs energy bounds from an XML element.
  104 + * Constructs energy boundaries from an XML element.
103 105 ***************************************************************************/
104 106 GEbounds::GEbounds(const GXmlElement& xml)
105 107 {
... ... @@ -115,12 +117,30 @@ GEbounds::GEbounds(const GXmlElement&amp; xml)
115 117  
116 118  
117 119 /***********************************************************************//**
  120 + * @brief Copy constructor
  121 + *
  122 + * @param[in] ebds Energy boundaries.
  123 + ***************************************************************************/
  124 +GEbounds::GEbounds(const GEbounds& ebds)
  125 +{
  126 + // Initialise class members for clean destruction
  127 + init_members();
  128 +
  129 + // Copy members
  130 + copy_members(ebds);
  131 +
  132 + // Return
  133 + return;
  134 +}
  135 +
  136 +
  137 +/***********************************************************************//**
118 138 * @brief Single energy band constructor
119 139 *
120 140 * @param[in] emin Minimum energy of the interval.
121 141 * @param[in] emax Maximum energy of the interval.
122 142 *
123   - * Constructs energy bounds for one (emin, emax) energy band.
  143 + * Constructs energy boundaries for one (emin, emax) energy band.
124 144 ***************************************************************************/
125 145 GEbounds::GEbounds(const GEnergy& emin, const GEnergy& emax)
126 146 {
... ... @@ -167,25 +187,6 @@ GEbounds::GEbounds(const int&amp; num, const GEnergy&amp; emin, const GEnergy&amp; emax,
167 187  
168 188  
169 189 /***********************************************************************//**
170   - * @brief Load constructor
171   - *
172   - * @param[in] filename FITS filename.
173   - * @param[in] extname FITS extension name (defaults to "EBOUNDS").
174   - ***************************************************************************/
175   -GEbounds::GEbounds(const std::string& filename, const std::string& extname)
176   -{
177   - // Initialise members
178   - init_members();
179   -
180   - // Load FITS file
181   - load(filename, extname);
182   -
183   - // Return
184   - return;
185   -}
186   -
187   -
188   -/***********************************************************************//**
189 190 * @brief Destructor
190 191 ***************************************************************************/
191 192 GEbounds::~GEbounds(void)
... ... @@ -568,21 +569,26 @@ void GEbounds::set_log(const int&amp; num, const GEnergy&amp; emin, const GEnergy&amp; emax)
568 569 /***********************************************************************//**
569 570 * @brief Load energy boundaries from FITS file
570 571 *
571   - * @param[in] filename FITS filename.
572   - * @param[in] extname FITS extension name (defaults to "EBOUNDS").
  572 + * @param[in] filename FITS file name.
573 573 *
574   - * Loads the energy boundaries from FITS file.
  574 + * Loads the energy boundaries from a FITS file.
  575 + *
  576 + * If no extension name is provided, the energy boundaries are loaded from
  577 + * the "EBOUNDS" extension.
575 578 ***************************************************************************/
576   -void GEbounds::load(const std::string& filename, const std::string& extname)
  579 +void GEbounds::load(const std::string& filename)
577 580 {
  581 + // Create file name
  582 + GFilename fname(filename);
  583 +
578 584 // Allocate FITS file
579 585 GFits file;
580 586  
581 587 // Open FITS file
582   - file.open(filename);
  588 + file.open(fname.filename());
583 589  
584 590 // Get energy boundary table
585   - const GFitsTable& table = *file.table(extname);
  591 + const GFitsTable& table = *file.table(fname.extname("EBOUNDS"));
586 592  
587 593 // Read energy boundaries from table
588 594 read(table);
... ... @@ -598,26 +604,30 @@ void GEbounds::load(const std::string&amp; filename, const std::string&amp; extname)
598 604 /***********************************************************************//**
599 605 * @brief Save energy boundaries into FITS file
600 606 *
601   - * @param[in] filename FITS filename.
602   - * @param[in] clobber Overwrite any existing file (defaults to false)?
603   - * @param[in] extname Energy boundary extension name (defaults to "EBOUNDS").
604   - * @param[in] unit Energy units (defaults to "keV")
  607 + * @param[in] filename FITS file name.
  608 + * @param[in] clobber Overwrite any existing file (default: false)?
  609 + * @param[in] unit Energy units (default: "keV")
605 610 *
606   - * Saves the energy boundaries into extension @p extname of a FITS file.
  611 + * Saves energy boundaries into a FITS file.
  612 + *
  613 + * If no extension name is provided, the energy boundaries are saved into
  614 + * an "EBOUNDS" extension.
607 615 ***************************************************************************/
608 616 void GEbounds::save(const std::string& filename,
609 617 const bool& clobber,
610   - const std::string& extname,
611 618 const std::string& unit) const
612 619 {
  620 + // Create file name
  621 + GFilename fname(filename);
  622 +
613 623 // Allocate FITS file
614 624 GFits file;
615 625  
616 626 // Write energy boundaries to FITS file
617   - write(file, extname, unit);
  627 + write(file, fname.extname("EBOUNDS"), unit);
618 628  
619 629 // Save to file
620   - file.saveto(filename, clobber);
  630 + file.saveto(fname.filename(), clobber);
621 631  
622 632 // Return
623 633 return;
... ...
src/obs/GEnergies.cpp
... ... @@ -30,6 +30,7 @@
30 30 #endif
31 31 #include "GTools.hpp"
32 32 #include "GException.hpp"
  33 +#include "GFilename.hpp"
33 34 #include "GEnergies.hpp"
34 35 #include "GFits.hpp"
35 36 #include "GFitsTable.hpp"
... ... @@ -71,20 +72,19 @@ GEnergies::GEnergies(void)
71 72  
72 73  
73 74 /***********************************************************************//**
74   - * @brief Load constructor
  75 + * @brief FITS file constructor
75 76 *
76   - * @param[in] filename FITS filename.
77   - * @param[in] extname Energies extension name (defaults to "ENERGIES")
  77 + * @param[in] filename FITS file name.
78 78 *
79   - * Constructs energy container by loading energies from FITS file.
  79 + * Constructs energy container from a FITS file.
80 80 ***************************************************************************/
81   -GEnergies::GEnergies(const std::string& filename, const std::string& extname)
  81 +GEnergies::GEnergies(const std::string& filename)
82 82 {
83 83 // Initialise members
84 84 init_members();
85 85  
86 86 // Load energies
87   - load(filename, extname);
  87 + load(filename);
88 88  
89 89 // Return
90 90 return;
... ... @@ -534,21 +534,26 @@ void GEnergies::set_log(const int&amp; num,
534 534 /***********************************************************************//**
535 535 * @brief Load energies from FITS file
536 536 *
537   - * @param[in] filename FITS filename.
538   - * @param[in] extname Energies extension name (defaults to "ENERGIES")
  537 + * @param[in] filename FITS file name.
539 538 *
540 539 * Loads the energies from FITS file.
  540 + *
  541 + * If no extension name is provided, the energies are loaded from the
  542 + * "ENERGIES" extension.
541 543 ***************************************************************************/
542   -void GEnergies::load(const std::string& filename, const std::string& extname)
  544 +void GEnergies::load(const std::string& filename)
543 545 {
  546 + // Create file name
  547 + GFilename fname(filename);
  548 +
544 549 // Allocate FITS file
545 550 GFits file;
546 551  
547 552 // Open FITS file
548   - file.open(filename);
  553 + file.open(fname.filename());
549 554  
550 555 // Get energies table
551   - const GFitsTable& table = *file.table(extname);
  556 + const GFitsTable& table = *file.table(fname.extname("ENERGIES"));
552 557  
553 558 // Read energies from table
554 559 read(table);
... ... @@ -566,24 +571,25 @@ void GEnergies::load(const std::string&amp; filename, const std::string&amp; extname)
566 571 *
567 572 * @param[in] filename FITS filename.
568 573 * @param[in] clobber Overwrite any existing energies extension?
569   - * @param[in] extname Energies extension name (defaults to "ENERGIES")
570 574 *
571   - * Saves energies into extension @p extname of a FITS file. If the file does
572   - * not exist it is created. If the file exists the energies are appended as
573   - * extension. If another energies extension exists already it is overwritten
574   - * if @p clobber=true.
  575 + * Saves energies into a FITS file.
  576 + *
  577 + * If no extension name is provided, the energies are saved into an
  578 + * "ENERGIES" extension.
575 579 ***************************************************************************/
576   -void GEnergies::save(const std::string& filename, const bool& clobber,
577   - const std::string& extname) const
  580 +void GEnergies::save(const std::string& filename, const bool& clobber) const
578 581 {
  582 + // Create file name
  583 + GFilename fname(filename);
  584 +
579 585 // Allocate FITS file
580 586 GFits file;
581 587  
582 588 // Write energies to FITS file
583   - write(file, extname);
  589 + write(file, fname.extname("ENERGIES"));
584 590  
585 591 // Save to file
586   - file.saveto(filename, clobber);
  592 + file.saveto(fname.filename(), clobber);
587 593  
588 594 // Return
589 595 return;
... ... @@ -637,7 +643,7 @@ void GEnergies::read(const GFitsTable&amp; table)
637 643 * @brief Write energies into FITS object
638 644 *
639 645 * @param[in] file FITS file.
640   - * @param[in] extname Energy extension name (defaults to "ENERGIES")
  646 + * @param[in] extname Energy extension name (default: "ENERGIES")
641 647 *
642 648 * Writes energies into FITS object.
643 649 ***************************************************************************/
... ...
src/obs/GGti.cpp
... ... @@ -30,6 +30,7 @@
30 30 #endif
31 31 #include "GException.hpp"
32 32 #include "GTools.hpp"
  33 +#include "GFilename.hpp"
33 34 #include "GGti.hpp"
34 35 #include "GFits.hpp"
35 36 #include "GFitsTable.hpp"
... ... @@ -73,6 +74,26 @@ GGti::GGti(void)
73 74  
74 75  
75 76 /***********************************************************************//**
  77 + * @brief FITS file constructor
  78 + *
  79 + * @param[in] filename FITS file name.
  80 + *
  81 + * Constructs Good Time Intervals from a FITS file.
  82 + ***************************************************************************/
  83 +GGti::GGti(const std::string& filename)
  84 +{
  85 + // Initialise members
  86 + init_members();
  87 +
  88 + // Load FITS file
  89 + load(filename);
  90 +
  91 + // Return
  92 + return;
  93 +}
  94 +
  95 +
  96 +/***********************************************************************//**
76 97 * @brief Copy constructor
77 98 *
78 99 * @param[in] gti Good Time Intervals.
... ... @@ -551,20 +572,25 @@ void GGti::extend(const GGti&amp; gti)
551 572 * @brief Load Good Time Intervals from FITS file
552 573 *
553 574 * @param[in] filename FITS filename.
554   - * @param[in] extname GTI extension name (defaults to "GTI")
555 575 *
556 576 * Loads the Good Time Intervals from FITS file.
  577 + *
  578 + * If no extension name is provided, the energy boundaries are loaded from
  579 + * the "GTI" extension.
557 580 ***************************************************************************/
558   -void GGti::load(const std::string& filename, const std::string& extname)
  581 +void GGti::load(const std::string& filename)
559 582 {
  583 + // Create file name
  584 + GFilename fname(filename);
  585 +
560 586 // Allocate FITS file
561 587 GFits file;
562 588  
563 589 // Open FITS file
564   - file.open(filename);
  590 + file.open(fname.filename());
565 591  
566 592 // Get GTI table
567   - const GFitsTable& table = *file.table(extname);
  593 + const GFitsTable& table = *file.table(fname.extname("GTI"));
568 594  
569 595 // Read GTI from table
570 596 read(table);
... ... @@ -582,24 +608,25 @@ void GGti::load(const std::string&amp; filename, const std::string&amp; extname)
582 608 *
583 609 * @param[in] filename FITS filename.
584 610 * @param[in] clobber Overwrite any existing GTI extension?
585   - * @param[in] extname GTI extension name (defaults to "GTI")
586 611 *
587   - * Saves Good Time Intervals into extension @p extname of a FITS file. If the
588   - * file does not exist it is created. If the file exists the GTI is appended
589   - * as extension. If another GTI exists already it is overwritten if
590   - * @p clobber=true.
  612 + * Saves Good Time Intervals into a FITS file.
  613 + *
  614 + * If no extension name is provided, the Good Time Intervals are saved into
  615 + * an "GTI" extension.
591 616 ***************************************************************************/
592   -void GGti::save(const std::string& filename, const bool& clobber,
593   - const std::string& extname) const
  617 +void GGti::save(const std::string& filename, const bool& clobber) const
594 618 {
  619 + // Create file name
  620 + GFilename fname(filename);
  621 +
595 622 // Allocate FITS file
596 623 GFits file;
597 624  
598 625 // Write GTI to FITS file
599   - write(file, extname);
  626 + write(file, fname.extname("GTI"));
600 627  
601 628 // Save to file
602   - file.saveto(filename, clobber);
  629 + file.saveto(fname.filename(), clobber);
603 630  
604 631 // Return
605 632 return;
... ...
src/sky/GSkyRegions.cpp
... ... @@ -159,58 +159,6 @@ GSkyRegions&amp; GSkyRegions::operator=(const GSkyRegions&amp; regions)
159 159 }
160 160  
161 161  
162   -/***********************************************************************//**
163   - * @brief Return pointer to region
164   - *
165   - * @param[in] name region name.
166   - *
167   - * @exception GException::invalid_argument
168   - * region with specified name not found in container.
169   - *
170   - * Returns a pointer to the region with the specified @p name.
171   - ***************************************************************************/
172   -GSkyRegion* GSkyRegions::operator[](const std::string& name)
173   -{
174   - // Get region index
175   - int index = get_index(name);
176   -
177   - // Throw exception if region name was not found
178   - if (index == -1) {
179   - std::string msg ="Region with name \""+name+"\" not found in container.";
180   - throw GException::invalid_argument(G_ACCESS, msg);
181   - }
182   -
183   - // Return pointer
184   - return m_regions[index];
185   -}
186   -
187   -
188   -/***********************************************************************//**
189   - * @brief Return pointer to region (const version)
190   - *
191   - * @param[in] name region name.
192   - *
193   - * @exception GException::invalid_argument
194   - * region with specified name not found in container.
195   - *
196   - * Returns a const pointer to the region with the specified @p name.
197   - ***************************************************************************/
198   -const GSkyRegion* GSkyRegions::operator[](const std::string& name) const
199   -{
200   - // Get region index
201   - int index = get_index(name);
202   -
203   - // Throw exception if region name was not found
204   - if (index == -1) {
205   - std::string msg ="Region with name \""+name+"\" not found in container.";
206   - throw GException::invalid_argument(G_ACCESS, msg);
207   - }
208   -
209   - // Return pointer
210   - return m_regions[index];
211   -}
212   -
213   -
214 162 /*==========================================================================
215 163 = =
216 164 = Public methods =
... ... @@ -315,65 +263,6 @@ GSkyRegion* GSkyRegions::set(const int&amp; index, const GSkyRegion&amp; region)
315 263 }
316 264 #endif
317 265  
318   - // Check if a region with specified name does not yet exist
319   - int inx = get_index(region.name());
320   - if (inx != -1 && inx != index) {
321   - std::string msg =
322   - "Attempt to set region with name \""+region.name()+"\" in region"
323   - " container at index "+gammalib::str(index)+", but a region with"
324   - " the same name exists already at index "+gammalib::str(inx)+
325   - " in the container.\n"
326   - "Every region in the region container needs a unique name.";
327   - throw GException::invalid_value(G_SET1, msg);
328   - }
329   -
330   - // Delete any existing region
331   - if (m_regions[index] != NULL) delete m_regions[index];
332   -
333   - // Assign new region by cloning
334   - m_regions[index] = region.clone();
335   -
336   - // Return pointer to region
337   - return m_regions[index];
338   -}
339   -
340   -
341   -/***********************************************************************//**
342   - * @brief Set region in container
343   - *
344   - * @param[in] name region name.
345   - * @param[in] region region pointer.
346   - * @return Pointer to deep copy of region.
347   - *
348   - * @exception GException::invalid_argument
349   - * region with specified name not found in container.
350   - * @exception GException::invalid_value
351   - * Name of region exists already in container.
352   - *
353   - * Set region in the container. A deep copy of the region will be made.
354   - ***************************************************************************/
355   -GSkyRegion* GSkyRegions::set(const std::string& name, const GSkyRegion& region)
356   -{
357   - // Get parameter index
358   - int index = get_index(name);
359   -
360   - // Throw exception if parameter name was not found
361   - if (index == -1) {
362   - throw GException::invalid_argument(G_SET2, name);
363   - }
364   -
365   - // Check if a region with specified name does not yet exist
366   - int inx = get_index(region.name());
367   - if (inx != -1 && inx != index) {
368   - std::string msg =
369   - "Attempt to set region with name \""+region.name()+"\" in region"
370   - " container at index "+gammalib::str(index)+", but a region with"
371   - " the same name exists already at index "+gammalib::str(inx)+
372   - " in the container.\n"
373   - "Every region in the region container needs a unique name.";
374   - throw GException::invalid_value(G_SET2, msg);
375   - }
376   -
377 266 // Delete any existing region
378 267 if (m_regions[index] != NULL) delete m_regions[index];
379 268  
... ... @@ -399,17 +288,6 @@ GSkyRegion* GSkyRegions::set(const std::string&amp; name, const GSkyRegion&amp; region)
399 288 ***************************************************************************/
400 289 GSkyRegion* GSkyRegions::append(const GSkyRegion& region)
401 290 {
402   - // Check if a region with specified name does not yet exist
403   - int inx = get_index(region.name());
404   - if (inx != -1) {
405   - std::string msg =
406   - "Attempt to append region with name \""+region.name()+"\" to region"
407   - " container, but a region with the same name exists already at"
408   - " index "+gammalib::str(inx)+" in the container.\n"
409   - "Every region in the region container needs a unique name.";
410   - throw GException::invalid_value(G_APPEND, msg);
411   - }
412   -
413 291 // Create deep copy of region
414 292 GSkyRegion* ptr = region.clone();
415 293  
... ... @@ -452,66 +330,6 @@ GSkyRegion* GSkyRegions::insert(const int&amp; index, const GSkyRegion&amp; region)
452 330 }
453 331 #endif
454 332  
455   - // Check if a region with specified name does not yet exist
456   - int inx = get_index(region.name());
457   - if (inx != -1) {
458   - std::string msg =
459   - "Attempt to insert region with name \""+region.name()+"\" in region"
460   - " container before index "+gammalib::str(index)+", but a region"
461   - " with the same name exists already at index "+gammalib::str(inx)+
462   - " in the container.\n"
463   - "Every region in the region container needs a unique name.";
464   - throw GException::invalid_value(G_INSERT1, msg);
465   - }
466   -
467   - // Create deep copy of region
468   - GSkyRegion* ptr = region.clone();
469   -
470   - // Inserts deep copy of region
471   - m_regions.insert(m_regions.begin()+index, ptr);
472   -
473   - // Return pointer to region
474   - return ptr;
475   -}
476   -
477   -
478   -/***********************************************************************//**
479   - * @brief Insert region into container
480   - *
481   - * @param[in] name region name.
482   - * @param[in] region region.
483   - * @return Pointer to deep copy of region.
484   - *
485   - * @exception GException::invalid_argument
486   - * region with specified name not found in container.
487   - * @exception GException::invalid_value
488   - * Name of region exists already in container.
489   - *
490   - * Inserts a @p region into the container before the region with the specified
491   - * @p name.
492   - ***************************************************************************/
493   -GSkyRegion* GSkyRegions::insert(const std::string& name, const GSkyRegion& region)
494   -{
495   - // Get parameter index
496   - int index = get_index(name);
497   -
498   - // Throw exception if parameter name was not found
499   - if (index == -1) {
500   - throw GException::invalid_argument(G_INSERT2, name);
501   - }
502   -
503   - // Check if a region with specified name does not yet exist
504   - int inx = get_index(region.name());
505   - if (inx != -1) {
506   - std::string msg =
507   - "Attempt to insert region with name \""+region.name()+"\" in region"
508   - " container before index "+gammalib::str(index)+", but a region"
509   - " with the same name exists already at index "+gammalib::str(inx)+
510   - " in the container.\n"
511   - "Every region in the region container needs a unique name.";
512   - throw GException::invalid_value(G_INSERT2, msg);
513   - }
514   -
515 333 // Create deep copy of region
516 334 GSkyRegion* ptr = region.clone();
517 335  
... ... @@ -554,37 +372,6 @@ void GSkyRegions::remove(const int&amp; index)
554 372  
555 373  
556 374 /***********************************************************************//**
557   - * @brief Remove region from container
558   - *
559   - * @param[in] name region name.
560   - *
561   - * @exception GException::invalid_argument
562   - * region with specified name not found in container.
563   - *
564   - * Remove region of specified @p name from container.
565   - ***************************************************************************/
566   -void GSkyRegions::remove(const std::string& name)
567   -{
568   - // Get parameter index
569   - int index = get_index(name);
570   -
571   - // Throw exception if region name was not found
572   - if (index == -1) {
573   - throw GException::invalid_argument(G_REMOVE2, name);
574   - }
575   -
576   - // Delete region
577   - delete m_regions[index];
578   -
579   - // Erase region component from container
580   - m_regions.erase(m_regions.begin() + index);
581   -
582   - // Return
583   - return;
584   -}
585   -
586   -
587   -/***********************************************************************//**
588 375 * @brief Append region container
589 376 *
590 377 * @param[in] regions region container.
... ... @@ -607,18 +394,6 @@ void GSkyRegions::extend(const GSkyRegions&amp; regions)
607 394 // Loop over all region components and append pointers to deep copies
608 395 for (int i = 0; i < num; ++i) {
609 396  
610   - // Check if region name does not yet exist
611   - int inx = get_index(regions[i]->name());
612   - if (inx != -1) {
613   - std::string msg =
614   - "Attempt to append region with name \""+regions[i]->name()+
615   - "\" to region container, but a region with the same name"
616   - " exists already at index "+gammalib::str(inx)+" in the"
617   - " container.\n"
618   - "Every region in the region container needs a unique name.";
619   - throw GException::invalid_value(G_EXTEND, msg);
620   - }
621   -
622 397 // Append region to container
623 398 m_regions.push_back(regions[i]->clone());
624 399  
... ... @@ -632,25 +407,6 @@ void GSkyRegions::extend(const GSkyRegions&amp; regions)
632 407  
633 408  
634 409 /***********************************************************************//**
635   - * @brief Signals if region name exists
636   - *
637   - * @param[in] name region name.
638   - * @return True if region with specified @p name exists.
639   - *
640   - * Searches all region names for a match with the specified @p name. If the
641   - * specified name has been found, true is returned.
642   - ***************************************************************************/
643   -bool GSkyRegions::contains(const std::string& name) const
644   -{
645   - // Get region index
646   - int index = get_index(name);
647   -
648   - // Return
649   - return (index != -1);
650   -}
651   -
652   -
653   -/***********************************************************************//**
654 410 * @brief Load regions from DS9 region file
655 411 *
656 412 * @param[in] filename DS9 region filename.
... ... @@ -931,29 +687,3 @@ void GSkyRegions::free_members(void)
931 687 return;
932 688 }
933 689  
934   -
935   -/***********************************************************************//**
936   - * @brief Return region index by name
937   - *
938   - * @param[in] name region name.
939   - * @return region index (-1 if region name has not been found)
940   - *
941   - * Returns region index based on the specified @p name. If no region with the
942   - * specified @p name is found the method returns -1.
943   - ***************************************************************************/
944   -int GSkyRegions::get_index(const std::string& name) const
945   -{
946   - // Initialise index
947   - int index = -1;
948   -
949   - // Search region with specified name
950   - for (int i = 0; i < size(); ++i) {
951   - if (m_regions[i]->name() == name) {
952   - index = i;
953   - break;
954   - }
955   - }
956   -
957   - // Return index
958   - return index;
959   -}
... ...
src/support/GCsv.cpp
1 1 /***************************************************************************
2   - * GCsv.cpp - Column separated values table class *
  2 + * GCsv.cpp - Comma-separated values table class *
3 3 * ----------------------------------------------------------------------- *
4 4 * copyright (C) 2010-2015 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
... ... @@ -20,7 +20,7 @@
20 20 ***************************************************************************/
21 21 /**
22 22 * @file GCsv.cpp
23   - * @brief Column separated values table class implementation
  23 + * @brief Comma-separated values table class implementation
24 24 * @author Juergen Knoedlseder
25 25 */
26 26  
... ... @@ -112,7 +112,7 @@ GCsv::GCsv(const std::string&amp; filename, const std::string&amp; sep)
112 112 /***********************************************************************//**
113 113 * @brief Copy constructor
114 114 *
115   - * @param[in] csv Column separated values table.
  115 + * @param[in] csv Comma-separated values table.
116 116 ***************************************************************************/
117 117 GCsv::GCsv(const GCsv& csv)
118 118 {
... ... @@ -149,8 +149,8 @@ GCsv::~GCsv(void)
149 149 /***********************************************************************//**
150 150 * @brief Assignment operator
151 151 *
152   - * @param[in] csv Column separated values table.
153   - * @return Column separated values table.
  152 + * @param[in] csv Comma-separated values table.
  153 + * @return Comma-separated values table.
154 154 ***************************************************************************/
155 155 GCsv& GCsv::operator=(const GCsv& csv)
156 156 {
... ... @@ -562,7 +562,7 @@ void GCsv::init_members(void)
562 562 /***********************************************************************//**
563 563 * @brief Copy class members
564 564 *
565   - * @param[in] csv Column separated values table.
  565 + * @param[in] csv Comma-separated values table.
566 566 ***************************************************************************/
567 567 void GCsv::copy_members(const GCsv& csv)
568 568 {
... ...