diff --git a/ChangeLog b/ChangeLog index fd1807a..e8c4397 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,9 @@ -2016-10-05 +2016-10-07 * Version 1.2.0 released ======================== + Add publish parameter and methods to ctobssim, ctselect, cslightcrv and csspec (#1871) Add csviscube script (#1853) Add zenith and azimuth angle information to IRF caldb (#1853) Fix ctbin segfault bug for varying energy thresholds (#1850) diff --git a/NEWS b/NEWS index f7fbe18..16b768f 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ New Features and Important Changes in ctools 1.2.0 -5 October 2016 +7 October 2016 Introduction @@ -63,6 +63,9 @@ ctobssim - CTA observation simulation The clear() method now calls GApplication::clear() to conserve the properties of the tool (#1835). +A publish() method has been added that publishes the simulated event lists on +a VO hub (#1871). + ctselect - CTA event selection ------------------------------ @@ -72,6 +75,9 @@ of the tool (#1835). The time_reference() method has been removed since the method is part of the ctool base class, and exposed in Python as _time_reference(). +A publish() method has been added that publishes the simulated event lists on +a VO hub (#1871). + ctbin - CTA event binning ------------------------- @@ -200,6 +206,9 @@ of hours that a given position on the sky is observable under a given zenith angle by an IACT array during a given time period. The tool implements so far a Sun constraint, but no Moon constraint (#1835). +A publish() method has been added to cslightcrv and csspec that publishes the +results on a VO hub (#1871). + Examples -------- diff --git a/cscripts/cslightcrv.par b/cscripts/cslightcrv.par index 558364e..db57174 100644 --- a/cscripts/cslightcrv.par +++ b/cscripts/cslightcrv.par @@ -5,7 +5,7 @@ # ------------------------------------------------------------------------- # # # # File: cslightcrv.par # -# Version: 1.1.0 # +# Version: 1.2.0 # # # # Author: Juergen Knoedlseder # # Jurgen.Knodlseder@irap.omp.eu # @@ -55,6 +55,7 @@ fix_bkg, b, h, no,,, "Fix background model parameters?" # # Standard parameters #==================== +publish, b, h, no,,, "Publish light curve on VO Hub?" 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" diff --git a/cscripts/cslightcrv.py b/cscripts/cslightcrv.py index ac3bbb3..ac44d82 100755 --- a/cscripts/cslightcrv.py +++ b/cscripts/cslightcrv.py @@ -614,6 +614,10 @@ class cslightcrv(ctools.cscript): self._fits = gammalib.GFits() self._fits.append(table) + # Optionally publish light curve + if self['publish'].boolean(): + self.publish() + # Return return @@ -658,6 +662,36 @@ class cslightcrv(ctools.cscript): # Return return + def publish(self, name=''): + """ + Publish light curve + + Parameters + ---------- + name : str, optional + Name of light curve + """ + # Write header + self._log_header1(gammalib.TERSE, 'Publish light curve') + + # Continue only if light curve is valid + if self._fits.contains('LIGHTCURVE'): + + # Set default name is user name is empty + if not name: + user_name = self._name + else: + user_name = name + + # Log file name + self._log_value(gammalib.NORMAL, 'Light curve name', user_name) + + # Publish light curve + self._fits.publish('LIGHTCURVE', user_name) + + # Return + return + def lightcurve(self): """ Return light curve FITS file diff --git a/cscripts/csresmap.py b/cscripts/csresmap.py index 5171af1..ff1e7cd 100755 --- a/cscripts/csresmap.py +++ b/cscripts/csresmap.py @@ -295,7 +295,7 @@ class csresmap(ctools.cscript): def publish(self, name=''): """ - Publish residual map. + Publish residual map Parameters ---------- diff --git a/cscripts/csspec.par b/cscripts/csspec.par index fde113a..d77dfd4 100644 --- a/cscripts/csspec.par +++ b/cscripts/csspec.par @@ -5,7 +5,7 @@ # ------------------------------------------------------------------------- # # # # File: csspec.par # -# Version: 1.1.0 # +# Version: 1.2.0 # # # # Author: Juergen Knoedlseder # # Jurgen.Knodlseder@irap.omp.eu # @@ -45,6 +45,7 @@ fix_bkg, b, h, no,,, "Fix background parameters" # # Standard parameters #==================== +publish, b, h, no,,, "Publish spectrum on VO Hub?" 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" diff --git a/cscripts/csspec.py b/cscripts/csspec.py index e064dbe..64a5ebd 100755 --- a/cscripts/csspec.py +++ b/cscripts/csspec.py @@ -268,18 +268,17 @@ class csspec(ctools.cscript): par.fix() # Write header + self._log_header1(gammalib.TERSE, 'Generate spectrum') if self._logTerse(): - self._log("\n") - self._log.header1("Generate spectrum") - self._log(str(self._ebounds)) + self._log(str(self._ebounds)) # Initialise FITS Table with extension "SPECTRUM" table = gammalib.GFitsBinTable(self._ebounds.size()) - table.extname("SPECTRUM") + table.extname('SPECTRUM') # Add Header for compatibility with gammalib.GMWLSpectrum - table.card("INSTRUME", "CTA", "Name of Instrument") - table.card("TELESCOP", "CTA", "Name of Telescope") + table.card('INSTRUME', 'CTA', 'Name of Instrument') + table.card('TELESCOP', 'CTA', 'Name of Telescope') # Create FITS table columns nrows = self._ebounds.size() @@ -470,12 +469,16 @@ class csspec(ctools.cscript): self._fits = gammalib.GFits() self._fits.append(table) + # Optionally publish light curve + if self['publish'].boolean(): + self.publish() + # Return return def execute(self): """ - Execute the script. + Execute the script """ # Open logfile self.logFileOpen() @@ -494,24 +497,19 @@ class csspec(ctools.cscript): def save(self): """ - Save spectrum. + Save spectrum """ # Write header - if self._logTerse(): - self._log("\n") - self._log.header1("Save spectrum") + self._log_header1(gammalib.TERSE, 'Save spectrum') # Get outmap parameter - outfile = self["outfile"].filename() + outfile = self['outfile'].filename() # Continue only filename and residual map are valid if self._fits != None: # Log file name - if self._logTerse(): - self._log(gammalib.parformat("Spectrum file")) - self._log(outfile.url()) - self._log("\n") + self._log_value(gammalib.NORMAL, 'Spectrum file', outfile.url()) # Save spectrum self._fits.saveto(outfile, self._clobber) @@ -519,6 +517,36 @@ class csspec(ctools.cscript): # Return return + def publish(self, name=''): + """ + Publish spectrum + + Parameters + ---------- + name : str, optional + Name of spectrum + """ + # Write header + self._log_header1(gammalib.TERSE, 'Publish spectrum') + + # Continue only if spectrum is valid + if self._fits.contains('SPECTRUM'): + + # Set default name is user name is empty + if not name: + user_name = self._name + else: + user_name = name + + # Log file name + self._log_value(gammalib.NORMAL, 'Spectrum name', user_name) + + # Publish spectrum + self._fits.publish('SPECTRUM', user_name) + + # Return + return + def spectrum(self): """ Return spectrum FITS file. diff --git a/cscripts/csviscube.par b/cscripts/csviscube.par index 56a2116..860816e 100644 --- a/cscripts/csviscube.par +++ b/cscripts/csviscube.par @@ -35,6 +35,7 @@ zmax, r, h, 60.0,,, "Maximum zenith angle (deg)" # # Standard parameters #==================== +publish, b, h, no,,, "Publish visibility cube on VO Hub?" 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" diff --git a/cscripts/csviscube.py b/cscripts/csviscube.py index a32821e..92c9c13 100755 --- a/cscripts/csviscube.py +++ b/cscripts/csviscube.py @@ -459,6 +459,10 @@ class csviscube(ctools.cscript): # Compute visibility cube self._visibility_cube() + # Optionally publish map + if self['publish'].boolean(): + self.publish() + # Return return @@ -481,6 +485,33 @@ class csviscube(ctools.cscript): # Return return + def publish(self, name=''): + """ + Publish visibility cube + + Parameters + ---------- + name : str, optional + Name of visibility cube + """ + # Write header + self._log_header1(gammalib.TERSE, 'Publish visibility cube') + + # Set default name is user name is empty + if not name: + user_name = self._name + else: + user_name = name + + # Log cube name + self._log_value(gammalib.TERSE, 'Visibility cube name', user_name) + + # Publish cube + self._cube.publish(user_name) + + # Return + return + def execute(self): """ Execute the script diff --git a/doc/source/users/reference_manual/cslightcrv.rst b/doc/source/users/reference_manual/cslightcrv.rst index cc2196d..8a91dd0 100644 --- a/doc/source/users/reference_manual/cslightcrv.rst +++ b/doc/source/users/reference_manual/cslightcrv.rst @@ -118,6 +118,9 @@ General parameters Standard parameters ------------------- +``(publish = no) [boolean]`` + Specifies whether the light curve should be published on VO Hub. + ``(chatter = 2) [integer]`` Verbosity of the executable: chatter = 0: no information will be logged diff --git a/doc/source/users/reference_manual/csspec.rst b/doc/source/users/reference_manual/csspec.rst index 4a8e55d..992f1eb 100644 --- a/doc/source/users/reference_manual/csspec.rst +++ b/doc/source/users/reference_manual/csspec.rst @@ -110,6 +110,9 @@ General parameters Standard parameters ------------------- +``(publish = no) [boolean]`` + Specifies whether the spectrum should be published on VO Hub. + ``(chatter = 2) [integer]`` Verbosity of the executable: chatter = 0: no information will be logged diff --git a/doc/source/users/reference_manual/csviscube.rst b/doc/source/users/reference_manual/csviscube.rst index bf24701..9353145 100644 --- a/doc/source/users/reference_manual/csviscube.rst +++ b/doc/source/users/reference_manual/csviscube.rst @@ -58,6 +58,9 @@ General parameters Standard parameters ------------------- +``(publish = no) [boolean]`` + Specifies whether the visibility cube should be published on VO Hub. + ``(chatter = 2) [integer]`` Verbosity of the executable: chatter = 0: no information will be logged diff --git a/doc/source/users/reference_manual/ctobssim.rst b/doc/source/users/reference_manual/ctobssim.rst index 2c021d2..de435c6 100644 --- a/doc/source/users/reference_manual/ctobssim.rst +++ b/doc/source/users/reference_manual/ctobssim.rst @@ -106,6 +106,9 @@ General parameters Standard parameters ------------------- +``(publish = no) [boolean]`` + Specifies whether the event list(s) should be published on VO Hub. + ``(chatter = 2) [integer]`` Verbosity of the executable: chatter = 0: no information will be logged diff --git a/doc/source/users/reference_manual/ctselect.rst b/doc/source/users/reference_manual/ctselect.rst index 7e281f1..b9b4a9f 100644 --- a/doc/source/users/reference_manual/ctselect.rst +++ b/doc/source/users/reference_manual/ctselect.rst @@ -95,6 +95,9 @@ General parameters Standard parameters ------------------- +``(publish = no) [boolean]`` + Specifies whether the event list(s) should be published on VO Hub. + ``(chatter = 2) [integer]`` Verbosity of the executable: chatter = 0: no information will be logged diff --git a/pyext/ctobssim.i b/pyext/ctobssim.i index 392f94b..f9d6d8e 100644 --- a/pyext/ctobssim.i +++ b/pyext/ctobssim.i @@ -1,7 +1,7 @@ /*************************************************************************** * ctobssim - Observation simulator tool * * ----------------------------------------------------------------------- * - * copyright (C) 2011-2015 by Juergen Knoedlseder * + * copyright (C) 2011-2016 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -47,6 +47,7 @@ public: void clear(void); void run(void); void save(void); + void publish(const std::string& name = ""); const double& max_rate(void) const; void max_rate(const double& max_rate); }; diff --git a/pyext/ctselect.i b/pyext/ctselect.i index f69ba79..17c4f9b 100644 --- a/pyext/ctselect.i +++ b/pyext/ctselect.i @@ -1,7 +1,7 @@ /*************************************************************************** * ctselect - Data selection tool * * ----------------------------------------------------------------------- * - * copyright (C) 2010-2014 by Jurgen Knodlseder * + * copyright (C) 2010-2016 by Jurgen Knodlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -47,6 +47,7 @@ public: void clear(void); void run(void); void save(void); + void publish(const std::string& name = ""); }; diff --git a/src/ctobssim/ctobssim.cpp b/src/ctobssim/ctobssim.cpp index 9de576f..2504c3b 100644 --- a/src/ctobssim/ctobssim.cpp +++ b/src/ctobssim/ctobssim.cpp @@ -32,6 +32,8 @@ #include #include "ctobssim.hpp" #include "GTools.hpp" +#include "GFits.hpp" + /* __ Method name definitions ____________________________________________ */ #define G_GET_PARAMETERS "ctobssim::get_parameters()" @@ -415,6 +417,11 @@ void ctobssim::run(void) // Restore energy dispersion flags of all CTA observations restore_edisp(m_obs, save_edisp); + // Optionally publish event list(s) + if ((*this)["publish"].boolean()) { + publish(); + } + // Return return; } @@ -459,6 +466,60 @@ void ctobssim::save(void) } +/***********************************************************************//** + * @brief Publish event lists + * + * @param[in] name Event list name. + ***************************************************************************/ +void ctobssim::publish(const std::string& name) +{ + // Write header into logger + log_header1(TERSE, gammalib::number("Publish event list", m_obs.size())); + + // Loop over all observation in the container + for (int i = 0; i < m_obs.size(); ++i) { + + // Get CTA observation + GCTAObservation* obs = dynamic_cast(m_obs[i]); + + // Handle only CTA observations + if (obs != NULL) { + + // Continue only if there is an event list + if (obs->events()->size() != 0) { + + // Set default name if user name is empty + std::string user_name(name); + if (user_name.empty()) { + user_name = CTOBSSIM_NAME; + } + + // If there are several event lists then add an index + if (m_use_xml) { + user_name += gammalib::str(i); + } + + // Write event list name into logger + log_value(NORMAL, "Event list name", user_name); + + // Write events into in-memory FITS file + GFits fits; + obs->write(fits); + + // Publish + fits.publish("EVENTS", user_name); + + } // endif: there were events + + } // endif: observation was a CTA observation + + } // endfor: looped over observations + + // Return + return; +} + + /*========================================================================== = = = Private methods = diff --git a/src/ctobssim/ctobssim.hpp b/src/ctobssim/ctobssim.hpp index 3721b6a..c9adb1f 100644 --- a/src/ctobssim/ctobssim.hpp +++ b/src/ctobssim/ctobssim.hpp @@ -34,7 +34,7 @@ /* __Definitions _________________________________________________________ */ #define CTOBSSIM_NAME "ctobssim" -#define CTOBSSIM_VERSION "1.1.0" +#define CTOBSSIM_VERSION "1.2.0" /***********************************************************************//** @@ -65,6 +65,7 @@ public: void clear(void); void run(void); void save(void); + void publish(const std::string& name = ""); const double& max_rate(void) const; void max_rate(const double& max_rate); diff --git a/src/ctobssim/ctobssim.par b/src/ctobssim/ctobssim.par index f6bfb2e..274e9aa 100644 --- a/src/ctobssim/ctobssim.par +++ b/src/ctobssim/ctobssim.par @@ -5,7 +5,7 @@ # ------------------------------------------------------------------------- # # # # File: ctobssim.par # -# Version: 1.1.0 # +# Version: 1.2.0 # # # # Author: Juergen Knoedlseder # # Jurgen.Knodlseder@irap.omp.eu # @@ -43,6 +43,7 @@ eslices, i, h, 10,1,100, "Number of energy slices" # # Standard parameters #==================== +publish, b, h, no,,, "Publish event list on VO Hub?" 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" diff --git a/src/ctselect/ctselect.cpp b/src/ctselect/ctselect.cpp index c43fb21..6c2f045 100644 --- a/src/ctselect/ctselect.cpp +++ b/src/ctselect/ctselect.cpp @@ -348,6 +348,11 @@ void ctselect::run(void) // Write observation(s) into logger log_observations(NORMAL, m_obs, "Output observation"); + // Optionally publish event list(s) + if ((*this)["publish"].boolean()) { + publish(); + } + // Return return; } @@ -392,6 +397,60 @@ void ctselect::save(void) } +/***********************************************************************//** + * @brief Publish event lists + * + * @param[in] name Event list name. + ***************************************************************************/ +void ctselect::publish(const std::string& name) +{ + // Write header into logger + log_header1(TERSE, gammalib::number("Publish event list", m_obs.size())); + + // Loop over all observation in the container + for (int i = 0; i < m_obs.size(); ++i) { + + // Get CTA observation + GCTAObservation* obs = dynamic_cast(m_obs[i]); + + // Handle only CTA observations + if (obs != NULL) { + + // Continue only if there is an event list + if (obs->events()->size() != 0) { + + // Set default name if user name is empty + std::string user_name(name); + if (user_name.empty()) { + user_name = CTSELECT_NAME; + } + + // If there are several event lists then add an index + if (m_use_xml) { + user_name += gammalib::str(i); + } + + // Write event list name into logger + log_value(NORMAL, "Event list name", user_name); + + // Write events into in-memory FITS file + GFits fits; + obs->write(fits); + + // Publish + fits.publish("EVENTS", user_name); + + } // endif: there were events + + } // endif: observation was a CTA observation + + } // endfor: looped over observations + + // Return + return; +} + + /*========================================================================== = = = Private methods = diff --git a/src/ctselect/ctselect.hpp b/src/ctselect/ctselect.hpp index cbde4c2..f41e209 100644 --- a/src/ctselect/ctselect.hpp +++ b/src/ctselect/ctselect.hpp @@ -61,6 +61,7 @@ public: void clear(void); void run(void); void save(void); + void publish(const std::string& name = ""); protected: // Protected methods diff --git a/src/ctselect/ctselect.par b/src/ctselect/ctselect.par index ce05ec4..af15510 100644 --- a/src/ctselect/ctselect.par +++ b/src/ctselect/ctselect.par @@ -5,7 +5,7 @@ # ------------------------------------------------------------------------- # # # # File: ctselect.par # -# Version: 1.0.0 # +# Version: 1.2.0 # # # # Author: Jurgen Knodlseder # # Jurgen.Knodlseder@irap.omp.eu # @@ -38,6 +38,7 @@ usethres,s, h, "NONE",NONE|DEFAULT|USER,, "Energy threshold type" # # Standard parameters #==================== +publish, b, h, no,,, "Publish event list on VO Hub?" 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" diff --git a/src/ctskymap/ctskymap.cpp b/src/ctskymap/ctskymap.cpp index dd6e959..a756c18 100644 --- a/src/ctskymap/ctskymap.cpp +++ b/src/ctskymap/ctskymap.cpp @@ -294,7 +294,7 @@ void ctskymap::publish(const std::string& name) // Write header into logger log_header1(TERSE, "Publish sky map"); - // Set default name is user name is empty + // Set default name if user name is empty std::string user_name(name); if (user_name.empty()) { user_name = CTSKYMAP_NAME; diff --git a/test/test_cslightcrv.py b/test/test_cslightcrv.py index 2b160d7..a5bcd71 100755 --- a/test/test_cslightcrv.py +++ b/test/test_cslightcrv.py @@ -126,6 +126,7 @@ class Test(test): lcrv['outfile'] = 'cslightcrv_py1.fits' lcrv['logfile'] = 'cslightcrv_py1.log' lcrv['chatter'] = 2 + lcrv['publish'] = True # Run cslightcrv script and save light curve lcrv.logFileOpen() # Make sure we get a log file diff --git a/test/test_csspec.py b/test/test_csspec.py index 4bf7382..ec77818 100755 --- a/test/test_csspec.py +++ b/test/test_csspec.py @@ -130,6 +130,7 @@ class Test(test): spec['emax'] = 100.0 spec['logfile'] = 'csspec_py1.log' spec['chatter'] = 2 + spec['publish'] = True # Run csspec script spec.logFileOpen() # Make sure we get a log file @@ -155,6 +156,7 @@ class Test(test): spec['emax'] = 100.0 spec['logfile'] = 'csspec_py2.log' spec['chatter'] = 3 + spec['publish'] = False # Execute csspec script spec.execute() diff --git a/test/test_csviscube.py b/test/test_csviscube.py index ffe7b61..421f2fa 100755 --- a/test/test_csviscube.py +++ b/test/test_csviscube.py @@ -34,7 +34,7 @@ class Test(test): # Constructor def __init__(self): """ - Constructor. + Constructor """ # Call base class constructor test.__init__(self) @@ -45,7 +45,7 @@ class Test(test): # Set test functions def set(self): """ - Set all test functions. + Set all test functions """ # Set test name self.name('csviscube') @@ -60,7 +60,7 @@ class Test(test): # Test csviscube on command line def _test_cmd(self): """ - Test csviscube on the command line. + Test csviscube on the command line """ # Set script name csviscube = self._script('csviscube') @@ -84,7 +84,7 @@ class Test(test): # Test csviscube from Python def _test_python(self): """ - Test csviscube from Python. + Test csviscube from Python """ # Set-up csviscube viscube = cscripts.csviscube() @@ -96,6 +96,7 @@ class Test(test): viscube['outfile'] = 'csviscube_py1.fits' viscube['logfile'] = 'csviscube_py1.log' viscube['chatter'] = 2 + viscube['publish'] = True # Run script viscube.logFileOpen() # Make sure we get a log file diff --git a/test/test_ctobssim.py b/test/test_ctobssim.py index c6e18db..0fa61ad 100755 --- a/test/test_ctobssim.py +++ b/test/test_ctobssim.py @@ -228,6 +228,7 @@ class Test(test): cpy_sim['outevents'] = 'ctobssim_py3.xml' cpy_sim['logfile'] = 'ctobssim_py3.log' cpy_sim['chatter'] = 4 + cpy_sim['publish'] = True cpy_sim.logFileOpen() # Needed to get a new log file cpy_sim.execute() diff --git a/test/test_ctselect.py b/test/test_ctselect.py index c70f51a..7b135c3 100755 --- a/test/test_ctselect.py +++ b/test/test_ctselect.py @@ -177,6 +177,7 @@ class Test(test): cpy_select['outobs'] = 'ctselect_py2.fits' cpy_select['logfile'] = 'ctselect_py2.log' cpy_select['chatter'] = 3 + cpy_select['publish'] = True cpy_select.logFileOpen() # Needed to get a new log file cpy_select.execute()