Commit 9e70368c21c40e581a77f1247852fb52ecfbbfdd
1 parent
a1e90215
Enable usage of ctmodel on stacked cubes.
Showing
5 changed files
with
160 additions
and
13 deletions
src/ctmodel/ctmodel.cpp
| ... | ... | @@ -365,7 +365,8 @@ void ctmodel::init_members(void) |
| 365 | 365 | m_obs.clear(); |
| 366 | 366 | m_cube.clear(); |
| 367 | 367 | m_gti.clear(); |
| 368 | - m_has_cube = false; | |
| 368 | + m_has_cube = false; | |
| 369 | + m_append_cube = false; | |
| 369 | 370 | |
| 370 | 371 | // Return |
| 371 | 372 | return; |
| ... | ... | @@ -384,10 +385,11 @@ void ctmodel::copy_members(const ctmodel& app) |
| 384 | 385 | m_apply_edisp = app.m_apply_edisp; |
| 385 | 386 | |
| 386 | 387 | // Copy protected members |
| 387 | - m_obs = app.m_obs; | |
| 388 | - m_cube = app.m_cube; | |
| 389 | - m_gti = app.m_gti; | |
| 390 | - m_has_cube = app.m_has_cube; | |
| 388 | + m_obs = app.m_obs; | |
| 389 | + m_cube = app.m_cube; | |
| 390 | + m_gti = app.m_gti; | |
| 391 | + m_has_cube = app.m_has_cube; | |
| 392 | + m_append_cube = app.m_append_cube; | |
| 391 | 393 | |
| 392 | 394 | // Return |
| 393 | 395 | return; |
| ... | ... | @@ -412,10 +414,13 @@ void ctmodel::free_members(void) |
| 412 | 414 | ***************************************************************************/ |
| 413 | 415 | void ctmodel::get_parameters(void) |
| 414 | 416 | { |
| 417 | + // Reset cube append flag | |
| 418 | + m_append_cube = false; | |
| 419 | + | |
| 415 | 420 | // If there are no observations in container then load them via user |
| 416 | 421 | // parameters |
| 417 | 422 | if (m_obs.size() == 0) { |
| 418 | - m_obs = get_observations(); | |
| 423 | + get_obs(); | |
| 419 | 424 | } |
| 420 | 425 | |
| 421 | 426 | // Read model definition file if required |
| ... | ... | @@ -468,10 +473,145 @@ void ctmodel::get_parameters(void) |
| 468 | 473 | m_outcube = (*this)["outcube"].filename(); |
| 469 | 474 | } |
| 470 | 475 | |
| 476 | + // If cube should be appended to first observation then do that now. | |
| 477 | + // This is a kluge that makes sure that the cube is passed as part | |
| 478 | + // of the observation in case that a cube response is used. The kluge | |
| 479 | + // is needed because the GCTACubeSourceDiffuse::set method needs to | |
| 480 | + // get the full event cube from the observation. | |
| 481 | + if (m_append_cube) { | |
| 482 | + | |
| 483 | + //TODO: Check that energy boundaries are compatible | |
| 484 | + | |
| 485 | + // Attach GTI of observations to model cube | |
| 486 | + m_cube.gti(m_obs[0]->events()->gti()); | |
| 487 | + | |
| 488 | + // Attach model cube to observations | |
| 489 | + m_obs[0]->events(m_cube); | |
| 490 | + | |
| 491 | + } // endif: cube was scheduled for appending | |
| 492 | + | |
| 471 | 493 | // Return |
| 472 | 494 | return; |
| 473 | 495 | } |
| 474 | 496 | |
| 497 | + | |
| 498 | +/***********************************************************************//** | |
| 499 | + * @brief Get observation container | |
| 500 | + * | |
| 501 | + * Get an observation container according to the user parameters. The method | |
| 502 | + * supports loading of a individual FITS file or an observation definition | |
| 503 | + * file in XML format. If the input filename is empty, parameters are read | |
| 504 | + * to build a CTA observation from scratch. | |
| 505 | + ***************************************************************************/ | |
| 506 | +void ctmodel::get_obs(void) | |
| 507 | +{ | |
| 508 | + // Get the filename from the input parameters | |
| 509 | + std::string filename = (*this)["inobs"].filename(); | |
| 510 | + | |
| 511 | + // If no observation definition file has been specified then read all | |
| 512 | + // parameters that are necessary to create an observation from scratch | |
| 513 | + if ((filename == "NONE") || (gammalib::strip_whitespace(filename) == "")) { | |
| 514 | + | |
| 515 | + // Get response cube filenames | |
| 516 | + std::string expcube = (*this)["expcube"].filename(); | |
| 517 | + std::string psfcube = (*this)["psfcube"].filename(); | |
| 518 | + | |
| 519 | + // If the filenames are valid then build an observation from cube | |
| 520 | + // response information | |
| 521 | + if ((expcube != "NONE") && (psfcube != "NONE") && | |
| 522 | + (gammalib::strip_whitespace(expcube) != "") && | |
| 523 | + (gammalib::strip_whitespace(psfcube) != "")) { | |
| 524 | + | |
| 525 | + // Get exposure and PSF cubes | |
| 526 | + GCTACubeExposure exposure(expcube); | |
| 527 | + GCTACubePsf psf(psfcube); | |
| 528 | + | |
| 529 | + // Create energy boundaries | |
| 530 | + GEbounds ebounds = create_ebounds(); | |
| 531 | + | |
| 532 | + // Create dummy sky map cube | |
| 533 | + GSkymap map("CAR","GAL",0.0,0.0,1.0,1.0,1,1,ebounds.size()); | |
| 534 | + m_append_cube = true; | |
| 535 | + | |
| 536 | + // Create event cube | |
| 537 | + GCTAEventCube cube(map, ebounds, exposure.gti()); | |
| 538 | + | |
| 539 | + // Create CTA observation | |
| 540 | + GCTAObservation cta; | |
| 541 | + cta.events(cube); | |
| 542 | + cta.response(exposure, psf); | |
| 543 | + | |
| 544 | + // Append observation to container | |
| 545 | + m_obs.append(cta); | |
| 546 | + | |
| 547 | + } // endif: cube response information was available | |
| 548 | + | |
| 549 | + // ... otherwise build an observation from IRF response information | |
| 550 | + else { | |
| 551 | + | |
| 552 | + // Create CTA observation | |
| 553 | + GCTAObservation cta = create_cta_obs(); | |
| 554 | + | |
| 555 | + // Set response | |
| 556 | + set_obs_response(&cta); | |
| 557 | + | |
| 558 | + // Append observation to container | |
| 559 | + m_obs.append(cta); | |
| 560 | + | |
| 561 | + } | |
| 562 | + | |
| 563 | + } // endif: filename was "NONE" or "" | |
| 564 | + | |
| 565 | + // ... otherwise we have a file name | |
| 566 | + else { | |
| 567 | + | |
| 568 | + // If file is a FITS file then create an empty CTA observation | |
| 569 | + // and load file into observation | |
| 570 | + if (gammalib::is_fits(filename)) { | |
| 571 | + | |
| 572 | + // Allocate empty CTA observation | |
| 573 | + GCTAObservation cta; | |
| 574 | + | |
| 575 | + // Load data | |
| 576 | + cta.load(filename); | |
| 577 | + | |
| 578 | + // Set response | |
| 579 | + set_obs_response(&cta); | |
| 580 | + | |
| 581 | + // Append observation to container | |
| 582 | + m_obs.append(cta); | |
| 583 | + | |
| 584 | + // Signal that no XML file should be used for storage | |
| 585 | + m_use_xml = false; | |
| 586 | + | |
| 587 | + } | |
| 588 | + | |
| 589 | + // ... otherwise load file into observation container | |
| 590 | + else { | |
| 591 | + | |
| 592 | + // Load observations from XML file | |
| 593 | + m_obs.load(filename); | |
| 594 | + | |
| 595 | + // For all observations that have no response, set the response | |
| 596 | + // from the task parameters | |
| 597 | + set_response(m_obs); | |
| 598 | + | |
| 599 | + // Set observation boundary parameters (emin, emax, rad) | |
| 600 | + set_obs_bounds(m_obs); | |
| 601 | + | |
| 602 | + // Signal that XML file should be used for storage | |
| 603 | + m_use_xml = true; | |
| 604 | + | |
| 605 | + } // endelse: file was an XML file | |
| 606 | + | |
| 607 | + } | |
| 608 | + | |
| 609 | + // Return | |
| 610 | + return; | |
| 611 | + | |
| 612 | +} | |
| 613 | + | |
| 614 | + | |
| 475 | 615 | /***********************************************************************//** |
| 476 | 616 | * @brief Fill model into model cube |
| 477 | 617 | * |
| ... | ... | @@ -515,6 +655,7 @@ void ctmodel::fill_cube(const GCTAObservation* obs) |
| 515 | 655 | |
| 516 | 656 | // Compute model value for cube bin |
| 517 | 657 | double model = m_obs.models().eval(*bin, *obs) * bin->size(); |
| 658 | + //double model = m_obs.models().eval(*bin, *ptr) * bin->size(); | |
| 518 | 659 | |
| 519 | 660 | // Add model to actual value |
| 520 | 661 | value += model; | ... | ... |
src/ctmodel/ctmodel.hpp
| ... | ... | @@ -78,6 +78,7 @@ protected: |
| 78 | 78 | void copy_members(const ctmodel& app); |
| 79 | 79 | void free_members(void); |
| 80 | 80 | void get_parameters(void); |
| 81 | + void get_obs(void); | |
| 81 | 82 | void fill_cube(const GCTAObservation* obs); |
| 82 | 83 | bool has_cube(void) const; |
| 83 | 84 | |
| ... | ... | @@ -86,10 +87,11 @@ protected: |
| 86 | 87 | bool m_apply_edisp; //!< Apply energy dispersion? |
| 87 | 88 | |
| 88 | 89 | // Protected members |
| 89 | - GObservations m_obs; //!< Observation container | |
| 90 | - GCTAEventCube m_cube; //!< Model cube | |
| 91 | - GGti m_gti; //!< Model cube GTIs | |
| 92 | - bool m_has_cube; //!< Signal if cube has been set or loaded | |
| 90 | + GObservations m_obs; //!< Observation container | |
| 91 | + GCTAEventCube m_cube; //!< Model cube | |
| 92 | + GGti m_gti; //!< Model cube GTIs | |
| 93 | + bool m_has_cube; //!< Signal if cube has been set or loaded | |
| 94 | + bool m_append_cube; //!< Signal that cube should be appended | |
| 93 | 95 | }; |
| 94 | 96 | |
| 95 | 97 | ... | ... |
src/support/ctool.cpp
test/test_ctmodel.py
| ... | ... | @@ -70,6 +70,8 @@ class Test(gammalib.GPythonTestSuite): |
| 70 | 70 | model["outcube"].filename("modmap.fits") |
| 71 | 71 | model["inmodel"].filename(self.model_name) |
| 72 | 72 | model["inobs"].filename("NONE") |
| 73 | + model["expcube"].filename("NONE") | |
| 74 | + model["psfcube"].filename("NONE") | |
| 73 | 75 | model["caldb"].string(self.caldb) |
| 74 | 76 | model["irf"].string(self.irf) |
| 75 | 77 | model["rad"].real(5.0) | ... | ... |
test/test_ctools.sh
| ... | ... | @@ -218,10 +218,12 @@ else |
| 218 | 218 | exit 1 |
| 219 | 219 | fi |
| 220 | 220 | # |
| 221 | -# Run 3 | |
| 221 | +# Run 2 | |
| 222 | 222 | $ctmodel inobs="NONE" \ |
| 223 | 223 | incube="NONE" \ |
| 224 | 224 | outcube="modmap3.fits" \ |
| 225 | + expcube="NONE" \ | |
| 226 | + psfcube="NONE" \ | |
| 225 | 227 | caldb="irf" \ |
| 226 | 228 | irf="cta_dummy_irf" \ |
| 227 | 229 | inmodel="data/crab.xml" \ |
| ... | ... | @@ -249,7 +251,7 @@ else |
| 249 | 251 | exit 1 |
| 250 | 252 | fi |
| 251 | 253 | # |
| 252 | -# Run 2 | |
| 254 | +# Run 3 | |
| 253 | 255 | $ctmodel inobs="cntmap2.fits" \ |
| 254 | 256 | incube="cntmap2.fits" \ |
| 255 | 257 | outcube="modmap2.fits" \ | ... | ... |