Go to the documentation of this file.00001 #include <functional>
00002 #include <algorithm>
00003 #include <vector>
00004 #include <memory>
00005 #include <string>
00006
00007 #include <Math/GenVector/Cartesian3D.h>
00008 #include <Math/GenVector/VectorUtil.h>
00009
00010 #include "DQMOffline/RecoB/interface/MatchJet.h"
00011
00012 #include "Matching.h"
00013
00014 using namespace btag;
00015
00016 namespace {
00017 template<typename T>
00018 static inline T sqr(const T & val) { return val * val; }
00019
00020 template<typename T1, typename T2, typename R>
00021 struct JetDistance : public std::binary_function<T1, T2, R> {
00022 JetDistance(double sigmaDeltaR, double sigmaDeltaE) :
00023 sigmaDeltaR2(sqr(sigmaDeltaR)),
00024 sigmaDeltaE2(sqr(sigmaDeltaE)) {}
00025
00026 double operator () (const T1 &v1, const T2 &v2) const
00027 {
00028 using namespace ROOT::Math;
00029
00030
00031
00032 double x = VectorUtil::DeltaR2(v1, v2) / sigmaDeltaR2 +
00033 sqr(2. * (v1.R() - v2.R()) /
00034 (v1.R() + v2.R())) / sigmaDeltaE2;
00035
00036 return x;
00037 }
00038
00039 double sigmaDeltaR2, sigmaDeltaE2;
00040 };
00041 }
00042
00043 MatchJet::MatchJet(const edm::ParameterSet& pSet) :
00044 refJetCorrector(pSet.getParameter<std::string>("refJetCorrection")),
00045 recJetCorrector(pSet.getParameter<std::string>("recJetCorrection")),
00046 maxChi2(pSet.getParameter<double>("maxChi2")),
00047 sigmaDeltaR(pSet.getParameter<double>("sigmaDeltaR")),
00048 sigmaDeltaE(pSet.getParameter<double>("sigmaDeltaE")),
00049 threshold(1.0)
00050 {
00051 }
00052
00053 void MatchJet::matchCollections(
00054 const edm::RefToBaseVector<reco::Jet> & refJets_,
00055 const edm::RefToBaseVector<reco::Jet> & recJets_,
00056 const edm::EventSetup & es)
00057 {
00058 refJetCorrector.setEventSetup(es);
00059 recJetCorrector.setEventSetup(es);
00060
00061 typedef ROOT::Math::Cartesian3D<double> Vector;
00062
00063 std::vector<Vector> corrRefJets;
00064 refJets.clear();
00065 for(edm::RefToBaseVector<reco::Jet>::const_iterator iter = refJets.begin();
00066 iter != refJets_.end(); ++iter) {
00067 edm::RefToBase<reco::Jet> jetRef = *iter;
00068 reco::Jet jet = refJetCorrector(*jetRef);
00069 if (jet.energy() < threshold)
00070 continue;
00071
00072 corrRefJets.push_back(Vector(jet.px(), jet.py(), jet.pz()));
00073 refJets.push_back(jetRef);
00074 }
00075
00076 std::vector<Vector> corrRecJets;
00077 recJets.clear();
00078 for(edm::RefToBaseVector<reco::Jet>::const_iterator iter = recJets.begin();
00079 iter != recJets_.end(); ++iter) {
00080 edm::RefToBase<reco::Jet> jetRec = *iter;
00081 reco::Jet jet = recJetCorrector(*jetRec);
00082 if (jet.energy() < threshold)
00083 continue;
00084
00085 corrRecJets.push_back(Vector(jet.px(), jet.py(), jet.pz()));
00086 recJets.push_back(jetRec);
00087 }
00088
00089 this->refJets = refJets;
00090 refToRec.clear();
00091 refToRec.resize(refJets.size(), -1);
00092
00093 this->recJets = recJets;
00094 recToRef.clear();
00095 recToRef.resize(recJets.size(), -1);
00096
00097 Matching<double> matching(corrRefJets, corrRecJets,
00098 JetDistance<Vector, Vector, double>(
00099 sigmaDeltaR, sigmaDeltaE));
00100 typedef Matching<double>::Match Match;
00101
00102 const std::vector<Match>& matches =
00103 matching.match(std::less<double>(),
00104 std::bind2nd(std::less<double>(), maxChi2));
00105 for(std::vector<Match>::const_iterator iter = matches.begin();
00106 iter != matches.end(); ++iter) {
00107 refToRec[iter->index1] = iter->index2;
00108 recToRef[iter->index2] = iter->index1;
00109 }
00110 }
00111
00112 edm::RefToBase<reco::Jet>
00113 MatchJet::operator() (const edm::RefToBase<reco::Jet> & recJet) const
00114 {
00115 edm::RefToBase<reco::Jet> result;
00116 if (recJet.id() != recJets.id())
00117 return result;
00118
00119 for(unsigned int i = 0; i != recJets.size(); ++i) {
00120 if (recJets[i] == recJet) {
00121 int match = recToRef[i];
00122 if (match >= 0)
00123 result = refJets[match];
00124 break;
00125 }
00126 }
00127
00128 return result;
00129 }