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