Commit 272721f91ca423df0bcec0fd0bc8808fb5e9f76a

Authored by Jürgen Knödlseder
1 parent 8e535189

Integrate code.

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 3 * Version 0.8.0 released
4 4 ========================
... ... @@ -17,6 +17,7 @@
17 17 ctmodel now always creates a single model cube
18 18 Support energy dispersion in ctobssim, ctlike and ctmodel
19 19 Correct ctobssim for thread safety
  20 + Support save and user energy thresholds in ctselect
20 21 Correctly apply time references in ctselect
21 22 Reduce memory usage
22 23 Move obsutils to ctools namespace
... ...
... ... @@ -2,7 +2,7 @@ New Features and Important Changes in ctools 00-08-00
2 2  
3 3 Author(s) : Juergen Knoedlseder
4 4  
5   -30 October 2014
  5 +8 November 2014
6 6  
7 7  
8 8 1. Introduction
... ... @@ -65,6 +65,30 @@ tmin and tmax parameters are given in CTA reference time, they are
65 65 internally converted to the reference time of the GTI before event
66 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 93 7. ctbin - CTA event binning
70 94 ----------------------------
... ...
src/ctselect/ctselect.cpp
... ... @@ -36,9 +36,8 @@
36 36 #define G_RUN "ctselect::run()"
37 37 #define G_SELECT_EVENTS "ctselect::select_events(GCTAObservation*, "\
38 38 "std::string&)"
39   -#define G_FIND_EBOUNDS "ctselect::find_ebounds(GCTAObservation*, "\
40   - "GEbounds&)"
41   -#define G_GET_PARAMETERS "ctselect::get_parameters()"
  39 +#define G_SET_EBOUNDS "ctselect::set_ebounds(GCTAObservation*, GEbounds&)"
  40 +#define G_GET_PARAMETERS "ctselect::get_parameters()"
42 41  
43 42 /* __ Debug definitions __________________________________________________ */
44 43  
... ... @@ -299,7 +298,6 @@ void ctselect::run(void)
299 298 // Load observation from temporary file, including event selection
300 299 select_events(obs, filename);
301 300  
302   -
303 301 // Close temporary file
304 302 #if G_USE_MKSTEMP
305 303 close(fileid);
... ... @@ -408,7 +406,7 @@ void ctselect::init_members(void)
408 406 m_infiles.clear();
409 407 m_timemin.clear();
410 408 m_timemax.clear();
411   - m_use_xml = false;
  409 + m_use_xml = false;
412 410  
413 411 // Set CTA time reference. G_CTA_MJDREF is the CTA reference MJD,
414 412 // which is defined in GCTALib.hpp. This is somehow a kluge. We need
... ... @@ -428,18 +426,18 @@ void ctselect::init_members(void)
428 426 void ctselect::copy_members(const ctselect& app)
429 427 {
430 428 // Copy parameters
431   - m_infile = app.m_infile;
432   - m_outfile = app.m_outfile;
433   - m_prefix = app.m_prefix;
434   - m_usepnt = app.m_usepnt;
435   - m_ra = app.m_ra;
436   - m_dec = app.m_dec;
437   - m_rad = app.m_rad;
438   - m_tmin = app.m_tmin;
439   - m_tmax = app.m_tmax;
440   - m_emin = app.m_emin;
441   - m_emax = app.m_emax;
442   - 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;
443 441 m_usethres = app.m_usethres;
444 442  
445 443 // Copy protected members
... ... @@ -520,15 +518,19 @@ void ctselect::get_parameters(void)
520 518 m_ra = (*this)["ra"].real();
521 519 m_dec = (*this)["dec"].real();
522 520 }
523   - m_rad = (*this)["rad"].real();
524   - m_tmin = (*this)["tmin"].real();
525   - m_tmax = (*this)["tmax"].real();
526   - m_emin = (*this)["emin"].real();
527   - m_emax = (*this)["emax"].real();
528   - 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();
529 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)
530 531 if (m_usethres != "NONE" && m_usethres != "DEFAULT" && m_usethres != "USER") {
531   - std::string msg = "Parameter \"usethres\" must be one of \"NONE\", \"DEFAULT\" or \"USER\"";
  532 + std::string msg = "Parameter \"usethres\" must be one of \"NONE\", "
  533 + "\"DEFAULT\" or \"USER\".";
532 534 throw GException::invalid_value(G_GET_PARAMETERS, msg);
533 535 }
534 536  
... ... @@ -574,23 +576,31 @@ void ctselect::get_parameters(void)
574 576 ***************************************************************************/
575 577 void ctselect::select_events(GCTAObservation* obs, const std::string& filename)
576 578 {
577   -
578 579 // Initialise selection string
579 580 std::string selection;
580 581  
581 582 // Initialise selection flags
582 583 bool remove_all = false;
583 584  
584   - // 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
585 599 bool select_time = (m_tmin != 0.0 || m_tmax != 0.0);
586   - bool select_energy = true;
  600 + bool select_energy = (emin != 0.0 || emax != 0.0);
587 601 bool select_roi = ((m_dec != -1.0 && m_ra != -1.0 && m_rad != -1.0) || m_usepnt);
588 602 bool select_expr = (gammalib::strip_whitespace(m_expr).length() > 0);
589 603  
590   - // Set energy selection
591   - double emin = m_emin;
592   - double emax = m_emax;
593   -
594 604 // Set RA/DEC selection. If the "usepnt" parameter is set to true then
595 605 // use the pointing direction as the ROI centre.
596 606 double ra = m_ra;
... ... @@ -601,10 +611,6 @@ void ctselect::select_events(GCTAObservation* obs, const std::string&amp; filename)
601 611 ra = pnt.dir().ra_deg();
602 612 dec = pnt.dir().dec_deg();
603 613 }
604   -
605   - // Get CTA event list pointer
606   - GCTAEventList* list =
607   - static_cast<GCTAEventList*>(const_cast<GEvents*>(obs->events()));
608 614  
609 615 // Set time selection interval. We make sure here that the time selection
610 616 // interval cannot be wider than the GTIs covering the data. This is done
... ... @@ -650,55 +656,58 @@ void ctselect::select_events(GCTAObservation* obs, const std::string&amp; filename)
650 656 selection += " && ";
651 657 }
652 658  
653   - // Log the requested energy range
  659 + // Log the requested energy selection
654 660 if (logTerse()) {
655   - log << gammalib::parformat("Requested energy range");
656   - log << m_emin << " - " << m_emax << " TeV" << std::endl;
657   - }
658   -
659   - // Set the energy boundaries. Make sure that they overlap with any
660   - // existing energy boundaries
661   -
662   - // Find the energy boundaries, taking into account any previous selections
663   - // and also user or default energy thresholds
664   - GEbounds ebounds = find_ebounds(obs,list->ebounds());
665   -
666   - // Check if energy bounds are valid
667   - if (ebounds.size() >= 1) {
668   -
669   - // Write ebounds to log
670   - if (logTerse()) {
671   - log << emin << " - " << emax << " TeV" << std::endl;
672   - }
673   -
674   - // Set emin and emax values
675   - emin = ebounds.emin(0).TeV();
676   - emax = ebounds.emax(0).TeV();
677   -
678   - } //endif: ebounds were valid
679   -
680   - else {
681   -
682   - // Write log that energy range is not existent
683   - if (logTerse()) {
684   - log << gammalib::parformat("Selected energy range");
  661 + log << gammalib::parformat("Selected energy range");
  662 + if (emin > 0.0 && emax > 0.0) {
685 663 if (emin >= emax) {
686 664 log << "None. There is no overlap between existing ";
687 665 log << "and requested energy range." << std::endl;
688 666 }
  667 + else {
  668 + log << emin << " - " << emax << " TeV" << std::endl;
  669 + }
  670 + }
  671 + else if (emin > 0.0) {
  672 + log << "> " << emin << " TeV" << std::endl;
  673 + }
  674 + else if (emax > 0.0) {
  675 + log << "< " << emax << " TeV" << std::endl;
689 676 }
  677 + else {
  678 + log << "None" << std::endl;
  679 + }
  680 + }
690 681  
691   - // Signal to remove all events
  682 + // Apply the requested energy selection
  683 + if (emin > 0.0 && emax > 0.0) {
  684 + if (emin >= emax) {
  685 + remove_all = true;
  686 + }
  687 + else {
  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);
  694 + }
  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;
692 708 remove_all = true;
693 709 }
694 710  
695   - // Format energy selection
696   - char cmin[80];
697   - char cmax[80];
698   - sprintf(cmin, "%.8f", emin);
699   - sprintf(cmax, "%.8f", emax);
700   - selection += "ENERGY >= "+std::string(cmin)+" && ENERGY <= "+std::string(cmax);
701   -
702 711 } // endif: made energy selection
703 712  
704 713 // Make ROI selection
... ... @@ -860,6 +869,137 @@ void ctselect::select_events(GCTAObservation* obs, const std::string&amp; filename)
860 869  
861 870  
862 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 +/***********************************************************************//**
863 1003 * @brief Check input filename
864 1004 *
865 1005 * @param[in] filename File name.
... ... @@ -1079,87 +1219,3 @@ void ctselect::save_event_list(const GCTAObservation* obs,
1079 1219 // Return
1080 1220 return;
1081 1221 }
1082   -
1083   -GEbounds ctselect::find_ebounds(GCTAObservation* obs, const GEbounds& list_ebounds) const
1084   -{
1085   - // Initialise ebounds
1086   - GEbounds ebounds;
1087   -
1088   - // Set emin and emax values from user parameters
1089   - double emin = m_emin;
1090   - double emax = m_emax;
1091   -
1092   - // Check if list already has ebounds
1093   - if (list_ebounds.size() >= 1) {
1094   -
1095   - // Make sure the user parameters don't condradict previous selections
1096   - if (emin < list_ebounds.emin(0).TeV()) {
1097   - emin = list_ebounds.emin(0).TeV();
1098   - }
1099   - if (emax > list_ebounds.emax(0).TeV()) {
1100   - emax = list_ebounds.emax(0).TeV();
1101   - }
1102   - } //endif: ebounds were valid
1103   -
1104   - // Check if threshold should be applied on default
1105   - if (m_usethres == "DEFAULT") {
1106   -
1107   - // Get CTA IRF respsonse pointer and throw exception
1108   - // if we don't find IRF
1109   - GCTAResponseIrf* rsp = static_cast<GCTAResponseIrf*>(const_cast<GCTAResponse*>(obs->response()));
1110   - if (rsp == NULL) {
1111   - std::string msg = "No IRF response attached to given observation";
1112   - throw GException::invalid_value(G_FIND_EBOUNDS, msg);
1113   - }
1114   -
1115   - // retrieve energy range from response information
1116   - double lo_save_thres = rsp->lo_save_thres();
1117   - double hi_save_thres = rsp->hi_save_thres();
1118   -
1119   - // Check threshold information for validity
1120   - // throw exception if not valid
1121   - if (lo_save_thres >= hi_save_thres){
1122   - std::string msg = "Energy range provided by response from \""+obs->name()+"\" not valid";
1123   - throw GException::invalid_value(G_FIND_EBOUNDS, msg);
1124   - }
1125   -
1126   - // Overwrite energy threshold definitions if necessary
1127   - if (emin < lo_save_thres) {
1128   - emin = lo_save_thres;
1129   - }
1130   - if (emax > hi_save_thres) {
1131   - emax = hi_save_thres;
1132   - }
1133   -
1134   - } //endif: m_usethres was "DEFAULT"
1135   -
1136   - else if (m_usethres == "USER") {
1137   -
1138   - // Retrieve parameters from observation
1139   - // these should have been set via the xml file
1140   - double lo_user_thres = obs->lo_user_thres();
1141   - double hi_user_thres = obs->hi_user_thres();
1142   -
1143   - // Check provided energy range for validity
1144   - if (lo_user_thres >= hi_user_thres) {
1145   - std::string msg = "User defined energy range which is provided in observation \""+obs->name()+"\" not valid";
1146   - throw GException::invalid_value(G_FIND_EBOUNDS, msg);
1147   - }
1148   -
1149   - // Overwrite energy range definition if necessary
1150   - if (emin < lo_user_thres) {
1151   - emin = lo_user_thres;
1152   - }
1153   - if (emax > hi_user_thres) {
1154   - emax = hi_user_thres;
1155   - }
1156   -
1157   - } // endif: usethres was "USER
1158   -
1159   - // set ebounds for selection
1160   - ebounds.append(GEnergy(emin, "TeV"), GEnergy(emax, "TeV"));
1161   -
1162   - // Return ebounds
1163   - return ebounds;
1164   -
1165   -}
... ...
src/ctselect/ctselect.hpp
... ... @@ -71,6 +71,8 @@ protected:
71 71 void free_members(void);
72 72 void get_parameters(void);
73 73 void select_events(GCTAObservation* obs, const std::string& filename);
  74 + GEbounds set_ebounds(GCTAObservation* obs,
  75 + const GEbounds& ebounds) const;
74 76 std::string check_infile(const std::string& filename) const;
75 77 std::string set_outfile_name(const std::string& filename) const;
76 78 void save_fits(void);
... ... @@ -78,7 +80,6 @@ protected:
78 80 void save_event_list(const GCTAObservation* obs,
79 81 const std::string& infile,
80 82 const std::string& outfile) const;
81   - GEbounds find_ebounds(GCTAObservation* obs, const GEbounds& list_ebounds) const;
82 83  
83 84 // User parameters
84 85 std::string m_infile; //!< Input event list or XML file
... ... @@ -93,7 +94,7 @@ protected:
93 94 double m_emin; //!< Lower energy
94 95 double m_emax; //!< Upper energy
95 96 std::string m_expr; //!< Selection expression
96   - std::string m_usethres;//!<Choice of energy threshold usage
  97 + std::string m_usethres; //!< Energy threshold type
97 98  
98 99 // Protected members
99 100 GObservations m_obs; //!< Observations container
... ...
src/ctselect/ctselect.par
... ... @@ -23,16 +23,16 @@ prefix, s, h, &quot;selected_&quot;,,,&quot;Prefix for event lists in observation definition fi
23 23 #
24 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"
35   -usethres,s,h,"NONE",NONE|DEFAULT|USER, ,"Threshold applying algorithm"
  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)"
36 36 #
37 37 # Standard parameters
38 38 #====================
... ...