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

# User Rev Content
1 gpetrucc 1.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);