00001 #ifndef RecoCandidate_IsoDeposit_H
00002 #define RecoCandidate_IsoDeposit_H
00003
00018 #include "DataFormats/RecoCandidate/interface/IsoDepositDirection.h"
00019 #include "DataFormats/Math/interface/Vector3D.h"
00020 #include "FWCore/Utilities/interface/Exception.h"
00021 #include <map>
00022 #include <cmath>
00023 #include <string>
00024 #include <vector>
00025 #include <typeinfo>
00026
00027 namespace reco {
00028 namespace isodeposit {
00029 struct AbsVeto {
00030 virtual ~AbsVeto() { }
00032 virtual bool veto(double eta, double phi, float value) const = 0;
00035 virtual void centerOn(double eta, double phi) {
00036 throw cms::Exception("Not Implemented") << "This AbsVeto implementation (" << typeid(this).name() << ") does not support the centerOn(eta,phi) method";
00037 }
00038 };
00039 typedef std::vector<AbsVeto*> AbsVetos;
00040 }
00041 }
00042
00043 namespace reco {
00044
00045 class IsoDeposit {
00046 public:
00047
00048 typedef isodeposit::Direction Direction;
00049 typedef isodeposit::AbsVeto AbsVeto;
00050 typedef isodeposit::AbsVetos AbsVetos;
00051
00052
00053 struct Veto {
00054 Direction vetoDir; float dR;
00055 Veto() {}
00056 Veto(Direction dir, double d):vetoDir(dir), dR(d) {}
00057 };
00058 typedef std::vector<Veto> Vetos;
00059
00061 IsoDeposit(double eta=0, double phi=0);
00062 IsoDeposit(const Direction & candDirection);
00063
00065 virtual ~IsoDeposit(){};
00066
00068 const Direction & direction() const { return theDirection; }
00069 double eta() const {return theDirection.eta();}
00070 double phi() const {return theDirection.phi();}
00071
00073 const Veto & veto() const { return theVeto; }
00075 void setVeto(const Veto & aVeto) { theVeto = aVeto; }
00076
00078 void addDeposit(double dr, double deposit);
00079 void addDeposit(const Direction & depDir, double deposit);
00080
00082 double depositWithin(
00083 double coneSize,
00084 const Vetos & vetos = Vetos(),
00085 bool skipDepositVeto = false
00086 ) const;
00087
00089 double depositWithin( Direction dir,
00090 double coneSize,
00091 const Vetos & vetos = Vetos(),
00092 bool skipDepositVeto = false
00093 ) const;
00094
00096 std::pair<double,int>
00097 depositAndCountWithin(
00098 double coneSize,
00099 const Vetos & vetos = Vetos(),
00100 double threshold = -1e+36,
00101 bool skipDepositVeto = false
00102 ) const;
00103
00105 std::pair<double,int>
00106 depositAndCountWithin(
00107 Direction dir,
00108 double coneSize,
00109 const Vetos & vetos = Vetos(),
00110 double threshold = -1e+36,
00111 bool skipDepositVeto = false
00112 ) const;
00113
00115 double depositWithin(
00116 double coneSize,
00117 const AbsVetos & vetos,
00118 bool skipDepositVeto = false
00119 ) const;
00120
00122 std::pair<double,int>
00123 depositAndCountWithin(
00124 double coneSize,
00125 const AbsVetos & vetos,
00126 bool skipDepositVeto = false
00127 ) const;
00128
00129
00131 double candEnergy() const {return theCandTag;}
00132
00134 void addCandEnergy(double et) { theCandTag += et;}
00135
00136 std::string print() const;
00137
00138 class const_iterator {
00139 public:
00140 const const_iterator & operator++() { ++it_; cacheReady_ = false; return *this; }
00141 const const_iterator * operator->() const { return this; }
00142 float dR() const { return it_->first.deltaR; }
00143 float eta() const { if (!cacheReady_) doDir(); return cache_.eta(); }
00144 float phi() const { if (!cacheReady_) doDir(); return cache_.phi(); }
00145 float value() const { return it_->second; }
00146 bool operator!=(const const_iterator &it2) { return it2.it_ != it_; }
00147 friend class IsoDeposit;
00148 private:
00149 typedef Direction::Distance Distance;
00150 void doDir() const { cache_ = parent_->direction() + it_->first; cacheReady_ = true; }
00151 const_iterator(const IsoDeposit* parent, std::multimap<Distance, float>::const_iterator it) :
00152 parent_(parent), it_(it), cache_(), cacheReady_(false) { }
00153 const reco::IsoDeposit* parent_;
00154 mutable std::multimap<Distance, float>::const_iterator it_;
00155 mutable Direction cache_;
00156 mutable bool cacheReady_;
00157 };
00158 const_iterator begin() const { return const_iterator(this, theDeposits.begin()); }
00159 const_iterator end() const { return const_iterator(this, theDeposits.end()); }
00160
00161 class SumAlgo {
00162 public:
00163 SumAlgo() : sum_(0) {}
00164 void operator+=(float deposit) { sum_ += deposit; }
00165 double result() const { return sum_; }
00166 private:
00167 double sum_;
00168 };
00169 class CountAlgo {
00170 public:
00171 CountAlgo() : count_(0) {}
00172 void operator+=(double deposit) { count_++; }
00173 double result() const { return count_; }
00174 private:
00175 size_t count_;
00176 };
00177 class Sum2Algo {
00178 public:
00179 Sum2Algo() : sum2_(0) {}
00180 void operator+=(double deposit) { sum2_ += deposit*deposit; }
00181 double result() const { return sum2_; }
00182 private:
00183 double sum2_;
00184 };
00185 class MaxAlgo {
00186 public:
00187 MaxAlgo() : max_(0) {}
00188 void operator+=(double deposit) { if (deposit > max_) max_ = deposit; }
00189 double result() const { return max_; }
00190 private:
00191 double max_;
00192 };
00194 template<typename Algo>
00195 double algoWithin( double coneSize,
00196 const AbsVetos & vetos = AbsVetos(),
00197 bool skipDepositVeto = false
00198 ) const;
00200 template<typename Algo>
00201 double algoWithin(const Direction &,
00202 double coneSize,
00203 const AbsVetos & vetos = AbsVetos(),
00204 bool skipDepositVeto = false
00205 ) const;
00206
00207 double countWithin( double coneSize,
00208 const AbsVetos & vetos = AbsVetos(),
00209 bool skipDepositVeto = false
00210 ) const;
00211
00212 double sumWithin( double coneSize,
00213 const AbsVetos & vetos = AbsVetos(),
00214 bool skipDepositVeto = false
00215 ) const;
00216
00217 double sumWithin(const Direction & dir,
00218 double coneSize,
00219 const AbsVetos & vetos = AbsVetos(),
00220 bool skipDepositVeto = false
00221 ) const;
00222 double sum2Within( double coneSize,
00223 const AbsVetos & vetos = AbsVetos(),
00224 bool skipDepositVeto = false
00225 ) const;
00226
00227 double maxWithin( double coneSize,
00228 const AbsVetos & vetos = AbsVetos(),
00229 bool skipDepositVeto = false
00230 ) const;
00231
00232 double nearestDR( double coneSize,
00233 const AbsVetos & vetos = AbsVetos(),
00234 bool skipDepositVeto = false
00235 ) const;
00236
00237
00238
00239
00240 private:
00241
00243 Direction theDirection;
00244
00246 Veto theVeto;
00247
00249 float theCandTag;
00250
00252 typedef Direction::Distance Distance;
00253 typedef std::multimap<Distance, float> DepositsMultimap;
00254
00255 DepositsMultimap theDeposits;
00256 };
00257
00258 }
00259
00260 template<typename Algo>
00261 double reco::IsoDeposit::algoWithin(double coneSize, const AbsVetos& vetos, bool skipDepositVeto) const
00262 {
00263 using namespace reco::isodeposit;
00264 Algo algo;
00265 typedef AbsVetos::const_iterator IV;
00266 IV ivEnd = vetos.end();
00267
00268 Distance maxDistance = {float(coneSize),999.f};
00269 typedef DepositsMultimap::const_iterator IM;
00270 IM imLoc = theDeposits.upper_bound( maxDistance );
00271 for (IM im = theDeposits.begin(); im != imLoc; ++im) {
00272 bool vetoed = false;
00273 Direction dirDep = theDirection+im->first;
00274 for (IV iv = vetos.begin(); iv < ivEnd; ++iv) {
00275 if ((*iv)->veto(dirDep.eta(), dirDep.phi(), im->second)) { vetoed = true; break; }
00276 }
00277 if (!vetoed) {
00278 if (skipDepositVeto || (dirDep.deltaR(theVeto.vetoDir) > theVeto.dR)) {
00279 algo += im->second;
00280 }
00281 }
00282 }
00283 return algo.result();
00284 }
00285
00286 template<typename Algo>
00287 double reco::IsoDeposit::algoWithin(const Direction& dir, double coneSize,
00288 const AbsVetos& vetos, bool skipDepositVeto) const
00289 {
00290 using namespace reco::isodeposit;
00291 Algo algo;
00292 typedef AbsVetos::const_iterator IV;
00293 IV ivEnd = vetos.end();
00294 typedef DepositsMultimap::const_iterator IM;
00295 IM imLoc = theDeposits.end();
00296 for (IM im = theDeposits.begin(); im != imLoc; ++im) {
00297 bool vetoed = false;
00298 Direction dirDep = theDirection+im->first;
00299 Distance newDist = dirDep - dir;
00300 if(newDist.deltaR > coneSize) continue;
00301 for (IV iv = vetos.begin(); iv < ivEnd; ++iv) {
00302 if ((*iv)->veto(dirDep.eta(), dirDep.phi(), im->second)) { vetoed = true; break; }
00303 }
00304 if (!vetoed) {
00305 if (skipDepositVeto || (dirDep.deltaR(theVeto.vetoDir) > theVeto.dR)) {
00306 algo += im->second;
00307 }
00308 }
00309 }
00310 return algo.result();
00311 }
00312
00313 #endif