Commit 2ee8bac10df977f80447a0a74b2aa08a9b5dede0
1 parent
28b19876
Implement counts cube weights computation in ctbin
Showing
4 changed files
with
239 additions
and
37 deletions
ChangeLog
| 1 | -2016-06-20 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu> | 1 | +2016-06-21 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu> |
| 2 | 2 | ||
| 3 | * Version 1.1.0 released | 3 | * Version 1.1.0 released |
| 4 | ======================== | 4 | ======================== |
| 5 | 5 | ||
| 6 | + Compute counts cube weights in ctbin (#1789) | ||
| 6 | Adapt to new stacked cube interface (#1788) | 7 | Adapt to new stacked cube interface (#1788) |
| 7 | Add ctools and cscripts unit tests | 8 | Add ctools and cscripts unit tests |
| 8 | Add "bgdoversample" and "bgdinfill" parameters to csroot2caldb | 9 | Add "bgdoversample" and "bgdinfill" parameters to csroot2caldb |
NEWS
| 1 | New Features and Important Changes in ctools 1.1.0 | 1 | New Features and Important Changes in ctools 1.1.0 |
| 2 | 2 | ||
| 3 | -20 June 2016 | 3 | +21 June 2016 |
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | Introduction | 6 | Introduction |
| @@ -92,6 +92,14 @@ ctbin - CTA event binning | @@ -92,6 +92,14 @@ ctbin - CTA event binning | ||
| 92 | Add publish() method to publish the counts cube via a SAMP Hub to Virtual | 92 | Add publish() method to publish the counts cube via a SAMP Hub to Virtual |
| 93 | Observatory interoperable tools (e.g. Aladin). | 93 | Observatory interoperable tools (e.g. Aladin). |
| 94 | 94 | ||
| 95 | +The tool now computes the counts cube weights according to the overlaps | ||
| 96 | +between the Region of Interests and energy boundaries with the counts | ||
| 97 | +cube bins. This allows in particular for a proper handling of different | ||
| 98 | +energy thresholds between observations that will be stacked into a single | ||
| 99 | +cube. Also different Region of Interests are now properly handled, and | ||
| 100 | +there is no longer an issue with counts cubes that are larger than the | ||
| 101 | +Region of Interest of the event list (#1789). | ||
| 102 | + | ||
| 95 | 103 | ||
| 96 | ctlike - Maximum likelihood fitting | 104 | ctlike - Maximum likelihood fitting |
| 97 | ----------------------------------- | 105 | ----------------------------------- |
src/ctbin/ctbin.cpp
| @@ -39,9 +39,9 @@ | @@ -39,9 +39,9 @@ | ||
| 39 | /* __ Debug definitions __________________________________________________ */ | 39 | /* __ Debug definitions __________________________________________________ */ |
| 40 | 40 | ||
| 41 | /* __ Coding definitions _________________________________________________ */ | 41 | /* __ Coding definitions _________________________________________________ */ |
| 42 | +#define G_PLAW_WEIGHTS //!< Use power law in energy weight computation | ||
| 42 | 43 | ||
| 43 | /* __ Constants __________________________________________________________ */ | 44 | /* __ Constants __________________________________________________________ */ |
| 44 | -const GEnergy g_energy_margin(1.0e-12, "TeV"); | ||
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | /*========================================================================== | 47 | /*========================================================================== |
| @@ -62,7 +62,7 @@ ctbin::ctbin(void) : ctool(CTBIN_NAME, CTBIN_VERSION) | @@ -62,7 +62,7 @@ ctbin::ctbin(void) : ctool(CTBIN_NAME, CTBIN_VERSION) | ||
| 62 | 62 | ||
| 63 | // Return | 63 | // Return |
| 64 | return; | 64 | return; |
| 65 | -} // GCOV_EXCL_LINE | 65 | +} |
| 66 | 66 | ||
| 67 | 67 | ||
| 68 | /***********************************************************************//** | 68 | /***********************************************************************//** |
| @@ -211,7 +211,9 @@ void ctbin::clear(void) | @@ -211,7 +211,9 @@ void ctbin::clear(void) | ||
| 211 | * @brief Run the ctbin tool | 211 | * @brief Run the ctbin tool |
| 212 | * | 212 | * |
| 213 | * Gets the user parameters and loops over all CTA observations in the | 213 | * Gets the user parameters and loops over all CTA observations in the |
| 214 | - * observation container to bin the events into a single counts cube. | 214 | + * observation container to bin the events into a single counts cube. All |
| 215 | + * observations in the observation container that do not contain CTA event | ||
| 216 | + * lists will be skipped. | ||
| 215 | ***************************************************************************/ | 217 | ***************************************************************************/ |
| 216 | void ctbin::run(void) | 218 | void ctbin::run(void) |
| 217 | { | 219 | { |
| @@ -275,6 +277,15 @@ void ctbin::run(void) | @@ -275,6 +277,15 @@ void ctbin::run(void) | ||
| 275 | 277 | ||
| 276 | } // endfor: looped over observations | 278 | } // endfor: looped over observations |
| 277 | 279 | ||
| 280 | + // Normalize weights counts map | ||
| 281 | + if (m_livetime > 0.0) { | ||
| 282 | + for (int iebin = 0; iebin < m_weights.nmaps(); ++iebin) { | ||
| 283 | + for (int index = 0; index < m_weights.npix(); ++index) { | ||
| 284 | + m_weights(index, iebin) /= m_livetime; | ||
| 285 | + } | ||
| 286 | + } | ||
| 287 | + } | ||
| 288 | + | ||
| 278 | // Set a single cube in the observation container | 289 | // Set a single cube in the observation container |
| 279 | obs_cube(); | 290 | obs_cube(); |
| 280 | 291 | ||
| @@ -364,7 +375,7 @@ void ctbin::publish(const std::string& name) | @@ -364,7 +375,7 @@ void ctbin::publish(const std::string& name) | ||
| 364 | } | 375 | } |
| 365 | 376 | ||
| 366 | // Publish counts cube | 377 | // Publish counts cube |
| 367 | - m_cube.publish(user_name); | 378 | + m_counts.publish(user_name); |
| 368 | 379 | ||
| 369 | // Return | 380 | // Return |
| 370 | return; | 381 | return; |
| @@ -389,7 +400,8 @@ void ctbin::init_members(void) | @@ -389,7 +400,8 @@ void ctbin::init_members(void) | ||
| 389 | 400 | ||
| 390 | // Initialise protected members | 401 | // Initialise protected members |
| 391 | m_obs.clear(); | 402 | m_obs.clear(); |
| 392 | - m_cube.clear(); | 403 | + m_counts.clear(); |
| 404 | + m_weights.clear(); | ||
| 393 | m_ebounds.clear(); | 405 | m_ebounds.clear(); |
| 394 | m_gti.clear(); | 406 | m_gti.clear(); |
| 395 | m_ontime = 0.0; | 407 | m_ontime = 0.0; |
| @@ -414,7 +426,8 @@ void ctbin::copy_members(const ctbin& app) | @@ -414,7 +426,8 @@ void ctbin::copy_members(const ctbin& app) | ||
| 414 | 426 | ||
| 415 | // Copy protected members | 427 | // Copy protected members |
| 416 | m_obs = app.m_obs; | 428 | m_obs = app.m_obs; |
| 417 | - m_cube = app.m_cube; | 429 | + m_counts = app.m_counts; |
| 430 | + m_weights = app.m_weights; | ||
| 418 | m_ebounds = app.m_ebounds; | 431 | m_ebounds = app.m_ebounds; |
| 419 | m_gti = app.m_gti; | 432 | m_gti = app.m_gti; |
| 420 | m_ontime = app.m_ontime; | 433 | m_ontime = app.m_ontime; |
| @@ -464,9 +477,11 @@ void ctbin::get_parameters(void) | @@ -464,9 +477,11 @@ void ctbin::get_parameters(void) | ||
| 464 | // Create an event cube based on task parameters | 477 | // Create an event cube based on task parameters |
| 465 | GCTAEventCube cube = create_cube(m_obs); | 478 | GCTAEventCube cube = create_cube(m_obs); |
| 466 | 479 | ||
| 467 | - // Get the skymap from the cube and initialise all pixels to zero | ||
| 468 | - m_cube = cube.counts(); | ||
| 469 | - m_cube = 0.0; | 480 | + // Get the skymap from the cube and initialise all counts cube bins and |
| 481 | + // weights to zero | ||
| 482 | + m_counts = cube.counts(); | ||
| 483 | + m_counts = 0.0; | ||
| 484 | + m_weights = m_counts; | ||
| 470 | 485 | ||
| 471 | // Get energy boundaries | 486 | // Get energy boundaries |
| 472 | m_ebounds = cube.ebounds(); | 487 | m_ebounds = cube.ebounds(); |
| @@ -497,7 +512,7 @@ void ctbin::get_parameters(void) | @@ -497,7 +512,7 @@ void ctbin::get_parameters(void) | ||
| 497 | * @param[in] obs CTA observation. | 512 | * @param[in] obs CTA observation. |
| 498 | * | 513 | * |
| 499 | * @exception GException::invalid_value | 514 | * @exception GException::invalid_value |
| 500 | - * No event list found in observation. | 515 | + * No event list or valid RoI found in observation. |
| 501 | * | 516 | * |
| 502 | * Fills the events from an event list in the counts cube setup by init_cube. | 517 | * Fills the events from an event list in the counts cube setup by init_cube. |
| 503 | ***************************************************************************/ | 518 | ***************************************************************************/ |
| @@ -508,7 +523,8 @@ void ctbin::fill_cube(GCTAObservation* obs) | @@ -508,7 +523,8 @@ void ctbin::fill_cube(GCTAObservation* obs) | ||
| 508 | 523 | ||
| 509 | // Make sure that the observation holds a CTA event list. If this | 524 | // Make sure that the observation holds a CTA event list. If this |
| 510 | // is not the case then throw an exception. | 525 | // is not the case then throw an exception. |
| 511 | - const GCTAEventList* events = dynamic_cast<const GCTAEventList*>(obs->events()); | 526 | + const GCTAEventList* events = |
| 527 | + dynamic_cast<const GCTAEventList*>(obs->events()); | ||
| 512 | if (events == NULL) { | 528 | if (events == NULL) { |
| 513 | std::string msg = "CTA Observation does not contain an event " | 529 | std::string msg = "CTA Observation does not contain an event " |
| 514 | "list. An event list is needed to fill the " | 530 | "list. An event list is needed to fill the " |
| @@ -519,9 +535,6 @@ void ctbin::fill_cube(GCTAObservation* obs) | @@ -519,9 +535,6 @@ void ctbin::fill_cube(GCTAObservation* obs) | ||
| 519 | // Get the RoI | 535 | // Get the RoI |
| 520 | const GCTARoi& roi = events->roi(); | 536 | const GCTARoi& roi = events->roi(); |
| 521 | 537 | ||
| 522 | - // Get the ebounds | ||
| 523 | - const GEbounds& obs_ebounds = events->ebounds(); | ||
| 524 | - | ||
| 525 | // Check for RoI sanity | 538 | // Check for RoI sanity |
| 526 | if (!roi.is_valid()) { | 539 | if (!roi.is_valid()) { |
| 527 | std::string msg = "No valid RoI found in input observation " | 540 | std::string msg = "No valid RoI found in input observation " |
| @@ -537,7 +550,7 @@ void ctbin::fill_cube(GCTAObservation* obs) | @@ -537,7 +550,7 @@ void ctbin::fill_cube(GCTAObservation* obs) | ||
| 537 | int num_outside_ebds = 0; | 550 | int num_outside_ebds = 0; |
| 538 | int num_in_map = 0; | 551 | int num_in_map = 0; |
| 539 | 552 | ||
| 540 | - // Fill sky map | 553 | + // Fill counts sky map |
| 541 | for (int i = 0; i < events->size(); ++i) { | 554 | for (int i = 0; i < events->size(); ++i) { |
| 542 | 555 | ||
| 543 | // Get event | 556 | // Get event |
| @@ -546,7 +559,7 @@ void ctbin::fill_cube(GCTAObservation* obs) | @@ -546,7 +559,7 @@ void ctbin::fill_cube(GCTAObservation* obs) | ||
| 546 | // Determine sky pixel | 559 | // Determine sky pixel |
| 547 | GCTAInstDir* inst = (GCTAInstDir*)&(event->dir()); | 560 | GCTAInstDir* inst = (GCTAInstDir*)&(event->dir()); |
| 548 | GSkyDir dir = inst->dir(); | 561 | GSkyDir dir = inst->dir(); |
| 549 | - GSkyPixel pixel = m_cube.dir2pix(dir); | 562 | + GSkyPixel pixel = m_counts.dir2pix(dir); |
| 550 | 563 | ||
| 551 | // Skip if pixel is outside RoI | 564 | // Skip if pixel is outside RoI |
| 552 | if (roi.centre().dir().dist_deg(dir) > roi.radius()) { | 565 | if (roi.centre().dir().dist_deg(dir) > roi.radius()) { |
| @@ -554,28 +567,42 @@ void ctbin::fill_cube(GCTAObservation* obs) | @@ -554,28 +567,42 @@ void ctbin::fill_cube(GCTAObservation* obs) | ||
| 554 | continue; | 567 | continue; |
| 555 | } | 568 | } |
| 556 | 569 | ||
| 557 | - // Skip if pixel is out of range | ||
| 558 | - if (pixel.x() < -0.5 || pixel.x() > (m_cube.nx()-0.5) || | ||
| 559 | - pixel.y() < -0.5 || pixel.y() > (m_cube.ny()-0.5)) { | 570 | + // Skip if pixel is out of map range |
| 571 | + if (pixel.x() < -0.5 || pixel.x() > (m_counts.nx()-0.5) || | ||
| 572 | + pixel.y() < -0.5 || pixel.y() > (m_counts.ny()-0.5)) { | ||
| 560 | num_outside_map++; | 573 | num_outside_map++; |
| 561 | continue; | 574 | continue; |
| 562 | } | 575 | } |
| 563 | 576 | ||
| 564 | - // Determine energy bin. Skip if we are outside the energy range | ||
| 565 | - int index = m_ebounds.index(event->energy()); | ||
| 566 | - if (index == -1 || | ||
| 567 | - !obs_ebounds.contains(m_ebounds.emin(index)+g_energy_margin, | ||
| 568 | - m_ebounds.emax(index)-g_energy_margin)) { | 577 | + // Determine energy bin |
| 578 | + int iebin = m_ebounds.index(event->energy()); | ||
| 579 | + | ||
| 580 | + // Skip if energy bin is outside counts cube boundaries | ||
| 581 | + if (iebin == -1) { | ||
| 569 | num_outside_ebds++; | 582 | num_outside_ebds++; |
| 570 | continue; | 583 | continue; |
| 571 | } | 584 | } |
| 572 | 585 | ||
| 573 | // Fill event in skymap | 586 | // Fill event in skymap |
| 574 | - m_cube(pixel, index) += 1.0; | 587 | + m_counts(pixel, iebin) += 1.0; |
| 575 | num_in_map++; | 588 | num_in_map++; |
| 576 | 589 | ||
| 577 | } // endfor: looped over all events | 590 | } // endfor: looped over all events |
| 578 | 591 | ||
| 592 | + // Get RoI and energy weights | ||
| 593 | + GSkyMap roi_weights = set_roi_weights(roi); | ||
| 594 | + std::vector<double> energy_weights = set_energy_weights(events->ebounds()); | ||
| 595 | + | ||
| 596 | + // Add weights multiplied by livetime to weight map. The map is later | ||
| 597 | + // divided by the cumulative livetime in run(). | ||
| 598 | + for (int iebin = 0; iebin < energy_weights.size(); ++iebin) { | ||
| 599 | + for (int index = 0; index < roi_weights.npix(); ++index) { | ||
| 600 | + m_weights(index, iebin) += roi_weights(index) * | ||
| 601 | + energy_weights[iebin] * | ||
| 602 | + obs->livetime(); | ||
| 603 | + } | ||
| 604 | + } | ||
| 605 | + | ||
| 579 | // Append GTIs | 606 | // Append GTIs |
| 580 | m_gti.extend(events->gti()); | 607 | m_gti.extend(events->gti()); |
| 581 | 608 | ||
| @@ -600,7 +627,7 @@ void ctbin::fill_cube(GCTAObservation* obs) | @@ -600,7 +627,7 @@ void ctbin::fill_cube(GCTAObservation* obs) | ||
| 600 | // Log cube | 627 | // Log cube |
| 601 | if (logExplicit()) { | 628 | if (logExplicit()) { |
| 602 | log.header1("Counts cube"); | 629 | log.header1("Counts cube"); |
| 603 | - log << m_cube << std::endl; | 630 | + log << m_counts << std::endl; |
| 604 | } | 631 | } |
| 605 | 632 | ||
| 606 | } // endif: observation was valid | 633 | } // endif: observation was valid |
| @@ -647,7 +674,7 @@ void ctbin::obs_cube(void) | @@ -647,7 +674,7 @@ void ctbin::obs_cube(void) | ||
| 647 | else { | 674 | else { |
| 648 | 675 | ||
| 649 | // Create empty counts cube | 676 | // Create empty counts cube |
| 650 | - GCTAEventCube cube(m_cube, m_ebounds, obs->gti()); | 677 | + GCTAEventCube cube(m_counts, m_weights, m_ebounds, obs->gti()); |
| 651 | 678 | ||
| 652 | // Assign empty cube to observation | 679 | // Assign empty cube to observation |
| 653 | obs->events(cube); | 680 | obs->events(cube); |
| @@ -732,3 +759,165 @@ void ctbin::obs_cube(void) | @@ -732,3 +759,165 @@ void ctbin::obs_cube(void) | ||
| 732 | // Return | 759 | // Return |
| 733 | return; | 760 | return; |
| 734 | } | 761 | } |
| 762 | + | ||
| 763 | + | ||
| 764 | +/***********************************************************************//** | ||
| 765 | + * @brief Set RoI weights. | ||
| 766 | + * | ||
| 767 | + * @param[in] roi Region of Interest. | ||
| 768 | + * @return Sky map with Region of Interest weights. | ||
| 769 | + * | ||
| 770 | + * Computes a sky map of Region of Interest (RoI) weights. All pixels of the | ||
| 771 | + * sky map that are fully comprised within the RoI will be set to unity. | ||
| 772 | + * Pixels that are only partly comprised will be devided into a 10x10 subgrid, | ||
| 773 | + * and a weight corresponding to the fraction of subgrid points that are | ||
| 774 | + * fully comprised within the RoI will be assigned to the sky map pixel. | ||
| 775 | + * The precision of the weights is about 1%. | ||
| 776 | + ***************************************************************************/ | ||
| 777 | +GSkyMap ctbin::set_roi_weights(const GCTARoi& roi) const | ||
| 778 | +{ | ||
| 779 | + // Set number of points in subgrid | ||
| 780 | + const int n_subgrid = 10; | ||
| 781 | + | ||
| 782 | + // Initialise ROI weight sky map with zero weights | ||
| 783 | + GSkyMap weights(m_counts.extract(0)); | ||
| 784 | + weights = 0.0; | ||
| 785 | + | ||
| 786 | + // Compute save RoI radius. All pixels with bin centre within that radius | ||
| 787 | + // will be set to unity. In case that the counts cube is not a WCS map | ||
| 788 | + // no pixels will be considered within the safe radius. | ||
| 789 | + double margin(roi.radius()); | ||
| 790 | + const GWcs* wcs(dynamic_cast<const GWcs*>(m_counts.projection())); | ||
| 791 | + if (wcs != NULL) { | ||
| 792 | + double dx = wcs->cdelt(0); | ||
| 793 | + double dy = wcs->cdelt(1); | ||
| 794 | + margin = (dx > dy) ? dx : dy; | ||
| 795 | + } | ||
| 796 | + double safe_radius = roi.radius() - margin; | ||
| 797 | + | ||
| 798 | + // Loop over all sky map pixels | ||
| 799 | + for (int i = 0; i < weights.npix(); ++i) { | ||
| 800 | + | ||
| 801 | + // Get pixel sky direction | ||
| 802 | + GSkyDir dir(weights.inx2dir(i)); | ||
| 803 | + | ||
| 804 | + // If pixel is within the safe radius then set the pixel weight to | ||
| 805 | + // unity ... | ||
| 806 | + if (roi.centre().dir().dist_deg(dir) <= safe_radius) { | ||
| 807 | + weights(i) = 1.0; | ||
| 808 | + } | ||
| 809 | + | ||
| 810 | + // ... otherwise define a subgrid a check all positions within that | ||
| 811 | + // subgrid that fall within the RoI. This is an approximation that | ||
| 812 | + // determines the weight of the pixels | ||
| 813 | + else { | ||
| 814 | + | ||
| 815 | + // Set pixel centre | ||
| 816 | + GSkyPixel centre(weights.inx2pix(i)); | ||
| 817 | + | ||
| 818 | + // Compute subgrid pixel step size | ||
| 819 | + double step = 1.0 / double(n_subgrid-1); | ||
| 820 | + | ||
| 821 | + // Compute sky direction weight | ||
| 822 | + double weight = 1.0 / (double(n_subgrid) * double(n_subgrid)); | ||
| 823 | + | ||
| 824 | + // Loop over X subgrid | ||
| 825 | + for (int ix = 0; ix < n_subgrid; ++ix) { | ||
| 826 | + | ||
| 827 | + // Compute X pixel value | ||
| 828 | + double x = ix * step - 0.5; | ||
| 829 | + | ||
| 830 | + // Loop over Y subgrid | ||
| 831 | + for (int iy = 0; iy < n_subgrid; ++iy) { | ||
| 832 | + | ||
| 833 | + // Compute Y pixel value | ||
| 834 | + double y = iy * step - 0.5; | ||
| 835 | + | ||
| 836 | + // Set pixel value | ||
| 837 | + GSkyPixel pixel(centre.x()+x, centre.y()+y); | ||
| 838 | + | ||
| 839 | + // Get pixel sky direction | ||
| 840 | + GSkyDir dir(weights.pix2dir(pixel)); | ||
| 841 | + | ||
| 842 | + // If sky direction is within the RoI then add the direction | ||
| 843 | + // to the weight for this pixel | ||
| 844 | + if (roi.centre().dir().dist_deg(dir) <= roi.radius()) { | ||
| 845 | + weights(i) += weight; | ||
| 846 | + } | ||
| 847 | + | ||
| 848 | + } // endfor: loop over Y subgrid | ||
| 849 | + | ||
| 850 | + } // endfor: loop over X subgrid | ||
| 851 | + | ||
| 852 | + } // endelse: pixel was outside safe radius | ||
| 853 | + | ||
| 854 | + } // endfor: looped over all pixel sky maps | ||
| 855 | + | ||
| 856 | + // Return | ||
| 857 | + return weights; | ||
| 858 | +} | ||
| 859 | + | ||
| 860 | + | ||
| 861 | +/***********************************************************************//** | ||
| 862 | + * @brief Set energy weights. | ||
| 863 | + * | ||
| 864 | + * @param[in] ebounds Energy boundaries. | ||
| 865 | + * @return Vector of energy boundary weights. | ||
| 866 | + * | ||
| 867 | + * Computes a vector of energy boundary weights from the overlap of the | ||
| 868 | + * event list energy boundaries with the counts cube boundaries. It is | ||
| 869 | + * assumed that within a bin the events are distributed according to a power | ||
| 870 | + * law with spectral index of -2, and the weights are computed according | ||
| 871 | + * to the fraction of this power law that is comprised within a counts cube | ||
| 872 | + * bin. | ||
| 873 | + * | ||
| 874 | + * This method properly handles event lists with multiple energy boundaries. | ||
| 875 | + ***************************************************************************/ | ||
| 876 | +std::vector<double> ctbin::set_energy_weights(const GEbounds& ebounds) const | ||
| 877 | +{ | ||
| 878 | + // Initialise energy boundary weights with zero weights | ||
| 879 | + std::vector<double> weights(m_ebounds.size(), 0.0); | ||
| 880 | + | ||
| 881 | + // Loop over all energy bins of counts cube | ||
| 882 | + for (int i = 0; i < m_ebounds.size(); ++i) { | ||
| 883 | + | ||
| 884 | + // Get energy boundaries of counts cube bin | ||
| 885 | + GEnergy emin(m_ebounds.emin(i)); | ||
| 886 | + GEnergy emax(m_ebounds.emax(i)); | ||
| 887 | + | ||
| 888 | + // Loop over all energy boundaries of the event list and add the | ||
| 889 | + // coverage fraction to the weights | ||
| 890 | + for (int k = 0; k < ebounds.size(); ++k) { | ||
| 891 | + | ||
| 892 | + // If there is no overlap then check next boundary | ||
| 893 | + if ((ebounds.emax(k) <= emin) || (ebounds.emin(k) >= emax)) { | ||
| 894 | + continue; | ||
| 895 | + } | ||
| 896 | + | ||
| 897 | + // Get minimum and maximum energy of overlap region | ||
| 898 | + GEnergy elow = (ebounds.emin(k) > emin) ? ebounds.emin(k) : emin; | ||
| 899 | + GEnergy ehigh = (ebounds.emax(k) < emax) ? ebounds.emax(k) : emax; | ||
| 900 | + | ||
| 901 | + // Compute overlap weight | ||
| 902 | + #if defined(G_PLAW_WEIGHTS) | ||
| 903 | + double w_overlap = gammalib::plaw_photon_flux(elow.TeV(), | ||
| 904 | + ehigh.TeV(), | ||
| 905 | + 1.0, -2.0); | ||
| 906 | + double w_full = gammalib::plaw_photon_flux(emin.TeV(), | ||
| 907 | + emax.TeV(), | ||
| 908 | + 1.0, -2.0); | ||
| 909 | + double weight = w_overlap / w_full; | ||
| 910 | + #else | ||
| 911 | + double weight = (ehigh - elow) / (emax - emin); | ||
| 912 | + #endif | ||
| 913 | + | ||
| 914 | + // Add overlap weight | ||
| 915 | + weights[i] += weight; | ||
| 916 | + | ||
| 917 | + } // endfor: looped over all energy boundaries of the event list | ||
| 918 | + | ||
| 919 | + } // endfor: looped over all energy boundaries of the counts cube | ||
| 920 | + | ||
| 921 | + // Return | ||
| 922 | + return weights; | ||
| 923 | +} |
src/ctbin/ctbin.hpp
| @@ -28,6 +28,7 @@ | @@ -28,6 +28,7 @@ | ||
| 28 | #define CTBIN_HPP | 28 | #define CTBIN_HPP |
| 29 | 29 | ||
| 30 | /* __ Includes ___________________________________________________________ */ | 30 | /* __ Includes ___________________________________________________________ */ |
| 31 | +#include <vector> | ||
| 31 | #include "GammaLib.hpp" | 32 | #include "GammaLib.hpp" |
| 32 | #include "GCTALib.hpp" | 33 | #include "GCTALib.hpp" |
| 33 | #include "ctool.hpp" | 34 | #include "ctool.hpp" |
| @@ -84,12 +85,14 @@ public: | @@ -84,12 +85,14 @@ public: | ||
| 84 | 85 | ||
| 85 | protected: | 86 | protected: |
| 86 | // Protected methods | 87 | // Protected methods |
| 87 | - void init_members(void); | ||
| 88 | - void copy_members(const ctbin& app); | ||
| 89 | - void free_members(void); | ||
| 90 | - void get_parameters(void); | ||
| 91 | - void fill_cube(GCTAObservation* obs); | ||
| 92 | - void obs_cube(void); | 88 | + void init_members(void); |
| 89 | + void copy_members(const ctbin& app); | ||
| 90 | + void free_members(void); | ||
| 91 | + void get_parameters(void); | ||
| 92 | + void fill_cube(GCTAObservation* obs); | ||
| 93 | + void obs_cube(void); | ||
| 94 | + GSkyMap set_roi_weights(const GCTARoi& roi) const; | ||
| 95 | + std::vector<double> set_energy_weights(const GEbounds& ebounds) const; | ||
| 93 | 96 | ||
| 94 | // User parameters | 97 | // User parameters |
| 95 | GFilename m_outcube; //!< Output counts map file name | 98 | GFilename m_outcube; //!< Output counts map file name |
| @@ -98,7 +101,8 @@ protected: | @@ -98,7 +101,8 @@ protected: | ||
| 98 | 101 | ||
| 99 | // Protected members | 102 | // Protected members |
| 100 | GObservations m_obs; //!< Observation container | 103 | GObservations m_obs; //!< Observation container |
| 101 | - GSkyMap m_cube; //!< Event cube | 104 | + GSkyMap m_counts; //!< Event cube counts |
| 105 | + GSkyMap m_weights; //!< Event cube weights | ||
| 102 | GEbounds m_ebounds; //!< Energy boundaries | 106 | GEbounds m_ebounds; //!< Energy boundaries |
| 103 | GGti m_gti; //!< Good time intervals | 107 | GGti m_gti; //!< Good time intervals |
| 104 | double m_ontime; //!< Total ontime | 108 | double m_ontime; //!< Total ontime |
| @@ -128,7 +132,7 @@ inline | @@ -128,7 +132,7 @@ inline | ||
| 128 | GCTAEventCube ctbin::cube(void) const | 132 | GCTAEventCube ctbin::cube(void) const |
| 129 | { | 133 | { |
| 130 | // Build event cube | 134 | // Build event cube |
| 131 | - GCTAEventCube cube(m_cube, m_ebounds, m_gti); | 135 | + GCTAEventCube cube(m_counts, m_weights, m_ebounds, m_gti); |
| 132 | 136 | ||
| 133 | // Return cube | 137 | // Return cube |
| 134 | return cube; | 138 | return cube; |