ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/GPetrucc/plugins/MuonMCClassifier.cc
Revision: 1.1
Committed: Tue Apr 14 23:20:25 2009 UTC (16 years, 1 month ago) by gpetrucc
Content type: text/plain
Branch: MAIN
CVS Tags: V03-00-00, V02-00-00, Before34X, V01-00-00, Checkpoint_2_2_10_v1, V00-00-05, V00-00-04, V00-00-03, V00-00-02, V00-00-01, HEAD
Log Message:
Classify muons according to MC matches of their parts

File Contents

# Content
1 // -*- C++ -*-
2 //
3 // Package: MuonMCClassifier
4 // Class: MuonMCClassifier
5 //
6 /**\class MuonMCClassifier MuonMCClassifier.cc PhysicsTools/PatAlgos/src/MuonMCClassifier.cc
7
8 Description: <one line class summary>
9
10 Implementation:
11 <Notes on implementation>
12 */
13 //
14 // Original Author: Nov 16 16:12 (lxplus231.cern.ch)
15 // Created: Sun Nov 16 16:14:09 CET 2008
16 // $Id: MuonMCClassifier.cc,v 1.1 2009/04/14 13:58:52 gpetrucc Exp $
17 //
18 //
19
20
21 // system include files
22 #include <memory>
23 #include <set>
24 #include <ext/hash_map>
25
26 // user include files
27 #include "FWCore/Framework/interface/Frameworkfwd.h"
28 #include "FWCore/Framework/interface/EDProducer.h"
29
30 #include "FWCore/Framework/interface/Event.h"
31 #include "FWCore/Framework/interface/MakerMacros.h"
32
33 #include "FWCore/ParameterSet/interface/ParameterSet.h"
34
35 #include "DataFormats/Common/interface/Association.h"
36 #include "DataFormats/Common/interface/View.h"
37 #include "DataFormats/Common/interface/RefProd.h"
38 #include "DataFormats/Math/interface/deltaR.h"
39 #include "DataFormats/Candidate/interface/CandidateFwd.h"
40 #include "DataFormats/Candidate/interface/Candidate.h"
41 #include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"
42 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
43
44 //
45 // class decleration
46 class MuonMCClassifier : public edm::EDProducer {
47 public:
48 explicit MuonMCClassifier(const edm::ParameterSet&);
49 ~MuonMCClassifier();
50
51 private:
52 virtual void produce(edm::Event&, const edm::EventSetup&);
53
54 /// Returns the flavour given a pdg id code
55 int flavour(int pdgId) const ;
56
57 /// Return the flavour of the first and of the heaviest ancestors of a given particle
58 std::pair<int,int> flavours(const reco::GenParticleRef & mc) const ;
59
60 /// Write a ValueMap<int> in the event
61 void writeValueMap(edm::Event &iEvent,
62 const edm::Handle<edm::View<reco::Candidate> > & handle,
63 const std::vector<int> & values,
64 const std::string & label) const ;
65
66 /// The RECO objects
67 edm::InputTag src_;
68
69 /// The GenParticle objects
70 edm::InputTag mc_;
71
72 /// The Associations
73 edm::InputTag assoHardByDr_, assoByDr_, assoByPulls_, assoInFlight_;
74
75 };
76
77 MuonMCClassifier::MuonMCClassifier(const edm::ParameterSet &iConfig) :
78 src_(iConfig.getParameter<edm::InputTag>("src")),
79 mc_(iConfig.getParameter<edm::InputTag>("mc")),
80 assoHardByDr_(iConfig.getParameter<edm::InputTag>("assoHardByDr")),
81 assoByDr_(iConfig.getParameter<edm::InputTag>("assoByDr")),
82 assoByPulls_(iConfig.getParameter<edm::InputTag>("assoByPulls")),
83 assoInFlight_(iConfig.getParameter<edm::InputTag>("assoInFlight"))
84 {
85 produces<edm::ValueMap<int> >("origin");
86 produces<edm::ValueMap<int> >("recoStatus");
87 produces<edm::ValueMap<int> >("flavourFirst");
88 produces<edm::ValueMap<int> >("flavourHeaviest");
89 }
90
91 MuonMCClassifier::~MuonMCClassifier()
92 {
93 }
94
95 void
96 MuonMCClassifier::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
97 {
98 edm::Handle<edm::View<reco::Candidate> > src;
99 iEvent.getByLabel(src_, src);
100
101 typedef std::vector<reco::GenParticle> MCColl;
102 edm::Handle<MCColl> mc;
103 iEvent.getByLabel(mc_, mc);
104
105 typedef edm::Association<MCColl> MCAssoc;
106 edm::Handle<MCAssoc> assoHardByDr, assoByDr, assoByPulls, assoInFlight;
107 iEvent.getByLabel(assoHardByDr_, assoHardByDr);
108 iEvent.getByLabel(assoByDr_, assoByDr);
109 iEvent.getByLabel(assoByPulls_, assoByPulls);
110 iEvent.getByLabel(assoInFlight_, assoInFlight);
111
112 std::vector<int> origin(src->size(), 0);
113 std::vector<int> reco( src->size(), 0);
114 std::vector<int> flavF( src->size(), 0);
115 std::vector<int> flavH( src->size(), 0);
116
117 for (size_t i = 0, n = src->size(); i < n; ++i) {
118 reco::CandidatePtr ptr = src->ptrAt(i);
119 reco::GenParticleRef mcHardByDr = (*assoHardByDr)[ptr];
120 reco::GenParticleRef mcByDr = (*assoByDr)[ptr];
121 reco::GenParticleRef mcByPulls = (*assoByPulls)[ptr];
122 reco::GenParticleRef mcInFlight = (*assoInFlight)[ptr];
123
124 if (mcHardByDr.isNonnull()) {
125 origin[i] = 1; // hard scattering muon
126 // std::cout << "Muon with pt " << ptr->pt() << " comes from hard scattering.\n";
127 flavF[i] = flavH[i] = 13;
128 } else if (mcByDr.isNonnull()) {
129 origin[i] = 2; // other generator-level decay muon
130 std::pair<int,int> flavs = flavours(mcByDr);
131 flavF[i] = flavs.first;
132 flavH[i] = flavs.second;
133 // std::cout << "Muon with pt " << ptr->pt() << " comes from primary source: flavour " << flavs.first << ", heaviest " << flavs.second << ".\n";
134 } else if (mcInFlight.isNonnull()) {
135 origin[i] = 3;
136 std::pair<int,int> flavs = flavours(mcInFlight);
137 flavF[i] = flavs.first;
138 flavH[i] = flavs.second;
139 // std::cout << "Muon with pt " << ptr->pt() << " is from in-flight decay only: flavour " << flavs.first << ", heaviest " << flavs.second << ".\n";
140 } else {
141 // std::cout << "Muon with pt " << ptr->pt() << " has undefined (non muonic) origin.\n";
142 }
143
144 switch (origin[i]) {
145 case 1:
146 case 2:
147 // bit 0 if TK reconstructed well some track
148 // bit 1 if TK reconstructed well the primary muon
149 // bit 2 if STA reconstructed the primary muon
150 reco[i] = mcByPulls.isNonnull() + 2*(mcByPulls == mcByDr) + 4*(mcInFlight == mcByDr);
151 break;
152 case 3:
153 // bit 0 if TK reconstructed well some track
154 // bit 1 if TK reconstructed well the primary muon or one of its ancestors
155 // bit 2 if STA reconstructed well the primary muon
156 reco[i] = mcByPulls.isNonnull() + 4*(mcByPulls == mcInFlight);
157 if (mcByPulls.isNonnull()) {
158 for(reco::GenParticleRef ref = mcInFlight; ref.isNonnull(); ref = ref->motherRef()) {
159 if (ref == mcByPulls) { reco[i] += 2; break; }
160 if (ref->motherRefVector().empty()) break;
161 }
162 }
163 break;
164 default:
165 // bit 0 if TK reconstructed well some track
166 reco[i] = mcByPulls.isNonnull();
167 };
168 // std::cout << " TK track matched by pulls? " << (reco[i] & 0x1 ? "Y" : "N") << std::endl;
169 // std::cout << " TK track matched correctly? " << (reco[i] & 0x2 ? "Y" : "N") << std::endl;
170 // std::cout << " ST track matched correctly? " << (reco[i] & 0x4 ? "Y" : "N") << std::endl;
171 }
172
173 writeValueMap(iEvent, src, origin, "origin");
174 writeValueMap(iEvent, src, reco, "recoStatus");
175 writeValueMap(iEvent, src, flavF, "flavourFirst");
176 writeValueMap(iEvent, src, flavH, "flavourHeaviest");
177 }
178
179 int
180 MuonMCClassifier::flavour(int pdgId) const {
181 int flav = abs(pdgId);
182 // muons and taus have themselves as flavour
183 if (flav == 13 || flav == 15) return flav;
184 // for quarks it's easy
185 if (flav <= 5) return flav;
186 // look for barions
187 int bflav = ((flav / 1000) % 10);
188 if (bflav != 0) return bflav;
189 // look for mesons
190 int mflav = ((flav / 100) % 10);
191 if (mflav != 0) return mflav;
192 return 0;
193 }
194
195 std::pair<int,int>
196 MuonMCClassifier::flavours(const reco::GenParticleRef & ref) const
197 {
198 if (ref.isNull()) return std::make_pair(0,0);
199
200 std::vector<reco::GenParticleRef> work;
201 work.insert(work.end(), ref->motherRefVector().begin(), ref->motherRefVector().end());
202 int first = -1, heaviest = 0;
203
204 while (!work.empty()) {
205 reco::GenParticleRef r = work.back(); work.pop_back();
206 int flav = flavour(r->pdgId());
207 if ((first == -1) && (flav != 0)) { first = flav; }
208 if (flav == 13 || flav == 15) {
209 if (r->status() == 3) {
210 heaviest = flav; // hard-scattering muon or tau
211 break;
212 } else {
213 flav = 0; // otherwise don't pollute the "heaviest" match
214 }
215 }
216 if (flav > heaviest) heaviest = flav;
217 work.insert(work.end(), r->motherRefVector().begin(), r->motherRefVector().end());
218 }
219
220 return std::make_pair(first,heaviest);
221 }
222
223
224 void
225 MuonMCClassifier::writeValueMap(edm::Event &iEvent,
226 const edm::Handle<edm::View<reco::Candidate> > & handle,
227 const std::vector<int> & values,
228 const std::string & label) const
229 {
230 using namespace edm;
231 using namespace std;
232 auto_ptr<ValueMap<int> > valMap(new ValueMap<int>());
233 edm::ValueMap<int>::Filler filler(*valMap);
234 filler.insert(handle, values.begin(), values.end());
235 filler.fill();
236 iEvent.put(valMap, label);
237 }
238
239
240 //define this as a plug-in
241 DEFINE_FWK_MODULE(MuonMCClassifier);