Commit d16893f961382c67a7c2a8cfbc7431b1227fc453
1 parent
93244a3d
A gti_extname() method has been added to GCTAObservation and GCTAEventList to se…
…t the name of the Good Time Intervals FITS extension. The data sub-space keyword is now also adjusted to the specified GTI extension name when the data are written to disk. This satisfies the feature request #1598.
Showing
8 changed files
with
205 additions
and
190 deletions
NEWS
| ... | ... | @@ -110,6 +110,11 @@ GTIs (and also event lists) in a single FITS file. We do however require that |
| 110 | 110 | the event and GTI extension reside in the same FITS file. This satisfies the |
| 111 | 111 | feature request #1598. |
| 112 | 112 | |
| 113 | +A gti_extname() method has been added to GCTAObservation and GCTAEventList to | |
| 114 | +set the name of the Good Time Intervals FITS extension. The data sub-space | |
| 115 | +keyword is now also adjusted to the specified GTI extension name when the | |
| 116 | +data are written to disk. This satisfies the feature request #1598. | |
| 117 | + | |
| 113 | 118 | |
| 114 | 119 | 21. COMPTEL interface |
| 115 | 120 | --------------------- | ... | ... |
inst/cta/include/GCTAEventList.hpp
| ... | ... | @@ -69,19 +69,21 @@ public: |
| 69 | 69 | virtual void load(const std::string& filename); |
| 70 | 70 | virtual void save(const std::string& filename, |
| 71 | 71 | const bool& clobber = false) const; |
| 72 | - virtual void read(const GFits& file); | |
| 73 | - virtual void write(GFits& file) const; | |
| 72 | + virtual void read(const GFits& fits); | |
| 73 | + virtual void write(GFits& fits) const; | |
| 74 | 74 | virtual int number(void) const; |
| 75 | 75 | virtual void roi(const GRoi& roi); |
| 76 | 76 | virtual const GCTARoi& roi(void) const; |
| 77 | 77 | std::string print(const GChatter& chatter = NORMAL) const; |
| 78 | 78 | |
| 79 | 79 | // Implement other methods |
| 80 | - void append(const GCTAEventAtom& event); | |
| 81 | - void reserve(const int& number); | |
| 82 | - double irf_cache(const std::string& name, const int& index) const; | |
| 83 | - void irf_cache(const std::string& name, const int& index, | |
| 84 | - const double& irf) const; | |
| 80 | + void append(const GCTAEventAtom& event); | |
| 81 | + void reserve(const int& number); | |
| 82 | + double irf_cache(const std::string& name, const int& index) const; | |
| 83 | + void irf_cache(const std::string& name, const int& index, | |
| 84 | + const double& irf) const; | |
| 85 | + void gti_extname(const std::string& extname); | |
| 86 | + std::string gti_extname(void) const; | |
| 85 | 87 | |
| 86 | 88 | protected: |
| 87 | 89 | // Protected methods |
| ... | ... | @@ -172,4 +174,33 @@ void GCTAEventList::reserve(const int& number) |
| 172 | 174 | return; |
| 173 | 175 | } |
| 174 | 176 | |
| 177 | + | |
| 178 | +/***********************************************************************//** | |
| 179 | + * @brief Return Good Time Intervals FITS extension name | |
| 180 | + * | |
| 181 | + * @return Good Time Intervals FITS extension name. | |
| 182 | + * | |
| 183 | + * Returns the FITS extension name of the Good Time Intervals. | |
| 184 | + ***************************************************************************/ | |
| 185 | +inline | |
| 186 | +std::string GCTAEventList::gti_extname(void) const | |
| 187 | +{ | |
| 188 | + return ((m_gti_extname.empty()) ? "GTI" : m_gti_extname); | |
| 189 | +} | |
| 190 | + | |
| 191 | + | |
| 192 | +/***********************************************************************//** | |
| 193 | + * @brief Set Good Time Intervals FITS extension name | |
| 194 | + * | |
| 195 | + * @param[in] extname Good Time Intervals FITS extension name. | |
| 196 | + * | |
| 197 | + * Sets the FITS extension name for the Good Time Intervals. | |
| 198 | + ***************************************************************************/ | |
| 199 | +inline | |
| 200 | +void GCTAEventList::gti_extname(const std::string& extname) | |
| 201 | +{ | |
| 202 | + m_gti_extname = extname; | |
| 203 | + return; | |
| 204 | +} | |
| 205 | + | |
| 175 | 206 | #endif /* GCTAEVENTLIST_HPP */ | ... | ... |
inst/cta/include/GCTAObservation.hpp
| ... | ... | @@ -128,6 +128,7 @@ public: |
| 128 | 128 | void eventfile(const std::string& filename); |
| 129 | 129 | const std::string& eventfile(void) const; |
| 130 | 130 | const std::string& eventtype(void) const; |
| 131 | + void gti_extname(const std::string& extname); | |
| 131 | 132 | void dispose_events(void); |
| 132 | 133 | const double& lo_user_thres(void) const; |
| 133 | 134 | const double& hi_user_thres(void) const; |
| ... | ... | @@ -146,7 +147,6 @@ protected: |
| 146 | 147 | // Protected members |
| 147 | 148 | std::string m_instrument; //!< Instrument name |
| 148 | 149 | std::string m_eventfile; //!< Event filename |
| 149 | - //std::string m_gtifile; //!< GTI filename | |
| 150 | 150 | std::string m_eventtype; //!< Event type (for XML file) |
| 151 | 151 | GCTAResponse* m_response; //!< Pointer to instrument response functions |
| 152 | 152 | GCTAPointing m_pointing; //!< Pointing direction | ... | ... |
inst/cta/pyext/GCTAEventList.i
| ... | ... | @@ -51,18 +51,20 @@ public: |
| 51 | 51 | virtual void load(const std::string& filename); |
| 52 | 52 | virtual void save(const std::string& filename, |
| 53 | 53 | const bool& clobber = false) const; |
| 54 | - virtual void read(const GFits& file); | |
| 55 | - virtual void write(GFits& file) const; | |
| 54 | + virtual void read(const GFits& fits); | |
| 55 | + virtual void write(GFits& fits) const; | |
| 56 | 56 | virtual int number(void) const; |
| 57 | 57 | virtual void roi(const GRoi& roi); |
| 58 | 58 | virtual const GCTARoi& roi(void) const; |
| 59 | 59 | |
| 60 | 60 | // Implement other methods |
| 61 | - void append(const GCTAEventAtom& event); | |
| 62 | - void reserve(const int& number); | |
| 63 | - double irf_cache(const std::string& name, const int& index) const; | |
| 64 | - void irf_cache(const std::string& name, const int& index, | |
| 65 | - const double& irf) const; | |
| 61 | + void append(const GCTAEventAtom& event); | |
| 62 | + void reserve(const int& number); | |
| 63 | + double irf_cache(const std::string& name, const int& index) const; | |
| 64 | + void irf_cache(const std::string& name, const int& index, | |
| 65 | + const double& irf) const; | |
| 66 | + void gti_extname(const std::string& extname); | |
| 67 | + std::string gti_extname(void) const; | |
| 66 | 68 | }; |
| 67 | 69 | |
| 68 | 70 | ... | ... |
inst/cta/pyext/GCTAObservation.i
| ... | ... | @@ -99,6 +99,7 @@ public: |
| 99 | 99 | void eventfile(const std::string& filename); |
| 100 | 100 | const std::string& eventfile(void) const; |
| 101 | 101 | const std::string& eventtype(void) const; |
| 102 | + void gti_extname(const std::string& extname); | |
| 102 | 103 | void dispose_events(void); |
| 103 | 104 | const double& lo_user_thres(void) const; |
| 104 | 105 | const double& hi_user_thres(void) const; | ... | ... |
inst/cta/src/GCTAEventList.cpp
| ... | ... | @@ -293,14 +293,14 @@ void GCTAEventList::load(const std::string& filename) |
| 293 | 293 | void GCTAEventList::save(const std::string& filename, |
| 294 | 294 | const bool& clobber) const |
| 295 | 295 | { |
| 296 | - // Create empty FITS file | |
| 297 | - GFits fits; | |
| 296 | + // Open or create FITS file | |
| 297 | + GFits fits(filename, true); | |
| 298 | 298 | |
| 299 | 299 | // Write event list |
| 300 | 300 | write(fits); |
| 301 | 301 | |
| 302 | 302 | // Save FITS file |
| 303 | - fits.saveto(filename, clobber); | |
| 303 | + fits.save(clobber); | |
| 304 | 304 | |
| 305 | 305 | // Return |
| 306 | 306 | return; |
| ... | ... | @@ -335,11 +335,8 @@ void GCTAEventList::read(const GFits& fits) |
| 335 | 335 | // Clear object |
| 336 | 336 | clear(); |
| 337 | 337 | |
| 338 | - // Initialise filename from fits file | |
| 339 | - GFilename fname = GFilename(fits.filename()); | |
| 340 | - | |
| 341 | - // Initialise extension name | |
| 342 | - std::string extname = fname.extname("EVENTS"); | |
| 338 | + // Initialise events extension name | |
| 339 | + std::string extname = fits.filename().extname("EVENTS"); | |
| 343 | 340 | |
| 344 | 341 | // Get event list HDU |
| 345 | 342 | const GFitsTable& events = *fits.table(extname); |
| ... | ... | @@ -400,31 +397,37 @@ void GCTAEventList::read(const GFits& fits) |
| 400 | 397 | /***********************************************************************//** |
| 401 | 398 | * @brief Write CTA events into FITS file. |
| 402 | 399 | * |
| 403 | - * @param[in] file FITS file. | |
| 400 | + * @param[in] fits FITS file. | |
| 401 | + * | |
| 402 | + * Writes the CTA event list into a FITS file. The events will be written by | |
| 403 | + * default into the extension "EVENTS" unless an extension name is explicitly | |
| 404 | + * specified in the FITS file name. The method also writes the data sub-space | |
| 405 | + * keywords in the FITS header of the events table. | |
| 404 | 406 | * |
| 405 | - * Write the CTA event list into FITS file. | |
| 407 | + * In addition, the method will also append a table containing the Good Time | |
| 408 | + * Intervals of the events to the FITS file. The extension name for the Good | |
| 409 | + * Time Intervals is either taken from the m_gti_extname member, or if empty, | |
| 410 | + * is set to "GTI". | |
| 406 | 411 | ***************************************************************************/ |
| 407 | -void GCTAEventList::write(GFits& file) const | |
| 412 | +void GCTAEventList::write(GFits& fits) const | |
| 408 | 413 | { |
| 409 | - // Allocate FITS binary table HDU | |
| 410 | - GFitsBinTable* events = new GFitsBinTable; | |
| 414 | + // Allocate empty FITS binary table | |
| 415 | + GFitsBinTable table; | |
| 411 | 416 | |
| 412 | - // Write events | |
| 413 | - write_events(*events); | |
| 417 | + // Write events into binary table | |
| 418 | + write_events(table); | |
| 419 | + | |
| 420 | + // Set FITS extension name (default: "EVENTS") | |
| 421 | + table.extname(fits.filename().extname("EVENTS")); | |
| 414 | 422 | |
| 415 | 423 | // Write data selection keywords |
| 416 | - write_ds_keys(*events); | |
| 424 | + write_ds_keys(table); | |
| 417 | 425 | |
| 418 | 426 | // Append event table to FITS file |
| 419 | - file.append(*events); | |
| 427 | + fits.append(table); | |
| 420 | 428 | |
| 421 | - // Free binary table | |
| 422 | - delete events; | |
| 423 | - | |
| 424 | - // Write GTI extension if we have an extension name | |
| 425 | - if (!m_gti_extname.empty()) { | |
| 426 | - gti().write(file, m_gti_extname); | |
| 427 | - } | |
| 429 | + // Write GTI extension | |
| 430 | + gti().write(fits, gti_extname()); | |
| 428 | 431 | |
| 429 | 432 | // Return |
| 430 | 433 | return; |
| ... | ... | @@ -895,16 +898,32 @@ void GCTAEventList::write_events(GFitsBinTable& hdu) const |
| 895 | 898 | |
| 896 | 899 | |
| 897 | 900 | /***********************************************************************//** |
| 898 | - * @brief Write data selection keywords into FITS HDU | |
| 901 | + * @brief Write data sub-space keywords into FITS HDU | |
| 899 | 902 | * |
| 900 | 903 | * @param[in] hdu FITS HDU. |
| 901 | 904 | * |
| 902 | - * This method does nothing if the HDU pointer is NULL. | |
| 905 | + * Writes the data sub-space keywords for an event list into the FITS HDU. | |
| 906 | + * The following keywords will be written: | |
| 907 | + * | |
| 908 | + * DSTYP1 = "TIME" / Data sub-space type | |
| 909 | + * DSUNI1 = "s" / Data sub-space unit | |
| 910 | + * DSVAL1 = "TABLE" / Data sub-space value | |
| 911 | + * DSREF1 = ":[extname]" / Data sub-space reference | |
| 912 | + * DSTYP2 = "ENERGY" / Data sub-space type | |
| 913 | + * DSUNI2 = "TeV" / Data sub-space unit | |
| 914 | + * DSVAL2 = "[emin]:[emax]" / Data sub-space value | |
| 915 | + * DSTYP3 = "POS(RA,DEC)" / Data sub-space type | |
| 916 | + * DSUNI3 = "deg" / Data sub-space unit | |
| 917 | + * DSVAL3 = "CIRCLE([ra],[dec],[rad])" / Data sub-space value | |
| 903 | 918 | * |
| 904 | - * @todo This is a very dumb data selection keyword writing routine that does | |
| 905 | - * not take into account any existing keywords. We definitely want a | |
| 906 | - * more secure logic that checks for existing keywords and possible | |
| 907 | - * conflicts. But for the moment, this code does the job. | |
| 919 | + * where | |
| 920 | + * | |
| 921 | + * [extname] is the GTI extension (default: GTI) | |
| 922 | + * [emin] is the minimum event energy in TeV | |
| 923 | + * [emax] is the maximum event energy in TeV | |
| 924 | + * [ra] is the Right Ascension of the Region of Interest centre in degrees | |
| 925 | + * [dec] is the Declination of the Region of Interest centre in degrees | |
| 926 | + * [rad] is the radius of the Region of Interest in degrees | |
| 908 | 927 | ***************************************************************************/ |
| 909 | 928 | void GCTAEventList::write_ds_keys(GFitsHDU& hdu) const |
| 910 | 929 | { |
| ... | ... | @@ -921,16 +940,19 @@ void GCTAEventList::write_ds_keys(GFitsHDU& hdu) const |
| 921 | 940 | std::string dsval2 = gammalib::str(e_min) + ":" + |
| 922 | 941 | gammalib::str(e_max); |
| 923 | 942 | |
| 943 | + // Set Good Time Intervals extension name | |
| 944 | + std::string dsref1 = ":"+gti_extname(); | |
| 945 | + | |
| 924 | 946 | // Add time selection keywords |
| 925 | - hdu.card("DSTYP1", "TIME", "Data selection type"); | |
| 926 | - hdu.card("DSUNI1", "s", "Data selection unit"); | |
| 927 | - hdu.card("DSVAL1", "TABLE", "Data selection value"); | |
| 928 | - hdu.card("DSREF1", ":GTI", "Data selection reference"); | |
| 947 | + hdu.card("DSTYP1", "TIME", "Data sub-space type"); | |
| 948 | + hdu.card("DSUNI1", "s", "Data sub-space unit"); | |
| 949 | + hdu.card("DSVAL1", "TABLE", "Data sub-space value"); | |
| 950 | + hdu.card("DSREF1", dsref1, "Data sub-space reference"); | |
| 929 | 951 | |
| 930 | 952 | // Add energy range selection |
| 931 | - hdu.card("DSTYP2", "ENERGY", "Data selection type"); | |
| 932 | - hdu.card("DSUNI2", "TeV", "Data selection unit"); | |
| 933 | - hdu.card("DSVAL2", dsval2, "Data selection value"); | |
| 953 | + hdu.card("DSTYP2", "ENERGY", "Data sub-space type"); | |
| 954 | + hdu.card("DSUNI2", "TeV", "Data sub-space unit"); | |
| 955 | + hdu.card("DSVAL2", dsval2, "Data sub-space value"); | |
| 934 | 956 | |
| 935 | 957 | // Initialise number of NDSKEYS |
| 936 | 958 | int ndskeys = 2; |
| ... | ... | @@ -945,15 +967,15 @@ void GCTAEventList::write_ds_keys(GFitsHDU& hdu) const |
| 945 | 967 | gammalib::str(rad) + ")"; |
| 946 | 968 | |
| 947 | 969 | // Write DS keywords |
| 948 | - hdu.card("DSTYP3", "POS(RA,DEC)", "Data selection type"); | |
| 949 | - hdu.card("DSUNI3", "deg", "Data selection unit"); | |
| 950 | - hdu.card("DSVAL3", dsval3, "Data selection value"); | |
| 970 | + hdu.card("DSTYP3", "POS(RA,DEC)", "Data sub-space type"); | |
| 971 | + hdu.card("DSUNI3", "deg", "Data sub-space unit"); | |
| 972 | + hdu.card("DSVAL3", dsval3, "Data sub-space value"); | |
| 951 | 973 | ndskeys++; |
| 952 | 974 | |
| 953 | 975 | } // endif: RoI was valid |
| 954 | 976 | |
| 955 | 977 | // Set number of data selection keys |
| 956 | - hdu.card("NDSKEYS", ndskeys, "Number of data selections"); | |
| 978 | + hdu.card("NDSKEYS", ndskeys, "Number of data sub-space keys"); | |
| 957 | 979 | |
| 958 | 980 | // Return |
| 959 | 981 | return; | ... | ... |
inst/cta/src/GCTAObservation.cpp
| ... | ... | @@ -480,37 +480,9 @@ GGti GCTAObservation::gti(void) const |
| 480 | 480 | // ... otherwise try reading the GTIs from file |
| 481 | 481 | else { |
| 482 | 482 | |
| 483 | - // If we know in which file the GTIs reside then extract the GTIs | |
| 484 | - // from that file ... | |
| 485 | - /* | |
| 486 | - if (!m_gtifile.empty()) { | |
| 487 | - | |
| 488 | - // Initialise filename | |
| 489 | - GFilename fname(m_gtifile); | |
| 490 | - | |
| 491 | - // Open FITS file | |
| 492 | - GFits fits(fname.filename()); | |
| 493 | - | |
| 494 | - // Get extension name | |
| 495 | - std::string extname = fname.extname("GTI"); | |
| 496 | - | |
| 497 | - // If the FITS file contains the specified extension, then read | |
| 498 | - // Good Time Intervals from that extension | |
| 499 | - if (fits.contains(extname)) { | |
| 500 | - const GFitsTable& table = *fits.table(extname); | |
| 501 | - gti.read(table); | |
| 502 | - } | |
| 503 | - | |
| 504 | - // Close FITS file | |
| 505 | - fits.close(); | |
| 506 | - | |
| 507 | - } // endif: gti file name was not not empty | |
| 508 | - | |
| 509 | - // ... otherwise we extract the GTIs on basis on the DSS keywords, | |
| 510 | - // and if these keywords are not present, we build the GTIs from | |
| 511 | - // the start and stop time that is provided in the event header | |
| 512 | - else if (!m_eventfile.empty()) { | |
| 513 | - */ | |
| 483 | + // Extract the GTIs on basis on the DSS keywords, and if these | |
| 484 | + // keywords are not present, we build the GTIs from the start and | |
| 485 | + // stop time that is provided in the event header | |
| 514 | 486 | if (!m_eventfile.empty()) { |
| 515 | 487 | |
| 516 | 488 | // Initialise filename |
| ... | ... | @@ -596,13 +568,6 @@ GGti GCTAObservation::gti(void) const |
| 596 | 568 | |
| 597 | 569 | // Check for GTI validity |
| 598 | 570 | if (gti.size() == 0) { |
| 599 | - /* | |
| 600 | - std::string msg = "Could not find Good Time Interval information " | |
| 601 | - "in the event file \""+m_eventfile+"\" or in " | |
| 602 | - "the GTI file "+m_gtifile+"\". Please " | |
| 603 | - "check that Good Time Interval information is " | |
| 604 | - "properly set in the event file."; | |
| 605 | - */ | |
| 606 | 571 | std::string msg = "Could not find Good Time Interval information " |
| 607 | 572 | "in the event file \""+m_eventfile+"\". Please " |
| 608 | 573 | "check that Good Time Interval information is " |
| ... | ... | @@ -858,16 +823,6 @@ void GCTAObservation::read(const GXmlElement& xml) |
| 858 | 823 | |
| 859 | 824 | } |
| 860 | 825 | |
| 861 | - // Read optional Good Time Intervals file name | |
| 862 | - /* | |
| 863 | - else if (par->attribute("name") == "GoodTimeIntervals") { | |
| 864 | - | |
| 865 | - // Read GTI filename | |
| 866 | - m_gtifile = par->attribute("file"); | |
| 867 | - | |
| 868 | - } | |
| 869 | - */ | |
| 870 | - | |
| 871 | 826 | } // endfor: looped over observation parameters |
| 872 | 827 | |
| 873 | 828 | // Analyse parameters |
| ... | ... | @@ -1113,15 +1068,6 @@ void GCTAObservation::write(GXmlElement& xml) const |
| 1113 | 1068 | GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, m_eventtype); |
| 1114 | 1069 | par->attribute("file", m_eventfile); |
| 1115 | 1070 | |
| 1116 | - // If we had a GTI file name upon reading from a XML file then write | |
| 1117 | - // back the GTI file name information into the XML file | |
| 1118 | - /* | |
| 1119 | - if (!m_gtifile.empty()) { | |
| 1120 | - GXmlElement* par = gammalib::xml_need_par(G_WRITE, xml, "GoodTimeIntervals"); | |
| 1121 | - par->attribute("file", m_gtifile); | |
| 1122 | - } | |
| 1123 | - */ | |
| 1124 | - | |
| 1125 | 1071 | } |
| 1126 | 1072 | |
| 1127 | 1073 | // ... otherwise write the observation definition information |
| ... | ... | @@ -1155,9 +1101,9 @@ void GCTAObservation::write(GXmlElement& xml) const |
| 1155 | 1101 | |
| 1156 | 1102 | |
| 1157 | 1103 | /***********************************************************************//** |
| 1158 | - * @brief Read data from FITS object | |
| 1104 | + * @brief Read data from FITS file | |
| 1159 | 1105 | * |
| 1160 | - * @param[in] fits FITS object. | |
| 1106 | + * @param[in] fits FITS file. | |
| 1161 | 1107 | ***************************************************************************/ |
| 1162 | 1108 | void GCTAObservation::read(const GFits& fits) |
| 1163 | 1109 | { |
| ... | ... | @@ -1218,11 +1164,23 @@ void GCTAObservation::read(const GFits& fits) |
| 1218 | 1164 | |
| 1219 | 1165 | |
| 1220 | 1166 | /***********************************************************************//** |
| 1221 | - * @brief Write CTA observation into FITS object. | |
| 1167 | + * @brief Write observation into FITS file. | |
| 1222 | 1168 | * |
| 1223 | - * @param[in] fits FITS object. | |
| 1169 | + * @param[in] fits FITS file. | |
| 1170 | + * @param[in] extname FITS extension name for event list (default: "EVENTS"). | |
| 1224 | 1171 | * |
| 1225 | - * This method does nothing if no events are within the CTA observation. | |
| 1172 | + * Writes the observation into a FITS file. | |
| 1173 | + * | |
| 1174 | + * If the observation contains an event list, the event list and Good Time | |
| 1175 | + * Interval will be written to the FITS file. The FITS extension name for the | |
| 1176 | + * event list can be optionally specified by the @p extname argument. If the | |
| 1177 | + * extension name of the GTI should be changed to a non-default value, the | |
| 1178 | + * gti_extname() method should be called prior to calling the write() method. | |
| 1179 | + * | |
| 1180 | + * If the observation contains an event cube, the event cube will be written | |
| 1181 | + * into the primary extension of the FITS file. | |
| 1182 | + * | |
| 1183 | + * This method does nothing if no events are in the CTA observation. | |
| 1226 | 1184 | ***************************************************************************/ |
| 1227 | 1185 | void GCTAObservation::write(GFits& fits, const std::string& extname) const |
| 1228 | 1186 | { |
| ... | ... | @@ -1237,8 +1195,9 @@ void GCTAObservation::write(GFits& fits, const std::string& extname) const |
| 1237 | 1195 | // the GTI if provided on loading. |
| 1238 | 1196 | list->write(fits); |
| 1239 | 1197 | |
| 1240 | - // Get reference to EVENTS HDU | |
| 1241 | - GFitsHDU& hdu = *fits.at("EVENTS"); | |
| 1198 | + // Get reference to EVENTS HDU (see GCTAEventList::write() for | |
| 1199 | + // consistency) | |
| 1200 | + GFitsHDU& hdu = *fits.at(fits.filename().extname("EVENTS")); | |
| 1242 | 1201 | |
| 1243 | 1202 | // Change extension name |
| 1244 | 1203 | hdu.extname(extname); |
| ... | ... | @@ -1294,34 +1253,6 @@ void GCTAObservation::load(const std::string& filename) |
| 1294 | 1253 | |
| 1295 | 1254 | |
| 1296 | 1255 | /***********************************************************************//** |
| 1297 | - * @brief Load GTIs FITS file. | |
| 1298 | - * | |
| 1299 | - * @param[in] filename Name of FITS file from which GTIs are loaded. | |
| 1300 | - * | |
| 1301 | - * Loads CTA GTIs from a separate file. | |
| 1302 | - ***************************************************************************/ | |
| 1303 | -/* | |
| 1304 | -void GCTAObservation::load_gti(const std::string& filename) | |
| 1305 | -{ | |
| 1306 | - | |
| 1307 | - // Check if we have an event list | |
| 1308 | - GCTAEventList* list = dynamic_cast<GCTAEventList*>(m_events); | |
| 1309 | - | |
| 1310 | - // Load GTI | |
| 1311 | - if (list != NULL) { | |
| 1312 | - list->load_gti(filename); | |
| 1313 | - } | |
| 1314 | - | |
| 1315 | - // Store GTI file name | |
| 1316 | - m_gtifile = filename; | |
| 1317 | - | |
| 1318 | - // Return | |
| 1319 | - return; | |
| 1320 | -} | |
| 1321 | -*/ | |
| 1322 | - | |
| 1323 | - | |
| 1324 | -/***********************************************************************//** | |
| 1325 | 1256 | * @brief Load stacked cube from FITS files |
| 1326 | 1257 | * |
| 1327 | 1258 | * @param[in] cntcube Counts cube file name. |
| ... | ... | @@ -1368,7 +1299,7 @@ void GCTAObservation::load(const std::string& cntcube, |
| 1368 | 1299 | * @brief Save CTA observation into FITS file. |
| 1369 | 1300 | * |
| 1370 | 1301 | * @param[in] filename FITS filename. |
| 1371 | - * @param[in] clobber Overwrite existing FITS file (default=false). | |
| 1302 | + * @param[in] clobber Overwrite existing FITS file? (default: false) | |
| 1372 | 1303 | ***************************************************************************/ |
| 1373 | 1304 | void GCTAObservation::save(const std::string& filename, const bool& clobber) const |
| 1374 | 1305 | { |
| ... | ... | @@ -1393,35 +1324,6 @@ void GCTAObservation::save(const std::string& filename, const bool& clobber) con |
| 1393 | 1324 | |
| 1394 | 1325 | |
| 1395 | 1326 | /***********************************************************************//** |
| 1396 | - * @brief Save CTA GTIs into FITS file. | |
| 1397 | - * | |
| 1398 | - * @param[in] filename FITS filename. | |
| 1399 | - * @param[in] clobber Overwrite existing FITS file (default=false). | |
| 1400 | - ***************************************************************************/ | |
| 1401 | -/* | |
| 1402 | -void GCTAObservation::save_gti(const std::string& filename, const bool& clobber) const | |
| 1403 | -{ | |
| 1404 | - // Initialise filename | |
| 1405 | - GFilename fname(filename); | |
| 1406 | - | |
| 1407 | - // Initialise extension name | |
| 1408 | - std::string extname = fname.extname("GTI"); | |
| 1409 | - | |
| 1410 | - // Initialise FITS file | |
| 1411 | - GFits fits(fname.filename(), true); | |
| 1412 | - | |
| 1413 | - // Write GTIs to fits files | |
| 1414 | - gti().write(fits, extname); | |
| 1415 | - | |
| 1416 | - // Save FITS file | |
| 1417 | - fits.save(clobber); | |
| 1418 | - | |
| 1419 | - // Return | |
| 1420 | - return; | |
| 1421 | -} | |
| 1422 | -*/ | |
| 1423 | - | |
| 1424 | -/***********************************************************************//** | |
| 1425 | 1327 | * @brief Set event container |
| 1426 | 1328 | * |
| 1427 | 1329 | * @param[in] events Event container. |
| ... | ... | @@ -1468,11 +1370,6 @@ const GEvents* GCTAObservation::events(void) const |
| 1468 | 1370 | { |
| 1469 | 1371 | try { |
| 1470 | 1372 | const_cast<GCTAObservation*>(this)->load(m_eventfile); |
| 1471 | - /* | |
| 1472 | - if (!m_gtifile.empty()) { | |
| 1473 | - const_cast<GCTAObservation*>(this)->load_gti(m_gtifile); | |
| 1474 | - } | |
| 1475 | - */ | |
| 1476 | 1373 | } |
| 1477 | 1374 | catch (...) { |
| 1478 | 1375 | ; |
| ... | ... | @@ -1503,6 +1400,31 @@ const GEvents* GCTAObservation::events(void) const |
| 1503 | 1400 | |
| 1504 | 1401 | |
| 1505 | 1402 | /***********************************************************************//** |
| 1403 | + * @brief Set Good Time Intervals extension name | |
| 1404 | + * | |
| 1405 | + * @param[in] extname Good Time Intervals extension name. | |
| 1406 | + * | |
| 1407 | + * Sets the FITS extension name of the Good Time Intervals. This method | |
| 1408 | + * should be used prior to saving or writing of the FITS file if the Good | |
| 1409 | + * Time Intervals should be used in an extension that differs from the | |
| 1410 | + * default extension ("GTI") | |
| 1411 | + ***************************************************************************/ | |
| 1412 | +void GCTAObservation::gti_extname(const std::string& extname) | |
| 1413 | +{ | |
| 1414 | + // Get non-const pointer to event list | |
| 1415 | + GCTAEventList* list = dynamic_cast<GCTAEventList*>(const_cast<GEvents*>(events())); | |
| 1416 | + | |
| 1417 | + // If we have a CTA event list then set the extension name | |
| 1418 | + if (list != NULL) { | |
| 1419 | + list->gti_extname(extname); | |
| 1420 | + } | |
| 1421 | + | |
| 1422 | + // Return | |
| 1423 | + return; | |
| 1424 | +} | |
| 1425 | + | |
| 1426 | + | |
| 1427 | +/***********************************************************************//** | |
| 1506 | 1428 | * @brief Dispose events |
| 1507 | 1429 | * |
| 1508 | 1430 | * Drops the events from the observation. Be careful with using this method |
| ... | ... | @@ -1619,7 +1541,6 @@ void GCTAObservation::init_members(void) |
| 1619 | 1541 | m_instrument = "CTA"; |
| 1620 | 1542 | m_object.clear(); |
| 1621 | 1543 | m_eventfile.clear(); |
| 1622 | - //m_gtifile.clear(); | |
| 1623 | 1544 | m_eventtype.clear(); |
| 1624 | 1545 | m_bgdfile.clear(); |
| 1625 | 1546 | m_response = NULL; |
| ... | ... | @@ -1650,7 +1571,6 @@ void GCTAObservation::copy_members(const GCTAObservation& obs) |
| 1650 | 1571 | m_instrument = obs.m_instrument; |
| 1651 | 1572 | m_object = obs.m_object; |
| 1652 | 1573 | m_eventfile = obs.m_eventfile; |
| 1653 | - //m_gtifile = obs.m_gtifile; | |
| 1654 | 1574 | m_eventtype = obs.m_eventtype; |
| 1655 | 1575 | m_bgdfile = obs.m_bgdfile; |
| 1656 | 1576 | m_pointing = obs.m_pointing; | ... | ... |
inst/cta/test/test_CTA.cpp
| ... | ... | @@ -1297,10 +1297,6 @@ void TestGCTAModel::test_model_aeff_bgd(void) |
| 1297 | 1297 | ***************************************************************************/ |
| 1298 | 1298 | void TestGCTAObservation::test_unbinned_obs(void) |
| 1299 | 1299 | { |
| 1300 | - // Set filenames | |
| 1301 | - const std::string file1 = "test_cta_obs_unbinned.xml"; | |
| 1302 | - const std::string file2 = "test_cta_obs_unbinned_gti.xml"; | |
| 1303 | - | |
| 1304 | 1300 | // Declare observations |
| 1305 | 1301 | GObservations obs; |
| 1306 | 1302 | GCTAObservation run; |
| ... | ... | @@ -1382,7 +1378,7 @@ void TestGCTAObservation::test_unbinned_obs(void) |
| 1382 | 1378 | test_try("Test XML loading and saving"); |
| 1383 | 1379 | try { |
| 1384 | 1380 | obs = GObservations(cta_unbin_xml); |
| 1385 | - obs.save(file1); | |
| 1381 | + obs.save("test_cta_obs_unbinned.xml"); | |
| 1386 | 1382 | GCTAObservation* run = dynamic_cast<GCTAObservation*>(obs[0]); |
| 1387 | 1383 | test_value(run->roi().centre().dir().ra_deg(), 83.63); |
| 1388 | 1384 | test_value(run->roi().centre().dir().dec_deg(), 22.01); |
| ... | ... | @@ -1405,6 +1401,44 @@ void TestGCTAObservation::test_unbinned_obs(void) |
| 1405 | 1401 | test_try_failure(e); |
| 1406 | 1402 | } |
| 1407 | 1403 | |
| 1404 | + // Test loading of the event file and saving into a different extension | |
| 1405 | + run.load(cta_events); | |
| 1406 | + run.gti_extname("GTI2"); | |
| 1407 | + run.save("test_cta_events1.fits[EVENTS2]", true); | |
| 1408 | + GFits fits("test_cta_events1.fits"); | |
| 1409 | + test_value(fits.size(), 3, "FITS file should contain 3 HDUs"); | |
| 1410 | + test_assert(fits.contains("EVENTS2"), "FITS should contain \"EVENTS2\" HDU"); | |
| 1411 | + test_assert(fits.contains("GTI2"), "FITS should contain \"GTI2\" HDU"); | |
| 1412 | + fits.close(); | |
| 1413 | + run.gti_extname("GTI3"); | |
| 1414 | + run.save("test_cta_events1.fits[EVENTS3]", true); | |
| 1415 | + fits.open("test_cta_events1.fits"); | |
| 1416 | + test_value(fits.size(), 3, "FITS file should contain 3 HDUs"); | |
| 1417 | + test_assert(fits.contains("EVENTS3"), "FITS should contain \"EVENTS3\" HDU"); | |
| 1418 | + test_assert(fits.contains("GTI3"), "FITS should contain \"GTI3\" HDU"); | |
| 1419 | + fits.close(); | |
| 1420 | + | |
| 1421 | + // Test writing of multiple event files into FITS file | |
| 1422 | + run.load(cta_events); | |
| 1423 | + GFits fits2; | |
| 1424 | + run.gti_extname("GTI1"); | |
| 1425 | + run.write(fits2, "EVENTS1"); | |
| 1426 | + run.gti_extname("GTI2"); | |
| 1427 | + run.write(fits2, "EVENTS2"); | |
| 1428 | + run.gti_extname("GTI3"); | |
| 1429 | + run.write(fits2, "EVENTS3"); | |
| 1430 | + fits2.saveto("test_cta_events2.fits", true); | |
| 1431 | + fits2.close(); | |
| 1432 | + fits.open("test_cta_events2.fits"); | |
| 1433 | + test_value(fits.size(), 7, "FITS file should contain 7 HDUs"); | |
| 1434 | + test_assert(fits.contains("EVENTS1"), "FITS should contain \"EVENTS1\" HDU"); | |
| 1435 | + test_assert(fits.contains("GTI1"), "FITS should contain \"GTI1\" HDU"); | |
| 1436 | + test_assert(fits.contains("EVENTS2"), "FITS should contain \"EVENTS2\" HDU"); | |
| 1437 | + test_assert(fits.contains("GTI2"), "FITS should contain \"GTI2\" HDU"); | |
| 1438 | + test_assert(fits.contains("EVENTS3"), "FITS should contain \"EVENTS3\" HDU"); | |
| 1439 | + test_assert(fits.contains("GTI3"), "FITS should contain \"GTI3\" HDU"); | |
| 1440 | + fits.close(); | |
| 1441 | + | |
| 1408 | 1442 | // Exit test |
| 1409 | 1443 | return; |
| 1410 | 1444 | ... | ... |