00001 #ifndef DataFormats_EventHypothesis_interface_EventHypothesis_h
00002 #define DataFormats_EventHypothesis_interface_EventHypothesis_h
00003
00004 #include "DataFormats/Candidate/interface/CandidateFwd.h"
00005 #include "DataFormats/Candidate/interface/Candidate.h"
00006 #include <boost/regex.hpp>
00007 #include <boost/shared_ptr.hpp>
00008
00009 namespace pat {
00010
00011 namespace eventhypothesis { template<typename T> struct Looper; }
00012
00013 namespace eventhypothesis {
00014
00015 typedef reco::CandidatePtr CandRefType;
00016
00017 struct ParticleFilter {
00018 virtual ~ParticleFilter() {}
00019 bool operator()(const std::pair<std::string, CandRefType> &p) const { return operator()(p.second, p.first); }
00020 virtual bool operator()(const CandRefType &cand, const std::string &role) const = 0;
00021 };
00022
00023 typedef boost::shared_ptr<const ParticleFilter> ParticleFilterPtr;
00024 }
00025
00026 class EventHypothesis {
00027 public:
00028 typedef eventhypothesis::CandRefType CandRefType;
00029 typedef std::pair<std::string, CandRefType> value_type;
00030 typedef std::vector<value_type> vector_type;
00031 typedef vector_type::const_iterator const_iterator;
00032 typedef vector_type::const_reverse_iterator const_reverse_iterator;
00033 typedef eventhypothesis::Looper<reco::Candidate> CandLooper;
00034
00035 void add(const CandRefType &ref, const std::string &role) ;
00036
00037 const_iterator begin() const { return particles_.begin(); }
00038 const_iterator end() const { return particles_.end(); }
00039 const_reverse_iterator rbegin() const { return particles_.rbegin(); }
00040 const_reverse_iterator rend() const { return particles_.rend(); }
00041
00042 class ByRole {
00043 public:
00044 ByRole(const std::string &role) : role_(role) {}
00045 bool operator()(const value_type &p) const { return p.first == role_; }
00046 private:
00047 const std::string &role_;
00048 };
00049
00050 typedef eventhypothesis::ParticleFilter ParticleFilter;
00051 typedef eventhypothesis::ParticleFilterPtr ParticleFilterPtr;
00052
00053 const CandRefType & get(const std::string &role, int index=0) const ;
00054 const CandRefType & get(const ParticleFilter &filter, int index=0) const ;
00055 template<typename T> const T * getAs(const std::string &role, int index=0) const ;
00056 template<typename T> const T * getAs(const ParticleFilter &filter, int index=0) const ;
00057 const CandRefType & operator[](const std::string &role) const { return get(role,0); }
00058 const CandRefType & operator[](const ParticleFilter &filter) const { return get(filter,0); }
00059
00061 std::vector<CandRefType> all(const std::string &roleRegexp) const;
00063 std::vector<CandRefType> all(const ParticleFilter &filter) const;
00064
00065 size_t count() const { return particles_.size(); }
00067 size_t count(const std::string &roleRegexp) const;
00069 size_t count(const ParticleFilter &role) const;
00070
00072 CandLooper loop() const ;
00074 CandLooper loop(const std::string &roleRegexp) const;
00077 CandLooper loop(const ParticleFilter &filter) const;
00081 CandLooper loop(const ParticleFilter *filter) const;
00083 CandLooper loop(const ParticleFilterPtr &filter) const;
00084
00085
00086
00088 template<typename T> eventhypothesis::Looper<T> loopAs(const std::string &roleRegexp) const ;
00091 template<typename T> eventhypothesis::Looper<T> loopAs(const ParticleFilter &filter) const;
00095 template<typename T> eventhypothesis::Looper<T> loopAs(const ParticleFilter *filter) const;
00097 template<typename T> eventhypothesis::Looper<T> loopAs(const ParticleFilterPtr &filter) const;
00098 private:
00099 template<typename Iterator, typename Predicate>
00100 Iterator realGet(const Iterator &realBegin, const Iterator &realEnd, const Predicate &p, size_t idx) const ;
00101
00102 std::vector<value_type> particles_;
00103
00104 } ;
00105
00106 namespace eventhypothesis {
00107 struct AcceptAllFilter : public ParticleFilter {
00108 static const AcceptAllFilter & get() { static AcceptAllFilter dummyFilter; return dummyFilter; }
00109 virtual bool operator()(const CandRefType &cand, const std::string &role) const { return true; }
00110 };
00111 class RoleRegexpFilter : public ParticleFilter {
00112 public:
00113 explicit RoleRegexpFilter(const std::string &roleRegexp) : re_(roleRegexp) {}
00114 virtual bool operator()(const CandRefType &cand, const std::string &role) const {
00115 return boost::regex_match(role, re_);
00116 }
00117 private:
00118 boost::regex re_;
00119 };
00120 }
00121
00122 template<typename Iterator, typename Predicate>
00123 Iterator EventHypothesis::realGet(const Iterator &realBegin, const Iterator &realEnd, const Predicate &pred, size_t idx) const
00124 {
00125 Iterator it = realBegin;
00126 while (it != realEnd) {
00127 if (pred(*it)) {
00128 if (idx == 0) return it;
00129 idx--;
00130 }
00131 ++it;
00132 }
00133 return it;
00134 }
00135
00136 template<typename T>
00137 const T *
00138 EventHypothesis::getAs(const std::string &role, int index) const
00139 {
00140 CandRefType ref = get(role, index);
00141 const T* ret = dynamic_cast<const T*>(ref.get());
00142 if ((ret == 0) && (ref.get() != 0)) throw cms::Exception("Type Checking") <<
00143 "You can't convert a " << typeid(*ref).name() << " to a " << typeid(T).name() << "\n" <<
00144 "note: you can use c++filt command to convert the above in human readable types.\n";
00145 return ret;
00146 }
00147 template<typename T>
00148 const T *
00149 EventHypothesis::getAs(const ParticleFilter &filter, int index) const
00150 {
00151 CandRefType ref = get(filter, index);
00152 const T* ret = dynamic_cast<const T*>(ref.get());
00153 if ((ret == 0) && (ref.get() != 0)) throw cms::Exception("Type Checking") <<
00154 "You can't convert a " << typeid(*ref).name() << " to a " << typeid(T).name() << "\n" <<
00155 "note: you can use c++filt command to convert the above in human readable types.\n";
00156 return ret;
00157 }
00158 template<typename T>
00159 eventhypothesis::Looper<T>
00160 EventHypothesis::loopAs(const std::string &roleRegexp) const
00161 {
00162 return loopAs<T>(new pat::eventhypothesis::RoleRegexpFilter(roleRegexp));
00163 }
00164
00165 template<typename T>
00166 eventhypothesis::Looper<T>
00167 EventHypothesis::loopAs(const ParticleFilter &role) const
00168 {
00169 return pat::eventhypothesis::Looper<T>(*this, role);
00170 }
00171
00172 template<typename T>
00173 eventhypothesis::Looper<T>
00174 EventHypothesis::loopAs(const ParticleFilter *role) const
00175 {
00176 return pat::eventhypothesis::Looper<T>(*this, role);
00177 }
00178
00179 template<typename T>
00180 eventhypothesis::Looper<T>
00181 EventHypothesis::loopAs(const ParticleFilterPtr &role) const
00182 {
00183 return pat::eventhypothesis::Looper<T>(*this, role);
00184 }
00185 }
00186
00187 #endif