From 07a98b27f51824dc08acd63cc6e5dff62f01fc7c Mon Sep 17 00:00:00 2001 From: Jürgen Knödlseder Date: Mon, 6 Oct 2014 17:25:16 +0200 Subject: [PATCH] Integrate code: - change evfile parameter to infile - added irf and caldb parameters - use pointer to GModel for test source - clean exception handling - minor code adjustments --- pyext/cttsmap.i | 33 +++++++++++++-------------------- src/cttsmap/cttsmap.cpp | 329 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------- src/cttsmap/cttsmap.hpp | 49 ++++++++++++++++++++++++++----------------------- src/cttsmap/cttsmap.par | 14 ++++++++------ src/cttsmap/main.cpp | 10 +++++----- 5 files changed, 272 insertions(+), 163 deletions(-) diff --git a/pyext/cttsmap.i b/pyext/cttsmap.i index b8dba08..c6fa854 100644 --- a/pyext/cttsmap.i +++ b/pyext/cttsmap.i @@ -1,7 +1,7 @@ /*************************************************************************** - * cttsmap - CTA data binning tool * + * cttsmap - TS map calculation tool * * ----------------------------------------------------------------------- * - * copyright (C) 2010-2014 by Juergen Knoedlseder * + * copyright (C) 2014 by Michael Mayer * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -20,8 +20,8 @@ ***************************************************************************/ /** * @file cttsmap.i - * @brief CTA data binning tool Python interface definition - * @author Juergen Knoedlseder + * @brief TS map calculation tool interface definition + * @author Michael Mayer */ %{ /* Put headers and other declarations here that are needed for compilation */ @@ -30,12 +30,11 @@ %} -/*********************************************************************** -//** -* @class cttsmap -* -* @brief CTA data binning tool Python interface -***************************************************************************/ +/***********************************************************************//** + * @class cttsmap + * + * @brief TS map calculation + ***************************************************************************/ class cttsmap : public GApplication { public: // Constructors and destructors @@ -51,19 +50,13 @@ public: void run(void); void save(void); const GObservations& obs(void) const; - const GSkymap& tsmap(void) const; - const GSkymap& fluxmap(void) const; - const GSkymap& indexmap(void) const; - const GSkymap& statusmap(void) const; - - + const GSkymap& tsmap(void) const; }; -/*********************************************************************** - //** -* @brief CTA data binning tool Python extension -***************************************************************************/ +/***********************************************************************//** + * @brief TS map calculation tool Python extensions + ***************************************************************************/ %extend cttsmap { cttsmap copy() { return (*self); diff --git a/src/cttsmap/cttsmap.cpp b/src/cttsmap/cttsmap.cpp index 096b4b5..a25ff72 100644 --- a/src/cttsmap/cttsmap.cpp +++ b/src/cttsmap/cttsmap.cpp @@ -1,7 +1,7 @@ /*************************************************************************** - * cttsmap - TS map computation tool * + * cttsmap - TS map calculation tool * * ----------------------------------------------------------------------- * - * copyright (C) 2010-2014 by Juergen Knoedlseder * + * copyright (C) 2014 by Michael Mayer * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -19,8 +19,8 @@ * * ***************************************************************************/ /** - * @file cttsmap.cpp - * @brief TS map computation tool + * @file cttsmap.hpp + * @brief TS map calculation tool interface implementation * @author Michael Mayer */ @@ -33,7 +33,7 @@ #include "GTools.hpp" /* __ Method name definitions ____________________________________________ */ -#define G_GET_PARAMETERS "cttsmap::get_parameters()" +#define G_GET_PARAMETERS "cttsmap::get_parameters()" /* __ Debug definitions __________________________________________________ */ @@ -71,7 +71,7 @@ cttsmap::cttsmap(void) : GApplication(CTTSMAP_NAME, CTTSMAP_VERSION) * observations container. ***************************************************************************/ cttsmap::cttsmap(const GObservations& obs) : - GApplication(CTTSMAP_NAME, CTTSMAP_VERSION) + GApplication(CTTSMAP_NAME, CTTSMAP_VERSION) { // Initialise members init_members(); @@ -95,7 +95,7 @@ cttsmap::cttsmap(const GObservations& obs) : * @param[in] argv Array of command line arguments. ***************************************************************************/ cttsmap::cttsmap(int argc, char *argv[]) : - GApplication(CTTSMAP_NAME, CTTSMAP_VERSION, argc, argv) + GApplication(CTTSMAP_NAME, CTTSMAP_VERSION, argc, argv) { // Initialise members init_members(); @@ -204,8 +204,8 @@ void cttsmap::clear(void) * This is the main execution method of the cttsmap class. It is invoked when * the executable is called from command line. * - * The method reads the task parameters, computed the TS values - * and stores it into map(s), and writes the results into FITS files on disk. + * The method reads the task parameters, computes the TS values, stores the + * results into map(s), and writes the maps into a FITS file on disk. ***************************************************************************/ void cttsmap::execute(void) { @@ -226,10 +226,9 @@ void cttsmap::execute(void) /***********************************************************************//** * @brief Computes the TS maps * - * This method moves a point-like source along a grid of coordinates - * and refits the given models including this additional source. - * The fit parameters of the source and its TS values are filled into - * respective position in the map. + * This method moves a source along a grid of coordinates and refits the + * given models including this additional source. The fit parameters of the + * source and its TS values are filled into respective position in the map. ***************************************************************************/ void cttsmap::run(void) { @@ -262,12 +261,7 @@ void cttsmap::run(void) // Write header if (logTerse()) { log << std::endl; - if (m_obs.size() > 1) { - log.header1("Bin observations"); - } - else { - log.header1("Bin observation"); - } + log.header1("Initialise TS map"); } // Initialise maps @@ -281,8 +275,8 @@ void cttsmap::run(void) int binmax = (m_binmax == -1) ? m_tsmap.npix() : m_binmax; // Initialise optimizer - GOptimizerLM* opt = (logTerse()) ? new GOptimizerLM(log) - : new GOptimizerLM(); + GOptimizerLM* opt = (logExplicit()) ? new GOptimizerLM(log) + : new GOptimizerLM(); // Store initial models GModels models_orig = m_obs.models(); @@ -296,29 +290,45 @@ void cttsmap::run(void) // Get likelihood of null hypothesis if not given before if (m_logL0 == 0.0) { + // Write header + if (logTerse()) { + log << std::endl; + log.header1("Compute NULL Hypothesis for TS computation"); + } + // Compute likelihood without the test source m_obs.models(models); m_obs.optimize(*opt); m_logL0 = -(opt->value()); + } - // Loop over all observations in the container + // Write header + if (logTerse()) { + log << std::endl; + log.header1("Generate TS map"); + } + + // Loop over grid positions for (int i = binmin; i < binmax; ++i) { // Get the coordinate of current bin GSkyDir bincentre = m_tsmap.inx2dir(i); - // Verbosity option - if ((*this)["chatter"].integer()>2) { - std::cout<<"Computing TS for bin number "<value()); // Compute TS value - double ts = 2.0 * (logL1-m_logL0); + double ts = 2.0 * (logL1 - m_logL0); + + // Log information + if (logExplicit()) { + log << " TS value ....: "; + log << ts << std::endl; + } + else if (logTerse()) { + log << "TS for bin number "; + log << i; + log << " at "; + log << bincentre.print(); + log << ": "; + log << ts << std::endl; + } // Get test source model instance GModels best_fit_model = m_obs.models(); - GModel* testsource = best_fit_model[m_srcname]; + GModel* testsource = best_fit_model[m_srcname]; // Assign values to the maps m_tsmap(i) = ts; - // Get fit values - for (int j = 0; j < m_mapnames.size(); j++) { - - // get best fit values and assign to maps - m_maps[j](i) = (*testsource)[m_mapnames[j]].value(); + // Extract fitted test source parameters + if (m_testsource != NULL) { + for (int j = 0; j < m_mapnames.size(); ++j) { + m_maps[j](i) = (*testsource)[m_mapnames[j]].value(); + } } // Set status of bin to true @@ -352,7 +376,7 @@ void cttsmap::run(void) // Remove model from container models.remove(m_srcname); - } // endfor: looped over bins + } // endfor: looped over grid positions // Bring models to initial state m_obs.models(models_orig); @@ -372,12 +396,7 @@ void cttsmap::save(void) // Write header if (logTerse()) { log << std::endl; - if (m_obs.size() > 1) { - log.header1("Save observations"); - } - else { - log.header1("Save observation"); - } + log.header1("Save TS map"); } // Get output filename @@ -388,11 +407,11 @@ void cttsmap::save(void) // Write the sky maps to the FITS file m_tsmap.write(fitsfile); - for (int i = 0; i < m_mapnames.size(); i++) { m_maps[i].write(fitsfile); } + // Set extension name for all maps for (int i = 0; i < m_mapnames.size(); i++) { fitsfile[i+1]->extname(m_mapnames[i]); } @@ -423,7 +442,9 @@ void cttsmap::save(void) void cttsmap::init_members(void) { // Initialise members - m_evfile.clear(); + m_infile.clear(); + m_caldb.clear(); + m_irf.clear(); m_outfile.clear(); m_proj.clear(); m_coordsys.clear(); @@ -436,14 +457,14 @@ void cttsmap::init_members(void) // Initialise protected members m_obs.clear(); m_read_ahead = false; - m_binmin = -1; - m_binmax = -1; - m_logL0 = 0.0; + m_binmin = -1; + m_binmax = -1; + m_logL0 = 0.0; m_tsmap.clear(); - m_maps.clear(); - m_mapnames.clear(); m_statusmap.clear(); - m_testsource.clear(); + m_mapnames.clear(); + m_maps.clear(); + m_testsource = NULL; // Set logger properties log.date(true); @@ -461,7 +482,9 @@ void cttsmap::init_members(void) void cttsmap::copy_members(const cttsmap& app) { // Copy attributes - m_evfile = app.m_evfile; + m_infile = app.m_infile; + m_caldb = app.m_caldb; + m_irf = app.m_irf; m_outfile = app.m_outfile; m_proj = app.m_proj; m_coordsys = app.m_coordsys; @@ -472,16 +495,19 @@ void cttsmap::copy_members(const cttsmap& app) m_nypix = app.m_nypix; // Copy protected members - m_binmin = app.m_binmin; - m_binmax = app.m_binmax; - m_logL0 = app.m_logL0; + m_binmin = app.m_binmin; + m_binmax = app.m_binmax; + m_logL0 = app.m_logL0; m_obs = app.m_obs; m_read_ahead = app.m_read_ahead; - m_tsmap = app.m_tsmap; - m_mapnames = app.m_mapnames; + m_tsmap = app.m_tsmap; + m_mapnames = app.m_mapnames; m_maps = app.m_maps; - m_statusmap = app.m_statusmap; - m_testsource = app.m_testsource; + m_statusmap = app.m_statusmap; + + // Clone protected members + m_testsource = (app.m_testsource != NULL) ? app.m_testsource->clone() : NULL; + // Return return; } @@ -505,6 +531,10 @@ void cttsmap::free_members(void) /***********************************************************************//** * @brief Get application parameters * + * @exception GException::invalid_value + * Test source not found or no RA/DEC parameters found for test + * source. + * * Get all task parameters from parameter file or (if required) by querying * the user. Most parameters are only required if no observation exists so * far in the observation container. In this case, a single CTA observation @@ -517,19 +547,38 @@ void cttsmap::get_parameters(void) // observation using the parameters from the parameter file if (m_obs.size() == 0) { - // Get name of CTA events file - m_evfile = (*this)["evfile"].filename(); - // Allocate CTA observation GCTAObservation obs; + // Get event file name + std::string filename = (*this)["infile"].filename(); + // Try first to open as FITS file try { - // Load event list in CTA observation - obs.load(m_evfile); - - // Append CTA observation to container + // Load data + obs.load(filename); + + // Get other task parameters + m_caldb = (*this)["caldb"].string(); + m_irf = (*this)["irf"].string(); + + // Set calibration database. If specified parameter is a + // directory then use this as the pathname to the calibration + // database. Otherwise interpret this as the instrument name, + // the mission being "cta" + GCaldb caldb; + if (gammalib::dir_exists(m_caldb)) { + caldb.rootdir(m_caldb); + } + else { + caldb.open("cta", m_caldb); + } + + // Set reponse + obs.response(m_irf, caldb); + + // Append observation to container m_obs.append(obs); } @@ -538,38 +587,95 @@ void cttsmap::get_parameters(void) catch (GException::fits_open_error &e) { // Load observations from XML file - m_obs.load(m_evfile); + m_obs.load(filename); - } + // Check if all observations have response information. If + // not, get the calibration database parameters and set + // the response properly + bool asked_for_response = false; + for (int i = 0; i < m_obs.size(); ++i) { + + // Get CTA observation + GCTAObservation* obs = dynamic_cast(m_obs[i]); - m_obs.models((*this)["srcmdl"].filename()); + // Continue only if observation is a CTA observation + if (obs != NULL) { + + // If response is not valid then set response from + // task parameters + if (!obs->has_response()) { + + // Get calibration parameters + if (!asked_for_response) { + m_caldb = (*this)["caldb"].string(); + m_irf = (*this)["irf"].string(); + asked_for_response = true; + } + + // Set response + GCaldb caldb; + if (gammalib::dir_exists(m_caldb)) { + caldb.rootdir(m_caldb); + } + else { + caldb.open("cta", m_caldb); + } + obs->response(m_irf, caldb); + + } // endif: there was no response + } // endif: observation was a CTA observation + + } // endfor: looped over observations + + } // endcatch: file was an XML file } // endif: there was no observation in the container + // If there is are no models associated with the observations then + // load now the model definition + if (m_obs.models().size() == 0) { + + // Get models XML filename + std::string filename = (*this)["srcmdl"].filename(); + + // Setup models for optimizing. + m_obs.models(GModels(filename)); + + } // endif: no models were associated with observations + // Get name of test source and check container for this name m_srcname = (*this)["srcname"].string(); if (!m_obs.models().contains(m_srcname)) { - throw GException::model_not_found(G_GET_PARAMETERS, m_srcname); + std::string msg = "Source \""+m_srcname+"\" not found in model " + "container. Please add a source with that name " + "or check for a possible typos."; + throw GException::invalid_value(G_GET_PARAMETERS, msg); } // Get Model and store it as protected member - GModel* model = m_obs.models()[m_srcname]->clone(); - m_testsource = *dynamic_cast(model); - - // Check if model has RA and DEC parameters which are necessary to continue - if (!m_testsource.has_par("RA") || !m_testsource.has_par("DEC")) { - - // Is this the correct exception? Do we need a new one? - throw GException::model_invalid(G_GET_PARAMETERS, m_srcname, "RA and DEC parameters required! "); + m_testsource = m_obs.models()[m_srcname]->clone(); + + // Check if model has RA and DEC parameters which are necessary to + // continue + if (m_testsource != NULL) { + if (!m_testsource->has_par("RA") || !m_testsource->has_par("DEC")) { + std::string msg = "Source \""+m_srcname+"\" has no \"RA\" and " + "\"DEC\" parameters. Only sources with \"RA\" " + " and \"DEC\" parameters can be used as test " + "sources."; + throw GException::invalid_value(G_GET_PARAMETERS, msg); + } } - // Fix the spatial parameters - m_testsource["RA"].fix(); - m_testsource["DEC"].fix(); + // Fix the spatial parameters of the test source + if (m_testsource != NULL) { + (*m_testsource)["RA"].fix(); + (*m_testsource)["DEC"].fix(); + } // Get map parameters - m_xref = (*this)["xref"].real(); - m_yref = (*this)["yref"].real(); + m_xref = (*this)["xref"].real(); + m_yref = (*this)["yref"].real(); m_proj = (*this)["proj"].string(); m_coordsys = (*this)["coordsys"].string(); m_binsz = (*this)["binsz"].real(); @@ -579,7 +685,7 @@ void cttsmap::get_parameters(void) // Get optional splitting parameters m_binmin = (*this)["binmin"].integer(); m_binmax = (*this)["binmax"].integer(); - m_logL0 = (*this)["logL0"].real(); + m_logL0 = (*this)["logL0"].real(); // Optionally read ahead parameters so that they get correctly // dumped into the log file @@ -593,9 +699,9 @@ void cttsmap::get_parameters(void) /***********************************************************************//** - * @brief Initialise map information + * @brief Initialise skymaps * - * Initialises the skymaps. + * Initialises skymaps that will contain map information. ***************************************************************************/ void cttsmap::init_maps(void) { @@ -604,34 +710,39 @@ void cttsmap::init_maps(void) // Create skymap m_tsmap = GSkymap(m_proj, m_coordsys, - m_xref, m_yref, -m_binsz, m_binsz, - m_nxpix, m_nypix, 1); + m_xref, m_yref, -m_binsz, m_binsz, + m_nxpix, m_nypix, 1); // Initialise map information m_statusmap.clear(); // Create status map m_statusmap = GSkymap(m_proj, m_coordsys, - m_xref, m_yref, -m_binsz, m_binsz, - m_nxpix, m_nypix, 1); - - // Initialise maps of other free parameters - for (int i = 0; i < m_testsource.size(); i++) { - if (m_testsource[i].is_fixed()) { - continue; - } - - // create sky map - GSkymap map = GSkymap(m_proj, m_coordsys, - m_xref, m_yref, -m_binsz, m_binsz, - m_nxpix, m_nypix, 1); - m_maps.push_back(map); - - // Store name of parameter - m_mapnames.push_back(m_testsource[i].name()); - } + m_xref, m_yref, -m_binsz, m_binsz, + m_nxpix, m_nypix, 1); + + // Initialise maps of free parameters + if (m_testsource != NULL) { + + // Loop over all model parameters + for (int i = 0; i < m_testsource->size(); i++) { + + // Skip fixed parameters + if ((*m_testsource)[i].is_fixed()) { + continue; + } + + // Add sky map for free parameters. Note that push_back will + // create a copy. + m_maps.push_back(m_tsmap); + + // Store parameter name + m_mapnames.push_back((*m_testsource)[i].name()); + + } // endfor: looped over all model parameters + + } // endif: test source was valid // Return return; } - diff --git a/src/cttsmap/cttsmap.hpp b/src/cttsmap/cttsmap.hpp index 0c243e6..bd95ca8 100644 --- a/src/cttsmap/cttsmap.hpp +++ b/src/cttsmap/cttsmap.hpp @@ -1,7 +1,7 @@ /*************************************************************************** - * cttsmap - TS map tool * + * cttsmap - TS map calculation tool * * ----------------------------------------------------------------------- * - * copyright (C) 2010-2014 by Juergen Knoedlseder * + * copyright (C) 2014 by Michael Mayer * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -20,7 +20,7 @@ ***************************************************************************/ /** * @file cttsmap.hpp - * @brief TS map calculation tool + * @brief TS map calculation tool interface definition * @author Michael Mayer */ @@ -39,19 +39,20 @@ /***********************************************************************//** * @class cttsmap * - * @brief TS map calculation interface + * @brief TS map calculation * * This class computes a set of maps from any kind of observations: - * - TS map - * - flux map - * - map of spectral index - * The class operates on predefined observation containers, an individual - * event list or an observation definition XML file. * - * During the computation a putative point-like source is moved along a - * grid of coordinates. The best fit results (TS, flux, index) are stored in maps - * which are saved in the output FITS files. + * - TS map + * - Flux map + * - Map of spectral index * + * The class operates on predefined observation containers, an individual + * event list or an observation definition XML file. + * + * During the computation a putative point-like source is moved along a + * grid of coordinates. The best fit results (TS, flux, index) are stored in + * maps which are saved in the output FITS files. ***************************************************************************/ class cttsmap : public GApplication { public: @@ -71,7 +72,7 @@ public: void run(void); void save(void); const GObservations& obs(void) const; - const GSkymap& tsmap(void) const; + const GSkymap& tsmap(void) const; protected: // Protected methods @@ -82,8 +83,10 @@ protected: void init_maps(void); // User parameters - std::string m_evfile; //!< Input event list or XML file - std::string m_srcname; //!< Name of source which is moved around + std::string m_infile; //!< Input file + std::string m_srcname; //!< Name of source which is moved around + std::string m_caldb; //!< Calibration database + std::string m_irf; //!< Instrument response functions std::string m_outfile; //!< Output counts map or XML file std::string m_proj; //!< WCS projection std::string m_coordsys; //!< Coordinate system @@ -96,19 +99,19 @@ protected: // Parameters to control speed and job splitting int m_binmin; //!< Map bin number from which computation should start int m_binmax; //!< Map bin number where map computation should end - double m_logL0; //!< Likelihood value of null hypothesis + double m_logL0; //!< Likelihood value of null hypothesis // Protected members GObservations m_obs; //!< Observation container bool m_read_ahead; //!< Read ahead parameters - GSkymap m_tsmap; //!< ts map - GSkymap m_statusmap; //!< map of computed bins - std::vector m_mapnames; // names of free parameters - std::vector m_maps; // sky maps for each free parameter - GModelSky m_testsource; //!< test source for TS computation - + GSkymap m_tsmap; //!< TS map + GSkymap m_statusmap; //!< Map of computed bins + std::vector m_mapnames; //!< Names of free parameters + std::vector m_maps; //!< Sky maps for each free parameter + GModel* m_testsource; //!< Pointer to test source for TS computation }; + /***********************************************************************//** * @brief Return observation container * @@ -120,6 +123,7 @@ const GObservations& cttsmap::obs(void) const return m_obs; } + /***********************************************************************//** * @brief Return TS skymap * @@ -131,5 +135,4 @@ const GSkymap& cttsmap::tsmap(void) const return m_tsmap; } - #endif /* CTTSMAP_HPP */ diff --git a/src/cttsmap/cttsmap.par b/src/cttsmap/cttsmap.par index c9ebf20..09c5628 100644 --- a/src/cttsmap/cttsmap.par +++ b/src/cttsmap/cttsmap.par @@ -17,10 +17,12 @@ # # General parameters #=================== -evfile, f, a, "events.fits",,,"Input event list or observation definition file" -srcmdl, f, a, "$CTOOLS/share/models/crab.xml",,, "Source model" -srcname, s,a,"TestSource",,,"Test source" -outfile, f, a, "tsmap.fits",,, "Output counts cube" +infile, f, a, "events.fits",,,"Input event list, cube or observation definition file" +srcmdl, f, a, "$CTOOLS/share/models/crab.xml",,, "Source model" +srcname, s, a, "TestSource",,,"Test source" +caldb, s, a, "dummy",,, "Calibration database" +irf, s, a, "cta_dummy_irf",,, "Instrument response function" +outfile, f, a, "tsmap.fits",,, "Output counts cube" # # Spatial binning parameters @@ -36,7 +38,7 @@ proj, s, a, "CAR", AIT|AZP|CAR|MER|STG|TAN,, "Projection method e.g. AIT|AZP # # Parameters for splitting and speed purpose #=========================== -binmin, i, h, -1,,, "First bin to compute" +binmin, i, h, -1,,, "First bin to compute" binmax, i, h, -1,,, "Last bin to compute" logL0, r, h, 0.0,,, "LogLikelihood value of null hypothesis" @@ -48,4 +50,4 @@ chatter, i, h, 2,0,4, "Chattiness of output" clobber, b, h, yes,,, "Overwrite existing output files with new output files?" debug, b, h, no,,, "Debugging mode activated" mode, s, h, "ql",,, "Mode of automatic parameters" -logfile, f, h, "ctbin.log",,, "Log filename" +logfile, f, h, "cttsmap.log",,, "Log filename" diff --git a/src/cttsmap/main.cpp b/src/cttsmap/main.cpp index 86e1d15..2d3bdbd 100644 --- a/src/cttsmap/main.cpp +++ b/src/cttsmap/main.cpp @@ -1,7 +1,7 @@ /*************************************************************************** - * ctbin - CTA data binning main code * + * cttsmap - TS map calculation tool * * ----------------------------------------------------------------------- * - * copyright (C) 2010-2011 by Jurgen Knodlseder * + * copyright (C) 2014 by Michael Mayer * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -19,9 +19,9 @@ * * ***************************************************************************/ /** - * @file ctbin/main.cpp - * @brief CTA data binning tool main code - * @author J. Knodlseder + * @file cttsmap/main.cpp + * @brief CTA TS map generation + * @author Michael Mayer */ /* __ Includes ___________________________________________________________ */ -- libgit2 0.21.4