Commit b6b50dc00463c2ae4f00ba9da68a9f8f687aa7bb
Merge branch 'devel' into release
# Conflicts: # ChangeLog # NEWS # README # inst/cta/src/GCTAEdisp2D.cpp
Showing
16 changed files
with
306 additions
and
486 deletions
ChangeLog
| 1 | -2015-12-17 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu> | |
| 1 | +2015-12-18 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu> | |
| 2 | 2 | |
| 3 | 3 | * Version 1.0.0 released |
| 4 | 4 | ========================= |
| 5 | 5 | |
| 6 | 6 | Ignore errors for El Capitan post processing (#1605) |
| 7 | + Read only mandatary columns in GCTAEventList (#1600) | |
| 8 | + Add GModel::has_ts() method (#1578) | |
| 7 | 9 | Remove extname arguments from classes (#1601) |
| 8 | 10 | Add GFilename class (#1599) |
| 9 | 11 | Check existence of files in CTA response loading (#1586) |
| 10 | 12 | GSkyMap::__getitem__ throw exception if out of bound (#1581) |
| 11 | 13 | Handle ~ in filenames (#1580) |
| 14 | + Add GModel::has_ts() method (#1578) | |
| 12 | 15 | Perform __init__.py creation only in build step (#1569) |
| 13 | 16 | Remove access by name methods from GSkyRegions (#1564) |
| 14 | 17 | Resolve Python test problem on El Capitan (#1563) | ... | ... |
NEWS
| ... | ... | @@ -58,7 +58,8 @@ None |
| 58 | 58 | |
| 59 | 59 | 8. Model module |
| 60 | 60 | --------------- |
| 61 | -None | |
| 61 | +Added GModel::has_ts() method that signals if a TS value has been computed | |
| 62 | +for a given model. | |
| 62 | 63 | |
| 63 | 64 | |
| 64 | 65 | 9. Numerics module |
| ... | ... | @@ -134,9 +135,12 @@ None |
| 134 | 135 | |
| 135 | 136 | 20. CTA interface |
| 136 | 137 | ----------------- |
| 137 | -The IRF loaders now check the existence of the file before loading, and now throw | |
| 138 | +The IRF loaders now check the existence of the file before loading, and now throws | |
| 138 | 139 | appropriate error messages in case that the files do not exist (#1586). |
| 139 | 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. | |
| 143 | + | |
| 140 | 144 | |
| 141 | 145 | 21. COMPTEL interface |
| 142 | 146 | --------------------- | ... | ... |
configure.ac
| ... | ... | @@ -29,7 +29,7 @@ |
| 29 | 29 | ############################################################################# |
| 30 | 30 | # Initialisation # |
| 31 | 31 | ############################################################################# |
| 32 | -AC_INIT([gammalib], [1.0.0], [jurgen.knodlseder@irap.omp.eu], [gammalib]) | |
| 32 | +AC_INIT([gammalib], [1.1.0.dev], [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]) | ... | ... |
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 = 1.0.0 | |
| 35 | +PROJECT_NUMBER = 1.1.0.dev | |
| 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/conf.py
| ... | ... | @@ -55,9 +55,10 @@ copyright = u'2006-2015, GammaLib developers' |
| 55 | 55 | # built documents. |
| 56 | 56 | # |
| 57 | 57 | # The short X.Y version. |
| 58 | -version = '1.0' | |
| 58 | +version = '1.1' | |
| 59 | + | |
| 59 | 60 | # The full version, including alpha/beta/rc tags. |
| 60 | -release = '1.0.0' | |
| 61 | +release = '1.1.0.dev' | |
| 61 | 62 | |
| 62 | 63 | # The language for content autogenerated by Sphinx. Refer to documentation |
| 63 | 64 | # for a list of supported languages. | ... | ... |
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& 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/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 | ... | ... |
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& 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& 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/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/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/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& 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& 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& 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& 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& table) |
| 908 | 761 | /***********************************************************************//** |
| 909 | 762 | * @brief Write CTA events into FITS table |
| 910 | 763 | * |
| 911 | - * @param[in] hdu FITS table HDU. | |
| 764 | + * @param[in] table 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& 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 | ... | ... |
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; | ... | ... |
src/vo/GVOClient.cpp
| ... | ... | @@ -517,7 +517,7 @@ bool GVOClient::find_hub(void) |
| 517 | 517 | if (!lockurl.empty()) { |
| 518 | 518 | |
| 519 | 519 | // If we have a file:// prefix then strip it now. This is a kluge |
| 520 | - // and should be remplaced by a method that allows opening any kind | |
| 520 | + // and should be replaced by a method that allows opening any kind | |
| 521 | 521 | // of URL |
| 522 | 522 | if (lockurl.compare(0, 7, "file://") == 0) { |
| 523 | 523 | lockurl = lockurl.substr(7, std::string::npos); |
| ... | ... | @@ -955,7 +955,6 @@ std::string GVOClient::receive_string(void) const |
| 955 | 955 | int n = 0; |
| 956 | 956 | do { |
| 957 | 957 | n = gammalib::recv(m_socket, buffer, 1000, 0, timeout); |
| 958 | - //n = recv(m_socket, buffer, 1000, 0); | |
| 959 | 958 | if (n > 0) { |
| 960 | 959 | buffer[n] = '\0'; |
| 961 | 960 | result.append(std::string(buffer)); |
| ... | ... | @@ -1074,7 +1073,7 @@ std::string GVOClient::get_hub_lockfile(void) const |
| 1074 | 1073 | char* hub_ptr = std::getenv("SAMP_HUB"); |
| 1075 | 1074 | if (hub_ptr != NULL) { |
| 1076 | 1075 | |
| 1077 | - // Check for mandatory std-lockurl: prefix (no other prefixe is | |
| 1076 | + // Check for mandatory std-lockurl: prefix (no other prefix is | |
| 1078 | 1077 | // supported so far) |
| 1079 | 1078 | std::string lockurl = std::string(hub_ptr); |
| 1080 | 1079 | if (lockurl.compare(0, 12, "std-lockurl:") == 0) { |
| ... | ... | @@ -1084,7 +1083,7 @@ std::string GVOClient::get_hub_lockfile(void) const |
| 1084 | 1083 | |
| 1085 | 1084 | } // endif: std-lockurl: prefix found |
| 1086 | 1085 | |
| 1087 | - } | |
| 1086 | + } // endif: SAMP_HUB environment variable found | |
| 1088 | 1087 | |
| 1089 | 1088 | // ... otherwise the lockfile should be $HOME/.samp |
| 1090 | 1089 | else { | ... | ... |
src/vo/GVOHub.cpp
| ... | ... | @@ -47,6 +47,7 @@ |
| 47 | 47 | |
| 48 | 48 | /* __ Method name definitions ____________________________________________ */ |
| 49 | 49 | #define G_START_HUB "GVOHub::start_hub()" |
| 50 | +#define G_START_SOCKET "GVOHub::start_socket()" | |
| 50 | 51 | |
| 51 | 52 | /* __ Macros _____________________________________________________________ */ |
| 52 | 53 | |
| ... | ... | @@ -179,9 +180,6 @@ GVOHub* GVOHub::clone(void) const |
| 179 | 180 | ***************************************************************************/ |
| 180 | 181 | void GVOHub::start(void) |
| 181 | 182 | { |
| 182 | - // Create SAMP file | |
| 183 | - create_samp_file(); | |
| 184 | - | |
| 185 | 183 | // Start Hub |
| 186 | 184 | start_hub(); |
| 187 | 185 | |
| ... | ... | @@ -210,7 +208,7 @@ std::string GVOHub::print(const GChatter& chatter) const |
| 210 | 208 | // Append Hub information |
| 211 | 209 | result.append("\n"+gammalib::parformat("Hub identifier")+m_hub_id); |
| 212 | 210 | result.append("\n"+gammalib::parformat("Hub key")+m_secret); |
| 213 | - result.append("\n"+gammalib::parformat("Hub URL")+m_hub_url); | |
| 211 | + result.append("\n"+gammalib::parformat("Hub URL")+hub_url()); | |
| 214 | 212 | result.append("\n"+gammalib::parformat("Hub host")+m_hub_host); |
| 215 | 213 | result.append("\n"+gammalib::parformat("Hub port")+m_hub_port); |
| 216 | 214 | result.append("\n"+gammalib::parformat("Hub path")+m_hub_path); |
| ... | ... | @@ -240,7 +238,6 @@ void GVOHub::init_members(void) |
| 240 | 238 | m_hub_host = "127.0.0.1"; |
| 241 | 239 | m_hub_port = "2526"; |
| 242 | 240 | m_hub_path = "xmlrpc"; |
| 243 | - m_hub_url = "http://"+m_hub_host+":"+m_hub_port+"/"+m_hub_path; | |
| 244 | 241 | m_version = "1.3"; |
| 245 | 242 | m_hub_id = "gammalib_hub"; |
| 246 | 243 | m_socket = -1; // Signals no socket |
| ... | ... | @@ -261,7 +258,6 @@ void GVOHub::copy_members(const GVOHub& hub) |
| 261 | 258 | { |
| 262 | 259 | // Copy members |
| 263 | 260 | m_secret = hub.m_secret; |
| 264 | - m_hub_url = hub.m_hub_url; | |
| 265 | 261 | m_hub_host = hub.m_hub_host; |
| 266 | 262 | m_hub_port = hub.m_hub_port; |
| 267 | 263 | m_hub_path = hub.m_hub_path; |
| ... | ... | @@ -288,8 +284,7 @@ void GVOHub::free_members(void) |
| 288 | 284 | } |
| 289 | 285 | |
| 290 | 286 | // Remove lockfile |
| 291 | - std::string lockurl = get_hub_lockfile(); | |
| 292 | - std::remove(lockurl.c_str()); | |
| 287 | + delete_samp_file(); | |
| 293 | 288 | |
| 294 | 289 | // Return |
| 295 | 290 | return; |
| ... | ... | @@ -306,46 +301,13 @@ void GVOHub::free_members(void) |
| 306 | 301 | ***************************************************************************/ |
| 307 | 302 | void GVOHub::start_hub(void) |
| 308 | 303 | { |
| 309 | - // Prepare TCP/IP structure | |
| 310 | - struct sockaddr_in serv_addr; | |
| 311 | - std::memset(&serv_addr, 0, sizeof(serv_addr)); | |
| 312 | - serv_addr.sin_family = AF_INET; | |
| 313 | - serv_addr.sin_addr.s_addr = inet_addr(m_hub_host.c_str()); | |
| 314 | - serv_addr.sin_port = htons(gammalib::toint(m_hub_port)); | |
| 315 | - | |
| 316 | - // Create Hub socket | |
| 317 | - m_socket = socket(AF_INET, SOCK_STREAM, 0); | |
| 318 | - | |
| 319 | - // Creation of hub main socket | |
| 320 | - if (m_socket < 0) { | |
| 321 | - std::string msg = "Unable to create Hub socket. Errno="+ | |
| 322 | - gammalib::str(errno); | |
| 323 | - throw GException::runtime_error(G_START_HUB, msg); | |
| 324 | - } | |
| 325 | - | |
| 326 | - // Set hub main socket to allow multiple connections | |
| 327 | - int opt = 1; | |
| 328 | - if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)) < 0) { | |
| 329 | - std::string msg = "Unable to set Hub socket to multiple connections." | |
| 330 | - " Errno="+gammalib::str(errno); | |
| 331 | - throw GException::runtime_error(G_START_HUB, msg); | |
| 332 | - } | |
| 333 | - #ifdef SO_REUSEPORT | |
| 334 | - if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEPORT, (char*)&opt, sizeof(opt)) < 0) { | |
| 335 | - std::string msg = "Unable to set Hub socket to multiple connections." | |
| 336 | - " Errno="+gammalib::str(errno); | |
| 337 | - throw GException::runtime_error(G_START_HUB, msg); | |
| 338 | - } | |
| 339 | - #endif | |
| 340 | - | |
| 341 | - // Server socket is opened. Now, bind it to the port, with family etc. | |
| 342 | - if (bind(m_socket, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { | |
| 343 | - std::string msg = "Unable to bind Hub socket to server socket. Errno="+ | |
| 344 | - gammalib::str(errno); | |
| 345 | - throw GException::runtime_error(G_START_HUB, msg); | |
| 346 | - } | |
| 304 | + // Get socket | |
| 305 | + m_socket = get_socket(); | |
| 306 | + | |
| 307 | + // Create SAMP file | |
| 308 | + create_samp_file(); | |
| 347 | 309 | |
| 348 | - // Now start listening for the clients: 5 requests simultaneously pending | |
| 310 | + // Start listening for the clients: 5 requests simultaneously pending | |
| 349 | 311 | // at maximum |
| 350 | 312 | if (listen(m_socket, 5) < 0) { |
| 351 | 313 | std::string msg = "Unable to start listening on Hub socket. Errno="+ |
| ... | ... | @@ -385,6 +347,9 @@ void GVOHub::start_hub(void) |
| 385 | 347 | close(m_socket); |
| 386 | 348 | m_socket = -1; |
| 387 | 349 | |
| 350 | + // Delete SAMP file | |
| 351 | + delete_samp_file(); | |
| 352 | + | |
| 388 | 353 | // Return |
| 389 | 354 | return; |
| 390 | 355 | } |
| ... | ... | @@ -596,7 +561,7 @@ void GVOHub::request_register(const GXml& xml, const socklen_t& sock) |
| 596 | 561 | response.append(" </member>\n"); |
| 597 | 562 | response.append(" <member>\n"); |
| 598 | 563 | response.append(" <name>samp.url-translator</name>\n"); |
| 599 | - response.append(" <value>"+m_hub_url+"</value>\n"); | |
| 564 | + response.append(" <value>"+hub_url()+"</value>\n"); | |
| 600 | 565 | response.append(" </member>\n"); |
| 601 | 566 | response.append(" </struct></value></param>\n"); |
| 602 | 567 | response.append("</params>\n"); |
| ... | ... | @@ -1628,9 +1593,10 @@ void GVOHub::send_notifications(const std::string& method, |
| 1628 | 1593 | |
| 1629 | 1594 | |
| 1630 | 1595 | /***********************************************************************//** |
| 1631 | - * @brief Creates the lockfile, fill it | |
| 1596 | + * @brief Create the lockfile | |
| 1632 | 1597 | * |
| 1633 | - * Implements IVOA standard REC-SAMP-1.3-20120411. | |
| 1598 | + * Creates the SAMP lockfile and fill it with information. Implements IVOA | |
| 1599 | + * standard REC-SAMP-1.3-20120411. | |
| 1634 | 1600 | ***************************************************************************/ |
| 1635 | 1601 | void GVOHub::create_samp_file(void) const |
| 1636 | 1602 | { |
| ... | ... | @@ -1647,7 +1613,7 @@ void GVOHub::create_samp_file(void) const |
| 1647 | 1613 | fprintf(fptr, "# SAMP lockfile\n"); |
| 1648 | 1614 | fprintf(fptr, "# Required keys:\n"); |
| 1649 | 1615 | fprintf(fptr, "samp.secret=%s\n", m_secret.c_str()); |
| 1650 | - fprintf(fptr, "samp.hub.xmlrpc.url=%s\n", m_hub_url.c_str()); | |
| 1616 | + fprintf(fptr, "samp.hub.xmlrpc.url=%s\n", hub_url().c_str()); | |
| 1651 | 1617 | fprintf(fptr, "samp.profile.version=%s\n", m_version.c_str()); |
| 1652 | 1618 | fprintf(fptr, "# Info stored by hub for some private reason:\n"); |
| 1653 | 1619 | fprintf(fptr, "gammalib.hubid=%s\n", m_hub_id.c_str()); |
| ... | ... | @@ -1663,6 +1629,87 @@ void GVOHub::create_samp_file(void) const |
| 1663 | 1629 | |
| 1664 | 1630 | |
| 1665 | 1631 | /***********************************************************************//** |
| 1632 | + * @brief Delete the lockfile | |
| 1633 | + * | |
| 1634 | + * Deletes the SAMP lockfile on disk. | |
| 1635 | + ***************************************************************************/ | |
| 1636 | +void GVOHub::delete_samp_file(void) const | |
| 1637 | +{ | |
| 1638 | + // Get lockfile URL | |
| 1639 | + std::string lockurl = get_hub_lockfile(); | |
| 1640 | + | |
| 1641 | + // Delete lockfile | |
| 1642 | + std::remove(lockurl.c_str()); | |
| 1643 | + | |
| 1644 | + // Return | |
| 1645 | + return; | |
| 1646 | +} | |
| 1647 | + | |
| 1648 | + | |
| 1649 | +/***********************************************************************//** | |
| 1650 | + * @brief Get Hub socket | |
| 1651 | + * | |
| 1652 | + * @return Hub socket (-1 if no socket was found). | |
| 1653 | + * | |
| 1654 | + * Returns Hub socket. Starting from an initial port of 2526 the method | |
| 1655 | + * searches for the next free port and binds it to a socket. | |
| 1656 | + ***************************************************************************/ | |
| 1657 | +int GVOHub::get_socket(void) | |
| 1658 | +{ | |
| 1659 | + // Initialise socket, port and socket address structure | |
| 1660 | + int sock = -1; | |
| 1661 | + int port = 2526; | |
| 1662 | + struct sockaddr_in serv_addr; | |
| 1663 | + | |
| 1664 | + // Loop over 100 ports at most | |
| 1665 | + for (int i = 0; i < 100; ++i) { | |
| 1666 | + | |
| 1667 | + // Clean TCP/IP structure | |
| 1668 | + std::memset(&serv_addr, 0, sizeof(serv_addr)); | |
| 1669 | + | |
| 1670 | + // Set TCP/IP structure | |
| 1671 | + serv_addr.sin_family = AF_INET; | |
| 1672 | + serv_addr.sin_addr.s_addr = inet_addr(m_hub_host.c_str()); | |
| 1673 | + serv_addr.sin_port = htons(port); | |
| 1674 | + | |
| 1675 | + // Create Hub socket | |
| 1676 | + sock = socket(AF_INET, SOCK_STREAM, 0); | |
| 1677 | + | |
| 1678 | + // Creation of hub main socket | |
| 1679 | + if (sock < 0) { | |
| 1680 | + std::string msg = "Unable to create Hub socket. Errno="+ | |
| 1681 | + gammalib::str(errno); | |
| 1682 | + throw GException::runtime_error(G_START_SOCKET, msg); | |
| 1683 | + } | |
| 1684 | + | |
| 1685 | + // Now bind socket to the address and port | |
| 1686 | + if (bind(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { | |
| 1687 | + if (errno == EADDRINUSE) { | |
| 1688 | + port++; | |
| 1689 | + close(sock); | |
| 1690 | + } | |
| 1691 | + else { | |
| 1692 | + std::string msg = "Unable to bind Hub socket to address "+ | |
| 1693 | + m_hub_host+":"+gammalib::str(port)+ | |
| 1694 | + ". Errno="+gammalib::str(errno); | |
| 1695 | + throw GException::runtime_error(G_START_HUB, msg); | |
| 1696 | + } | |
| 1697 | + } | |
| 1698 | + else { | |
| 1699 | + break; | |
| 1700 | + } | |
| 1701 | + | |
| 1702 | + } // endfor: looped over ports | |
| 1703 | + | |
| 1704 | + // Store port as string | |
| 1705 | + m_hub_port = gammalib::str(port); | |
| 1706 | + | |
| 1707 | + // Return socket | |
| 1708 | + return sock; | |
| 1709 | +} | |
| 1710 | + | |
| 1711 | + | |
| 1712 | +/***********************************************************************//** | |
| 1666 | 1713 | * @brief Post string content to client |
| 1667 | 1714 | * |
| 1668 | 1715 | * @param[in] content String content to post. |
| ... | ... | @@ -1948,3 +1995,20 @@ std::string GVOHub::random_string(const size_t& length) const |
| 1948 | 1995 | return str; |
| 1949 | 1996 | } |
| 1950 | 1997 | |
| 1998 | + | |
| 1999 | +/***********************************************************************//** | |
| 2000 | + * @brief Return Hub URL | |
| 2001 | + * | |
| 2002 | + * @return Hub URL. | |
| 2003 | + * | |
| 2004 | + * Returns the XML-RPC endpoint for communication with the hub. | |
| 2005 | + ***************************************************************************/ | |
| 2006 | +std::string GVOHub::hub_url(void) const | |
| 2007 | +{ | |
| 2008 | + // Set Hub URL | |
| 2009 | + std::string hub_url = "http://"+m_hub_host+":"+m_hub_port+"/"+m_hub_path; | |
| 2010 | + | |
| 2011 | + // Return Hub URL | |
| 2012 | + return (hub_url); | |
| 2013 | +} | |
| 2014 | + | ... | ... |
test/test_GVO.cpp
| ... | ... | @@ -175,6 +175,10 @@ int main(void) |
| 175 | 175 | // Allocate test suit container |
| 176 | 176 | GTestSuites testsuites("VO module"); |
| 177 | 177 | |
| 178 | + // Unset HOME environment variable (so that the .samp file is written | |
| 179 | + // into the test directory) | |
| 180 | + unsetenv("HOME"); | |
| 181 | + | |
| 178 | 182 | // Initially assume that we pass all tests |
| 179 | 183 | bool success = true; |
| 180 | 184 | ... | ... |