Commit 98c5cdc0aeb766e4269dafa77da4f527d5594d57
Merge branch '1039-allow-energy-thresholds-in-ctselect' into integration
Showing
5 changed files
with
258 additions
and
71 deletions
ChangeLog
| 1 | -2014-10-30 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu> | 1 | +2014-11-08 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu> |
| 2 | 2 | ||
| 3 | * Version 0.8.0 released | 3 | * Version 0.8.0 released |
| 4 | ======================== | 4 | ======================== |
| @@ -17,6 +17,7 @@ | @@ -17,6 +17,7 @@ | ||
| 17 | ctmodel now always creates a single model cube | 17 | ctmodel now always creates a single model cube |
| 18 | Support energy dispersion in ctobssim, ctlike and ctmodel | 18 | Support energy dispersion in ctobssim, ctlike and ctmodel |
| 19 | Correct ctobssim for thread safety | 19 | Correct ctobssim for thread safety |
| 20 | + Support save and user energy thresholds in ctselect | ||
| 20 | Correctly apply time references in ctselect | 21 | Correctly apply time references in ctselect |
| 21 | Reduce memory usage | 22 | Reduce memory usage |
| 22 | Move obsutils to ctools namespace | 23 | Move obsutils to ctools namespace |
NEWS
| @@ -2,7 +2,7 @@ New Features and Important Changes in ctools 00-08-00 | @@ -2,7 +2,7 @@ New Features and Important Changes in ctools 00-08-00 | ||
| 2 | 2 | ||
| 3 | Author(s) : Juergen Knoedlseder | 3 | Author(s) : Juergen Knoedlseder |
| 4 | 4 | ||
| 5 | -30 October 2014 | 5 | +8 November 2014 |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | 1. Introduction | 8 | 1. Introduction |
| @@ -65,6 +65,30 @@ tmin and tmax parameters are given in CTA reference time, they are | @@ -65,6 +65,30 @@ tmin and tmax parameters are given in CTA reference time, they are | ||
| 65 | internally converted to the reference time of the GTI before event | 65 | internally converted to the reference time of the GTI before event |
| 66 | selection (#1329). | 66 | selection (#1329). |
| 67 | 67 | ||
| 68 | +ctselect now supports save and user energy thresholds (#1039). There | ||
| 69 | +are three different possibilities for specifying a threshold. They | ||
| 70 | +are toggled using the hidden usethres parameter: | ||
| 71 | + | ||
| 72 | +NONE: Use the emin and emax parameters to select an energy range. | ||
| 73 | + This is the default mode which is identical to the previous | ||
| 74 | + workings. The only difference is now that if the emin and/or | ||
| 75 | + emax parameter is set to 0.0, the threshold will be ignored. | ||
| 76 | + This allows to select all events above or below a given | ||
| 77 | + threshold. | ||
| 78 | + | ||
| 79 | +DEFAULT: Use the save threshold that is found in the effective | ||
| 80 | + area FITS header keywords LO_THRES and HI_THRES. If the | ||
| 81 | + emin and emax parameters are non-zero, they will provide | ||
| 82 | + an additional energy constraint. | ||
| 83 | + | ||
| 84 | +USER: Use the user specified threshold that are found in the | ||
| 85 | + XML observation definition file. If the emin and emax | ||
| 86 | + parameters are non-zero, they will provide an additional | ||
| 87 | + energy constraint. | ||
| 88 | + | ||
| 89 | +Note that any existing energy boundaries will be used as envelope, | ||
| 90 | +i.e. a wider energy threshold specification will have no effect. | ||
| 91 | + | ||
| 68 | 92 | ||
| 69 | 7. ctbin - CTA event binning | 93 | 7. ctbin - CTA event binning |
| 70 | ---------------------------- | 94 | ---------------------------- |
src/ctselect/ctselect.cpp
| @@ -36,6 +36,8 @@ | @@ -36,6 +36,8 @@ | ||
| 36 | #define G_RUN "ctselect::run()" | 36 | #define G_RUN "ctselect::run()" |
| 37 | #define G_SELECT_EVENTS "ctselect::select_events(GCTAObservation*, "\ | 37 | #define G_SELECT_EVENTS "ctselect::select_events(GCTAObservation*, "\ |
| 38 | "std::string&)" | 38 | "std::string&)" |
| 39 | +#define G_SET_EBOUNDS "ctselect::set_ebounds(GCTAObservation*, GEbounds&)" | ||
| 40 | +#define G_GET_PARAMETERS "ctselect::get_parameters()" | ||
| 39 | 41 | ||
| 40 | /* __ Debug definitions __________________________________________________ */ | 42 | /* __ Debug definitions __________________________________________________ */ |
| 41 | 43 | ||
| @@ -397,13 +399,14 @@ void ctselect::init_members(void) | @@ -397,13 +399,14 @@ void ctselect::init_members(void) | ||
| 397 | m_emin = 0.0; | 399 | m_emin = 0.0; |
| 398 | m_emax = 0.0; | 400 | m_emax = 0.0; |
| 399 | m_expr.clear(); | 401 | m_expr.clear(); |
| 402 | + m_usethres.clear(); | ||
| 400 | 403 | ||
| 401 | // Initialise protected members | 404 | // Initialise protected members |
| 402 | m_obs.clear(); | 405 | m_obs.clear(); |
| 403 | m_infiles.clear(); | 406 | m_infiles.clear(); |
| 404 | m_timemin.clear(); | 407 | m_timemin.clear(); |
| 405 | m_timemax.clear(); | 408 | m_timemax.clear(); |
| 406 | - m_use_xml = false; | 409 | + m_use_xml = false; |
| 407 | 410 | ||
| 408 | // Set CTA time reference. G_CTA_MJDREF is the CTA reference MJD, | 411 | // Set CTA time reference. G_CTA_MJDREF is the CTA reference MJD, |
| 409 | // which is defined in GCTALib.hpp. This is somehow a kluge. We need | 412 | // which is defined in GCTALib.hpp. This is somehow a kluge. We need |
| @@ -423,18 +426,19 @@ void ctselect::init_members(void) | @@ -423,18 +426,19 @@ void ctselect::init_members(void) | ||
| 423 | void ctselect::copy_members(const ctselect& app) | 426 | void ctselect::copy_members(const ctselect& app) |
| 424 | { | 427 | { |
| 425 | // Copy parameters | 428 | // Copy parameters |
| 426 | - m_infile = app.m_infile; | ||
| 427 | - m_outfile = app.m_outfile; | ||
| 428 | - m_prefix = app.m_prefix; | ||
| 429 | - m_usepnt = app.m_usepnt; | ||
| 430 | - m_ra = app.m_ra; | ||
| 431 | - m_dec = app.m_dec; | ||
| 432 | - m_rad = app.m_rad; | ||
| 433 | - m_tmin = app.m_tmin; | ||
| 434 | - m_tmax = app.m_tmax; | ||
| 435 | - m_emin = app.m_emin; | ||
| 436 | - m_emax = app.m_emax; | ||
| 437 | - m_expr = app.m_expr; | 429 | + m_infile = app.m_infile; |
| 430 | + m_outfile = app.m_outfile; | ||
| 431 | + m_prefix = app.m_prefix; | ||
| 432 | + m_usepnt = app.m_usepnt; | ||
| 433 | + m_ra = app.m_ra; | ||
| 434 | + m_dec = app.m_dec; | ||
| 435 | + m_rad = app.m_rad; | ||
| 436 | + m_tmin = app.m_tmin; | ||
| 437 | + m_tmax = app.m_tmax; | ||
| 438 | + m_emin = app.m_emin; | ||
| 439 | + m_emax = app.m_emax; | ||
| 440 | + m_expr = app.m_expr; | ||
| 441 | + m_usethres = app.m_usethres; | ||
| 438 | 442 | ||
| 439 | // Copy protected members | 443 | // Copy protected members |
| 440 | m_obs = app.m_obs; | 444 | m_obs = app.m_obs; |
| @@ -514,12 +518,21 @@ void ctselect::get_parameters(void) | @@ -514,12 +518,21 @@ void ctselect::get_parameters(void) | ||
| 514 | m_ra = (*this)["ra"].real(); | 518 | m_ra = (*this)["ra"].real(); |
| 515 | m_dec = (*this)["dec"].real(); | 519 | m_dec = (*this)["dec"].real(); |
| 516 | } | 520 | } |
| 517 | - m_rad = (*this)["rad"].real(); | ||
| 518 | - m_tmin = (*this)["tmin"].real(); | ||
| 519 | - m_tmax = (*this)["tmax"].real(); | ||
| 520 | - m_emin = (*this)["emin"].real(); | ||
| 521 | - m_emax = (*this)["emax"].real(); | ||
| 522 | - m_expr = (*this)["expr"].string(); | 521 | + m_rad = (*this)["rad"].real(); |
| 522 | + m_tmin = (*this)["tmin"].real(); | ||
| 523 | + m_tmax = (*this)["tmax"].real(); | ||
| 524 | + m_emin = (*this)["emin"].real(); | ||
| 525 | + m_emax = (*this)["emax"].real(); | ||
| 526 | + m_expr = (*this)["expr"].string(); | ||
| 527 | + m_usethres = (*this)["usethres"].string(); | ||
| 528 | + | ||
| 529 | + // Check parameters (Kluge as the parfile interface does not yet check | ||
| 530 | + // parameters; this can be removed once this is done properly) | ||
| 531 | + if (m_usethres != "NONE" && m_usethres != "DEFAULT" && m_usethres != "USER") { | ||
| 532 | + std::string msg = "Parameter \"usethres\" must be one of \"NONE\", " | ||
| 533 | + "\"DEFAULT\" or \"USER\"."; | ||
| 534 | + throw GException::invalid_value(G_GET_PARAMETERS, msg); | ||
| 535 | + } | ||
| 523 | 536 | ||
| 524 | // Optionally read ahead parameters so that they get correctly | 537 | // Optionally read ahead parameters so that they get correctly |
| 525 | // dumped into the log file | 538 | // dumped into the log file |
| @@ -569,16 +582,25 @@ void ctselect::select_events(GCTAObservation* obs, const std::string& filename) | @@ -569,16 +582,25 @@ void ctselect::select_events(GCTAObservation* obs, const std::string& filename) | ||
| 569 | // Initialise selection flags | 582 | // Initialise selection flags |
| 570 | bool remove_all = false; | 583 | bool remove_all = false; |
| 571 | 584 | ||
| 572 | - // Analyse task parameters to see what selections are required | 585 | + // Get CTA event list pointer |
| 586 | + GCTAEventList* list = | ||
| 587 | + static_cast<GCTAEventList*>(const_cast<GEvents*>(obs->events())); | ||
| 588 | + | ||
| 589 | + // Get energy boundaries | ||
| 590 | + double emin = 0.0; | ||
| 591 | + double emax = 0.0; | ||
| 592 | + GEbounds ebounds = set_ebounds(obs, list->ebounds()); | ||
| 593 | + if (ebounds.size() >= 1) { | ||
| 594 | + emin = ebounds.emin(0).TeV(); | ||
| 595 | + emax = ebounds.emax(0).TeV(); | ||
| 596 | + } | ||
| 597 | + | ||
| 598 | + // Analyse parameters to see what selections are required | ||
| 573 | bool select_time = (m_tmin != 0.0 || m_tmax != 0.0); | 599 | bool select_time = (m_tmin != 0.0 || m_tmax != 0.0); |
| 574 | - bool select_energy = true; | 600 | + bool select_energy = (emin != 0.0 || emax != 0.0); |
| 575 | bool select_roi = ((m_dec != -1.0 && m_ra != -1.0 && m_rad != -1.0) || m_usepnt); | 601 | bool select_roi = ((m_dec != -1.0 && m_ra != -1.0 && m_rad != -1.0) || m_usepnt); |
| 576 | bool select_expr = (gammalib::strip_whitespace(m_expr).length() > 0); | 602 | bool select_expr = (gammalib::strip_whitespace(m_expr).length() > 0); |
| 577 | 603 | ||
| 578 | - // Set energy selection | ||
| 579 | - double emin = m_emin; | ||
| 580 | - double emax = m_emax; | ||
| 581 | - | ||
| 582 | // Set RA/DEC selection. If the "usepnt" parameter is set to true then | 604 | // Set RA/DEC selection. If the "usepnt" parameter is set to true then |
| 583 | // use the pointing direction as the ROI centre. | 605 | // use the pointing direction as the ROI centre. |
| 584 | double ra = m_ra; | 606 | double ra = m_ra; |
| @@ -589,10 +611,6 @@ void ctselect::select_events(GCTAObservation* obs, const std::string& filename) | @@ -589,10 +611,6 @@ void ctselect::select_events(GCTAObservation* obs, const std::string& filename) | ||
| 589 | ra = pnt.dir().ra_deg(); | 611 | ra = pnt.dir().ra_deg(); |
| 590 | dec = pnt.dir().dec_deg(); | 612 | dec = pnt.dir().dec_deg(); |
| 591 | } | 613 | } |
| 592 | - | ||
| 593 | - // Get CTA event list pointer | ||
| 594 | - GCTAEventList* list = | ||
| 595 | - static_cast<GCTAEventList*>(const_cast<GEvents*>(obs->events())); | ||
| 596 | 614 | ||
| 597 | // Set time selection interval. We make sure here that the time selection | 615 | // Set time selection interval. We make sure here that the time selection |
| 598 | // interval cannot be wider than the GTIs covering the data. This is done | 616 | // interval cannot be wider than the GTIs covering the data. This is done |
| @@ -638,48 +656,58 @@ void ctselect::select_events(GCTAObservation* obs, const std::string& filename) | @@ -638,48 +656,58 @@ void ctselect::select_events(GCTAObservation* obs, const std::string& filename) | ||
| 638 | selection += " && "; | 656 | selection += " && "; |
| 639 | } | 657 | } |
| 640 | 658 | ||
| 641 | - // Log the requested energy range | 659 | + // Log the requested energy selection |
| 642 | if (logTerse()) { | 660 | if (logTerse()) { |
| 643 | - log << gammalib::parformat("Requested energy range"); | ||
| 644 | - log << m_emin << " - " << m_emax << " TeV" << std::endl; | ||
| 645 | - } | ||
| 646 | - | ||
| 647 | - // Set the energy boundaries. Make sure that they overlap with any | ||
| 648 | - // existing energy boundaries | ||
| 649 | - const GEbounds& ebounds = list->ebounds(); | ||
| 650 | - if (ebounds.size() >= 1) { | ||
| 651 | - if (logTerse()) { | ||
| 652 | - log << gammalib::parformat("Energy range of data"); | ||
| 653 | - log << ebounds.emin(0).TeV() << " - "; | ||
| 654 | - log << ebounds.emax(0).TeV() << " TeV" << std::endl; | 661 | + log << gammalib::parformat("Selected energy range"); |
| 662 | + if (emin > 0.0 && emax > 0.0) { | ||
| 663 | + if (emin >= emax) { | ||
| 664 | + log << "None. There is no overlap between existing "; | ||
| 665 | + log << "and requested energy range." << std::endl; | ||
| 666 | + } | ||
| 667 | + else { | ||
| 668 | + log << emin << " - " << emax << " TeV" << std::endl; | ||
| 669 | + } | ||
| 670 | + } | ||
| 671 | + else if (emin > 0.0) { | ||
| 672 | + log << "> " << emin << " TeV" << std::endl; | ||
| 655 | } | 673 | } |
| 656 | - if (emin < ebounds.emin(0).TeV()) { | ||
| 657 | - emin = ebounds.emin(0).TeV(); | 674 | + else if (emax > 0.0) { |
| 675 | + log << "< " << emax << " TeV" << std::endl; | ||
| 658 | } | 676 | } |
| 659 | - if (emax > ebounds.emax(0).TeV()) { | ||
| 660 | - emax = ebounds.emax(0).TeV(); | 677 | + else { |
| 678 | + log << "None" << std::endl; | ||
| 661 | } | 679 | } |
| 662 | } | 680 | } |
| 663 | 681 | ||
| 664 | - // Log the selected energy range | ||
| 665 | - if (logTerse()) { | ||
| 666 | - log << gammalib::parformat("Selected energy range"); | 682 | + // Apply the requested energy selection |
| 683 | + if (emin > 0.0 && emax > 0.0) { | ||
| 667 | if (emin >= emax) { | 684 | if (emin >= emax) { |
| 668 | - log << "None. There is no overlap between existing "; | ||
| 669 | - log << "and requested energy range." << std::endl; | 685 | + remove_all = true; |
| 670 | } | 686 | } |
| 671 | else { | 687 | else { |
| 672 | - log << emin << " - " << emax << " TeV" << std::endl; | 688 | + char cmin[80]; |
| 689 | + char cmax[80]; | ||
| 690 | + sprintf(cmin, "%.8f", emin); | ||
| 691 | + sprintf(cmax, "%.8f", emax); | ||
| 692 | + selection += "ENERGY >= "+std::string(cmin)+" && ENERGY <= "+ | ||
| 693 | + std::string(cmax); | ||
| 673 | } | 694 | } |
| 674 | } | 695 | } |
| 696 | + else if (emin > 0.0) { | ||
| 697 | + char cmin[80]; | ||
| 698 | + sprintf(cmin, "%.8f", emin); | ||
| 699 | + selection += "ENERGY >= "+std::string(cmin); | ||
| 700 | + } | ||
| 701 | + else if (emax > 0.0) { | ||
| 702 | + char cmax[80]; | ||
| 703 | + sprintf(cmax, "%.8f", emax); | ||
| 704 | + selection += "ENERGY <= "+std::string(cmax); | ||
| 705 | + } | ||
| 706 | + else { | ||
| 707 | + log << "None" << std::endl; | ||
| 708 | + remove_all = true; | ||
| 709 | + } | ||
| 675 | 710 | ||
| 676 | - // Format energy selection | ||
| 677 | - char cmin[80]; | ||
| 678 | - char cmax[80]; | ||
| 679 | - sprintf(cmin, "%.8f", emin); | ||
| 680 | - sprintf(cmax, "%.8f", emax); | ||
| 681 | - selection += "ENERGY >= "+std::string(cmin)+" && ENERGY <= "+std::string(cmax); | ||
| 682 | - | ||
| 683 | } // endif: made energy selection | 711 | } // endif: made energy selection |
| 684 | 712 | ||
| 685 | // Make ROI selection | 713 | // Make ROI selection |
| @@ -841,6 +869,137 @@ void ctselect::select_events(GCTAObservation* obs, const std::string& filename) | @@ -841,6 +869,137 @@ void ctselect::select_events(GCTAObservation* obs, const std::string& filename) | ||
| 841 | 869 | ||
| 842 | 870 | ||
| 843 | /***********************************************************************//** | 871 | /***********************************************************************//** |
| 872 | + * @brief Return energy boundaries for a given observation | ||
| 873 | + * | ||
| 874 | + * @param[in] obs Pointer to CTA observation. | ||
| 875 | + * @param[in] ebounds Current energy boundaries. | ||
| 876 | + * @return Energy boundaries. | ||
| 877 | + * | ||
| 878 | + * Returns the energy boundaries for a given observation. Depending on the | ||
| 879 | + * value of the usethres parameter, the following values will be | ||
| 880 | + * returned: | ||
| 881 | + * | ||
| 882 | + * NONE: [max(emin,emin_exist),min(emax,emax_exist)] | ||
| 883 | + * DEFAULT: [max(emin,emin_exist,emin_save),min(emax,emax_exist,emax_save)] | ||
| 884 | + * USER: [max(emin,emin_exist,emin_user),min(emax,emax_exist,emax_user)] | ||
| 885 | + * | ||
| 886 | + * where | ||
| 887 | + * | ||
| 888 | + * emin is the value of the emin parameter | ||
| 889 | + * emax is the value of the emax parameter | ||
| 890 | + * emin_exist is the value of any existing minimum boundary | ||
| 891 | + * emax_exist is the value of any existing maximum boundary | ||
| 892 | + * emin_save is the lower save threshold | ||
| 893 | + * emax_save is the upper save threshold | ||
| 894 | + * emin_user is the lower user threshold | ||
| 895 | + * emax_user is the upper user threshold | ||
| 896 | + * | ||
| 897 | + * Any threshold value of 0 will be ignored. | ||
| 898 | + ***************************************************************************/ | ||
| 899 | +GEbounds ctselect::set_ebounds(GCTAObservation* obs, const GEbounds& ebounds) const | ||
| 900 | +{ | ||
| 901 | + // Set emin and emax values from user parameters | ||
| 902 | + double emin = m_emin; | ||
| 903 | + double emax = m_emax; | ||
| 904 | + | ||
| 905 | + // Check if we have already energy boundaries | ||
| 906 | + if (ebounds.size() > 0) { | ||
| 907 | + | ||
| 908 | + // Raise minimum energy to lower boundary | ||
| 909 | + if ((emin == 0.0) || | ||
| 910 | + ((ebounds.emin(0).TeV() > 0.0) && (emin < ebounds.emin(0).TeV()))) { | ||
| 911 | + emin = ebounds.emin(0).TeV(); | ||
| 912 | + } | ||
| 913 | + | ||
| 914 | + // Lower maximum energy to upper boundary | ||
| 915 | + if ((emax == 0.0) || | ||
| 916 | + ((ebounds.emax(0).TeV() > 0.0) && (emax > ebounds.emax(0).TeV()))) { | ||
| 917 | + emax = ebounds.emax(0).TeV(); | ||
| 918 | + } | ||
| 919 | + | ||
| 920 | + } // endif: there were already energy boundaries | ||
| 921 | + | ||
| 922 | + // Check if default threshold (the one from the IRF, also known as save | ||
| 923 | + // threshold) should be applied | ||
| 924 | + if (m_usethres == "DEFAULT") { | ||
| 925 | + | ||
| 926 | + // Get CTA IRF respsonse pointer and throw exception if we don't | ||
| 927 | + // find IRF | ||
| 928 | + const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(obs->response()); | ||
| 929 | + if (rsp == NULL) { | ||
| 930 | + std::string msg = "No IRF response attached to given observation."; | ||
| 931 | + throw GException::invalid_value(G_SET_EBOUNDS, msg); | ||
| 932 | + } | ||
| 933 | + | ||
| 934 | + // Retrieve energy range from response information | ||
| 935 | + double lo_save_thres = rsp->lo_save_thres(); | ||
| 936 | + double hi_save_thres = rsp->hi_save_thres(); | ||
| 937 | + | ||
| 938 | + // Check threshold information for validity | ||
| 939 | + if ((lo_save_thres > 0.0) && | ||
| 940 | + (hi_save_thres > 0.0) && | ||
| 941 | + (lo_save_thres >= hi_save_thres)) { | ||
| 942 | + std::string msg = "IRF \""+obs->name()+"\" contains an invalid " | ||
| 943 | + "energy range ["+gammalib::str(lo_save_thres)+","+ | ||
| 944 | + gammalib::str(hi_save_thres)+"] TeV."; | ||
| 945 | + throw GException::invalid_value(G_SET_EBOUNDS, msg); | ||
| 946 | + } | ||
| 947 | + | ||
| 948 | + // Raise minimum energy to lower threshold (if lower threshold exists) | ||
| 949 | + if ((emin == 0.0) || | ||
| 950 | + ((lo_save_thres > 0.0) && (emin < lo_save_thres))) { | ||
| 951 | + emin = lo_save_thres; | ||
| 952 | + } | ||
| 953 | + | ||
| 954 | + // Lower maximum energy to upper threshold (if upper threshold exists) | ||
| 955 | + if ((emax == 0.0) || | ||
| 956 | + ((hi_save_thres > 0.0) && (emax > hi_save_thres))) { | ||
| 957 | + emax = hi_save_thres; | ||
| 958 | + } | ||
| 959 | + | ||
| 960 | + } //endif: usethres was "DEFAULT" | ||
| 961 | + | ||
| 962 | + // ... otherwise check if a user specified threshold should be applied | ||
| 963 | + else if (m_usethres == "USER") { | ||
| 964 | + | ||
| 965 | + // Retrieve thresholds from observation | ||
| 966 | + double lo_user_thres = obs->lo_user_thres(); | ||
| 967 | + double hi_user_thres = obs->hi_user_thres(); | ||
| 968 | + | ||
| 969 | + // Check threshold information for validity | ||
| 970 | + if ((lo_user_thres > 0.0) && | ||
| 971 | + (hi_user_thres > 0.0) && | ||
| 972 | + (lo_user_thres >= hi_user_thres)) { | ||
| 973 | + std::string msg = "User energy range ["+gammalib::str(lo_user_thres)+ | ||
| 974 | + ","+gammalib::str(hi_user_thres)+"] TeV is invalid."; | ||
| 975 | + throw GException::invalid_value(G_SET_EBOUNDS, msg); | ||
| 976 | + } | ||
| 977 | + | ||
| 978 | + // Raise minimum energy to lower threshold (if lower threshold exists) | ||
| 979 | + if ((emin == 0.0) || | ||
| 980 | + ((lo_user_thres > 0.0) && (emin < lo_user_thres))) { | ||
| 981 | + emin = lo_user_thres; | ||
| 982 | + } | ||
| 983 | + | ||
| 984 | + // Lower maximum energy to upper threshold (if upper threshold exists) | ||
| 985 | + if ((emax == 0.0) || | ||
| 986 | + ((hi_user_thres > 0.0) && (emax > hi_user_thres))) { | ||
| 987 | + emax = hi_user_thres; | ||
| 988 | + } | ||
| 989 | + | ||
| 990 | + } // endif: usethres was "USER | ||
| 991 | + | ||
| 992 | + // Set selection energy boundaries | ||
| 993 | + GEbounds result; | ||
| 994 | + result.append(GEnergy(emin, "TeV"), GEnergy(emax, "TeV")); | ||
| 995 | + | ||
| 996 | + // Return result | ||
| 997 | + return result; | ||
| 998 | + | ||
| 999 | +} | ||
| 1000 | + | ||
| 1001 | + | ||
| 1002 | +/***********************************************************************//** | ||
| 844 | * @brief Check input filename | 1003 | * @brief Check input filename |
| 845 | * | 1004 | * |
| 846 | * @param[in] filename File name. | 1005 | * @param[in] filename File name. |
| @@ -1060,4 +1219,3 @@ void ctselect::save_event_list(const GCTAObservation* obs, | @@ -1060,4 +1219,3 @@ void ctselect::save_event_list(const GCTAObservation* obs, | ||
| 1060 | // Return | 1219 | // Return |
| 1061 | return; | 1220 | return; |
| 1062 | } | 1221 | } |
| 1063 | - |
src/ctselect/ctselect.hpp
| @@ -71,6 +71,8 @@ protected: | @@ -71,6 +71,8 @@ protected: | ||
| 71 | void free_members(void); | 71 | void free_members(void); |
| 72 | void get_parameters(void); | 72 | void get_parameters(void); |
| 73 | void select_events(GCTAObservation* obs, const std::string& filename); | 73 | void select_events(GCTAObservation* obs, const std::string& filename); |
| 74 | + GEbounds set_ebounds(GCTAObservation* obs, | ||
| 75 | + const GEbounds& ebounds) const; | ||
| 74 | std::string check_infile(const std::string& filename) const; | 76 | std::string check_infile(const std::string& filename) const; |
| 75 | std::string set_outfile_name(const std::string& filename) const; | 77 | std::string set_outfile_name(const std::string& filename) const; |
| 76 | void save_fits(void); | 78 | void save_fits(void); |
| @@ -92,6 +94,7 @@ protected: | @@ -92,6 +94,7 @@ protected: | ||
| 92 | double m_emin; //!< Lower energy | 94 | double m_emin; //!< Lower energy |
| 93 | double m_emax; //!< Upper energy | 95 | double m_emax; //!< Upper energy |
| 94 | std::string m_expr; //!< Selection expression | 96 | std::string m_expr; //!< Selection expression |
| 97 | + std::string m_usethres; //!< Energy threshold type | ||
| 95 | 98 | ||
| 96 | // Protected members | 99 | // Protected members |
| 97 | GObservations m_obs; //!< Observations container | 100 | GObservations m_obs; //!< Observations container |
src/ctselect/ctselect.par
| @@ -23,15 +23,16 @@ prefix, s, h, "selected_",,,"Prefix for event lists in observation definition fi | @@ -23,15 +23,16 @@ prefix, s, h, "selected_",,,"Prefix for event lists in observation definition fi | ||
| 23 | # | 23 | # |
| 24 | # Selection parameters | 24 | # Selection parameters |
| 25 | #===================== | 25 | #===================== |
| 26 | -usepnt, b, h, no,,, "Use pointing instead of RA/DEC parameters?" | ||
| 27 | -ra, r, a, 83.63, 0,360, "RA for ROI centre (degrees)" | ||
| 28 | -dec, r, a, 22.01, -90, 90, "Dec for ROI centre (degrees)" | ||
| 29 | -rad, r, a, 3.0, 0,180, "Radius of ROI (degrees)" | ||
| 30 | -tmin, r, a, 0.0, 0, , "Start time (CTA MET in seconds)" | ||
| 31 | -tmax, r, a, 0.0, 0, , "End time (CTA MET in seconds)" | ||
| 32 | -emin, r, a, 0.1, 0, , "Lower energy limit (TeV)" | ||
| 33 | -emax, r, a, 100.0, 0, , "Upper energy limit (TeV)" | ||
| 34 | -expr, s, h, "", , , "Additional selection expression" | 26 | +usepnt, b, h, no,,, "Use pointing instead of RA/DEC parameters?" |
| 27 | +ra, r, a, 83.63, 0,360, "RA for ROI centre (degrees)" | ||
| 28 | +dec, r, a, 22.01, -90, 90, "Dec for ROI centre (degrees)" | ||
| 29 | +rad, r, a, 3.0, 0,180, "Radius of ROI (degrees)" | ||
| 30 | +tmin, r, a, 0.0, 0, , "Start time (CTA MET in seconds)" | ||
| 31 | +tmax, r, a, 0.0, 0, , "End time (CTA MET in seconds)" | ||
| 32 | +emin, r, a, 0.1, 0, , "Lower energy limit (TeV)" | ||
| 33 | +emax, r, a, 100.0, 0, , "Upper energy limit (TeV)" | ||
| 34 | +expr, s, h, "", , , "Additional selection expression" | ||
| 35 | +usethres,s, h,"NONE",NONE|DEFAULT|USER,,"Energy threshold type (NONE|DEFAULT|USER)" | ||
| 35 | # | 36 | # |
| 36 | # Standard parameters | 37 | # Standard parameters |
| 37 | #==================== | 38 | #==================== |