CMS 3D CMS Logo

PFDisplacedVertexCandidateFinder.cc
Go to the documentation of this file.
2 
6 
8 
9 using namespace std;
10 using namespace reco;
11 
12 //for debug only
13 //#define PFLOW_DEBUG
14 
16  : vertexCandidates_(new PFDisplacedVertexCandidateCollection),
17  dcaCut_(1000),
18  primaryVertexCut2_(0.0),
19  dcaPInnerHitCut2_(1000.0),
20  vertexCandidatesSize_(50),
21  theMinimum_(TwoTrackMinimumDistance::SlowMode),
22  debug_(false),
23  magField_(nullptr) {}
24 
26 #ifdef PFLOW_DEBUG
27  if (debug_)
28  cout << "~PFDisplacedVertexCandidateFinder - number of remaining elements: " << eventTracks_.size() << endl;
29 #endif
30 }
31 
33  edm::Handle<reco::BeamSpot> beamSpotHandle) {
34  const math::XYZPoint beamSpot = beamSpotHandle.isValid()
35  ? math::XYZPoint(beamSpotHandle->x0(), beamSpotHandle->y0(), beamSpotHandle->z0())
36  : math::XYZPoint(0, 0, 0);
37 
38  // The primary vertex is taken from the refitted list,
39  // if does not exist from the average offline beam spot position
40  // if does not exist (0,0,0) is used
41  pvtx_ = mainVertexHandle.isValid()
43  mainVertexHandle->begin()->x(), mainVertexHandle->begin()->y(), mainVertexHandle->begin()->z())
44  : beamSpot;
45 }
46 
47 // Set the imput collection of tracks and calculate their
48 // trajectory parameters the Global Trajectory Parameters
50  const MagneticField* magField) {
51  magField_ = magField;
52  trackMask_.clear();
53  trackMask_.resize(trackh->size());
55  eventTrackTrajectories_.resize(trackh->size());
56 
57  for (unsigned i = 0; i < trackMask_.size(); i++)
58  trackMask_[i] = true;
59 
60  eventTracks_.clear();
61  if (trackh.isValid()) {
62  for (unsigned i = 0; i < trackh->size(); i++) {
63  TrackRef tref(trackh, i);
64  TrackBaseRef tbref(tref);
65 
66  if (!isSelected(tbref)) {
67  trackMask_[i] = false;
68  continue;
69  }
70 
71  const Track* trk = tref.get();
72  eventTracks_.push_back(tbref);
74  }
75  }
76 }
77 
78 // -------- Main function which find vertices -------- //
79 
81  if (debug_)
82  cout << "========= Start Finding Displaced Vertex Candidates =========" << endl;
83 
84  // The vertexCandidates have not been passed to the event, and need to be cleared
85  if (vertexCandidates_.get())
86  vertexCandidates_->clear();
87  else
89 
91  for (IE ie = eventTracks_.begin(); ie != eventTracks_.end();) {
92  // Run the recursive procedure to find all tracks link together
93  // In one blob called Candidate
94 
95  PFDisplacedVertexCandidate tempVertexCandidate;
96 
97  ie = associate(eventTracks_.end(), ie, tempVertexCandidate);
98 
99  // Build remaining links in current block
100  if (tempVertexCandidate.isValid()) {
101  packLinks(tempVertexCandidate);
102  vertexCandidates_->push_back(tempVertexCandidate);
103  }
104  }
105 
106  if (debug_)
107  cout << "========= End Finding Displaced Vertex Candidates =========" << endl;
108 }
109 
111  IE last, IE next, PFDisplacedVertexCandidate& tempVertexCandidate) {
112 #ifdef PFLOW_DEBUG
113  if (debug_)
114  cout << "== Start the association procedure ==" << endl;
115 #endif
116 
117  if (last != eventTracks_.end()) {
118  double dist = -1;
119  GlobalPoint P(0, 0, 0);
121  link((*last), (*next), dist, P, linktest);
122 
123  if (dist < -0.5) {
124 #ifdef PFLOW_DEBUG
125  if (debug_)
126  cout << "link failed" << endl;
127 #endif
128  return ++next; // association failed
129  } else {
130  // add next element to the current pflowblock
131  tempVertexCandidate.addElement((*next));
132  trackMask_[(*next).key()] = false;
133 #ifdef PFLOW_DEBUG
134  if (debug_)
135  cout << "link parameters "
136  << " *next = " << (*next).key() << " *last = " << (*last).key() << " dist = " << dist
137  << " P.x = " << P.x() << " P.y = " << P.y() << " P.z = " << P.z() << endl;
138 #endif
139  }
140  } else {
141  // add next element to this eflowblock
142 #ifdef PFLOW_DEBUG
143  if (debug_)
144  cout << "adding to block element " << (*next).key() << endl;
145 #endif
146  tempVertexCandidate.addElement((*next));
147  trackMask_[(*next).key()] = false;
148  }
149 
150  // recursive call: associate next and other unused elements
151 #ifdef PFLOW_DEBUG
152  if (debug_) {
153  for (unsigned i = 0; i < trackMask_.size(); i++)
154  cout << " Mask[" << i << "] = " << trackMask_[i];
155  cout << "" << endl;
156  }
157 #endif
158 
159  for (IE ie = eventTracks_.begin(); ie != eventTracks_.end();) {
160  if (ie == last || ie == next) {
161  ++ie;
162  continue;
163  }
164 
165  // *ie already included to a block
166  if (!trackMask_[(*ie).key()]) {
167  ++ie;
168  continue;
169  }
170 
171 #ifdef PFLOW_DEBUG
172  if (debug_)
173  cout << "calling associate " << (*next).key() << " & " << (*ie).key() << endl;
174 #endif
175  ie = associate(next, ie, tempVertexCandidate);
176  }
177 
178 #ifdef PFLOW_DEBUG
179  if (debug_) {
180  cout << "**** removing element " << endl;
181  }
182 #endif
183 
184  IE iteratorToNextFreeElement = eventTracks_.erase(next);
185 
186 #ifdef PFLOW_DEBUG
187  if (debug_)
188  cout << "== End the association procedure ==" << endl;
189 #endif
190 
191  return iteratorToNextFreeElement;
192 }
193 
195  const TrackBaseRef& el2,
196  double& dist,
197  GlobalPoint& P,
199  if (fabs(el1->eta() - el2->eta()) > 1) {
200  dist = -1;
201  return;
202  }
203  if (el1->pt() > 2 && el2->pt() > 2 && fabs(el1->phi() - el2->phi()) > 1) {
204  dist = -1;
205  return;
206  }
207 
210 
211  // Closest approach
212  theMinimum_.calculate(gt1, gt2);
213 
214  // Fill the parameters
215  dist = theMinimum_.distance();
217 
218  vertexLinkTest = PFDisplacedVertexCandidate::LINKTEST_DCA; //rechit by default
219 
220  // Check if the link test fails
221  if (dist > dcaCut_) {
222  dist = -1;
223  return;
224  }
225 
226  // Check if the closses approach point is too close to the primary vertex/beam pipe
227  double rho2 = P.x() * P.x() + P.y() * P.y();
228 
229  if (rho2 < primaryVertexCut2_) {
230  dist = -1;
231  return;
232  }
233 
234  // Check if the closses approach point is out of range of the tracker
235 
236  double tob_rho_limit2 = 10000;
237  double tec_z_limit = 270;
238 
239  if (rho2 > tob_rho_limit2) {
240  dist = -1;
241  return;
242  }
243  if (fabs(P.z()) > tec_z_limit) {
244  dist = -1;
245  return;
246  }
247 
248  return;
249 
250  /*
251  // Check if the inner hit of one of the tracks is not too far away from the vertex
252  double dx = el1->innerPosition().x()-P.x();
253  double dy = el1->innerPosition().y()-P.y();
254  double dz = el1->innerPosition().z()-P.z();
255  double dist2 = dx*dx+dy*dy+dz*dz;
256 
257  if (dist2 > dcaPInnerHitCut2_) {
258  dist = -1;
259  if (debug_) cout << "track " << el1.key() << " dist to vertex " << sqrt(dist2) << endl;
260  return;
261  }
262 
263  dx = el2->innerPosition().x()-P.x();
264  dy = el2->innerPosition().y()-P.y();
265  dz = el2->innerPosition().z()-P.z();
266  dist2 = dx*dx+dy*dy+dz*dz;
267 
268  if (dist2 > dcaPInnerHitCut2_) {
269  dist = -1;
270  if (debug_) cout << "track " << el2.key() << " dist to vertex " << sqrt(dist2) << endl;
271  return;
272  }
273  */
274 }
275 
276 // Build up a matrix of all the links between different tracks in
277 // In the Candidate
279  const vector<TrackBaseRef>& els = vertexCandidate.elements();
280 
281  //First Loop: update all link data
282  for (unsigned i1 = 0; i1 < els.size(); i1++) {
283  for (unsigned i2 = i1 + 1; i2 < els.size(); i2++) {
284  // no reflexive link
285  if (i1 == i2)
286  continue;
287 
288  double dist = -1;
289  GlobalPoint P(0, 0, 0);
291 
292  link(els[i1], els[i2], dist, P, linktest);
293 
294 #ifdef PFLOW_DEBUG
295  if (debug_)
296  cout << "Setting link between elements " << i1 << " key " << els[i1].key() << " and " << i2 << " key "
297  << els[i2].key() << " of dist =" << dist << " computed from link test " << linktest << endl;
298 #endif
299 
300  if (dist > -0.5)
301  vertexCandidate.setLink(i1, i2, dist, P, linktest);
302  }
303  }
304 }
305 
306 // --------------- TOOLS -------------- //
307 
308 // This tool is a copy from VZeroFinder
310  const GlobalPoint position(track->vx(), track->vy(), track->vz());
311 
312  const GlobalVector momentum(track->momentum().x(), track->momentum().y(), track->momentum().z());
313 
314  GlobalTrajectoryParameters gtp(position, momentum, track->charge(), magField_);
315 
316  return gtp;
317 }
318 
319 // This tool allow to pre-select the track for the displaced vertex finder
321  double nChi2 = trackref->normalizedChi2();
322  double pt = trackref->pt();
323  double dpt = trackref->ptError();
324  double dxy = trackref->dxy(pvtx_);
325 
326  double pt_error = dpt / pt * 100;
327 
328  if (debug_)
329  cout << " PFDisplacedVertexFinder: PFrecTrack->Track Pt= " << pt << " dPt/Pt = " << pt_error
330  << "% nChi2 = " << nChi2 << endl;
331  if (nChi2 > nChi2_max_ || pt < pt_min_) {
332  if (debug_)
333  cout << " PFBlockAlgo: skip badly measured or low pt track"
334  << " nChi2_cut = " << 5 << " pt_cut = " << 0.2 << endl;
335  return false;
336  }
337  // cout << "dxy = " << dxy << endl;
338  if (fabs(dxy) < dxy_ && pt < pt_min_prim_)
339  return false;
340  // if (fabs(dxy) < 0.2 && pt < 0.8) return false;
341 
342  return true;
343 }
344 
345 ostream& operator<<(std::ostream& out, const PFDisplacedVertexCandidateFinder& a) {
346  if (!out)
347  return out;
348 
349  out << "====== Particle Flow Block Algorithm ======= ";
350  out << endl;
351  out << "number of unassociated elements : " << a.eventTracks_.size() << endl;
352  out << endl;
353 
354  out << " Tracks selection based on " << std::endl;
355  out << " pvtx_ = " << a.pvtx_ << std::endl;
356  out << " fabs(dxy) < " << a.dxy_ << " and pt < " << a.pt_min_prim_ << std::endl;
357  out << " nChi2 < " << a.nChi2_max_ << " and pt < " << a.pt_min_ << std::endl;
358 
359  out << endl;
360 
361  for (PFDisplacedVertexCandidateFinder::IEC ie = a.eventTracks_.begin(); ie != a.eventTracks_.end(); ie++) {
362  double pt = (*ie).get()->pt();
363 
364  math::XYZPoint Pi = (*ie).get()->innerPosition();
365  math::XYZPoint Po = (*ie).get()->outerPosition();
366 
367  double innermost_radius = sqrt(Pi.x() * Pi.x() + Pi.y() * Pi.y() + Pi.z() * Pi.z());
368  double outermost_radius = sqrt(Po.x() * Po.x() + Po.y() * Po.y() + Po.z() * Po.z());
369  double innermost_rho = sqrt(Pi.x() * Pi.x() + Pi.y() * Pi.y());
370  double outermost_rho = sqrt(Po.x() * Po.x() + Po.y() * Po.y());
371 
372  out << "ie = " << (*ie).key() << " pt = " << pt << " innermost hit radius = " << innermost_radius
373  << " rho = " << innermost_rho << " outermost hit radius = " << outermost_radius << " rho = " << outermost_rho
374  << endl;
375  }
376 
377  const std::unique_ptr<reco::PFDisplacedVertexCandidateCollection>& vertexCandidates = std::move(a.vertexCandidates());
378 
379  if (!vertexCandidates.get()) {
380  out << "vertexCandidates already transfered" << endl;
381  } else {
382  out << "number of vertexCandidates : " << vertexCandidates->size() << endl;
383  out << endl;
384 
385  for (PFDisplacedVertexCandidateFinder::IBC ib = vertexCandidates->begin(); ib != vertexCandidates->end(); ib++)
386  ib->Dump();
387  }
388 
389  return out;
390 }
void setInput(const edm::Handle< reco::TrackCollection > &trackh, const MagneticField *magField)
const double Pi
void addElement(const TrackBaseRef)
add a track Reference to the current Candidate
void link(const reco::TrackBaseRef &el1, const reco::TrackBaseRef &el2, double &dist, GlobalPoint &P, reco::PFDisplacedVertexCandidate::VertexLinkTest &linktest)
Check whether 2 elements are linked and fill the link parameters.
double z0() const
z coordinate
Definition: BeamSpot.h:65
std::vector< PFDisplacedVertexCandidate > PFDisplacedVertexCandidateCollection
collection of PFDisplacedVertexCandidate objects
A block of tracks linked together.
double normalizedChi2() const
chi-squared divided by n.d.o.f. (or chi-squared * 1e6 if n.d.o.f. is zero)
Definition: TrackBase.h:572
GlobalTrajectoryParameters getGlobalTrajectoryParameters(const reco::Track *) const
--—— TOOLS --—— //
IE associate(IE next, IE last, reco::PFDisplacedVertexCandidate &tempVertexCandidate)
--—— Different steps of the finder algorithm --—— ///
void setPrimaryVertex(edm::Handle< reco::VertexCollection > mainVertexHandle, edm::Handle< reco::BeamSpot > beamSpotHandle)
#define nullptr
const std::vector< TrackBaseRef > & elements() const
T y() const
Definition: PV3DBase.h:60
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:614
const Vector & momentum() const
track momentum vector
Definition: TrackBase.h:629
friend std::ostream & operator<<(std::ostream &, const PFDisplacedVertexCandidateFinder &)
const std::unique_ptr< reco::PFDisplacedVertexCandidateCollection > & vertexCandidates() const
std::list< reco::TrackBaseRef > eventTracks_
The track refs.
bool calculate(const TrajectoryStateOnSurface &sta, const TrajectoryStateOnSurface &stb) override
void setLink(unsigned i1, unsigned i2, const float dist, const GlobalPoint &dcaPoint, const VertexLinkTest test=LINKTEST_DCA)
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:617
std::list< reco::TrackBaseRef >::iterator IE
size_t key() const
Definition: RefToBase.h:219
T sqrt(T t)
Definition: SSEVec.h:19
double dcaCut_
–— Algo parameters for the vertex finder -— ///
double pt() const
track transverse momentum
Definition: TrackBase.h:602
T z() const
Definition: PV3DBase.h:61
double ptError() const
error on Pt (set to 1000 TeV if charge==0 for safety)
Definition: TrackBase.h:696
bool isValid() const
A Vertex Candidate is valid if it has at least two tracks.
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
std::unique_ptr< reco::PFDisplacedVertexCandidateCollection > vertexCandidates_
-----— Members -----— ///
bool isValid() const
Definition: HandleBase.h:70
GlobalPoint crossingPoint() const override
double vz() const
z coordinate of the reference point on track
Definition: TrackBase.h:626
std::vector< GlobalTrajectoryParameters > eventTrackTrajectories_
reco::PFDisplacedVertexCandidateCollection::const_iterator IBC
float distance() const override
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
std::pair< OmniClusterRef, TrackingParticleRef > P
bool goodPtResolution(const reco::TrackBaseRef &trackref) const
Quality Criterion on the Pt resolution to select a Track.
bool isSelected(const reco::TrackBaseRef &trackref)
std::list< reco::TrackBaseRef >::const_iterator IEC
double vy() const
y coordinate of the reference point on track
Definition: TrackBase.h:623
fixed size matrix
double a
Definition: hdecay.h:119
static int position[264][3]
Definition: ReadPGInfo.cc:289
void packLinks(reco::PFDisplacedVertexCandidate &vertexCandidate)
void findDisplacedVertexCandidates()
-----— Main function which find vertices -----— ///
double y0() const
y coordinate
Definition: BeamSpot.h:63
double primaryVertexCut2_
Do not reconstruct vertices wich are too close to the beam pipe.
int charge() const
track electric charge
Definition: TrackBase.h:575
double dxy() const
dxy parameter. (This is the transverse impact parameter w.r.t. to (0,0,0) ONLY if refPoint is close t...
Definition: TrackBase.h:587
T x() const
Definition: PV3DBase.h:59
bool debug_
if true, debug printouts activated
def move(src, dest)
Definition: eostools.py:511
double vx() const
x coordinate of the reference point on track
Definition: TrackBase.h:620
ib
Definition: cuy.py:662
double x0() const
x coordinate
Definition: BeamSpot.h:61