00001 #ifndef PhysicsTools_SelectorUtils_Selector_h
00002 #define PhysicsTools_SelectorUtils_Selector_h
00003
00017 #include "PhysicsTools/SelectorUtils/interface/strbitset.h"
00018 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00019 #include "FWCore/Common/interface/EventBase.h"
00020 #include <fstream>
00021 #include <functional>
00022
00024 template<class T>
00025 class Selector : public std::binary_function<T, pat::strbitset, bool> {
00026
00027 public:
00028 typedef T data_type;
00029 typedef std::binary_function<T,pat::strbitset,bool> base_type;
00030 typedef pat::strbitset::index_type index_type;
00031 typedef std::pair<index_type, size_t> cut_flow_item;
00032 typedef std::vector<cut_flow_item> cut_flow_map;
00033 typedef std::map<index_type, int> int_map;
00034 typedef std::map<index_type, double> double_map;
00035
00037 Selector( ) {
00038 bits_.clear();
00039 intCuts_.clear();
00040 doubleCuts_.clear();
00041 cutFlow_.clear();
00042 retInternal_ = getBitTemplate();
00043 }
00044 virtual ~Selector() {}
00045
00047 virtual void push_back( std::string const & s) {
00048 bits_.push_back(s);
00049 index_type i(&bits_,s);
00050
00051
00052 cutFlow_.push_back( cut_flow_item(i, 0) );
00053 }
00054
00055
00057 virtual void push_back( std::string const & s, int cut) {
00058 bits_.push_back(s);
00059 index_type i(&bits_,s);
00060 intCuts_[i] = cut;
00061
00062
00063 cutFlow_.push_back( cut_flow_item(i,0) );
00064 }
00065
00067 virtual void push_back( std::string const & s, double cut) {
00068 bits_.push_back(s);
00069 index_type i(&bits_,s);
00070 doubleCuts_[i] = cut;
00071
00072
00073 cutFlow_.push_back( cut_flow_item(i,0) );
00074 }
00075
00077 virtual bool operator()( T const & t, pat::strbitset & ret ) = 0;
00078
00080 virtual bool operator()( T const & t )
00081 {
00082 retInternal_.set(false);
00083 operator()(t, retInternal_);
00084 setIgnored(retInternal_);
00085 return (bool)retInternal_;
00086 }
00087
00088
00090 virtual bool operator()( T const & t, edm::EventBase const & e, pat::strbitset & ret)
00091 {
00092 return operator()(t, ret);
00093 }
00094
00096 virtual bool operator()( T const & t, edm::EventBase const & e)
00097 {
00098 retInternal_.set(false);
00099 operator()(t, e, retInternal_);
00100 setIgnored(retInternal_);
00101 return (bool)retInternal_;
00102 }
00103
00104
00106 void set(std::string const & s, bool val = true) {
00107 set( index_type(&bits_,s), val);
00108 }
00109 void set(index_type const & i, bool val = true) {
00110 bits_[i] = val;
00111 }
00112
00114 void set(std::string const & s, int cut, bool val = true) {
00115 set( index_type(&bits_,s), cut);
00116 }
00117 void set(index_type const & i, int cut, bool val = true) {
00118 bits_[i] = val;
00119 intCuts_[i] = cut;
00120 }
00121
00123 void set(std::string const & s, double cut, bool val = true) {
00124 set( index_type(&bits_,s), cut);
00125 }
00126 void set(index_type const & i, double cut, bool val = true) {
00127 bits_[i] = val;
00128 doubleCuts_[i] = cut;
00129 }
00130
00132 void clear(std::string const & s) {
00133 clear(index_type(&bits_,s));
00134 }
00135
00136 void clear(index_type const & i) {
00137 bits_[i] = false;
00138 }
00139
00143 bool operator[] ( std::string const & s ) const {
00144 return bits_[s];
00145 }
00146
00147 bool operator[] ( index_type const & i ) const {
00148 return bits_[i];
00149 }
00150
00152 bool considerCut( std::string const & s ) const {
00153 return bits_[s] == true;
00154 }
00155 bool considerCut( index_type const & i ) const {
00156 return bits_[i] == true;
00157 }
00158
00160 bool ignoreCut( std::string const & s ) const {
00161 return bits_[s] == false;
00162 }
00163 bool ignoreCut( index_type const & i ) const {
00164 return bits_[i] == false;
00165 }
00166
00168 void setIgnoredCuts( std::vector<std::string> const & bitsToIgnore ) {
00169 for ( std::vector<std::string>::const_iterator ignoreBegin = bitsToIgnore.begin(),
00170 ignoreEnd = bitsToIgnore.end(), ibit = ignoreBegin;
00171 ibit != ignoreEnd; ++ibit ) {
00172 set(*ibit, false );
00173 }
00174 }
00175
00177 void passCut( pat::strbitset & ret, std::string const & s ) {
00178 passCut( ret, index_type(&bits_,s));
00179 }
00180
00181 void passCut( pat::strbitset & ret, index_type const & i ) {
00182 ret[i] = true;
00183 cut_flow_map::iterator found = cutFlow_.end();
00184 for ( cut_flow_map::iterator cutsBegin = cutFlow_.begin(),
00185 cutsEnd = cutFlow_.end(), icut = cutsBegin;
00186 icut != cutsEnd && found == cutsEnd; ++icut ) {
00187 if ( icut->first == i ) {
00188 found = icut;
00189 }
00190 }
00191 ++(found->second);
00192 }
00193
00195 int cut( index_type const & i, int val ) const {
00196 return intCuts_.find( i )->second;
00197 };
00199 double cut( index_type const & i, double val ) const {
00200 return doubleCuts_.find( i )->second;
00201 };
00202
00204 int cut( std::string s, int val ) const {
00205 return cut( index_type(&bits_,s), val);
00206 };
00208 double cut( std::string s, double val ) const {
00209 return cut( index_type(&bits_,s), val);
00210 };
00211
00213 pat::strbitset getBitTemplate() const {
00214 pat::strbitset ret = bits_;
00215 ret.set(false);
00216 for ( cut_flow_map::const_iterator cutsBegin = cutFlow_.begin(),
00217 cutsEnd = cutFlow_.end(), icut = cutsBegin;
00218 icut != cutsEnd; ++icut ) {
00219 if ( ignoreCut(icut->first) ) ret[icut->first] = true;
00220 }
00221 return ret;
00222 }
00223
00225 void setIgnored( pat::strbitset & ret ) {
00226 for ( cut_flow_map::const_iterator cutsBegin = cutFlow_.begin(),
00227 cutsEnd = cutFlow_.end(), icut = cutsBegin;
00228 icut != cutsEnd; ++icut ) {
00229 if ( ignoreCut(icut->first) ) ret[icut->first] = true;
00230 }
00231 }
00232
00234 void print(std::ostream & out) const {
00235 for ( cut_flow_map::const_iterator cutsBegin = cutFlow_.begin(),
00236 cutsEnd = cutFlow_.end(), icut = cutsBegin;
00237 icut != cutsEnd; ++icut ) {
00238 char buff[1000];
00239 if ( considerCut( icut->first ) ) {
00240 sprintf(buff, "%6lu : %20s %10lu",
00241 static_cast<unsigned long>(icut - cutsBegin),
00242 icut->first.str().c_str(),
00243 static_cast<unsigned long>(icut->second) );
00244 } else {
00245 sprintf(buff, "%6lu : %20s %10s",
00246 static_cast<unsigned long>(icut - cutsBegin),
00247 icut->first.str().c_str(),
00248 "off" );
00249 }
00250 out << buff << std::endl;
00251 }
00252 }
00253
00255 void printActiveCuts(std::ostream & out) const {
00256 bool already_printed_one = false;
00257 for ( cut_flow_map::const_iterator cutsBegin = cutFlow_.begin(),
00258 cutsEnd = cutFlow_.end(), icut = cutsBegin;
00259 icut != cutsEnd; ++icut ) {
00260 if ( considerCut( icut->first ) ) {
00261 if( already_printed_one ) out << ", ";
00262 out << icut->first;
00263 already_printed_one = true;
00264 }
00265 }
00266 out << std::endl;
00267 }
00268
00270 double getPasses( std::string const & s ) const {
00271 return getPasses( index_type(&bits_,s) );
00272 }
00273 double getPasses( index_type const &i ) const {
00274 cut_flow_map::iterator found = cutFlow_.end();
00275 for ( cut_flow_map::iterator cutsBegin = cutFlow_.begin(),
00276 cutsEnd = cutFlow_.end(), icut = cutsBegin;
00277 icut != cutsEnd && found == cutsEnd; ++icut ) {
00278 if ( icut->first == i ) {
00279 found = icut;
00280 }
00281 }
00282 return found->second;
00283 }
00284
00285
00286 protected:
00287 pat::strbitset bits_;
00288 pat::strbitset retInternal_;
00289 int_map intCuts_;
00290 double_map doubleCuts_;
00291 cut_flow_map cutFlow_;
00292 };
00293
00294 #endif