1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#include "Alignment/CommonAlignmentProducer/interface/AlignmentTracksFromVertexSelector.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Framework/interface/Event.h"
#include "DataFormats/TrackReco/interface/Track.h"
#include "RecoVertex/VertexPrimitives/interface/TransientVertex.h"
#include "RecoVertex/KalmanVertexFit/interface/KalmanVertexFitter.h"
// vertices
#include "RecoVertex/VertexTools/interface/VertexDistanceXY.h"
#include "RecoVertex/VertexTools/interface/VertexDistance3D.h"
// constructor ----------------------------------------------------------------
AlignmentTrackFromVertexSelector::AlignmentTrackFromVertexSelector(const edm::ParameterSet& cfg,
edm::ConsumesCollector& iC)
: ttbESToken_(
iC.esConsumes<TransientTrackBuilder, TransientTrackRecord>(edm::ESInputTag("", "TransientTrackBuilder"))),
vertexToken_(iC.consumes<reco::VertexCollection>(cfg.getParameter<edm::InputTag>("vertices"))),
diLeptonToken_(iC.consumes<reco::TrackCollection>(cfg.getParameter<edm::InputTag>("leptonTracks"))),
useClosestVertex_(cfg.getParameter<bool>("useClosestVertexToDilepton")),
vertexIndex_(cfg.getParameter<unsigned int>("vertexIndex")) {}
// destructor -----------------------------------------------------------------
AlignmentTrackFromVertexSelector::~AlignmentTrackFromVertexSelector() {}
// compute the closest vertex to di-lepton ------------------------------------
const reco::Vertex* AlignmentTrackFromVertexSelector::findClosestVertex(const reco::TrackCollection& leptonTracks,
const reco::VertexCollection* vertices,
const edm::EventSetup& setup) const {
reco::Vertex* defaultVtx = nullptr;
// fill the transient track collection with the lepton tracks
const TransientTrackBuilder* theB = &setup.getData(ttbESToken_);
std::vector<reco::TransientTrack> tks;
for (const auto& track : leptonTracks) {
reco::TransientTrack trajectory = theB->build(track);
tks.push_back(trajectory);
}
// compute the secondary vertex
TransientVertex aTransVtx;
KalmanVertexFitter kalman(true);
aTransVtx = kalman.vertex(tks);
if (!aTransVtx.isValid())
return defaultVtx;
// find the closest vertex to the secondary vertex in 3D
VertexDistance3D vertTool3D;
float minD = 9999.;
int closestVtxIndex = 0;
int counter = 0;
for (const auto& vtx : *vertices) {
double dist3D = vertTool3D.distance(aTransVtx, vtx).value();
if (dist3D < minD) {
minD = dist3D;
closestVtxIndex = counter;
}
counter++;
}
if ((*vertices).at(closestVtxIndex).isValid()) {
return &(vertices->at(closestVtxIndex));
} else {
return defaultVtx;
}
}
// do selection ---------------------------------------------------------------
AlignmentTrackFromVertexSelector::Tracks AlignmentTrackFromVertexSelector::select(
const edm::Handle<reco::TrackCollection>& tc, const edm::Event& evt, const edm::EventSetup& setup) const {
Tracks result;
std::vector<unsigned int> thePVkeys;
// get collection of reconstructed vertices from event
edm::Handle<reco::VertexCollection> vertexHandle = evt.getHandle(vertexToken_);
// get collection of the di-lepton traxks
const auto& leptonTracks = evt.get(diLeptonToken_);
// fill the vector of keys
if (vertexHandle.isValid()) {
const reco::VertexCollection* vertices = vertexHandle.product();
const reco::Vertex* theVtx = nullptr;
if (useClosestVertex_) {
theVtx = findClosestVertex(leptonTracks, vertices, setup);
} else {
if ((*vertices).at(vertexIndex_).isValid()) {
theVtx = &(vertices->at(vertexIndex_));
}
}
if (theVtx) {
for (auto tv = theVtx->tracks_begin(); tv != theVtx->tracks_end(); tv++) {
if (tv->isNonnull()) {
const reco::TrackRef trackRef = tv->castTo<reco::TrackRef>();
thePVkeys.push_back(trackRef.key());
}
}
}
}
std::sort(thePVkeys.begin(), thePVkeys.end());
LogDebug("AlignmentTrackFromVertexSelector")
<< "after collecting the PV keys: thePVkeys.size()" << thePVkeys.size() << std::endl;
for (const auto& key : thePVkeys) {
LogDebug("AlignmentTrackFromVertexSelector") << key << ", ";
}
LogDebug("AlignmentTrackFromVertexSelector") << std::endl;
if (tc.isValid()) {
int indx(0);
// put the track in the collection is it was used for the vertex
for (reco::TrackCollection::const_iterator tk = tc->begin(); tk != tc->end(); ++tk, ++indx) {
reco::TrackRef trackRef = reco::TrackRef(tc, indx);
if (std::find(thePVkeys.begin(), thePVkeys.end(), trackRef.key()) != thePVkeys.end()) {
LogDebug("AlignmentTrackFromVertexSelector") << "track index: " << indx << "filling result vector" << std::endl;
result.push_back(&(*tk));
} // if a valid key is found
} // end loop over tracks
} // if the handle is valid
return result;
}
|