Commit 464e5f56e8e68780528fc90b96dcb740912d892e

Authored by Maria Haupt
1 parent 30daf3a5

new ctool ctedispcube computing energy dispersion cube (#1724)

configure.ac
... ... @@ -957,6 +957,7 @@ AC_CONFIG_FILES([Makefile
957 957 src/ctselect/Makefile
958 958 src/ctexpcube/Makefile
959 959 src/ctpsfcube/Makefile
  960 + src/ctedispcube/Makefile
960 961 src/ctbkgcube/Makefile
961 962 src/ctcubemask/Makefile
962 963 src/cttsmap/Makefile
... ...
src/Makefile.am
... ... @@ -14,6 +14,7 @@ SUBDIRS = support \
14 14 ctskymap \
15 15 ctexpcube \
16 16 ctpsfcube \
  17 + ctedispcube \
17 18 ctbkgcube \
18 19 ctcubemask \
19 20 cttsmap \
... ... @@ -40,6 +41,7 @@ libctools_la_LIBADD = support/libsupport.la \
40 41 ctskymap/libctskymap.la \
41 42 ctexpcube/libctexpcube.la \
42 43 ctpsfcube/libctpsfcube.la \
  44 + ctedispcube/libctedispcube.la \
43 45 ctbkgcube/libctbkgcube.la \
44 46 ctcubemask/libctcubemask.la \
45 47 cttsmap/libcttsmap.la \
... ...
src/ctedispcube/Makefile.am 0 โ†’ 100644
  1 +## Process this file with automake to produce Makefile.in
  2 +
  3 +# Set include directories
  4 +INCLUDES = -I$(top_srcdir)/src/support
  5 +
  6 +# Program name
  7 +bin_PROGRAMS = ctedispcube
  8 +
  9 +# Sources
  10 +sources = ctedispcube.cpp
  11 +
  12 +# Libtool library
  13 +noinst_LTLIBRARIES = libctedispcube.la
  14 +libctedispcube_la_SOURCES = $(sources)
  15 +libctedispcube_la_LDFLAGS = @OPENMP_LIB_LDFLAGS@
  16 +
  17 +# Program definition
  18 +ctedispcube_SOURCES = main.cpp
  19 +ctedispcube_LDFLAGS = $(LIB_LINK_OPTION) @LDFLAGS@
  20 +ctedispcube_CPPFLAGS = @CPPFLAGS@
  21 +ctedispcube_LDADD = libctedispcube.la $(top_srcdir)/src/support/libsupport.la
  22 +
  23 +# Parameter files
  24 +pfilesdir = $(prefix)/syspfiles
  25 +pfiles_DATA = ctedispcube.par
... ...
src/ctedispcube/ctedispcube.cpp 0 โ†’ 100644
  1 +/***************************************************************************
  2 + * ctedispcube - EDISP cube generation tool *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2016 by Maria Haupt *
  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 ctedispcube.cpp
  23 + * @brief EDISP cube generation tool implementation
  24 + * @author Maria Haupt
  25 + */
  26 +
  27 +/* __ Includes ___________________________________________________________ */
  28 +#ifdef HAVE_CONFIG_H
  29 +#include <config.h>
  30 +#endif
  31 +#include <cstdio>
  32 +#include "ctedispcube.hpp"
  33 +#include "GTools.hpp"
  34 +#include "GWcs.hpp"
  35 +
  36 +/* __ Method name definitions ____________________________________________ */
  37 +#define G_GET_PARAMETERS "ctedispcube::get_parameters()"
  38 +
  39 +/* __ Debug definitions __________________________________________________ */
  40 +
  41 +/* __ Coding definitions _________________________________________________ */
  42 +
  43 +
  44 +/*==========================================================================
  45 + = =
  46 + = Constructors/destructors =
  47 + = =
  48 + ==========================================================================*/
  49 +
  50 +/***********************************************************************//**
  51 + * @brief Void constructor
  52 + ***************************************************************************/
  53 +ctedispcube::ctedispcube(void) : ctool(CTEDISPCUBE_NAME, CTEDISPCUBE_VERSION)
  54 +{
  55 + // Initialise members
  56 + init_members();
  57 +
  58 + // Return
  59 + return;
  60 +}
  61 +
  62 +
  63 +/***********************************************************************//**
  64 + * @brief Observations constructor
  65 + *
  66 + * @param[in] obs Observation container.
  67 + *
  68 + * This method creates an instance of the class by copying an existing
  69 + * observations container.
  70 + ***************************************************************************/
  71 +ctedispcube::ctedispcube(const GObservations& obs) :
  72 + ctool(CTEDISPCUBE_NAME, CTEDISPCUBE_VERSION)
  73 +{
  74 + // Initialise members
  75 + init_members();
  76 +
  77 + // Set observations
  78 + m_obs = obs;
  79 +
  80 + // Return
  81 + return;
  82 +}
  83 +
  84 +
  85 +
  86 +/***********************************************************************//**
  87 + * @brief Command line constructor
  88 + *
  89 + * @param[in] argc Number of arguments in command line.
  90 + * @param[in] argv Array of command line arguments.
  91 + ***************************************************************************/
  92 +ctedispcube::ctedispcube(int argc, char *argv[]) :
  93 + ctool(CTEDISPCUBE_NAME, CTEDISPCUBE_VERSION, argc, argv)
  94 +{
  95 + // Initialise members
  96 + init_members();
  97 +
  98 + // Return
  99 + return;
  100 +}
  101 +
  102 +
  103 +/***********************************************************************//**
  104 + * @brief Copy constructor
  105 + *
  106 + * @param[in] app Application.
  107 + ***************************************************************************/
  108 +ctedispcube::ctedispcube(const ctedispcube& app) : ctool(app)
  109 +{
  110 + // Initialise members
  111 + init_members();
  112 +
  113 + // Copy members
  114 + copy_members(app);
  115 +
  116 + // Return
  117 + return;
  118 +}
  119 +
  120 +
  121 +/***********************************************************************//**
  122 + * @brief Destructor
  123 + ***************************************************************************/
  124 +ctedispcube::~ctedispcube(void)
  125 +{
  126 + // Free members
  127 + free_members();
  128 +
  129 + // Return
  130 + return;
  131 +}
  132 +
  133 +
  134 +/*==========================================================================
  135 + = =
  136 + = Operators =
  137 + = =
  138 + ==========================================================================*/
  139 +
  140 +/***********************************************************************//**
  141 + * @brief Assignment operator
  142 + *
  143 + * @param[in] app Application.
  144 + * @return Application.
  145 + ***************************************************************************/
  146 +ctedispcube& ctedispcube::operator=(const ctedispcube& app)
  147 +{
  148 + // Execute only if object is not identical
  149 + if (this != &app) {
  150 +
  151 + // Copy base class members
  152 + this->ctool::operator=(app);
  153 +
  154 + // Free members
  155 + free_members();
  156 +
  157 + // Initialise members
  158 + init_members();
  159 +
  160 + // Copy members
  161 + copy_members(app);
  162 +
  163 + } // endif: object was not identical
  164 +
  165 + // Return this object
  166 + return *this;
  167 +}
  168 +
  169 +
  170 +/*==========================================================================
  171 + = =
  172 + = Public methods =
  173 + = =
  174 + ==========================================================================*/
  175 +
  176 +/***********************************************************************//**
  177 + * @brief Clear instance
  178 + ***************************************************************************/
  179 +void ctedispcube::clear(void)
  180 +{
  181 + // Free members
  182 + free_members();
  183 + this->ctool::free_members();
  184 + this->GApplication::free_members();
  185 +
  186 + // Initialise members
  187 + this->GApplication::init_members();
  188 + this->ctool::init_members();
  189 + init_members();
  190 +
  191 + // Return
  192 + return;
  193 +}
  194 +
  195 +
  196 +/***********************************************************************//**
  197 + * @brief Generate the model map(s)
  198 + *
  199 + * This method reads the task parameters from the parfile, sets up the
  200 + * observation container, loops over all CTA observations in the container
  201 + * and generates an EDISP cube from the CTA observations.
  202 + ***************************************************************************/
  203 +void ctedispcube::run(void)
  204 +{
  205 + // If we're in debug mode then all output is also dumped on the screen
  206 + if (logDebug()) {
  207 + log.cout(true);
  208 + }
  209 +
  210 + // Get task parameters
  211 + get_parameters();
  212 +
  213 + // Write parameters into logger
  214 + if (logTerse()) {
  215 + log_parameters();
  216 + log << std::endl;
  217 + }
  218 +
  219 + // Set energy dispersion flag for all CTA observations and save old
  220 + // values in save_edisp vector
  221 +// std::vector<bool> save_edisp;
  222 +// save_edisp.assign(m_obs.size(), false);
  223 +// for (int i = 0; i < m_obs.size(); ++i) {
  224 +// GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
  225 +// if (obs != NULL) {
  226 +// save_edisp[i] = obs->response()->apply_edisp();
  227 +// obs->response()->apply_edisp(m_apply_edisp);
  228 +// }
  229 +// }
  230 +
  231 + // Write observation(s) into logger
  232 + if (logTerse()) {
  233 + log << std::endl;
  234 + if (m_obs.size() > 1) {
  235 + log.header1("Observations");
  236 + }
  237 + else {
  238 + log.header1("Observation");
  239 + }
  240 + log << m_obs << std::endl;
  241 + }
  242 +
  243 + // Write header
  244 + if (logTerse()) {
  245 + log << std::endl;
  246 + log.header1("Generate EDISP cube");
  247 + }
  248 +
  249 + // Fill EDISP
  250 + m_edispcube.fill(m_obs, &log);
  251 +
  252 + // Restore energy dispersion flag for all CTA observations
  253 +// for (int i = 0; i < m_obs.size(); ++i) {
  254 +// GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
  255 +// if (obs != NULL) {
  256 +// obs->response()->apply_edisp(save_edisp[i]);
  257 +// }
  258 +// }
  259 +
  260 + // Return
  261 + return;
  262 +}
  263 +
  264 +
  265 +/***********************************************************************//**
  266 + * @brief Save EDISP cube
  267 + ***************************************************************************/
  268 +void ctedispcube::save(void)
  269 +{
  270 + // Write header
  271 + if (logTerse()) {
  272 + log << std::endl;
  273 + log.header1("Save EDISP cube");
  274 + }
  275 +
  276 + // Get output filename
  277 + m_outcube = (*this)["outcube"].filename();
  278 +
  279 + // Save only if filename is non-empty
  280 + if (!m_outcube.is_empty()) {
  281 +
  282 + // Log filename
  283 + if (logTerse()) {
  284 + log << "Save EDISP cube into file \""+m_outcube+"\".";
  285 + log << std::endl;
  286 + }
  287 +
  288 + // Save EDISP cube
  289 + m_edispcube.save(m_outcube, clobber());
  290 +
  291 + }
  292 +
  293 + // Return
  294 + return;
  295 +}
  296 +
  297 +
  298 +/*==========================================================================
  299 + = =
  300 + = Private methods =
  301 + = =
  302 + ==========================================================================*/
  303 +
  304 +/***********************************************************************//**
  305 + * @brief Initialise class members
  306 + ***************************************************************************/
  307 +void ctedispcube::init_members(void)
  308 +{
  309 + // Initialise members
  310 + m_outcube.clear();
  311 +// m_apply_edisp = false;
  312 +
  313 + // Initialise protected members
  314 + m_obs.clear();
  315 + m_edispcube.clear();
  316 +
  317 + // Return
  318 + return;
  319 +}
  320 +
  321 +
  322 +/***********************************************************************//**
  323 + * @brief Copy class members
  324 + *
  325 + * @param[in] app Application.
  326 + ***************************************************************************/
  327 +void ctedispcube::copy_members(const ctedispcube& app)
  328 +{
  329 + // Copy attributes
  330 + m_outcube = app.m_outcube;
  331 +// m_apply_edisp = app.m_apply_edisp;
  332 +
  333 + // Copy protected members
  334 + m_obs = app.m_obs;
  335 + m_edispcube = app.m_edispcube;
  336 +
  337 + // Return
  338 + return;
  339 +}
  340 +
  341 +
  342 +/***********************************************************************//**
  343 + * @brief Delete class members
  344 + ***************************************************************************/
  345 +void ctedispcube::free_members(void)
  346 +{
  347 + // Return
  348 + return;
  349 +}
  350 +
  351 +
  352 +/***********************************************************************//**
  353 + * @brief Get application parameters
  354 + *
  355 + * Get all task parameters from parameter file or (if required) by querying
  356 + * the user. The parameters are read in the correct order.
  357 + ***************************************************************************/
  358 +void ctedispcube::get_parameters(void)
  359 +{
  360 + // If there are no observations in container then load them via user
  361 + // parameters
  362 + if (m_obs.size() == 0) {
  363 +
  364 + // Throw exception if no input observation file is given
  365 + require_inobs(G_GET_PARAMETERS);
  366 +
  367 + // Throw exception if counts cube is given
  368 + require_inobs_nocube(G_GET_PARAMETERS);
  369 +
  370 + // Build observation container
  371 + m_obs = get_observations();
  372 +
  373 + } // endif: there was no observation in the container
  374 +
  375 + // Get the incube filename
  376 + std::string incube = (*this)["incube"].filename();
  377 +
  378 + // Get additional binning parameters
  379 + double amax = (*this)["amax"].real();
  380 + int anumbins = (*this)["anumbins"].integer();
  381 +
  382 + // Check for filename validity
  383 + if ((incube == "NONE") || (gammalib::strip_whitespace(incube) == "")) {
  384 +
  385 + // Create an event cube based on task parameters
  386 + GCTAEventCube cube = create_cube(m_obs);
  387 +
  388 + // Define edisp cube
  389 + m_edispcube = GCTACubeEdisp(cube, amax, anumbins);
  390 +
  391 + }
  392 +
  393 + // ... otherwise setup the exposure cube from the counts map
  394 + else {
  395 +
  396 + // Load event cube from filename
  397 + GCTAEventCube cube(incube);
  398 +
  399 + // Define edisp cube
  400 + m_edispcube = GCTACubeEdisp(cube, amax, anumbins);
  401 +
  402 + } // endelse: cube loaded from file
  403 +
  404 + // Read energy dispersion flag
  405 +// m_apply_edisp = (*this)["edisp"].boolean();
  406 +
  407 + // Read output filename (if needed)
  408 + if (read_ahead()) {
  409 + m_outcube = (*this)["outcube"].filename();
  410 + }
  411 +
  412 + // Return
  413 + return;
  414 +}
... ...
src/ctedispcube/ctedispcube.hpp 0 โ†’ 100644
  1 +/***************************************************************************
  2 + * ctedispcube - EDISP cube generation tool *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2014-2016 by Chia-Chun Lu *
  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 ctedispcube.hpp
  23 + * @brief EDISP cube generation tool definition
  24 + * @author Chia-Chun Lu
  25 + */
  26 +
  27 +#ifndef CTEDISPCUBE_HPP
  28 +#define CTEDISPCUBE_HPP
  29 +
  30 +/* __ Includes ___________________________________________________________ */
  31 +#include "GammaLib.hpp"
  32 +#include "GCTALib.hpp"
  33 +#include "ctool.hpp"
  34 +
  35 +/* __Definitions _________________________________________________________ */
  36 +#define CTEDISPCUBE_NAME "ctedispcube"
  37 +#define CTEDISPCUBE_VERSION "1.1.0"
  38 +
  39 +
  40 +/***********************************************************************//**
  41 + * @class ctedispcube
  42 + *
  43 + * @brief EDISP cube generation tool
  44 + ***************************************************************************/
  45 +class ctedispcube : public ctool {
  46 +
  47 +public:
  48 + // Constructors and destructors
  49 + ctedispcube(void);
  50 + explicit ctedispcube(const GObservations& obs);
  51 + ctedispcube(int argc, char *argv[]);
  52 + ctedispcube(const ctedispcube& app);
  53 + virtual ~ctedispcube(void);
  54 +
  55 + // Operators
  56 + ctedispcube& operator=(const ctedispcube& app);
  57 +
  58 + // Methods
  59 + void clear(void);
  60 + void run(void);
  61 + void save(void);
  62 + const GCTACubeEdisp& edispcube(void) const;
  63 +
  64 +protected:
  65 + // Protected methods
  66 + void init_members(void);
  67 + void copy_members(const ctedispcube& app);
  68 + void free_members(void);
  69 + void get_parameters(void);
  70 +
  71 + // User parameters
  72 + GFilename m_outcube; //!< Output EDISP cube file name
  73 + bool m_apply_edisp; //!< Apply energy dispersion?
  74 +
  75 + // Protected members
  76 + GObservations m_obs; //!< Observation container
  77 + GCTACubeEdisp m_edispcube; //!< EDISP cube
  78 +};
  79 +
  80 +
  81 +/***********************************************************************//**
  82 + * @brief Return EDISP cube
  83 + *
  84 + * @return EDISP cube
  85 + ***************************************************************************/
  86 +inline
  87 +const GCTACubeEdisp& ctedispcube::edispcube(void) const
  88 +{
  89 + return (m_edispcube);
  90 +}
  91 +
  92 +#endif /* CTEDISPCUBE_HPP */
... ...
src/ctedispcube/ctedispcube.par 0 โ†’ 100644
  1 +#############################################################################
  2 +# #
  3 +# CTA Science Analysis Tools #
  4 +# #
  5 +# ------------------------------------------------------------------------- #
  6 +# #
  7 +# File: ctpsfcube.par #
  8 +# Version: 1.0.0 #
  9 +# #
  10 +# Author: Chia-Chun Lu #
  11 +# c.lu@mpi-hd.mpg.de #
  12 +# MPIK #
  13 +# #
  14 +# Purpose: Parameter file for the ctpsfcube application #
  15 +# #
  16 +#############################################################################
  17 +#
  18 +# Observational parameters
  19 +#===================
  20 +inobs, f, a, "NONE",,, "Input event list or observation definition XML file"
  21 +incube, f, a, "NONE",,, "Input counts cube file to extract PSF cube definition"
  22 +caldb, s, a, "prod2",,, "Calibration database"
  23 +irf, s, a, "South_0.5h",,, "Instrument response function"
  24 +edisp, b, h, no,,, "Apply energy dispersion?"
  25 +outcube, f, a, "psfcube.fits",,, "Output PSF cube file"
  26 +
  27 +#
  28 +# Energy binning parameters
  29 +#==========================
  30 +ebinalg, s, h, "LOG", FILE|LIN|LOG,, "Algorithm for defining energy bins"
  31 +emin, r, a, 0.1,,, "Lower energy limit (TeV)"
  32 +emax, r, a, 100.0,,, "Upper energy limit (TeV)"
  33 +enumbins, i, a, 20,,, "Number of energy bins"
  34 +ebinfile, f, h, "NONE",,, "Name of the file containing the energy bin definition"
  35 +
  36 +#
  37 +# Spatial binning parameters
  38 +#===========================
  39 +usepnt, b, h, no,,, "Use pointing instead of xref/yref parameters?"
  40 +nxpix, i, a, 10,,, "Size of the X axis in pixels"
  41 +nypix, i, a, 10,,, "Size of the Y axis in pixels"
  42 +binsz, r, a, 1.0,,, "Image scale (in degrees/pixel)"
  43 +coordsys, s, a, "CEL", CEL|GAL,,"Coordinate system (CEL - celestial, GAL - galactic)"
  44 +xref, r, a, 83.63,0,360, "First coordinate of image center in degrees (RA or galactic l)"
  45 +yref, r, a, 22.01,-90,90, "Second coordinate of image center in degrees (DEC or galactic b)"
  46 +proj, s, a, "CAR", AIT|AZP|CAR|MER|MOL|STG|TAN,, "Projection method"
  47 +
  48 +#
  49 +# Angular separation binning parameters
  50 +#======================================
  51 +amax, r, h, 0.3,,, "Upper bound of angular separation between true and measued photon direction (degrees)"
  52 +anumbins, i, h, 200,,, "Number of angular separation bins"
  53 +
  54 +#
  55 +# Standard parameters
  56 +#====================
  57 +chatter, i, h, 2,0,4, "Chattiness of output"
  58 +clobber, b, h, yes,,, "Overwrite existing output files with new output files?"
  59 +debug, b, h, no,,, "Debugging mode activated"
  60 +mode, s, h, "ql",,, "Mode of automatic parameters"
  61 +logfile, f, h, "ctpsfcube.log",,, "Log filename"
... ...
src/ctedispcube/main.cpp 0 โ†’ 100644
  1 +/***************************************************************************
  2 + * ctedispcube - CTA EDISP cube tool *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2016 by Maria Haupt *
  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 ctedispcube/main.cpp
  23 + * @brief CTA EDISP cube tool main code
  24 + * @author Maria Haupt
  25 + */
  26 +
  27 +/* __ Includes ___________________________________________________________ */
  28 +#ifdef HAVE_CONFIG_H
  29 +#include <config.h>
  30 +#endif
  31 +#include <cstdio>
  32 +#include "ctedispcube.hpp"
  33 +
  34 +
  35 +/***********************************************************************//**
  36 + * @brief Main entry point of application
  37 + *
  38 + * @param[in] argc Number of command line arguments.
  39 + * @param[in] argv Command line arguments.
  40 + *
  41 + * This is the main entry point of the ctedispcube application. It allocates a
  42 + * ctedispcube object and runs the application.
  43 + ***************************************************************************/
  44 +int main (int argc, char *argv[])
  45 +{
  46 + // Initialise return code
  47 + int rc = 1;
  48 +
  49 + // Create instance of application
  50 + ctedispcube application(argc, argv);
  51 +
  52 + // Run application
  53 + try {
  54 + // Execute application
  55 + application.execute();
  56 +
  57 + // Signal success
  58 + rc = 0;
  59 + }
  60 + catch (std::exception &e) {
  61 +
  62 + // Extract error message
  63 + std::string message = e.what();
  64 + std::string signal = "*** ERROR encounterted in the execution of"
  65 + " ctedispcube. Run aborted ...";
  66 +
  67 + // Write error in logger
  68 + application.log << signal << std::endl;
  69 + application.log << message << std::endl;
  70 +
  71 + // Write error on standard output
  72 + std::cout << signal << std::endl;
  73 + std::cout << message << std::endl;
  74 +
  75 + } // endcatch: catched any application error
  76 +
  77 + // Return
  78 + return rc;
  79 +}
... ...