ATLAS Offline Software
Loading...
Searching...
No Matches
BeamspotVertexPreProcessor.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
12
14#include "GaudiKernel/SmartDataPtr.h"
15
16//++ new one
17
23#include "TrkTrack/Track.h"
26
27#include <cmath>
28#include <algorithm>
29#include <limits>
30
31
32namespace Trk {
33
34//________________________________________________________________________
36 const std::string & name,
37 const IInterface * parent)
38 : AthAlgTool(type,name,parent)
39 , m_trackTypeCounter(AlignTrack::NTrackTypes,0)
40{
41 declareInterface<IAlignTrackPreProcessor>(this);
42}
43
44//________________________________________________________________________
46= default;
47
48//________________________________________________________________________
50{
51 ATH_MSG_INFO("BeamspotVertexPreProcessor::initialize()");
52
53 // configure main track selector if requested
54 if (!m_trkSelector.empty()) {
55 if (m_trkSelector.retrieve().isFailure())
56 ATH_MSG_ERROR("Failed to retrieve tool "<<m_trkSelector<<". No Track Selection will be done.");
57 else
58 ATH_MSG_INFO("Retrieved " << m_trkSelector);
59 }
60
61 if (m_refitTracks) {
62 // configure main track fitter
63 if(m_trackFitter.retrieve().isFailure()) {
64 ATH_MSG_FATAL("Could not get " << m_trackFitter);
65 return StatusCode::FAILURE;
66 }
67 ATH_MSG_INFO("Retrieved " << m_trackFitter);
68
69 // configure straight-line track fitter if requested
70 if (!m_useSingleFitter) {
71 if (m_SLTrackFitter.retrieve().isFailure()) {
72 ATH_MSG_FATAL("Could not get " << m_SLTrackFitter);
73 return StatusCode::FAILURE;
74 }
75 ATH_MSG_INFO("Retrieved " << m_SLTrackFitter);
76 }
77
78 // TrackToVertexIPEstimator
79 if (m_trackToVertexIPEstimatorTool.retrieve().isFailure()) {
80 ATH_MSG_FATAL("Can not retrieve TrackToVertexIPEstimator of type " << m_trackToVertexIPEstimatorTool.typeAndName());
81 return StatusCode::FAILURE;
82 } else {
83 ATH_MSG_INFO ( "Retrieved TrackToVertexIPEstimator Tool " << m_trackToVertexIPEstimatorTool.typeAndName() );
84 }
85
86 // configure Atlas extrapolator
87 if (m_extrapolator.retrieve().isFailure()) {
88 ATH_MSG_FATAL("Failed to retrieve tool "<<m_extrapolator);
89 return StatusCode::FAILURE;
90 }
91 ATH_MSG_INFO("Retrieved " << m_extrapolator);
92
93 // configure beam-spot conditions service
94 ATH_CHECK(m_beamSpotKey.initialize());
95
96 ATH_CHECK(m_PVContainerName.initialize());
97
98 // configure beam-spot track selector if requested
100 if(m_BSTrackSelector.empty()) {
101 ATH_MSG_FATAL("Requested BeamSpot track selection but Track Selector not configured");
102 return StatusCode::FAILURE;
103 }
104 if (m_BSTrackSelector.retrieve().isFailure()) {
105 ATH_MSG_FATAL("Could not get " << m_BSTrackSelector);
106 return StatusCode::FAILURE;
107 }
108 ATH_MSG_INFO("Retrieved " << m_BSTrackSelector);
109 }
110
111 } // end of 'if (m_refitTracks)'
112
113 else if (m_doBeamspotConstraint) {
114 ATH_MSG_FATAL("Requested beam-spot constraint but RefitTracks is False.");
115 return StatusCode::FAILURE;
116 }
117
119 if ( m_alignModuleTool.retrieve().isFailure() ) {
120 ATH_MSG_FATAL("Failed to retrieve tool " << m_alignModuleTool);
121 return StatusCode::FAILURE;
122 }
123 else {
124 ATH_MSG_INFO("Retrieved tool " << m_alignModuleTool);
125
126 ATH_MSG_INFO("************************************************************************");
127 ATH_MSG_INFO("* *");
128 ATH_MSG_INFO("* You have requested the Full Vertex Constraint option. *");
129 ATH_MSG_INFO("* It is your duty to assure that all detector elements *");
130 ATH_MSG_INFO("* used for track fitting are also loaded in the alignment framework!!! *");
131 ATH_MSG_INFO("* *");
132 ATH_MSG_INFO("* Also make sure the accurate track covariance matrix *");
133 ATH_MSG_INFO("* is returned by the GlobalChi2Fitter! *");
134 ATH_MSG_INFO("* *");
135 ATH_MSG_INFO("************************************************************************");
136 }
137
138 }
139 return StatusCode::SUCCESS;
140}
141
142
143bool CompareTwoTracks::operator()(VxTrackAtVertex vtxTrk){ // MD: took away deref*
144
145 ITrackLink* trkLink = vtxTrk.trackOrParticleLink();
146 LinkToTrackParticleBase* linkToTrackParticle = dynamic_cast<Trk::LinkToTrackParticleBase*>(trkLink);
147 if(!linkToTrackParticle) return false;
148 const TrackParticleBase* tpb = *(linkToTrackParticle->cptr());
149
150 const Track* originalTrk = tpb->originalTrack();
151
152 bool equal = false;
153 // compare the addresses of these two tracks directly
154 if(m_method.find("compareAddress") != std::string::npos){
155 if (m_track == originalTrk) equal = true;
156 }
157
158 // compare the perigee parameters of these two tracks, should safer
159 if(m_method.find("comparePerigee") != std::string::npos){
160 const Trk::Perigee * measPer1 = m_track->perigeeParameters();
161 const Trk::Perigee * measPer2 = originalTrk->perigeeParameters();
162 if(! (measPer1 && measPer2 )) equal = false;
163 else{
164 float diff = std::abs(std::numeric_limits<float>::epsilon());
165 if( ( std::abs(measPer1->parameters()[Trk::d0] - measPer2->parameters()[Trk::d0]) > diff)
166 || ( std::abs(measPer1->parameters()[Trk::z0] - measPer2->parameters()[Trk::z0]) > diff)
167 || ( std::abs(measPer1->parameters()[Trk::phi] - measPer2->parameters()[Trk::phi]) > diff)
168 || ( std::abs(measPer1->parameters()[Trk::theta] - measPer2->parameters()[Trk::theta]) > diff)
169 || ( std::abs(measPer1->parameters()[Trk::qOverP] - measPer2->parameters()[Trk::qOverP]) > diff))
170 equal = false;
171 }
172 }
173 return equal;
174}
175
176
177
179
180 if(0 == vtx->vertexType()) {
181 ATH_MSG_DEBUG("this primary vertex has been rejected as type dummy");
182 return false;
183 }
184 if (vtx->numberDoF() <= 0){
185 ATH_MSG_WARNING(" VERY STRANGE!!!, this primary vertex has been rejected as non-positive DoF "<< vtx->numberDoF() <<" the type of this vertex: "<< vtx->vertexType() );
186 return false;
187 }
188 if (static_cast<int>(vtx->vxTrackAtVertex().size()) < m_minTrksInVtx){
189 ATH_MSG_DEBUG(" this primary vertex vxTrackAtVertex size: "<< vtx->vxTrackAtVertex().size() );
190 return false;
191 }
192 return true;
193}
194
195
197
198 if (vtx->numberDoF() <= 0){
199 ATH_MSG_WARNING(" VERY STRANGE!!! , the updated vertex has been rejected as non-positive DoF: "<< vtx->numberDoF() <<" the type of this vertex:"<< vtx->vertexType() );
200 return false;
201 }
202
203 if (static_cast<int>(vtx->vxTrackAtVertex().size()) < m_minTrksInVtx){
204 ATH_MSG_DEBUG(" the updated vertex has been rejected as vxTrackAtVertex size: "<< vtx->vxTrackAtVertex().size() );
205 return false;
206 }
207
208 if ((vtx->covariancePosition())(0,0)<=0 ||
209 (vtx->covariancePosition())(1,1)<=0 ||
210 (vtx->covariancePosition())(2,2)<=0){
211 ATH_MSG_WARNING(" VERY STRANGE!!! , this updated vertex has been rejected as negative diagonal error matrix ");
212 return false;
213 }
214 return true;
215}
216
217
219{
220 if(!vertices) return false;
221
222 for (const xAOD::Vertex* vtx : *vertices) {
223 if (vtx->vertexType() != 1) break;
224 if (isAssociatedToVertex(track, vtx)) return true;
225 }
226
227 return false;
228}
229
230
231//____________________________________________________________________________
233{
234 if(!vertex) return false;
235
236 std::vector<VxTrackAtVertex > vertexTracks = vertex->vxTrackAtVertex();
237 Trk::CompareTwoTracks thisCompare(track, "compareAddress");
238
239 std::vector<VxTrackAtVertex >::const_iterator iVxTrackBegin = vertexTracks.begin();
240 std::vector<VxTrackAtVertex >::const_iterator iVxTrackEnd = vertexTracks.end();
241
242 std::vector<VxTrackAtVertex>::const_iterator findResult = std::find_if(iVxTrackBegin, iVxTrackEnd, thisCompare);
243
244 return findResult != iVxTrackEnd;
245}
246
247
249
250 // do clean up firstly
251 m_allTracksVector.clear();
252
253 const EventContext& ctx = Gaudi::Hive::currentContext();
255
256 for(const xAOD::Vertex* vtx : *vtxReadHandle){
257 if(!selectVertices(vtx)) {
258 ATH_MSG_DEBUG("this vertex did not pass the primary vertex selection...");
259 continue;
260 }
261 if (vtx->vxTrackAtVertexAvailable()){
262 std::vector<VxTrackAtVertex> vtxTracks = vtx->vxTrackAtVertex();
263 m_allTracksVector.emplace_back(vtx, vtxTracks);
264 }
265 else {
266 ATH_MSG_DEBUG("this vertex did not pass the vxTrackAtVertexAvailable() call...");
267 continue;
268 }
269 }
270
271 ATH_MSG_DEBUG("m_allTracksVector size: "<<m_allTracksVector.size());
272}
273
274
276
277 const xAOD::Vertex* findVxCandidate = nullptr;
278
279 for(const auto& thisPair : m_allTracksVector){
280 auto iVxTrackBegin = thisPair.second.begin();
281 auto iVxTrackEnd = thisPair.second.end();
282 Trk::CompareTwoTracks thisCompare(track, "compareAddress");
283
284 auto findResult = std::find_if(iVxTrackBegin, iVxTrackEnd, thisCompare);
285
286 if(findResult != iVxTrackEnd){
287 ATH_MSG_DEBUG("the found VxTrackAtVertex: "<<*findResult);
288 findVxCandidate = thisPair.first;
289 break;
290 }
291 }
292
293 return findVxCandidate;
294}
295
296
298
299 const EventContext& ctx = Gaudi::Hive::currentContext();
300 const VertexOnTrack * vot = nullptr;
301 const xAOD::Vertex* tmpVtx = nullptr;
302 const xAOD::Vertex* updatedVtx = nullptr;
303
304 const xAOD::Vertex* findVtx = findVertexCandidate(track);
305
306 ATH_MSG_DEBUG("findVtx in provideVotFromVertex: "<<findVtx);
307
308 if (!( nullptr==findVtx) ) {
309 vtx = findVtx;
310
312 updatedVtx = new xAOD::Vertex(*vtx);
313 } else {
314 tmpVtx = new xAOD::Vertex(*vtx);
315 updatedVtx = m_trackToVertexIPEstimatorTool->getUnbiasedVertex(track->perigeeParameters(), vtx );
316 }
317
318
319 if(updatedVtx){
320
321 if(!selectUpdatedVertices(updatedVtx))
322 return vot;
323
325 ATH_MSG_DEBUG(" updated Vertex by KalmanVertexUpdator: "<<updatedVtx);
326
328 Amg::Vector3D globPos(updatedVtx->position()); //look
329 const PerigeeSurface surface(globPos);
330 const Perigee* perigee = nullptr;
331 std::unique_ptr<const Trk::TrackParameters> tmp =
332 m_extrapolator->extrapolateTrack(ctx, *track, surface);
333 //pass ownership only if of correct type
334 if (tmp && tmp->associatedSurface().type() == Trk::SurfaceType::Perigee) {
335 perigee = static_cast<const Perigee*> (tmp.release());
336 }
337 if (!perigee) {
338 const Perigee * trackPerigee = track->perigeeParameters();
339 if ( trackPerigee && trackPerigee->associatedSurface() == surface )
340 perigee = trackPerigee->clone();
341 }
342 //if the perigee is still nonsense ...
343 if (not perigee){
344 //clean up
345 if (updatedVtx!= tmpVtx) delete updatedVtx;
346 delete tmpVtx;
347 //WARNING
348 ATH_MSG_WARNING("Perigee is nullptr in "<<__FILE__<<":"<<__LINE__);
349 //exit
350 return vot;
351 }
352
353 // create the Jacobian matrix from Cartisian to Perigee
354 AmgMatrix(2,3) Jacobian;
355 Jacobian.setZero();
356 //perigee is dereferenced here, must not be nullptr!
357 double ptInv = 1./perigee->momentum().perp();
358 Jacobian(0,0) = -ptInv*perigee->momentum().y();
359 Jacobian(0,1) = ptInv*perigee->momentum().x();
360 Jacobian(1,2) = 1.0;
361
362 ATH_MSG_DEBUG(" Jacobian matrix from Cartesian to Perigee: "<< Jacobian);
363
364 AmgSymMatrix(3) vtxCov = updatedVtx->covariancePosition();
366
367 Amg::MatrixX errorMatrix;
369 AmgSymMatrix(3) tmpCov;
370 tmpCov.setZero();
371 tmpCov(0,0) = 1.e-10 ;
372 tmpCov(1,1) = 1.e-10;
373 tmpCov(2,2) = 1.e-10;
374 errorMatrix = Amg::MatrixX( tmpCov.similarity(Jacobian) );
375 } else {
376 errorMatrix = Amg::MatrixX( vtxCov.similarity(Jacobian) );
377 }
378 delete perigee;
379
380 // in fact, in most of the normal situation, pointer tmpVtx and updatedVtx are the same. You can check the source code
381 // But for safety, I would like to delete them seperately
382 // sroe(2016.09.23): This would result in an illegal double delete, if they really point to the same thing!
383 // http://stackoverflow.com/questions/9169774/what-happens-in-a-double-delete
384 if (tmpVtx != updatedVtx){
385 delete updatedVtx;
386 }
387 delete tmpVtx;
388 tmpVtx=nullptr;
389 updatedVtx=nullptr;
390
392
393 // VertexOnTrack Object
394 vot = new VertexOnTrack(std::move(localParams), std::move(errorMatrix), surface);
395 ATH_MSG_DEBUG("the VertexOnTrack created from vertex: "<<*vot);
396 }
397 }
398
399 return vot;
400
401}
402
403
405
406 const EventContext& ctx = Gaudi::Hive::currentContext();
407 const VertexOnTrack * vot = nullptr;
409 Amg::Vector3D bpos = beamSpotHandle->beamPos();
410 ATH_MSG_DEBUG("beam spot: "<<bpos);
411 float beamSpotX = bpos.x();
412 float beamSpotY = bpos.y();
413 float beamSpotZ = bpos.z();
414 float beamTiltX = beamSpotHandle->beamTilt(0);
415 float beamTiltY = beamSpotHandle->beamTilt(1);
416 float beamSigmaX = m_BSScalingFactor * beamSpotHandle->beamSigma(0);
417 float beamSigmaY = m_BSScalingFactor * beamSpotHandle->beamSigma(1);
418
419 ATH_MSG_DEBUG("running refit with beam-spot");
420
421 float z0 = track->perigeeParameters()->parameters()[Trk::z0];
422 float beamX = beamSpotX + std::tan(beamTiltX) * (z0-beamSpotZ);
423 float beamY = beamSpotY + std::tan(beamTiltY) * (z0-beamSpotZ);
424 Amg::Vector3D BSC(beamX, beamY, z0);
425 ATH_MSG_DEBUG("constructing beam point (x,y,z) = ( "<<beamX<<" , "<<beamY<<" , "<<z0<<" )");
426 std::optional<PerigeeSurface> surface = std::nullopt;
427 Amg::MatrixX errorMatrix;
428 LocalParameters beamSpotParameters;
429
430 // covariance matrix of the beam-spot
431 AmgSymMatrix(2) beamSpotCov;
432 beamSpotCov.setZero();
433 beamSpotCov(0,0) = beamSigmaX * beamSigmaX;
434 beamSpotCov(1,1) = beamSigmaY * beamSigmaY;
435
436 if(m_constraintMode == 0u) {
437
438 const Amg::Vector3D& globPos(BSC);
439 surface.emplace(globPos);
440
441 // create a measurement for the beamspot
442 DefinedParameter Par0(0.,Trk::d0);
443 beamSpotParameters = LocalParameters(Par0);
444
445 // calculate perigee parameters wrt. beam-spot
446 const Perigee* perigee = nullptr;
447 std::unique_ptr<const Trk::TrackParameters> tmp =
448 m_extrapolator->extrapolateTrack(ctx, *track, *surface);
449 // pass ownership only if of correct type
450 if (tmp && tmp->associatedSurface().type() == Trk::SurfaceType::Perigee) {
451 perigee = static_cast<const Perigee*>(tmp.release());
452 }
453
454 if (!perigee) {
455 const Perigee * trackPerigee = track->perigeeParameters();
456 if ( trackPerigee && trackPerigee->associatedSurface() == *surface )
457 perigee = trackPerigee->clone();
458 }
459 if (not perigee){
460 ATH_MSG_WARNING("Perigee is nullptr in "<<__FILE__<<":"<<__LINE__);
461 return vot;
462 }
463
464 Eigen::Matrix<double,1,2> jacobian;
465 jacobian.setZero();
466 //perigee is dereferenced here, must not be nullptr
467 double ptInv = 1./perigee->momentum().perp();
468 jacobian(0,0) = -ptInv * perigee->momentum().y();
469 jacobian(0,1) = ptInv * perigee->momentum().x();
470
471 errorMatrix = Amg::MatrixX( jacobian*(beamSpotCov*jacobian.transpose()));
472 if( errorMatrix.cols() != 1 )
473 ATH_MSG_FATAL("Similarity transpose done incorrectly");
474 delete perigee;
475 }
476 if (surface){
477 vot = new VertexOnTrack(std::move(beamSpotParameters),
478 std::move(errorMatrix),
479 *surface);
480 } else {
481 ATH_MSG_WARNING("surface is nullptr in "<<__FILE__<<":"<<__LINE__);
482 }
483 if (vot){
484 ATH_MSG_DEBUG(" the VertexOnTrack objects created from BeamSpot are " << *vot);
485 }
486
487 return vot;
488}
489
490
492
494 Amg::Vector3D bpos = beamSpotHandle->beamPos();
495 ATH_MSG_DEBUG("beam spot: "<<bpos);
496 float beamSpotX = bpos.x();
497 float beamSpotY = bpos.y();
498 float beamSpotZ = bpos.z();
499 float beamTiltX = beamSpotHandle->beamTilt(0);
500 float beamTiltY = beamSpotHandle->beamTilt(1);
501 float beamSigmaX = m_BSScalingFactor * beamSpotHandle->beamSigma(0);
502 float beamSigmaY = m_BSScalingFactor * beamSpotHandle->beamSigma(1);
503 float beamSigmaZ = m_BSScalingFactor * beamSpotHandle->beamSigma(2);
504
505 float z0 = b->originalPosition()->z();
506 (*v)(0) = beamSpotX + std::tan(beamTiltX) * (z0-beamSpotZ);
507 (*v)(1) = beamSpotY + std::tan(beamTiltY) * (z0-beamSpotZ);
508 (*v)(2) = beamSpotZ;
509 (*q)(0,0) = beamSigmaX*beamSigmaX;
510 (*q)(1,1) = beamSigmaY*beamSigmaY;
511 (*q)(2,2) = beamSigmaZ*beamSigmaZ;
512
513 ATH_MSG_DEBUG("VTX constraint point (x,y,z) = ( "<< (*v)[0] <<" , "<< (*v)[1] <<" , "<< (*v)[2] <<" )");
514 ATH_MSG_DEBUG("VTX constraint size (x,y,z) = ( "<< beamSigmaX <<" , "<< beamSigmaY <<" , "<< beamSigmaZ <<" )");
515}
516
517const Track*
519 ToolHandle<Trk::IGlobalTrackFitter>& fitter,
520 const Track* track,
521 const VertexOnTrack* vot,
522 const ParticleHypothesis& particleHypothesis) const
523{
524 const EventContext& ctx = Gaudi::Hive::currentContext();
525 const Track* newTrack = nullptr;
526
527 if(vot){
528
529 std::vector<const MeasurementBase *> measurementCollection;
530 measurementCollection.push_back(vot);
531 // add all other measurements
532 const auto &measurements = *(track->measurementsOnTrack());
533 for(const MeasurementBase* meas : measurements)
534 measurementCollection.push_back(meas);
535
537 // get track parameters at the vertex:
538 const PerigeeSurface& surface=vot->associatedSurface();
539 ATH_MSG_DEBUG(" Track reference surface will be: " << surface);
540 const TrackParameters* parsATvertex=m_extrapolator->extrapolateTrack(ctx, *track, surface).release();
541
542 ATH_MSG_DEBUG(" Track will be refitted at this surface ");
543 newTrack = (fitter->fit(ctx, measurementCollection,
544 *parsATvertex, m_runOutlierRemoval, particleHypothesis)).release();
545 delete parsATvertex;
546 } else {
547 newTrack = (fitter->fit(ctx,
548 measurementCollection, *(track->trackParameters()->front()),
549 m_runOutlierRemoval, particleHypothesis)).release();
550 }
551 }
552
553 return newTrack;
554}
555
557
558 const xAOD::VertexContainer* vertices = nullptr;
559 const xAOD::Vertex* vertex = nullptr;
560 bool haveVertex = false;
561
562 // retrieve the primary vertex if needed
564
565 const EventContext& ctx = Gaudi::Hive::currentContext();
567 if(!vtxReadHandle.isValid()){
568 ATH_MSG_ERROR("Cannot retrieve the \'"<<m_PVContainerName<<"\' vertex collection from StoreGate");
570 } else {
571 vertices = vtxReadHandle.cptr();
572 // if there is no vertex, we can't associate the tracks to it
573 if(vertices) {
574 ATH_MSG_DEBUG("Primary vertex collection for this event has "<<vertices->size()<<" vertices");
575 if (vertices->size()<2){
576 ATH_MSG_DEBUG("Only Dummy vertex present, no Primary vertices.");
577 } else {
578 vertex = (*vertices)[0];
579 haveVertex = true;
580 }
581 }
582 else
583 ATH_MSG_DEBUG("Could not retrieve primary vertex collection from the StoreGate");
584 }
585 }
586
587
588 if( ( m_doAssociatedToPVSelection && haveVertex && vertex && isAssociatedToPV(track,vertices) ) ||
589 ( m_doBSTrackSelection && m_BSTrackSelector->accept(*track) ) ){
590
591 if (m_maxPt > 0 )
592 {
593 const Trk::Perigee* perigee = track->perigeeParameters();
594 if (!perigee) {
595 ATH_MSG_DEBUG("NO perigee on this track");
596 return false;
597 }
598 const double qoverP = perigee->parameters()[Trk::qOverP] * 1000.;
599 double pt = 0.;
600 if (qoverP != 0 )
601 pt = std::abs(1.0/qoverP)*sin(perigee->parameters()[Trk::theta]);
602 ATH_MSG_DEBUG( " pt : "<< pt );
603 if (pt > m_maxPt)
604 return false;
605 } //maxPt selection
606
607 ATH_MSG_DEBUG("this track passes the beamspot track selection, will do beamspot constraint on it ");
608 return true;
609 }
610 else return false;
611}
612
613
615
616 AlignTrack * alignTrack = nullptr;
617 const Track* newTrack = nullptr;
618 const VertexOnTrack* vot = nullptr;
619 const xAOD::Vertex* vtx = nullptr;
621 // configuration of the material effects needed for track fitter
623
624 // initialization the GX2 track fitter
625 ToolHandle<Trk::IGlobalTrackFitter> fitter = m_trackFitter;
627 fitter = m_SLTrackFitter;
628
630
631 ATH_MSG_DEBUG( "doTrackRefit ** START ** ");
632
634 vot = provideVotFromVertex(track, vtx);
635 if( !vot ) ATH_MSG_INFO( "VoT not found for this track! ");
636 if( !vtx ) ATH_MSG_INFO( "VTX pointer not found for this track! ");
637 if(vot){
638 newTrack = doConstraintRefit(fitter, track, vot, particleHypothesis);
640 // this track failed the PV constraint reift
641 if (!newTrack) {
643 ATH_MSG_DEBUG("VertexConstraint track refit failed! ");
644 }
645 }
646 }
647
649 vot = provideVotFromBeamspot(track);
650 if(vot){
651 newTrack = doConstraintRefit(fitter, track, vot, particleHypothesis);
653 // this track failed the BS constraint refit
654 if (!newTrack) {
656 ATH_MSG_DEBUG("BSConstraint track refit failed! ");
657 }
658 }
659 }
660
661
662 //Refit to get full fitter covariance matrix
663 // @TODO This is a little inefficienct and should
664 // be addressed when the alignment code is made MT safe
665 if(newTrack){
666 Trk::Track* tmpTrk = fitter->alignmentFit(alignCache,*newTrack,m_runOutlierRemoval,particleHypothesis);
667 delete newTrack;
668 newTrack = tmpTrk;
669 if(!tmpTrk){
671 {
673 ATH_MSG_DEBUG("VertexConstraint track refit2 failed! ");
675 {
677 ATH_MSG_DEBUG("BSConstraint track refit2 failed! ");
678 }
679 }
680 }
681
682 if(!newTrack && m_doNormalRefit){
683 newTrack = fitter->alignmentFit(alignCache,*track,m_runOutlierRemoval,particleHypothesis);
685 // this track failed the normal refit
686 if (!newTrack) {
688 ATH_MSG_DEBUG("Normal track refit failed! ");
689 }
690 }
691
692
693
694
695
696 if(newTrack) {
697 alignTrack = new AlignTrack(*newTrack);
698 // set original track pointer
699 alignTrack->setOriginalTrack(track);
700 // set the refit type
701 alignTrack->setType(type);
702
703
704 if (msgLvl(MSG::DEBUG) || msgLvl(MSG::VERBOSE)) {
705 ATH_MSG_DEBUG("before refit: "<< *track);
706 if (msgLvl(MSG::VERBOSE)) AlignTrack::dumpLessTrackInfo(*track,msg(MSG::DEBUG));
707
708 ATH_MSG_DEBUG("after refit: "<< *newTrack);
709 if (msgLvl(MSG::VERBOSE)) AlignTrack::dumpLessTrackInfo(*newTrack,msg(MSG::DEBUG));
710 }
711
713
714 if (m_storeFitMatrices) {
715 alignTrack->setFullCovarianceMatrix(alignCache.m_fullCovarianceMatrix);
716 alignTrack->setDerivativeMatrix(alignCache.m_derivMatrix);
717 }
718 delete newTrack;
719
721 // try to log the track-vertex association in the AlignVertex object:
722 bool ifound=false;
723 for (AlignVertex* ivtx : m_AlignVertices) {
724 if( (ivtx->originalVertex())==vtx ) {
725 ifound = true;
726 }
727 }
728 if( !ifound ) {
729 AlignVertex* avtx=new AlignVertex(vtx);
730 ATH_MSG_DEBUG(" New AlignVertex has ben created.");
731
732 // Beam Spot constraint on the vertex:
733 if( m_doBeamspotConstraint && (xAOD::VxType::PriVtx == vtx->vertexType() || xAOD::VxType::PileUp == vtx->vertexType()) && vtx->vxTrackAtVertex().size()>4 ) { // a beam line verex
734 ATH_MSG_DEBUG(" The Beam Spot constraint will be added to the vertex.." );
735 AmgSymMatrix(3) qtemp;
736 AmgVector(3) vtemp;
737 provideVtxBeamspot(avtx, &qtemp, &vtemp);
738 (qtemp)(2,2) = 1000000.0; // disable Z constraint
739 avtx->setConstraint( &qtemp, &vtemp);
740 }
741
742 m_AlignVertices.push_back(avtx);
743 }
744 }
745 // increment counters
747 ++m_nTracks;
748
749 }
750 // garbage collection:
751 if(vot) delete vot;
752
753 ATH_MSG_DEBUG( "doTrackRefit ** COMPLETED ** ");
754 return alignTrack;
755}
756
757
758
759
760//____________________________________________________________________________
762{
763 ATH_MSG_DEBUG("BeamspotVertexPreProcessor::processTrackCollection()");
764
765 if( !tracks || (tracks->empty()) )
766 return nullptr;
767
768 // Clear the AlignVertex container (will destruct the objects it owns as well!)
769 m_AlignVertices.clear();
770
773
774 // the output collection of AlignTracks
775 // we define it as collection of Tracks but fill AlignTracks inside
776 DataVector<Track> * newTrks = new DataVector<Track>;
777
778 int index(0);
779 // loop over tracks
780 ATH_MSG_DEBUG( "Starting loop on input track collection: "<<index);
781 for (const auto* track : *tracks){
782 ++index;
783 ATH_MSG_DEBUG("Processing track "<<index);
784 AlignTrack * alignTrack = nullptr;
785 if (not track) continue;
786
787 // check whether the track passes the basic selection
788 if (m_doTrkSelection) {
789 ATH_MSG_DEBUG( "Testing track selection on track: "<<index);
790 if ((not m_trkSelector.empty()) and (not m_trkSelector->accept(*track))) continue;
791 } // appliying track selection
792
793 if(m_refitTracks){
794 ATH_MSG_DEBUG( "Refitting track: "<<index );
795 alignTrack = doTrackRefit(track);
796
797 // 2nd track check after refit
798 if(alignTrack && !m_trkSelector.empty()) {
799 // refitted track loses the summary information, restoring it here
800 alignTrack->setTrackSummary( std::make_unique<Trk::TrackSummary> (*track->trackSummary()) );
801 // do not check for FullVertex tracks:
802 if( !(alignTrack->getVtx()) ) {
803 if( m_doTrkSelection && !m_trkSelector->accept(*alignTrack))
804 continue;
805 }
806 }
807 else {
808 ATH_MSG_DEBUG( "Refit of track " << index << " ended with no alignTrack" );
809 }
810 } else {
811 ATH_MSG_DEBUG( "No Track refit for track " << index << " --> building new aligntrack");
812 alignTrack = new AlignTrack(*track);
813 alignTrack->setOriginalTrack(track);
814 alignTrack->setType(AlignTrack::Original);
815 }
816 // add the new align track to the collection
817 if (alignTrack) newTrks->push_back(alignTrack);
818 } // end of loop over tracks
819
820 ATH_MSG_INFO( "Processing of input track collection completed (size: " << tracks->size() << "). Size of the alignTrack collection: " << newTrks->size() );
821 // delete the collection if it's empty
822 if (newTrks->empty()) {
823 delete newTrks;
824 return nullptr;
825 }
826
827 return newTrks;
828}
829
830//____________________________________________________________________________
832
833 if( !m_doFullVertexConstraint ) return;
834
835 AlignVertex* alignVertex = alignTrack->getVtx();
836
837 ATH_MSG_DEBUG( " In accumulateVTX ");
838 if( !alignVertex ) {
839 ATH_MSG_DEBUG( "This alignTrack is not associated to any vertex -> return. ");
840 return;
841 }
842
843 // get pointers so we can reuse them if they're valid
844 const Amg::MatrixX * ptrWeights = alignTrack->weightMatrix();
845 const Amg::MatrixX * ptrWeightsFD = alignTrack->weightMatrixFirstDeriv();
846 const Amg::VectorX * ptrResiduals = alignTrack->residualVector();
847 const std::vector<AlignModuleDerivatives> * ptrDerivs = alignTrack->derivatives();
848
849 // check if pointers are valid
850 if (!ptrWeights || !ptrWeightsFD || !ptrResiduals || !ptrDerivs) {
851 ATH_MSG_ERROR("something missing from alignTrack!");
852 if (!ptrWeights) ATH_MSG_ERROR("no weights!");
853 if (!ptrWeightsFD) ATH_MSG_ERROR("no weights for first deriv!");
854 if (!ptrResiduals) ATH_MSG_ERROR("no residuals!");
855 if (!ptrDerivs) ATH_MSG_ERROR("no derivatives!");
856 return;
857 }
858
859 // get vectors
860 const Amg::VectorX& residuals = *ptrResiduals;
861 std::vector<AlignModuleDerivatives> derivatives = *ptrDerivs;
862
863 // get weight matrices
864 const Amg::MatrixX& weights = *ptrWeights;
865 const Amg::MatrixX& weightsFirstDeriv = *ptrWeightsFD;
866 ATH_MSG_VERBOSE("weights="<<weights);
867 ATH_MSG_VERBOSE("weightsFirstDeriv="<<weightsFirstDeriv);
868
869 // get all alignPars and all derivatives
870 ATH_MSG_DEBUG("accumulateVTX: The derivative vector size is " << derivatives.size() );
871
872 std::vector<const Amg::VectorX*> allDerivatives[3];
873 Amg::VectorX VTXDerivatives[3];
874 const int WSize(weights.cols());
875 Amg::MatrixX WF(3,WSize);
876 std::vector<AlignModuleVertexDerivatives> derivX;
877
878 for (const auto& deriv : derivatives) {
879 // get AlignModule
880 const AlignModule* module=deriv.first;
881
882 // get alignment parameters
883 if( module ) {
884 Amg::MatrixX F(3,WSize);
885 const std::vector<Amg::VectorX>& deriv_vec = deriv.second;
886 ATH_MSG_VERBOSE( "accumulateVTX: The deriv_vec size is " << deriv_vec.size() );
887 DataVector<AlignPar>* alignPars = m_alignModuleTool->getAlignPars(module);
888 int nModPars = alignPars->size();
889 if ((nModPars+3) != std::ssize(deriv_vec)) {
890 ATH_MSG_ERROR("accumulateVTX: Derivatives w.r.t. the vertex seem to be missing");
891 return;
892 }
893 for (int i=0;i<3;i++) {
894 allDerivatives[i].push_back(&deriv_vec[nModPars+i]);
895 for (int j=0;j<WSize;j++) {
896 F(i,j) = deriv_vec[nModPars+i][j];
897 }
898 }
899
900 // prepare the X object in the AlignVertex:
901 WF += F * weights;
902
903 } else {
904 ATH_MSG_ERROR("accumulateVTX: Derivatives do not have a valid pointer to the module.");
905 return;
906 }
907 }
908
909
910 // second loop to fill the X object:
911 for (const auto& deriv : derivatives) {
912 // get AlignModule
913 const AlignModule* module=deriv.first;
914
915 // get alignment parameters
916 if( module ) {
917 const std::vector<Amg::VectorX>& deriv_vec = deriv.second;
918 std::vector<Amg::VectorX> drdaWF;
919 ATH_MSG_DEBUG("accumulateVTX: The deriv_vec size is "
920 << deriv_vec.size());
921 DataVector<AlignPar>* alignPars = m_alignModuleTool->getAlignPars(module);
922 int nModPars = alignPars->size();
923 if ((nModPars + 3) != std::ssize(deriv_vec)) {
925 "accumulateVTX: Derivatives w.r.t. the vertex seem to be missing");
926 return;
927 }
928 drdaWF.reserve(nModPars);
929 for (int i = 0; i < nModPars; i++) {
930 drdaWF.emplace_back(2.0 * WF * deriv_vec[i]);
931 }
932 ATH_MSG_DEBUG("accumulateVTX: derivX incremented by: " << drdaWF);
933 // now add contribution from this track to the X object:
934 derivX.emplace_back(module,std::move(drdaWF));
935
936 } else {
937 ATH_MSG_ERROR("accumulateVTX: Derivatives do not have a valid pointer to the module.");
938 return;
939 }
940 }
941
942 // prepare derivatives w.r.t. the vertex position:
943 int nmodules = allDerivatives[0].size();
944 ATH_MSG_DEBUG("accumulateVTX: allDerivatives size is " << nmodules);
945 for( int ii=0; ii<3; ++ii ) {
946 VTXDerivatives[ii] = (*(allDerivatives[ii])[0]);
947 for( int jj=1; jj<nmodules; ++jj ) {
948 VTXDerivatives[ii] += (*(allDerivatives[ii])[jj]);
949 }
950 }
951
952 AmgVector(3) vtxV;
953 AmgSymMatrix(3) vtxM;
954
955 Amg::VectorX RHM= weightsFirstDeriv * residuals;
956 ATH_MSG_DEBUG("RHM: "<<RHM);
957
958 for (int ipar=0;ipar<3;ipar++) {
959
960 // calculate first derivative
961 Amg::MatrixX derivativesT = (VTXDerivatives[ipar]).transpose();
962 ATH_MSG_DEBUG("derivativesT (size "<<derivativesT.cols()<<"): "<<derivativesT);
963
964 Amg::MatrixX tempV = (2.* derivativesT * RHM);
965 vtxV[ipar] = tempV(0,0);
966
967 for (int jpar=ipar;jpar<3;jpar++) {
968
969 // calculate second derivatives
970 Amg::MatrixX RHM2 = weights * (VTXDerivatives[jpar]);
971
972 Amg::MatrixX tempM = (2.* derivativesT * RHM2);
973 vtxM(ipar,jpar) = tempM(0,0);
974
975 }
976
977 }
978
979 // increment the vtx algebra objects:
980
981 alignVertex->incrementVector(vtxV);
982 alignVertex->incrementMatrix(vtxM);
983 // ATH_MSG_DEBUG("accumulateVTX: derivX size = "<< derivX->size());
984 alignVertex->addDerivatives(&derivX);
985
986}
987
988
989//____________________________________________________________________________
991
993 ATH_MSG_DEBUG("In solveVTX. Number of vertices = " << m_AlignVertices.size() );
994 for (AlignVertex* ivtx : m_AlignVertices) {
995 if( ivtx->Ntracks()>1 ) {
996 ivtx->fitVertex();
997 } else {
998 ATH_MSG_WARNING("This vertex contains " << ivtx->Ntracks() << " tracks. No solution possible.");
999 }
1000
1001 ATH_MSG_DEBUG( "This vertex contains " << ivtx->Ntracks() << " tracks.");
1002 if( msgLvl(MSG::DEBUG) ) ivtx->dump(msg(MSG::DEBUG));
1003 }
1004 }
1005}
1006
1007//____________________________________________________________________________
1009{
1010 if(m_logStream) {
1011
1012 *m_logStream<<"*************************************************************"<<std::endl;
1013 *m_logStream<<"****** BeamspotVertexPreProcessor summary ******"<<std::endl;
1014 *m_logStream<<"*"<<std::endl;
1015 *m_logStream<<"* number of created AlignTracks : "<<m_nTracks<<std::endl;
1016 if(m_nTracks>0) {
1017 *m_logStream<<"* --------------------------------------------"<<std::endl;
1018 for(int i=0; i<AlignTrack::NTrackTypes; ++i) {
1019 if(m_trackTypeCounter[i]>0)
1020 *m_logStream<<"* "<<(AlignTrack::AlignTrackType)i<<": "<<m_trackTypeCounter[i]<<std::endl;
1021 }
1022 }
1023 *m_logStream<<"*"<<std::endl;
1024 *m_logStream<<"* number of failed normal refits : " << m_nFailedNormalRefits << std::endl;
1025 *m_logStream<<"* number of failed refits with primary vertex : " << m_nFailedPVRefits << std::endl;
1026 *m_logStream<<"* number of failed refits with beam-spot : " << m_nFailedBSRefits << std::endl;
1027 *m_logStream<<"*"<<std::endl;
1028 }
1029}
1030
1031//____________________________________________________________________________
1033{
1034 ATH_MSG_INFO("BeamspotVertexPreProcessor::finalize()");
1035
1036 return StatusCode::SUCCESS;
1037}
1038
1039//____________________________________________________________________________
1040}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
An STL vector of pointers that by default owns its pointed-to elements.
#define AmgSymMatrix(dim)
#define AmgVector(rows)
#define AmgMatrix(rows, cols)
#define F(x, y, z)
Definition MD5.cxx:112
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
Derived DataVector<T>.
Definition DataVector.h:795
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
bool fit(const LArSamples::AbsShape &data, const AbsShape &reference, double &k, double &deltaT, double &chi2, const ScaledErrorData *sed=0) const
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
const std::vector< AlignModuleDerivatives > * derivatives() const
The Amg::VectorX is a vector of first-derivatives of the alignTSOS on the alignTrack w....
Definition AlignTrack.h:133
void setOriginalTrack(const Track *track)
set pointer to original track
Definition AlignTrack.h:93
@ NTrackTypes
total number of track types
Definition AlignTrack.h:53
@ NormalRefitted
normally refitted, without adding any pseudo-measurement
Definition AlignTrack.h:48
@ Original
not refitted, just copy constructed from original Track
Definition AlignTrack.h:47
@ Unknown
default type
Definition AlignTrack.h:46
@ BeamspotConstrained
refitted with beamspot constraint
Definition AlignTrack.h:49
@ VertexConstrained
refitted with vertex constraint
Definition AlignTrack.h:50
const Amg::VectorX * residualVector() const
Vector of residuals of the alignTSOS on the alignTrack, to be set by AlignTrackDresser.
Definition AlignTrack.h:150
static void dumpLessTrackInfo(const Track &track, MsgStream &msg)
dump less track information
void doFindPerigee() const
For the AlignTrack, if there is pseudo-measurement in the TSOS collection, the perigee will not alway...
Definition AlignTrack.h:104
void setType(AlignTrackType type)
Definition AlignTrack.h:97
const Amg::SymMatrixX * weightMatrixFirstDeriv() const
First deriv weight matrix can be either W from Si alignment (see Eqn.
Definition AlignTrack.h:161
void setDerivativeMatrix(const Amg::MatrixX *matrix)
Definition AlignTrack.h:269
const AlignVertex * getVtx() const
set and get pointer to the associated vertex
Definition AlignTrack.h:188
const Amg::SymMatrixX * weightMatrix() const
Weight matrix is W from Si alignment (see Eqn.
Definition AlignTrack.h:156
void setFullCovarianceMatrix(const Amg::SymMatrixX *matrix)
Definition AlignTrack.h:274
bool isSLTrack() const
method to determine whether a straight line track or not
void addDerivatives(std::vector< AlignModuleVertexDerivatives > *vec)
void incrementMatrix(const AmgSymMatrix(3) vtxM)
void setConstraint(AmgSymMatrix(3) *, Amg::Vector3D *)
set and get the constraint on VTX position
void incrementVector(const Amg::Vector3D &vtxV)
increment algebra objects for this verterx:
bool doBeamspotConstraintTrackSelection(const Track *track)
PublicToolHandle< IAlignModuleTool > m_alignModuleTool
Pointer to AlignModuleTool.
SG::ReadHandleKey< xAOD::VertexContainer > m_PVContainerName
void accumulateVTX(AlignTrack *alignTrack) override
methods added for the full VTX fit:
const VertexOnTrack * provideVotFromVertex(const Track *track, const xAOD::Vertex *&vtx) const
bool selectVertices(const xAOD::Vertex *vtx) const
bool isAssociatedToVertex(const Track *track, const xAOD::Vertex *vertex)
ToolHandle< InDet::IInDetTrackSelectionTool > m_trkSelector
bool isAssociatedToPV(const Track *track, const xAOD::VertexContainer *vertices)
ToolHandle< IGlobalTrackFitter > m_trackFitter
const xAOD::Vertex * findVertexCandidate(const Track *track) const
AlignTrack * doTrackRefit(const Track *track)
virtual DataVector< Track > * processTrackCollection(const DataVector< Track > *trks) override
Main processing of track collection.
void provideVtxBeamspot(const AlignVertex *b, AmgSymMatrix(3) *q, Amg::Vector3D *v) const
ToolHandle< IExtrapolator > m_extrapolator
DataVector< AlignVertex > m_AlignVertices
collection of AlignVertices used in FullVertex constraint option
std::vector< std::pair< const xAOD::Vertex *, std::vector< VxTrackAtVertex > > > m_allTracksVector
const Track * doConstraintRefit(ToolHandle< IGlobalTrackFitter > &fitter, const Track *track, const VertexOnTrack *vot, const ParticleHypothesis &particleHypothesis) const
ToolHandle< IGlobalTrackFitter > m_SLTrackFitter
virtual StatusCode initialize() override
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
ToolHandle< InDet::IInDetTrackSelectionTool > m_BSTrackSelector
ToolHandle< ITrackToVertexIPEstimator > m_trackToVertexIPEstimatorTool
virtual void printSummary() override
Print processing summary to logfile.
bool selectUpdatedVertices(const xAOD::Vertex *updatedVtx) const
BeamspotVertexPreProcessor(const std::string &type, const std::string &name, const IInterface *parent)
const VertexOnTrack * provideVotFromBeamspot(const Track *track) const
bool operator()(VxTrackAtVertex vtxTrk)
std::ostream * m_logStream
logfile output stream
This class is the pure abstract base class for all fittable tracking measurements.
const Amg::Vector3D & momentum() const
Access method for the momentum.
virtual ParametersT< DIM, T, S > * clone() const override final
Virtual clone.
virtual const S & associatedSurface() const override final
Access to the Surface method.
Class describing the Line to which the Perigee refers to.
const Track * originalTrack() const
Return pointer to associated track.
void setTrackSummary(std::unique_ptr< Trk::TrackSummary > input)
Set the track summary.
const Perigee * perigeeParameters() const
return Perigee.
Class to handle Vertex On Tracks, it inherits from the common MeasurementBase.
virtual const PerigeeSurface & associatedSurface() const override final
returns the surface for the local to global transformation
The VxTrackAtVertex is a common class for all present TrkVertexFitters The VxTrackAtVertex is designe...
const ITrackLink * trackOrParticleLink(void) const
float numberDoF() const
Returns the number of degrees of freedom of the vertex fit as float.
VxType::VertexType vertexType() const
The type of the vertex.
std::vector< Trk::VxTrackAtVertex > & vxTrackAtVertex()
Non-const access to the VxTrackAtVertex vector.
const Amg::Vector3D & position() const
Returns the 3-pos.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Ensure that the ATLAS eigen extensions are properly loaded.
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ v
Definition ParamDefs.h:78
@ u
Enums for curvilinear frames.
Definition ParamDefs.h:77
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ phi
Definition ParamDefs.h:75
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
std::pair< double, ParamDefs > DefinedParameter
Typedef to of a std::pair<double, ParamDefs> to identify a passed-through double as a specific type o...
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
ParametersBase< TrackParametersDim, Charged > TrackParameters
Definition index.py:1
@ PileUp
Pile-up vertex.
@ PriVtx
Primary vertex.
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
Amg::MatrixX * m_derivMatrix
access to the matrix of derivatives used during the latest global-chi2 track fit.
Amg::MatrixX * m_fullCovarianceMatrix
access to the global fitter's full covariance matrix.