Commit e8719183f1b457c156db04d9fe3795dd2156fff6
1 parent
74bcfe43
Revert to considering only fully contained counts cube bins (#1819)
It turned out that the partial coverage of counts cube bins using the weighting array does not work. The problem is spill over of events from one RoI to another than can not be dealt with at the level of a stacked analysis. The old logic of using only fully contained pixel is put back into place. The weighting array is (for the moment) conserved as it could serve other purposes. However, excluding of pixels is already accomplished by setting a pixel value to -1, so it remains to be seen whether we would like to keep that logic or if we would like to use the weighting array (which is more universal).
Showing
2 changed files
with
142 additions
and
195 deletions
src/ctbin/ctbin.cpp
| ... | ... | @@ -33,8 +33,9 @@ |
| 33 | 33 | #include "GTools.hpp" |
| 34 | 34 | |
| 35 | 35 | /* __ Method name definitions ____________________________________________ */ |
| 36 | -#define G_FILL_CUBE "ctbin::fill_cube(GCTAObservation*)" | |
| 37 | 36 | #define G_GET_PARAMETERS "ctbin::get_parameters()" |
| 37 | +#define G_FILL_CUBE "ctbin::fill_cube(GCTAObservation*)" | |
| 38 | +#define G_SET_WEIGHTS "ctbin::set_weights(GCTAObservation*)" | |
| 38 | 39 | |
| 39 | 40 | /* __ Debug definitions __________________________________________________ */ |
| 40 | 41 | |
| ... | ... | @@ -229,7 +230,7 @@ void ctbin::run(void) |
| 229 | 230 | if (logTerse()) { |
| 230 | 231 | log << std::endl; |
| 231 | 232 | log.header1(gammalib::number("Observation", m_obs.size())); |
| 232 | - log << m_obs << std::endl; | |
| 233 | + log << m_obs.print(m_chatter) << std::endl; | |
| 233 | 234 | } |
| 234 | 235 | |
| 235 | 236 | // Write header |
| ... | ... | @@ -272,20 +273,14 @@ void ctbin::run(void) |
| 272 | 273 | // Fill the cube |
| 273 | 274 | fill_cube(obs); |
| 274 | 275 | |
| 276 | + // Set the counts cube weights | |
| 277 | + set_weights(obs); | |
| 278 | + | |
| 275 | 279 | // Dispose events to free memory |
| 276 | 280 | obs->dispose_events(); |
| 277 | 281 | |
| 278 | 282 | } // endfor: looped over observations |
| 279 | 283 | |
| 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 | - | |
| 289 | 284 | // Set a single cube in the observation container |
| 290 | 285 | obs_cube(); |
| 291 | 286 | |
| ... | ... | @@ -293,7 +288,7 @@ void ctbin::run(void) |
| 293 | 288 | if (logTerse()) { |
| 294 | 289 | log << std::endl; |
| 295 | 290 | log.header1(gammalib::number("Binned observation", m_obs.size())); |
| 296 | - log << m_obs << std::endl; | |
| 291 | + log << m_obs.print(m_chatter) << std::endl; | |
| 297 | 292 | } |
| 298 | 293 | |
| 299 | 294 | // Optionally publish counts cube |
| ... | ... | @@ -397,6 +392,7 @@ void ctbin::init_members(void) |
| 397 | 392 | m_outcube.clear(); |
| 398 | 393 | m_usepnt = false; |
| 399 | 394 | m_publish = false; |
| 395 | + m_chatter = static_cast<GChatter>(2); | |
| 400 | 396 | |
| 401 | 397 | // Initialise protected members |
| 402 | 398 | m_obs.clear(); |
| ... | ... | @@ -423,15 +419,16 @@ void ctbin::copy_members(const ctbin& app) |
| 423 | 419 | m_outcube = app.m_outcube; |
| 424 | 420 | m_usepnt = app.m_usepnt; |
| 425 | 421 | m_publish = app.m_publish; |
| 422 | + m_chatter = app.m_chatter; | |
| 426 | 423 | |
| 427 | 424 | // Copy protected members |
| 428 | - m_obs = app.m_obs; | |
| 429 | - m_counts = app.m_counts; | |
| 430 | - m_weights = app.m_weights; | |
| 431 | - m_ebounds = app.m_ebounds; | |
| 432 | - m_gti = app.m_gti; | |
| 433 | - m_ontime = app.m_ontime; | |
| 434 | - m_livetime = app.m_livetime; | |
| 425 | + m_obs = app.m_obs; | |
| 426 | + m_counts = app.m_counts; | |
| 427 | + m_weights = app.m_weights; | |
| 428 | + m_ebounds = app.m_ebounds; | |
| 429 | + m_gti = app.m_gti; | |
| 430 | + m_ontime = app.m_ontime; | |
| 431 | + m_livetime = app.m_livetime; | |
| 435 | 432 | |
| 436 | 433 | // Return |
| 437 | 434 | return; |
| ... | ... | @@ -484,10 +481,11 @@ void ctbin::get_parameters(void) |
| 484 | 481 | m_weights = m_counts; |
| 485 | 482 | |
| 486 | 483 | // Get energy boundaries |
| 487 | - m_ebounds = cube.ebounds(); | |
| 484 | + m_ebounds = cube.ebounds(); | |
| 488 | 485 | |
| 489 | 486 | // Get remaining parameters |
| 490 | 487 | m_publish = (*this)["publish"].boolean(); |
| 488 | + m_chatter = static_cast<GChatter>((*this)["chatter"].integer()); | |
| 491 | 489 | |
| 492 | 490 | // Optionally read ahead parameters so that they get correctly |
| 493 | 491 | // dumped into the log file |
| ... | ... | @@ -523,8 +521,8 @@ void ctbin::fill_cube(GCTAObservation* obs) |
| 523 | 521 | |
| 524 | 522 | // Make sure that the observation holds a CTA event list. If this |
| 525 | 523 | // is not the case then throw an exception. |
| 526 | - const GCTAEventList* events = | |
| 527 | - dynamic_cast<const GCTAEventList*>(obs->events()); | |
| 524 | + const GCTAEventList* events = dynamic_cast<const GCTAEventList*> | |
| 525 | + (obs->events()); | |
| 528 | 526 | if (events == NULL) { |
| 529 | 527 | std::string msg = "CTA Observation does not contain an event " |
| 530 | 528 | "list. An event list is needed to fill the " |
| ... | ... | @@ -544,6 +542,9 @@ void ctbin::fill_cube(GCTAObservation* obs) |
| 544 | 542 | throw GException::invalid_value(G_FILL_CUBE, msg); |
| 545 | 543 | } |
| 546 | 544 | |
| 545 | + // Get counts cube usage flags | |
| 546 | + std::vector<bool> usage = cube_layer_usage(events->ebounds()); | |
| 547 | + | |
| 547 | 548 | // Initialise binning statistics |
| 548 | 549 | int num_outside_roi = 0; |
| 549 | 550 | int num_outside_map = 0; |
| ... | ... | @@ -561,24 +562,27 @@ void ctbin::fill_cube(GCTAObservation* obs) |
| 561 | 562 | GSkyDir dir = inst->dir(); |
| 562 | 563 | GSkyPixel pixel = m_counts.dir2pix(dir); |
| 563 | 564 | |
| 564 | - // Skip if pixel is outside RoI | |
| 565 | + // Skip event if corresponding counts cube pixel is outside RoI | |
| 565 | 566 | if (roi.centre().dir().dist_deg(dir) > roi.radius()) { |
| 566 | 567 | num_outside_roi++; |
| 567 | 568 | continue; |
| 568 | 569 | } |
| 569 | 570 | |
| 570 | - // Skip if pixel is out of map range | |
| 571 | + // Skip event if corresponding counts cube pixel is outside the | |
| 572 | + // counts cube map range | |
| 571 | 573 | if (pixel.x() < -0.5 || pixel.x() > (m_counts.nx()-0.5) || |
| 572 | 574 | pixel.y() < -0.5 || pixel.y() > (m_counts.ny()-0.5)) { |
| 573 | 575 | num_outside_map++; |
| 574 | 576 | continue; |
| 575 | 577 | } |
| 576 | 578 | |
| 577 | - // Determine energy bin | |
| 579 | + // Determine counts cube energy bin | |
| 578 | 580 | int iebin = m_ebounds.index(event->energy()); |
| 579 | 581 | |
| 580 | - // Skip if energy bin is outside counts cube boundaries | |
| 581 | - if (iebin == -1) { | |
| 582 | + // Skip event if the corresponding counts cube energy bin is not | |
| 583 | + // fully contained in the event list energy range. This avoids | |
| 584 | + // having partially filled bins. | |
| 585 | + if (!usage[iebin]) { | |
| 582 | 586 | num_outside_ebds++; |
| 583 | 587 | continue; |
| 584 | 588 | } |
| ... | ... | @@ -587,21 +591,10 @@ void ctbin::fill_cube(GCTAObservation* obs) |
| 587 | 591 | m_counts(pixel, iebin) += 1.0; |
| 588 | 592 | num_in_map++; |
| 589 | 593 | |
| 590 | - } // endfor: looped over all events | |
| 594 | + // Signal that bin was filled | |
| 595 | + m_weights(pixel, iebin) = 1.0; | |
| 591 | 596 | |
| 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 | - } | |
| 597 | + } // endfor: looped over all events | |
| 605 | 598 | |
| 606 | 599 | // Append GTIs |
| 607 | 600 | m_gti.extend(events->gti()); |
| ... | ... | @@ -638,6 +631,80 @@ void ctbin::fill_cube(GCTAObservation* obs) |
| 638 | 631 | |
| 639 | 632 | |
| 640 | 633 | /***********************************************************************//** |
| 634 | + * @brief Set counts cube weights for a given observation | |
| 635 | + * | |
| 636 | + * @param[in] obs CTA observation. | |
| 637 | + * | |
| 638 | + * @exception GException::invalid_value | |
| 639 | + * No event list or valid RoI found in observation. | |
| 640 | + * | |
| 641 | + * Sets the counts cube weights for all bins that are considered for the | |
| 642 | + * specific observation to unity. | |
| 643 | + ***************************************************************************/ | |
| 644 | +void ctbin::set_weights(GCTAObservation* obs) | |
| 645 | +{ | |
| 646 | + // Continue only if observation pointer is valid | |
| 647 | + if (obs != NULL) { | |
| 648 | + | |
| 649 | + // Make sure that the observation holds a CTA event list. If this | |
| 650 | + // is not the case then throw an exception. | |
| 651 | + const GCTAEventList* events = dynamic_cast<const GCTAEventList*> | |
| 652 | + (obs->events()); | |
| 653 | + if (events == NULL) { | |
| 654 | + std::string msg = "CTA Observation does not contain an event " | |
| 655 | + "list. An event list is needed to fill the " | |
| 656 | + "counts cube."; | |
| 657 | + throw GException::invalid_value(G_SET_WEIGHTS, msg); | |
| 658 | + } | |
| 659 | + | |
| 660 | + // Get the RoI | |
| 661 | + const GCTARoi& roi = events->roi(); | |
| 662 | + | |
| 663 | + // Check for RoI sanity | |
| 664 | + if (!roi.is_valid()) { | |
| 665 | + std::string msg = "No valid RoI found in input observation " | |
| 666 | + "\""+obs->name()+"\". Run ctselect to specify " | |
| 667 | + "an RoI for this observation before running " | |
| 668 | + "ctbin."; | |
| 669 | + throw GException::invalid_value(G_SET_WEIGHTS, msg); | |
| 670 | + } | |
| 671 | + | |
| 672 | + // Get counts cube usage flags | |
| 673 | + std::vector<bool> usage = cube_layer_usage(events->ebounds()); | |
| 674 | + | |
| 675 | + // Loop over all pixels in counts cube | |
| 676 | + for (int pixel = 0; pixel < m_counts.npix(); ++pixel) { | |
| 677 | + | |
| 678 | + // Get pixel sky direction | |
| 679 | + GSkyDir dir = m_counts.inx2dir(pixel); | |
| 680 | + | |
| 681 | + // Skip pixel if it is outside the RoI | |
| 682 | + if (roi.centre().dir().dist_deg(dir) > roi.radius()) { | |
| 683 | + continue; | |
| 684 | + } | |
| 685 | + | |
| 686 | + // Loop over all energy layers of counts cube | |
| 687 | + for (int iebin = 0; iebin < m_ebounds.size(); ++iebin){ | |
| 688 | + | |
| 689 | + // Skip energy layer if the usage flag is false | |
| 690 | + if (!usage[iebin]) { | |
| 691 | + continue; | |
| 692 | + } | |
| 693 | + // Signal that bin was filled | |
| 694 | + m_weights(pixel, iebin) = 1.0; | |
| 695 | + | |
| 696 | + } // endfor: looped over energy layers of counts cube | |
| 697 | + | |
| 698 | + } // endfor: looped over pixels of counts cube | |
| 699 | + | |
| 700 | + } // endif: observation was valid | |
| 701 | + | |
| 702 | + // Return | |
| 703 | + return; | |
| 704 | +} | |
| 705 | + | |
| 706 | + | |
| 707 | +/***********************************************************************//** | |
| 641 | 708 | * @brief Create output observation container. |
| 642 | 709 | * |
| 643 | 710 | * Creates an output observation container that combines all input CTA |
| ... | ... | @@ -761,163 +828,42 @@ void ctbin::obs_cube(void) |
| 761 | 828 | } |
| 762 | 829 | |
| 763 | 830 | |
| 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 | 831 | |
| 860 | 832 | |
| 861 | 833 | /***********************************************************************//** |
| 862 | - * @brief Set energy weights. | |
| 863 | - * | |
| 864 | - * @param[in] ebounds Energy boundaries. | |
| 865 | - * @return Vector of energy boundary weights. | |
| 834 | + * @brief Determine the counts cube layer usage. | |
| 866 | 835 | * |
| 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. | |
| 836 | + * @param[in] ebounds Energy boundaries of the event list. | |
| 837 | + * @return Vector of usage flags. | |
| 873 | 838 | * |
| 874 | - * This method properly handles event lists with multiple energy boundaries. | |
| 839 | + * Determines a vector of counts cube layer usage flags that signal whether | |
| 840 | + * an event should actually be filled in the counts cube or not. This makes | |
| 841 | + * sure that no partially filled bins will exist in the counts cube. | |
| 875 | 842 | ***************************************************************************/ |
| 876 | -std::vector<double> ctbin::set_energy_weights(const GEbounds& ebounds) const | |
| 843 | +std::vector<bool> ctbin::cube_layer_usage(const GEbounds& ebounds) const | |
| 877 | 844 | { |
| 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; | |
| 845 | + // Set energy margin | |
| 846 | + const GEnergy energy_margin(0.01, "GeV"); | |
| 847 | + | |
| 848 | + // Initialise usage vector | |
| 849 | + std::vector<bool> usage(m_ebounds.size(), true); | |
| 850 | + | |
| 851 | + // Loop over all energy bins of the cube | |
| 852 | + for (int iebin = 0; iebin < m_ebounds.size(); ++iebin) { | |
| 853 | + | |
| 854 | + // If the counts cube energy bin is fully contained within the | |
| 855 | + // energy boundaries of the event list the signal usage of this | |
| 856 | + // counts cube bin. Partially overlapping energy bins are signaled | |
| 857 | + // for non-usage, which avoids having partially filled bins in the | |
| 858 | + // counts cube. Some margin is applied that effectively reduces the | |
| 859 | + // width of the counts cube energy bin. This should cope with any | |
| 860 | + // rounding errors that come from reading and writing the energy | |
| 861 | + // boundary information to a FITS file. | |
| 862 | + usage[iebin] = ebounds.contains(m_ebounds.emin(iebin) + energy_margin, | |
| 863 | + m_ebounds.emax(iebin) - energy_margin); | |
| 864 | + | |
| 865 | + } // endfor: looped over all energy bins | |
| 866 | + | |
| 867 | + // Return usage | |
| 868 | + return usage; | |
| 923 | 869 | } | ... | ... |
src/ctbin/ctbin.hpp
| ... | ... | @@ -90,14 +90,15 @@ protected: |
| 90 | 90 | void free_members(void); |
| 91 | 91 | void get_parameters(void); |
| 92 | 92 | void fill_cube(GCTAObservation* obs); |
| 93 | + void set_weights(GCTAObservation* obs); | |
| 93 | 94 | void obs_cube(void); |
| 94 | - GSkyMap set_roi_weights(const GCTARoi& roi) const; | |
| 95 | - std::vector<double> set_energy_weights(const GEbounds& ebounds) const; | |
| 95 | + std::vector<bool> cube_layer_usage(const GEbounds& ebounds) const; | |
| 96 | 96 | |
| 97 | 97 | // User parameters |
| 98 | 98 | GFilename m_outcube; //!< Output counts map file name |
| 99 | 99 | bool m_usepnt; //!< Use pointing instead of xref/yref parameters |
| 100 | 100 | bool m_publish; //!< Publish counts cube? |
| 101 | + GChatter m_chatter; //!< Chattiness | |
| 101 | 102 | |
| 102 | 103 | // Protected members |
| 103 | 104 | GObservations m_obs; //!< Observation container | ... | ... |