1 |
//
|
2 |
// $Id: PATMuonProducer.cc,v 1.40 2010/09/03 15:41:26 hegner Exp $
|
3 |
//
|
4 |
|
5 |
#include "PhysicsTools/PatAlgos/plugins/PATMuonProducer.h"
|
6 |
|
7 |
#include "FWCore/MessageLogger/interface/MessageLogger.h"
|
8 |
#include "FWCore/ParameterSet/interface/FileInPath.h"
|
9 |
#include "FWCore/Utilities/interface/Exception.h"
|
10 |
|
11 |
#include "DataFormats/MuonReco/interface/Muon.h"
|
12 |
#include "DataFormats/MuonReco/interface/MuonFwd.h"
|
13 |
|
14 |
#include "DataFormats/TrackReco/interface/TrackToTrackMap.h"
|
15 |
|
16 |
#include "DataFormats/ParticleFlowCandidate/interface/IsolatedPFCandidateFwd.h"
|
17 |
#include "DataFormats/ParticleFlowCandidate/interface/IsolatedPFCandidate.h"
|
18 |
|
19 |
#include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"
|
20 |
#include "DataFormats/HepMCCandidate/interface/GenParticle.h"
|
21 |
|
22 |
#include "DataFormats/Common/interface/Association.h"
|
23 |
|
24 |
#include "DataFormats/BeamSpot/interface/BeamSpot.h"
|
25 |
#include "DataFormats/VertexReco/interface/Vertex.h"
|
26 |
|
27 |
|
28 |
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
|
29 |
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
|
30 |
|
31 |
#include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
|
32 |
#include "TrackingTools/Records/interface/TransientTrackRecord.h"
|
33 |
#include "TrackingTools/TransientTrack/interface/TransientTrack.h"
|
34 |
#include "TrackingTools/IPTools/interface/IPTools.h"
|
35 |
|
36 |
|
37 |
#include "TMath.h"
|
38 |
|
39 |
#include <vector>
|
40 |
#include <memory>
|
41 |
|
42 |
|
43 |
using namespace pat;
|
44 |
using namespace std;
|
45 |
|
46 |
|
47 |
PATMuonProducer::PATMuonProducer(const edm::ParameterSet & iConfig) : useUserData_(iConfig.exists("userData")),
|
48 |
isolator_(iConfig.exists("userIsolation") ? iConfig.getParameter<edm::ParameterSet>("userIsolation") : edm::ParameterSet(), false)
|
49 |
{
|
50 |
// input source
|
51 |
muonSrc_ = iConfig.getParameter<edm::InputTag>( "muonSource" );
|
52 |
// embedding of tracks
|
53 |
embedTrack_ = iConfig.getParameter<bool>( "embedTrack" );
|
54 |
embedCombinedMuon_ = iConfig.getParameter<bool>( "embedCombinedMuon" );
|
55 |
embedStandAloneMuon_ = iConfig.getParameter<bool>( "embedStandAloneMuon" );
|
56 |
|
57 |
// embedding of muon MET correction information
|
58 |
embedCaloMETMuonCorrs_ = iConfig.getParameter<bool>("embedCaloMETMuonCorrs" );
|
59 |
embedTcMETMuonCorrs_ = iConfig.getParameter<bool>("embedTcMETMuonCorrs" );
|
60 |
caloMETMuonCorrs_ = iConfig.getParameter<edm::InputTag>("caloMETMuonCorrs" );
|
61 |
tcMETMuonCorrs_ = iConfig.getParameter<edm::InputTag>("tcMETMuonCorrs" );
|
62 |
|
63 |
// pflow specific configurables
|
64 |
useParticleFlow_ = iConfig.getParameter<bool>( "useParticleFlow" );
|
65 |
embedPFCandidate_ = iConfig.getParameter<bool>( "embedPFCandidate" );
|
66 |
pfMuonSrc_ = iConfig.getParameter<edm::InputTag>( "pfMuonSource" );
|
67 |
|
68 |
// TeV track refits
|
69 |
addTeVRefits_ = iConfig.getParameter<bool>("addTeVRefits");
|
70 |
if(addTeVRefits_){
|
71 |
pickySrc_ = iConfig.getParameter<edm::InputTag>("pickySrc");
|
72 |
tpfmsSrc_ = iConfig.getParameter<edm::InputTag>("tpfmsSrc");
|
73 |
}
|
74 |
// embedding of tracks from TeV refit
|
75 |
embedPickyMuon_ = iConfig.getParameter<bool>( "embedPickyMuon" );
|
76 |
embedTpfmsMuon_ = iConfig.getParameter<bool>( "embedTpfmsMuon" );
|
77 |
|
78 |
// Monte Carlo matching
|
79 |
addGenMatch_ = iConfig.getParameter<bool>( "addGenMatch" );
|
80 |
if(addGenMatch_){
|
81 |
embedGenMatch_ = iConfig.getParameter<bool>( "embedGenMatch" );
|
82 |
if(iConfig.existsAs<edm::InputTag>("genParticleMatch")){
|
83 |
genMatchSrc_.push_back(iConfig.getParameter<edm::InputTag>( "genParticleMatch" ));
|
84 |
} else {
|
85 |
genMatchSrc_ = iConfig.getParameter<std::vector<edm::InputTag> >( "genParticleMatch" );
|
86 |
}
|
87 |
}
|
88 |
|
89 |
// efficiencies
|
90 |
addEfficiencies_ = iConfig.getParameter<bool>("addEfficiencies");
|
91 |
if(addEfficiencies_){
|
92 |
efficiencyLoader_ = pat::helper::EfficiencyLoader(iConfig.getParameter<edm::ParameterSet>("efficiencies"));
|
93 |
}
|
94 |
|
95 |
// resolutions
|
96 |
addResolutions_ = iConfig.getParameter<bool>("addResolutions");
|
97 |
if (addResolutions_) {
|
98 |
resolutionLoader_ = pat::helper::KinResolutionsLoader(iConfig.getParameter<edm::ParameterSet>("resolutions"));
|
99 |
}
|
100 |
|
101 |
// read isoDeposit labels, for direct embedding
|
102 |
readIsolationLabels(iConfig, "isoDeposits", isoDepositLabels_);
|
103 |
// read isolation value labels, for direct embedding
|
104 |
readIsolationLabels(iConfig, "isolationValues", isolationValueLabels_);
|
105 |
|
106 |
// check to see if the user wants to add user data
|
107 |
if( useUserData_ ){
|
108 |
userDataHelper_ = PATUserDataHelper<Muon>(iConfig.getParameter<edm::ParameterSet>("userData"));
|
109 |
}
|
110 |
|
111 |
// embed high level selection variables
|
112 |
usePV_ = true;
|
113 |
embedHighLevelSelection_ = iConfig.getParameter<bool>("embedHighLevelSelection");
|
114 |
if ( embedHighLevelSelection_ ) {
|
115 |
beamLineSrc_ = iConfig.getParameter<edm::InputTag>("beamLineSrc");
|
116 |
usePV_ = iConfig.getParameter<bool>("usePV");
|
117 |
pvSrc_ = iConfig.getParameter<edm::InputTag>("pvSrc");
|
118 |
}
|
119 |
|
120 |
// produces vector of muons
|
121 |
produces<std::vector<Muon> >();
|
122 |
}
|
123 |
|
124 |
|
125 |
PATMuonProducer::~PATMuonProducer()
|
126 |
{
|
127 |
}
|
128 |
|
129 |
void PATMuonProducer::produce(edm::Event & iEvent, const edm::EventSetup & iSetup)
|
130 |
{
|
131 |
edm::Handle<edm::View<reco::Muon> > muons;
|
132 |
iEvent.getByLabel(muonSrc_, muons);
|
133 |
|
134 |
if (iEvent.isRealData()){
|
135 |
addGenMatch_ = false;
|
136 |
embedGenMatch_ = false;
|
137 |
}
|
138 |
|
139 |
// get the ESHandle for the transient track builder,
|
140 |
// if needed for high level selection embedding
|
141 |
edm::ESHandle<TransientTrackBuilder> trackBuilder;
|
142 |
|
143 |
if(isolator_.enabled()) isolator_.beginEvent(iEvent,iSetup);
|
144 |
if(efficiencyLoader_.enabled()) efficiencyLoader_.newEvent(iEvent);
|
145 |
if(resolutionLoader_.enabled()) resolutionLoader_.newEvent(iEvent, iSetup);
|
146 |
|
147 |
IsoDepositMaps deposits(isoDepositLabels_.size());
|
148 |
for (size_t j = 0; j<isoDepositLabels_.size(); ++j) {
|
149 |
iEvent.getByLabel(isoDepositLabels_[j].second, deposits[j]);
|
150 |
}
|
151 |
|
152 |
IsolationValueMaps isolationValues(isolationValueLabels_.size());
|
153 |
for (size_t j = 0; j<isolationValueLabels_.size(); ++j) {
|
154 |
iEvent.getByLabel(isolationValueLabels_[j].second, isolationValues[j]);
|
155 |
}
|
156 |
|
157 |
// prepare the MC matching
|
158 |
GenAssociations genMatches(genMatchSrc_.size());
|
159 |
if (addGenMatch_) {
|
160 |
for (size_t j = 0, nd = genMatchSrc_.size(); j < nd; ++j) {
|
161 |
iEvent.getByLabel(genMatchSrc_[j], genMatches[j]);
|
162 |
}
|
163 |
}
|
164 |
|
165 |
// prepare the high level selection: needs beamline
|
166 |
// OR primary vertex, depending on user selection
|
167 |
reco::TrackBase::Point beamPoint(0,0,0);
|
168 |
reco::Vertex primaryVertex;
|
169 |
reco::BeamSpot beamSpot;
|
170 |
bool beamSpotIsValid = false;
|
171 |
bool primaryVertexIsValid = false;
|
172 |
if ( embedHighLevelSelection_ ) {
|
173 |
// get the beamspot
|
174 |
edm::Handle<reco::BeamSpot> beamSpotHandle;
|
175 |
iEvent.getByLabel(beamLineSrc_, beamSpotHandle);
|
176 |
|
177 |
// get the primary vertex
|
178 |
edm::Handle< std::vector<reco::Vertex> > pvHandle;
|
179 |
iEvent.getByLabel( pvSrc_, pvHandle );
|
180 |
|
181 |
if( beamSpotHandle.isValid() ){
|
182 |
beamSpot = *beamSpotHandle;
|
183 |
beamSpotIsValid = true;
|
184 |
} else{
|
185 |
edm::LogError("DataNotAvailable")
|
186 |
<< "No beam spot available from EventSetup, not adding high level selection \n";
|
187 |
}
|
188 |
beamPoint = reco::TrackBase::Point ( beamSpot.x0(), beamSpot.y0(), beamSpot.z0() );
|
189 |
if( pvHandle.isValid() ) {
|
190 |
primaryVertex = pvHandle->at(0);
|
191 |
primaryVertexIsValid = true;
|
192 |
} else {
|
193 |
edm::LogError("DataNotAvailable")
|
194 |
<< "No primary vertex available from EventSetup, not adding high level selection \n";
|
195 |
}
|
196 |
// this is needed by the IPTools methods from the tracking group
|
197 |
iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", trackBuilder);
|
198 |
}
|
199 |
|
200 |
// this will be the new object collection
|
201 |
std::vector<Muon> * patMuons = new std::vector<Muon>();
|
202 |
|
203 |
if( useParticleFlow_ ){
|
204 |
// get the PFCandidates of type muons
|
205 |
edm::Handle< reco::PFCandidateCollection > pfMuons;
|
206 |
iEvent.getByLabel(pfMuonSrc_, pfMuons);
|
207 |
|
208 |
unsigned index=0;
|
209 |
for( reco::PFCandidateConstIterator i = pfMuons->begin(); i != pfMuons->end(); ++i, ++index) {
|
210 |
const reco::PFCandidate& pfmu = *i;
|
211 |
//const reco::IsolaPFCandidate& pfmu = *i;
|
212 |
const reco::MuonRef& muonRef = pfmu.muonRef();
|
213 |
assert( muonRef.isNonnull() );
|
214 |
|
215 |
MuonBaseRef muonBaseRef(muonRef);
|
216 |
Muon aMuon(muonBaseRef);
|
217 |
|
218 |
if ( useUserData_ ) {
|
219 |
userDataHelper_.add( aMuon, iEvent, iSetup );
|
220 |
}
|
221 |
|
222 |
// embed high level selection
|
223 |
if ( embedHighLevelSelection_ ) {
|
224 |
// get the tracks
|
225 |
reco::TrackRef innerTrack = muonBaseRef->innerTrack();
|
226 |
reco::TrackRef globalTrack= muonBaseRef->globalTrack();
|
227 |
// Make sure the collection it points to is there
|
228 |
if ( innerTrack.isNonnull() && innerTrack.isAvailable() ) {
|
229 |
unsigned int nhits = innerTrack->numberOfValidHits();
|
230 |
aMuon.setNumberOfValidHits( nhits );
|
231 |
|
232 |
reco::TransientTrack tt = trackBuilder->build(innerTrack);
|
233 |
embedHighLevel( aMuon,
|
234 |
innerTrack,
|
235 |
tt,
|
236 |
primaryVertex,
|
237 |
primaryVertexIsValid,
|
238 |
beamSpot,
|
239 |
beamSpotIsValid );
|
240 |
|
241 |
// Correct to PV, or beam spot
|
242 |
if ( !usePV_ ) {
|
243 |
double corr_d0 = -1.0 * innerTrack->dxy( beamPoint );
|
244 |
aMuon.setDB( corr_d0, -1.0 );
|
245 |
} else {
|
246 |
std::pair<bool,Measurement1D> result = IPTools::absoluteTransverseImpactParameter(tt, primaryVertex);
|
247 |
double d0_corr = result.second.value();
|
248 |
double d0_err = result.second.error();
|
249 |
aMuon.setDB( d0_corr, d0_err );
|
250 |
}
|
251 |
}
|
252 |
|
253 |
if ( globalTrack.isNonnull() && globalTrack.isAvailable() ) {
|
254 |
double norm_chi2 = globalTrack->chi2() / globalTrack->ndof();
|
255 |
aMuon.setNormChi2( norm_chi2 );
|
256 |
}
|
257 |
}
|
258 |
|
259 |
reco::PFCandidateRef pfRef(pfMuons,index);
|
260 |
//reco::PFCandidatePtr ptrToMother(pfMuons,index);
|
261 |
reco::CandidateBaseRef pfBaseRef( pfRef );
|
262 |
|
263 |
aMuon.setPFCandidateRef( pfRef );
|
264 |
if( embedPFCandidate_ ) aMuon.embedPFCandidate();
|
265 |
fillMuon( aMuon, muonBaseRef, pfBaseRef, genMatches, deposits, isolationValues );
|
266 |
patMuons->push_back(aMuon);
|
267 |
}
|
268 |
}
|
269 |
else {
|
270 |
edm::Handle<edm::View<reco::Muon> > muons;
|
271 |
iEvent.getByLabel(muonSrc_, muons);
|
272 |
|
273 |
// prepare the TeV refit track retrieval
|
274 |
edm::Handle<reco::TrackToTrackMap> pickyMap, tpfmsMap;
|
275 |
if (addTeVRefits_) {
|
276 |
iEvent.getByLabel(pickySrc_, pickyMap);
|
277 |
iEvent.getByLabel(tpfmsSrc_, tpfmsMap);
|
278 |
}
|
279 |
|
280 |
// embedding of muon MET corrections
|
281 |
edm::Handle<edm::ValueMap<reco::MuonMETCorrectionData> > caloMETMuonCorrs;
|
282 |
//edm::ValueMap<reco::MuonMETCorrectionData> caloMETmuCorValueMap;
|
283 |
if(embedCaloMETMuonCorrs_){
|
284 |
iEvent.getByLabel(caloMETMuonCorrs_, caloMETMuonCorrs);
|
285 |
//caloMETmuCorValueMap = *caloMETmuCorValueMap_h;
|
286 |
}
|
287 |
edm::Handle<edm::ValueMap<reco::MuonMETCorrectionData> > tcMETMuonCorrs;
|
288 |
//edm::ValueMap<reco::MuonMETCorrectionData> tcMETmuCorValueMap;
|
289 |
if(embedTcMETMuonCorrs_) {
|
290 |
iEvent.getByLabel(tcMETMuonCorrs_, tcMETMuonCorrs);
|
291 |
//tcMETmuCorValueMap = *tcMETmuCorValueMap_h;
|
292 |
}
|
293 |
|
294 |
for (edm::View<reco::Muon>::const_iterator itMuon = muons->begin(); itMuon != muons->end(); ++itMuon) {
|
295 |
// construct the Muon from the ref -> save ref to original object
|
296 |
unsigned int idx = itMuon - muons->begin();
|
297 |
MuonBaseRef muonRef = muons->refAt(idx);
|
298 |
reco::CandidateBaseRef muonBaseRef( muonRef );
|
299 |
|
300 |
Muon aMuon(muonRef);
|
301 |
fillMuon( aMuon, muonRef, muonBaseRef, genMatches, deposits, isolationValues);
|
302 |
|
303 |
// store the TeV refit track refs (only available for globalMuons)
|
304 |
if (addTeVRefits_ && itMuon->isGlobalMuon()) {
|
305 |
reco::TrackToTrackMap::const_iterator it;
|
306 |
const reco::TrackRef& globalTrack = itMuon->globalTrack();
|
307 |
|
308 |
// If the getByLabel calls failed above (i.e. if the TeV refit
|
309 |
// maps/collections were not in the event), then the TrackRefs
|
310 |
// in the Muon object will remain null.
|
311 |
if (!pickyMap.failedToGet()) {
|
312 |
it = pickyMap->find(globalTrack);
|
313 |
if (it != pickyMap->end()) aMuon.setPickyMuon(it->val);
|
314 |
if (embedPickyMuon_) aMuon.embedPickyMuon();
|
315 |
}
|
316 |
|
317 |
if (!tpfmsMap.failedToGet()) {
|
318 |
it = tpfmsMap->find(globalTrack);
|
319 |
if (it != tpfmsMap->end()) aMuon.setTpfmsMuon(it->val);
|
320 |
if (embedTpfmsMuon_) aMuon.embedTpfmsMuon();
|
321 |
}
|
322 |
}
|
323 |
|
324 |
// Isolation
|
325 |
if (isolator_.enabled()) {
|
326 |
//reco::CandidatePtr mother = ptrToMother->sourceCandidatePtr(0);
|
327 |
isolator_.fill(*muons, idx, isolatorTmpStorage_);
|
328 |
typedef pat::helper::MultiIsolator::IsolationValuePairs IsolationValuePairs;
|
329 |
// better to loop backwards, so the vector is resized less times
|
330 |
for (IsolationValuePairs::const_reverse_iterator it = isolatorTmpStorage_.rbegin(), ed = isolatorTmpStorage_.rend(); it != ed; ++it) {
|
331 |
aMuon.setIsolation(it->first, it->second);
|
332 |
}
|
333 |
}
|
334 |
|
335 |
// for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
|
336 |
// aMuon.setIsoDeposit(isoDepositLabels_[j].first,
|
337 |
// (*deposits[j])[muonRef]);
|
338 |
// }
|
339 |
|
340 |
// add sel to selected
|
341 |
edm::Ptr<reco::Muon> muonsPtr = muons->ptrAt(idx);
|
342 |
if ( useUserData_ ) {
|
343 |
userDataHelper_.add( aMuon, iEvent, iSetup );
|
344 |
}
|
345 |
|
346 |
// embed high level selection
|
347 |
if ( embedHighLevelSelection_ ) {
|
348 |
// get the tracks
|
349 |
reco::TrackRef innerTrack = itMuon->innerTrack();
|
350 |
reco::TrackRef globalTrack= itMuon->globalTrack();
|
351 |
// Make sure the collection it points to is there
|
352 |
if ( innerTrack.isNonnull() && innerTrack.isAvailable() ) {
|
353 |
unsigned int nhits = innerTrack->numberOfValidHits();
|
354 |
aMuon.setNumberOfValidHits( nhits );
|
355 |
|
356 |
reco::TransientTrack tt = trackBuilder->build(innerTrack);
|
357 |
embedHighLevel( aMuon,
|
358 |
innerTrack,
|
359 |
tt,
|
360 |
primaryVertex,
|
361 |
primaryVertexIsValid,
|
362 |
beamSpot,
|
363 |
beamSpotIsValid );
|
364 |
|
365 |
// Correct to PV, or beam spot
|
366 |
if ( !usePV_ ) {
|
367 |
double corr_d0 = -1.0 * innerTrack->dxy( beamPoint );
|
368 |
aMuon.setDB( corr_d0, -1.0 );
|
369 |
} else {
|
370 |
std::pair<bool,Measurement1D> result = IPTools::absoluteTransverseImpactParameter(tt, primaryVertex);
|
371 |
double d0_corr = result.second.value();
|
372 |
double d0_err = result.second.error();
|
373 |
aMuon.setDB( d0_corr, d0_err );
|
374 |
}
|
375 |
}
|
376 |
|
377 |
if ( globalTrack.isNonnull() && globalTrack.isAvailable() ) {
|
378 |
double norm_chi2 = globalTrack->chi2() / globalTrack->ndof();
|
379 |
aMuon.setNormChi2( norm_chi2 );
|
380 |
}
|
381 |
}
|
382 |
|
383 |
// embed MET muon corrections
|
384 |
if( embedCaloMETMuonCorrs_ ) aMuon.embedCaloMETMuonCorrs((*caloMETMuonCorrs)[muonRef]);
|
385 |
if( embedTcMETMuonCorrs_ ) aMuon.embedTcMETMuonCorrs((*tcMETMuonCorrs )[muonRef]);
|
386 |
|
387 |
patMuons->push_back(aMuon);
|
388 |
}
|
389 |
}
|
390 |
|
391 |
// sort muons in pt
|
392 |
std::sort(patMuons->begin(), patMuons->end(), pTComparator_);
|
393 |
|
394 |
// put genEvt object in Event
|
395 |
std::auto_ptr<std::vector<Muon> > ptr(patMuons);
|
396 |
iEvent.put(ptr);
|
397 |
|
398 |
if (isolator_.enabled()) isolator_.endEvent();
|
399 |
}
|
400 |
|
401 |
|
402 |
void PATMuonProducer::fillMuon( Muon& aMuon, const MuonBaseRef& muonRef, const reco::CandidateBaseRef& baseRef, const GenAssociations& genMatches, const IsoDepositMaps& deposits, const IsolationValueMaps& isolationValues ) const
|
403 |
{
|
404 |
// in the particle flow algorithm,
|
405 |
// the muon momentum is recomputed.
|
406 |
// the new value is stored as the momentum of the
|
407 |
// resulting PFCandidate of type Muon, and choosen
|
408 |
// as the pat::Muon momentum
|
409 |
if (useParticleFlow_)
|
410 |
aMuon.setP4( aMuon.pfCandidateRef()->p4() );
|
411 |
|
412 |
if (embedTrack_) aMuon.embedTrack();
|
413 |
if (embedStandAloneMuon_) aMuon.embedStandAloneMuon();
|
414 |
if (embedCombinedMuon_) aMuon.embedCombinedMuon();
|
415 |
|
416 |
// store the match to the generated final state muons
|
417 |
if (addGenMatch_) {
|
418 |
for(size_t i = 0, n = genMatches.size(); i < n; ++i) {
|
419 |
reco::GenParticleRef genMuon = (*genMatches[i])[baseRef];
|
420 |
aMuon.addGenParticleRef(genMuon);
|
421 |
}
|
422 |
if (embedGenMatch_) aMuon.embedGenParticle();
|
423 |
}
|
424 |
|
425 |
if (efficiencyLoader_.enabled()) {
|
426 |
efficiencyLoader_.setEfficiencies( aMuon, muonRef );
|
427 |
}
|
428 |
|
429 |
for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
|
430 |
if(useParticleFlow_) {
|
431 |
reco::CandidatePtr source = aMuon.pfCandidateRef()->sourceCandidatePtr(0);
|
432 |
aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[source]);
|
433 |
}
|
434 |
else{
|
435 |
aMuon.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[muonRef]);
|
436 |
}
|
437 |
}
|
438 |
|
439 |
for (size_t j = 0; j<isolationValues.size(); ++j) {
|
440 |
if(useParticleFlow_) {
|
441 |
reco::CandidatePtr source = aMuon.pfCandidateRef()->sourceCandidatePtr(0);
|
442 |
aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[source]);
|
443 |
}
|
444 |
else{
|
445 |
aMuon.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[muonRef]);
|
446 |
}
|
447 |
}
|
448 |
|
449 |
if (resolutionLoader_.enabled()) {
|
450 |
resolutionLoader_.setResolutions(aMuon);
|
451 |
}
|
452 |
}
|
453 |
|
454 |
// ParameterSet description for module
|
455 |
void PATMuonProducer::fillDescriptions(edm::ConfigurationDescriptions & descriptions)
|
456 |
{
|
457 |
edm::ParameterSetDescription iDesc;
|
458 |
iDesc.setComment("PAT muon producer module");
|
459 |
|
460 |
// input source
|
461 |
iDesc.add<edm::InputTag>("muonSource", edm::InputTag("no default"))->setComment("input collection");
|
462 |
|
463 |
// embedding
|
464 |
iDesc.add<bool>("embedTrack", true)->setComment("embed external track");
|
465 |
iDesc.add<bool>("embedStandAloneMuon", true)->setComment("embed external stand-alone muon");
|
466 |
iDesc.add<bool>("embedCombinedMuon", false)->setComment("embed external combined muon");
|
467 |
iDesc.add<bool>("embedPickyMuon", false)->setComment("embed external picky muon");
|
468 |
iDesc.add<bool>("embedTpfmsMuon", false)->setComment("embed external tpfms muon");
|
469 |
|
470 |
// embedding of MET muon corrections
|
471 |
iDesc.add<bool>("embedCaloMETMuonCorrs", true)->setComment("whether to add MET muon correction for caloMET or not");
|
472 |
iDesc.add<edm::InputTag>("caloMETMuonCorrs", edm::InputTag("muonMETValueMapProducer" , "muCorrData"))->setComment("source of MET muon corrections for caloMET");
|
473 |
iDesc.add<bool>("embedTcMETMuonCorrs", true)->setComment("whether to add MET muon correction for tcMET or not");
|
474 |
iDesc.add<edm::InputTag>("tcMETMuonCorrs", edm::InputTag("muonTCMETValueMapProducer" , "muCorrData"))->setComment("source of MET muon corrections for tcMET");
|
475 |
|
476 |
// pf specific parameters
|
477 |
iDesc.add<edm::InputTag>("pfMuonSource", edm::InputTag("pfMuons"))->setComment("particle flow input collection");
|
478 |
iDesc.add<bool>("useParticleFlow", false)->setComment("whether to use particle flow or not");
|
479 |
iDesc.add<bool>("embedPFCandidate", false)->setComment("embed external particle flow object");
|
480 |
|
481 |
// TeV refit
|
482 |
iDesc.ifValue( edm::ParameterDescription<bool>("addTeVRefits", true, true),
|
483 |
true >> (edm::ParameterDescription<edm::InputTag>("pickySrc", edm::InputTag(), true) and
|
484 |
edm::ParameterDescription<edm::InputTag>("tpfmsSrc", edm::InputTag(), true))
|
485 |
)->setComment("If TeV refits are added, their sources need to be specified");
|
486 |
|
487 |
// MC matching configurables
|
488 |
iDesc.add<bool>("addGenMatch", true)->setComment("add MC matching");
|
489 |
iDesc.add<bool>("embedGenMatch", false)->setComment("embed MC matched MC information");
|
490 |
std::vector<edm::InputTag> emptySourceVector;
|
491 |
iDesc.addNode( edm::ParameterDescription<edm::InputTag>("genParticleMatch", edm::InputTag(), true) xor
|
492 |
edm::ParameterDescription<std::vector<edm::InputTag> >("genParticleMatch", emptySourceVector, true)
|
493 |
)->setComment("input with MC match information");
|
494 |
|
495 |
pat::helper::KinResolutionsLoader::fillDescription(iDesc);
|
496 |
|
497 |
// IsoDeposit configurables
|
498 |
edm::ParameterSetDescription isoDepositsPSet;
|
499 |
isoDepositsPSet.addOptional<edm::InputTag>("tracker");
|
500 |
isoDepositsPSet.addOptional<edm::InputTag>("ecal");
|
501 |
isoDepositsPSet.addOptional<edm::InputTag>("hcal");
|
502 |
isoDepositsPSet.addOptional<edm::InputTag>("particle");
|
503 |
isoDepositsPSet.addOptional<edm::InputTag>("pfChargedHadrons");
|
504 |
isoDepositsPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
|
505 |
isoDepositsPSet.addOptional<edm::InputTag>("pfPhotons");
|
506 |
isoDepositsPSet.addOptional<std::vector<edm::InputTag> >("user");
|
507 |
iDesc.addOptional("isoDeposits", isoDepositsPSet);
|
508 |
|
509 |
// isolation values configurables
|
510 |
edm::ParameterSetDescription isolationValuesPSet;
|
511 |
isolationValuesPSet.addOptional<edm::InputTag>("tracker");
|
512 |
isolationValuesPSet.addOptional<edm::InputTag>("ecal");
|
513 |
isolationValuesPSet.addOptional<edm::InputTag>("hcal");
|
514 |
isolationValuesPSet.addOptional<edm::InputTag>("particle");
|
515 |
isolationValuesPSet.addOptional<edm::InputTag>("pfChargedHadrons");
|
516 |
isolationValuesPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
|
517 |
isolationValuesPSet.addOptional<edm::InputTag>("pfPhotons");
|
518 |
iDesc.addOptional("isolationValues", isolationValuesPSet);
|
519 |
|
520 |
// Efficiency configurables
|
521 |
edm::ParameterSetDescription efficienciesPSet;
|
522 |
efficienciesPSet.setAllowAnything(); // TODO: the pat helper needs to implement a description.
|
523 |
iDesc.add("efficiencies", efficienciesPSet);
|
524 |
iDesc.add<bool>("addEfficiencies", false);
|
525 |
|
526 |
// Check to see if the user wants to add user data
|
527 |
edm::ParameterSetDescription userDataPSet;
|
528 |
PATUserDataHelper<Muon>::fillDescription(userDataPSet);
|
529 |
iDesc.addOptional("userData", userDataPSet);
|
530 |
|
531 |
edm::ParameterSetDescription isolationPSet;
|
532 |
isolationPSet.setAllowAnything(); // TODO: the pat helper needs to implement a description.
|
533 |
iDesc.add("userIsolation", isolationPSet);
|
534 |
|
535 |
iDesc.add<bool>("embedHighLevelSelection", true)->setComment("embed high level selection");
|
536 |
edm::ParameterSetDescription highLevelPSet;
|
537 |
highLevelPSet.setAllowAnything();
|
538 |
iDesc.addNode( edm::ParameterDescription<edm::InputTag>("beamLineSrc", edm::InputTag(), true)
|
539 |
)->setComment("input with high level selection");
|
540 |
iDesc.addNode( edm::ParameterDescription<edm::InputTag>("pvSrc", edm::InputTag(), true)
|
541 |
)->setComment("input with high level selection");
|
542 |
iDesc.addNode( edm::ParameterDescription<bool>("usePV", bool(), true)
|
543 |
)->setComment("input with high level selection, use primary vertex (true) or beam line (false)");
|
544 |
|
545 |
//descriptions.add("PATMuonProducer", iDesc);
|
546 |
}
|
547 |
|
548 |
|
549 |
void PATMuonProducer::readIsolationLabels( const edm::ParameterSet & iConfig, const char* psetName, IsolationLabels& labels)
|
550 |
{
|
551 |
labels.clear();
|
552 |
|
553 |
if (iConfig.exists( psetName )) {
|
554 |
edm::ParameterSet depconf = iConfig.getParameter<edm::ParameterSet>(psetName);
|
555 |
|
556 |
if (depconf.exists("tracker")) labels.push_back(std::make_pair(pat::TrackIso, depconf.getParameter<edm::InputTag>("tracker")));
|
557 |
if (depconf.exists("ecal")) labels.push_back(std::make_pair(pat::EcalIso, depconf.getParameter<edm::InputTag>("ecal")));
|
558 |
if (depconf.exists("hcal")) labels.push_back(std::make_pair(pat::HcalIso, depconf.getParameter<edm::InputTag>("hcal")));
|
559 |
if (depconf.exists("pfAllParticles")) {
|
560 |
labels.push_back(std::make_pair(pat::PfAllParticleIso, depconf.getParameter<edm::InputTag>("pfAllParticles")));
|
561 |
}
|
562 |
if (depconf.exists("pfChargedHadrons")) {
|
563 |
labels.push_back(std::make_pair(pat::PfChargedHadronIso, depconf.getParameter<edm::InputTag>("pfChargedHadrons")));
|
564 |
}
|
565 |
if (depconf.exists("pfNeutralHadrons")) {
|
566 |
labels.push_back(std::make_pair(pat::PfNeutralHadronIso, depconf.getParameter<edm::InputTag>("pfNeutralHadrons")));
|
567 |
}
|
568 |
if (depconf.exists("pfPhotons")) {
|
569 |
labels.push_back(std::make_pair(pat::PfGammaIso, depconf.getParameter<edm::InputTag>("pfPhotons")));
|
570 |
}
|
571 |
if (depconf.exists("user")) {
|
572 |
std::vector<edm::InputTag> userdeps = depconf.getParameter<std::vector<edm::InputTag> >("user");
|
573 |
std::vector<edm::InputTag>::const_iterator it = userdeps.begin(), ed = userdeps.end();
|
574 |
int key = UserBaseIso;
|
575 |
for ( ; it != ed; ++it, ++key) {
|
576 |
labels.push_back(std::make_pair(IsolationKeys(key), *it));
|
577 |
}
|
578 |
}
|
579 |
}
|
580 |
}
|
581 |
|
582 |
|
583 |
|
584 |
// embed various impact parameters with errors
|
585 |
// embed high level selection
|
586 |
void PATMuonProducer::embedHighLevel( pat::Muon & aMuon,
|
587 |
reco::TrackRef innerTrack,
|
588 |
reco::TransientTrack & tt,
|
589 |
reco::Vertex & primaryVertex,
|
590 |
bool primaryVertexIsValid,
|
591 |
reco::BeamSpot & beamspot,
|
592 |
bool beamspotIsValid
|
593 |
)
|
594 |
{
|
595 |
// Correct to PV
|
596 |
|
597 |
// PV2D
|
598 |
std::pair<bool,Measurement1D> result =
|
599 |
IPTools::signedTransverseImpactParameter(tt,
|
600 |
GlobalVector(innerTrack->px(),
|
601 |
innerTrack->py(),
|
602 |
innerTrack->pz()),
|
603 |
primaryVertex);
|
604 |
double d0_corr = result.second.value();
|
605 |
double d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
|
606 |
aMuon.setDB( d0_corr, d0_err, pat::Muon::PV2D);
|
607 |
|
608 |
|
609 |
// PV3D
|
610 |
result =
|
611 |
IPTools::signedImpactParameter3D(tt,
|
612 |
GlobalVector(innerTrack->px(),
|
613 |
innerTrack->py(),
|
614 |
innerTrack->pz()),
|
615 |
primaryVertex);
|
616 |
d0_corr = result.second.value();
|
617 |
d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
|
618 |
aMuon.setDB( d0_corr, d0_err, pat::Muon::PV3D);
|
619 |
|
620 |
|
621 |
// Correct to beam spot
|
622 |
// make a fake vertex out of beam spot
|
623 |
reco::Vertex vBeamspot(beamspot.position(), beamspot.covariance3D());
|
624 |
|
625 |
// BS2D
|
626 |
result =
|
627 |
IPTools::signedTransverseImpactParameter(tt,
|
628 |
GlobalVector(innerTrack->px(),
|
629 |
innerTrack->py(),
|
630 |
innerTrack->pz()),
|
631 |
vBeamspot);
|
632 |
d0_corr = result.second.value();
|
633 |
d0_err = beamspotIsValid ? result.second.error() : -1.0;
|
634 |
aMuon.setDB( d0_corr, d0_err, pat::Muon::BS2D);
|
635 |
|
636 |
// BS3D
|
637 |
result =
|
638 |
IPTools::signedImpactParameter3D(tt,
|
639 |
GlobalVector(innerTrack->px(),
|
640 |
innerTrack->py(),
|
641 |
innerTrack->pz()),
|
642 |
vBeamspot);
|
643 |
d0_corr = result.second.value();
|
644 |
d0_err = beamspotIsValid ? result.second.error() : -1.0;
|
645 |
aMuon.setDB( d0_corr, d0_err, pat::Muon::BS3D);
|
646 |
}
|
647 |
|
648 |
#include "FWCore/Framework/interface/MakerMacros.h"
|
649 |
|
650 |
DEFINE_FWK_MODULE(PATMuonProducer);
|