Commit 51c989497196f4f357e23ed1b8c2b16ce886ec77
1 parent
23dd86c9
Adapted ctools to handle observation type consistently
Showing
10 changed files
with
91 additions
and
149 deletions
scripts/cslightcrv.py
| @@ -107,7 +107,7 @@ class cslightcrv(ctools.cscript): | @@ -107,7 +107,7 @@ class cslightcrv(ctools.cscript): | ||
| 107 | pars.append(gammalib.GApplicationPar("bkgcube","s","a","NONE","","","Background cube file (only needed for stacked analysis)")) | 107 | pars.append(gammalib.GApplicationPar("bkgcube","s","a","NONE","","","Background cube file (only needed for stacked analysis)")) |
| 108 | pars.append(gammalib.GApplicationPar("caldb","s","a","prod2","","","Calibration database")) | 108 | pars.append(gammalib.GApplicationPar("caldb","s","a","prod2","","","Calibration database")) |
| 109 | pars.append(gammalib.GApplicationPar("irf","s","a","South_50h","","","Instrument response function")) | 109 | pars.append(gammalib.GApplicationPar("irf","s","a","South_50h","","","Instrument response function")) |
| 110 | - pars.append(gammalib.GApplicationPar("tbinalg","s","h","GTI","FILE|LIN|GTI","", "Algorithm for defining time bins")) | 110 | + pars.append(gammalib.GApplicationPar("tbinalg","s","a","GTI","FILE|LIN|GTI","", "Algorithm for defining time bins")) |
| 111 | pars.append(gammalib.GApplicationPar("tmin","r","a","51544.5","","days","Lightcurve start time [MJD]")) | 111 | pars.append(gammalib.GApplicationPar("tmin","r","a","51544.5","","days","Lightcurve start time [MJD]")) |
| 112 | pars.append(gammalib.GApplicationPar("tmax","r","a","51544.6","","days","Lightcurve stop time [MJD]")) | 112 | pars.append(gammalib.GApplicationPar("tmax","r","a","51544.6","","days","Lightcurve stop time [MJD]")) |
| 113 | pars.append(gammalib.GApplicationPar("tbins","i","a","5","","","Number of time bins")) | 113 | pars.append(gammalib.GApplicationPar("tbins","i","a","5","","","Number of time bins")) |
src/ctbin/ctbin.cpp
| @@ -257,6 +257,17 @@ void ctbin::run(void) | @@ -257,6 +257,17 @@ void ctbin::run(void) | ||
| 257 | } | 257 | } |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | + // Skip observation if we don't have an unbinned observation | ||
| 261 | + if (obs->eventtype() != "EventList") { | ||
| 262 | + | ||
| 263 | + // Log that we skip the this observation | ||
| 264 | + if (logTerse()) { | ||
| 265 | + log << "Warning: Skipping binned observation \""+obs->name()+"\""; | ||
| 266 | + log << std::endl; | ||
| 267 | + } | ||
| 268 | + continue; | ||
| 269 | + } | ||
| 270 | + | ||
| 260 | // Fill the cube | 271 | // Fill the cube |
| 261 | fill_cube(obs); | 272 | fill_cube(obs); |
| 262 | 273 | ||
| @@ -561,11 +572,25 @@ void ctbin::obs_cube(void) | @@ -561,11 +572,25 @@ void ctbin::obs_cube(void) | ||
| 561 | // Attach event cube to CTA observation | 572 | // Attach event cube to CTA observation |
| 562 | GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]); | 573 | GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]); |
| 563 | if (obs != NULL) { | 574 | if (obs != NULL) { |
| 564 | - obs->events(this->cube()); | ||
| 565 | - obs->eventfile(""); | ||
| 566 | - } | ||
| 567 | 575 | ||
| 568 | - } | 576 | + // Only change the event type if we had an unbinned observation |
| 577 | + if (obs->eventtype() == "EventList") { | ||
| 578 | + | ||
| 579 | + obs->events(this->cube()); | ||
| 580 | + obs->eventfile(""); | ||
| 581 | + } // endif: observation was unbinned | ||
| 582 | + else { // input observation was binned and skipped | ||
| 583 | + | ||
| 584 | + // Create new and empty cube | ||
| 585 | + GCTAEventCube cube = GCTAEventCube(m_cube, m_ebounds, obs->gti()); | ||
| 586 | + | ||
| 587 | + // Assign empty cube to have a new binned observation | ||
| 588 | + obs->events(cube); | ||
| 589 | + } | ||
| 590 | + | ||
| 591 | + } // endif: obervation was valid | ||
| 592 | + | ||
| 593 | + } // endif: we only had one observation in the container | ||
| 569 | 594 | ||
| 570 | // ... otherwise put a single CTA observation in container | 595 | // ... otherwise put a single CTA observation in container |
| 571 | else { | 596 | else { |
src/ctbkgcube/ctbkgcube.cpp
| @@ -308,7 +308,7 @@ void ctbkgcube::run(void) | @@ -308,7 +308,7 @@ void ctbkgcube::run(void) | ||
| 308 | m_obs.models(m_bkgmdl); | 308 | m_obs.models(m_bkgmdl); |
| 309 | 309 | ||
| 310 | // Fill background cube from observations | 310 | // Fill background cube from observations |
| 311 | - m_background.fill(m_obs); | 311 | + m_background.fill(m_obs, &log); |
| 312 | 312 | ||
| 313 | // Create a background model for the output background cube and append | 313 | // Create a background model for the output background cube and append |
| 314 | // that model to the input model in place of the original | 314 | // that model to the input model in place of the original |
src/ctexpcube/ctexpcube.cpp
| @@ -248,7 +248,7 @@ void ctexpcube::run(void) | @@ -248,7 +248,7 @@ void ctexpcube::run(void) | ||
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | // Fill exposure | 250 | // Fill exposure |
| 251 | - m_expcube.fill(m_obs); | 251 | + m_expcube.fill(m_obs, &log); |
| 252 | 252 | ||
| 253 | // Restore energy dispersion flag for all CTA observations | 253 | // Restore energy dispersion flag for all CTA observations |
| 254 | for (int i = 0; i < m_obs.size(); ++i) { | 254 | for (int i = 0; i < m_obs.size(); ++i) { |
src/ctmodel/ctmodel.cpp
| @@ -427,7 +427,7 @@ void ctmodel::get_parameters(void) | @@ -427,7 +427,7 @@ void ctmodel::get_parameters(void) | ||
| 427 | // If there are no observations in container then load them via user | 427 | // If there are no observations in container then load them via user |
| 428 | // parameters | 428 | // parameters |
| 429 | if (m_obs.size() == 0) { | 429 | if (m_obs.size() == 0) { |
| 430 | - get_obs(); | 430 | + m_obs = get_observations(); |
| 431 | } | 431 | } |
| 432 | 432 | ||
| 433 | // Read model definition file if required | 433 | // Read model definition file if required |
| @@ -505,126 +505,6 @@ void ctmodel::get_parameters(void) | @@ -505,126 +505,6 @@ void ctmodel::get_parameters(void) | ||
| 505 | 505 | ||
| 506 | 506 | ||
| 507 | /***********************************************************************//** | 507 | /***********************************************************************//** |
| 508 | - * @brief Get observation container | ||
| 509 | - * | ||
| 510 | - * Get an observation container according to the user parameters. The method | ||
| 511 | - * supports loading of a individual FITS file or an observation definition | ||
| 512 | - * file in XML format. If the input filename is empty, parameters are read | ||
| 513 | - * to build a CTA observation from scratch. | ||
| 514 | - ***************************************************************************/ | ||
| 515 | -void ctmodel::get_obs(void) | ||
| 516 | -{ | ||
| 517 | - // Get the filename from the input parameters | ||
| 518 | - std::string filename = (*this)["inobs"].filename(); | ||
| 519 | - | ||
| 520 | - // If no observation definition file has been specified then read all | ||
| 521 | - // parameters that are necessary to create an observation from scratch | ||
| 522 | - if ((filename == "NONE") || (gammalib::strip_whitespace(filename) == "")) { | ||
| 523 | - | ||
| 524 | - // Get response cube filenames | ||
| 525 | - std::string expcube = (*this)["expcube"].filename(); | ||
| 526 | - std::string psfcube = (*this)["psfcube"].filename(); | ||
| 527 | - std::string bkgcube = (*this)["bkgcube"].filename(); | ||
| 528 | - | ||
| 529 | - // If the filenames are valid then build an observation from cube | ||
| 530 | - // response information | ||
| 531 | - if ((expcube != "NONE") && (psfcube != "NONE") && (bkgcube != "NONE") && | ||
| 532 | - (gammalib::strip_whitespace(expcube) != "") && | ||
| 533 | - (gammalib::strip_whitespace(psfcube) != "") && | ||
| 534 | - (gammalib::strip_whitespace(bkgcube) != "")) { | ||
| 535 | - | ||
| 536 | - // Get exposure, PSF and background cubes | ||
| 537 | - GCTACubeExposure exposure(expcube); | ||
| 538 | - GCTACubePsf psf(psfcube); | ||
| 539 | - GCTACubeBackground background(bkgcube); | ||
| 540 | - | ||
| 541 | - // Create energy boundaries | ||
| 542 | - GEbounds ebounds = create_ebounds(); | ||
| 543 | - | ||
| 544 | - // Create dummy sky map cube | ||
| 545 | - GSkymap map("CAR","GAL",0.0,0.0,1.0,1.0,1,1,ebounds.size()); | ||
| 546 | - m_append_cube = true; | ||
| 547 | - | ||
| 548 | - // Create event cube | ||
| 549 | - GCTAEventCube cube(map, ebounds, exposure.gti()); | ||
| 550 | - | ||
| 551 | - // Create CTA observation | ||
| 552 | - GCTAObservation cta; | ||
| 553 | - cta.events(cube); | ||
| 554 | - cta.response(exposure, psf, background); | ||
| 555 | - | ||
| 556 | - // Append observation to container | ||
| 557 | - m_obs.append(cta); | ||
| 558 | - | ||
| 559 | - } // endif: cube response information was available | ||
| 560 | - | ||
| 561 | - // ... otherwise build an observation from IRF response information | ||
| 562 | - else { | ||
| 563 | - | ||
| 564 | - // Create CTA observation | ||
| 565 | - GCTAObservation cta = create_cta_obs(); | ||
| 566 | - | ||
| 567 | - // Set response | ||
| 568 | - set_obs_response(&cta); | ||
| 569 | - | ||
| 570 | - // Append observation to container | ||
| 571 | - m_obs.append(cta); | ||
| 572 | - | ||
| 573 | - } | ||
| 574 | - | ||
| 575 | - } // endif: filename was "NONE" or "" | ||
| 576 | - | ||
| 577 | - // ... otherwise we have a file name | ||
| 578 | - else { | ||
| 579 | - | ||
| 580 | - // If file is a FITS file then create an empty CTA observation | ||
| 581 | - // and load file into observation | ||
| 582 | - if (gammalib::is_fits(filename)) { | ||
| 583 | - | ||
| 584 | - // Allocate empty CTA observation | ||
| 585 | - GCTAObservation cta; | ||
| 586 | - | ||
| 587 | - // Load data | ||
| 588 | - cta.load(filename); | ||
| 589 | - | ||
| 590 | - // Set response | ||
| 591 | - set_obs_response(&cta); | ||
| 592 | - | ||
| 593 | - // Append observation to container | ||
| 594 | - m_obs.append(cta); | ||
| 595 | - | ||
| 596 | - // Signal that no XML file should be used for storage | ||
| 597 | - m_use_xml = false; | ||
| 598 | - | ||
| 599 | - } | ||
| 600 | - | ||
| 601 | - // ... otherwise load file into observation container | ||
| 602 | - else { | ||
| 603 | - | ||
| 604 | - // Load observations from XML file | ||
| 605 | - m_obs.load(filename); | ||
| 606 | - | ||
| 607 | - // For all observations that have no response, set the response | ||
| 608 | - // from the task parameters | ||
| 609 | - set_response(m_obs); | ||
| 610 | - | ||
| 611 | - // Set observation boundary parameters (emin, emax, rad) | ||
| 612 | - set_obs_bounds(m_obs); | ||
| 613 | - | ||
| 614 | - // Signal that XML file should be used for storage | ||
| 615 | - m_use_xml = true; | ||
| 616 | - | ||
| 617 | - } // endelse: file was an XML file | ||
| 618 | - | ||
| 619 | - } | ||
| 620 | - | ||
| 621 | - // Return | ||
| 622 | - return; | ||
| 623 | - | ||
| 624 | -} | ||
| 625 | - | ||
| 626 | - | ||
| 627 | -/***********************************************************************//** | ||
| 628 | * @brief Fill model into model cube | 508 | * @brief Fill model into model cube |
| 629 | * | 509 | * |
| 630 | * @param[in] obs CTA observation. | 510 | * @param[in] obs CTA observation. |
src/ctmodel/ctmodel.hpp
| @@ -79,7 +79,6 @@ protected: | @@ -79,7 +79,6 @@ protected: | ||
| 79 | void copy_members(const ctmodel& app); | 79 | void copy_members(const ctmodel& app); |
| 80 | void free_members(void); | 80 | void free_members(void); |
| 81 | void get_parameters(void); | 81 | void get_parameters(void); |
| 82 | - void get_obs(void); | ||
| 83 | void fill_cube(const GCTAObservation* obs); | 82 | void fill_cube(const GCTAObservation* obs); |
| 84 | bool has_cube(void) const; | 83 | bool has_cube(void) const; |
| 85 | 84 |
src/ctobssim/ctobssim.cpp
| @@ -340,6 +340,17 @@ void ctobssim::run(void) | @@ -340,6 +340,17 @@ void ctobssim::run(void) | ||
| 340 | } | 340 | } |
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | + // Skip observation if we don't have an unbinned observation | ||
| 344 | + if (obs->eventtype() != "EventList") { | ||
| 345 | + | ||
| 346 | + // Log that we skip the this observation | ||
| 347 | + if (logTerse()) { | ||
| 348 | + log << "Warning: Skipping binned observation \""+obs->name()+"\""; | ||
| 349 | + log << std::endl; | ||
| 350 | + } | ||
| 351 | + continue; | ||
| 352 | + } | ||
| 353 | + | ||
| 343 | // Work on a clone of the CTA observation. This makes sure that | 354 | // Work on a clone of the CTA observation. This makes sure that |
| 344 | // any memory allocated for computing (for example a response | 355 | // any memory allocated for computing (for example a response |
| 345 | // cache) is properly de-allocated on exit of this run | 356 | // cache) is properly de-allocated on exit of this run |
src/ctpsfcube/ctpsfcube.cpp
| @@ -247,7 +247,7 @@ void ctpsfcube::run(void) | @@ -247,7 +247,7 @@ void ctpsfcube::run(void) | ||
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | // Fill PSF | 249 | // Fill PSF |
| 250 | - m_psfcube.fill(m_obs); | 250 | + m_psfcube.fill(m_obs, &log); |
| 251 | 251 | ||
| 252 | // Restore energy dispersion flag for all CTA observations | 252 | // Restore energy dispersion flag for all CTA observations |
| 253 | for (int i = 0; i < m_obs.size(); ++i) { | 253 | for (int i = 0; i < m_obs.size(); ++i) { |
src/ctselect/ctselect.cpp
| @@ -268,6 +268,17 @@ void ctselect::run(void) | @@ -268,6 +268,17 @@ void ctselect::run(void) | ||
| 268 | // Save event file name (for possible saving) | 268 | // Save event file name (for possible saving) |
| 269 | m_infiles[i] = obs->eventfile(); | 269 | m_infiles[i] = obs->eventfile(); |
| 270 | 270 | ||
| 271 | + // Skip observation if we don't have an unbinned observation | ||
| 272 | + if (obs->eventtype() != "EventList") { | ||
| 273 | + | ||
| 274 | + // Log that we skip the this observation | ||
| 275 | + if (logTerse()) { | ||
| 276 | + log << "Warning: Skipping binned observation \""+obs->name()+"\""; | ||
| 277 | + log << std::endl; | ||
| 278 | + } | ||
| 279 | + continue; | ||
| 280 | + } | ||
| 281 | + | ||
| 271 | // Fall through in case that the event file is empty | 282 | // Fall through in case that the event file is empty |
| 272 | if (obs->events()->size() == 0) { | 283 | if (obs->events()->size() == 0) { |
| 273 | if (logTerse()) { | 284 | if (logTerse()) { |
| @@ -1218,28 +1229,33 @@ void ctselect::save_event_list(const GCTAObservation* obs, | @@ -1218,28 +1229,33 @@ void ctselect::save_event_list(const GCTAObservation* obs, | ||
| 1218 | // Save only if observation is valid | 1229 | // Save only if observation is valid |
| 1219 | if (obs != NULL) { | 1230 | if (obs != NULL) { |
| 1220 | 1231 | ||
| 1221 | - // Save observation into FITS file | ||
| 1222 | - obs->save(outfile, clobber()); | ||
| 1223 | - | ||
| 1224 | - // Copy all extensions other than EVENTS and GTI from the input to | ||
| 1225 | - // the output event list. The EVENTS and GTI extensions are written | ||
| 1226 | - // by the save method, all others that may eventually be present | ||
| 1227 | - // have to be copied by hand. | ||
| 1228 | - GFits infits(infile); | ||
| 1229 | - GFits outfits(outfile); | ||
| 1230 | - for (int extno = 1; extno < infits.size(); ++extno) { | ||
| 1231 | - GFitsHDU* hdu = infits.at(extno); | ||
| 1232 | - if (hdu->extname() != "EVENTS" && hdu->extname() != "GTI") { | ||
| 1233 | - outfits.append(*hdu); | 1232 | + // Save only if we have an event list |
| 1233 | + if (obs->eventtype() == "EventList") { | ||
| 1234 | + | ||
| 1235 | + // Save observation into FITS file | ||
| 1236 | + obs->save(outfile, clobber()); | ||
| 1237 | + | ||
| 1238 | + // Copy all extensions other than EVENTS and GTI from the input to | ||
| 1239 | + // the output event list. The EVENTS and GTI extensions are written | ||
| 1240 | + // by the save method, all others that may eventually be present | ||
| 1241 | + // have to be copied by hand. | ||
| 1242 | + GFits infits(infile); | ||
| 1243 | + GFits outfits(outfile); | ||
| 1244 | + for (int extno = 1; extno < infits.size(); ++extno) { | ||
| 1245 | + GFitsHDU* hdu = infits.at(extno); | ||
| 1246 | + if (hdu->extname() != "EVENTS" && hdu->extname() != "GTI") { | ||
| 1247 | + outfits.append(*hdu); | ||
| 1248 | + } | ||
| 1234 | } | 1249 | } |
| 1235 | - } | ||
| 1236 | 1250 | ||
| 1237 | - // Close input file | ||
| 1238 | - infits.close(); | 1251 | + // Close input file |
| 1252 | + infits.close(); | ||
| 1253 | + | ||
| 1254 | + // Save file to disk and close it (we need both operations) | ||
| 1255 | + outfits.save(true); | ||
| 1256 | + outfits.close(); | ||
| 1239 | 1257 | ||
| 1240 | - // Save file to disk and close it (we need both operations) | ||
| 1241 | - outfits.save(true); | ||
| 1242 | - outfits.close(); | 1258 | + } // endif: observation was unbinned |
| 1243 | 1259 | ||
| 1244 | } // endif: observation was valid | 1260 | } // endif: observation was valid |
| 1245 | 1261 |
src/ctskymap/ctskymap.cpp
| @@ -263,6 +263,17 @@ void ctskymap::run(void) | @@ -263,6 +263,17 @@ void ctskymap::run(void) | ||
| 263 | } | 263 | } |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | + // Skip observation if we don't have an unbinned observation | ||
| 267 | + if (obs->eventtype() != "EventList") { | ||
| 268 | + | ||
| 269 | + // Log that we skip the this observation | ||
| 270 | + if (logTerse()) { | ||
| 271 | + log << "Warning: Skipping binned observation \""+obs->name()+"\""; | ||
| 272 | + log << std::endl; | ||
| 273 | + } | ||
| 274 | + continue; | ||
| 275 | + } | ||
| 276 | + | ||
| 266 | // Map events into sky map | 277 | // Map events into sky map |
| 267 | map_events(obs); | 278 | map_events(obs); |
| 268 | 279 |