17 #include "GaudiKernel/SmartDataPtr.h"
40 #include <ext/algorithm>
48 const std::string &
name,
51 , m_trackFitter(
"Trk::GlobalChi2Fitter/InDetTrackFitter")
53 , m_extrapolator(
"Trk::Extrapolator/AtlasExtrapolator")
55 , m_BSTrackSelector(
"")
56 , m_alignModuleTool(
"Trk::AlignModuleTool/AlignModuleTool")
57 , m_PVContainerName(
"PrimaryVertices")
58 , m_runOutlierRemoval(false)
59 , m_selectVertices(true)
61 , m_doTrkSelection (true)
62 , m_doBSTrackSelection(false)
63 , m_doAssociatedToPVSelection(true)
65 , m_compareMethod(
"compareAddress")
66 , m_doBeamspotConstraint(true)
67 , m_doPrimaryVertexConstraint(false)
68 , m_doFullVertexConstraint(false)
69 , m_doNormalRefit(true)
72 , m_storeFitMatrices(true)
73 , m_useSingleFitter(false)
74 , m_BSScalingFactor(1.)
75 , m_PVScalingFactor(1.)
78 , m_trackTypeCounter(
AlignTrack::NTrackTypes,0)
79 , m_nFailedNormalRefits(0)
80 , m_nFailedBSRefits(0)
81 , m_nFailedPVRefits(0)
83 declareInterface<IAlignTrackPreProcessor>(
this);
101 declareProperty(
"DoFullVertex",
m_doFullVertexConstraint ,
"Full 3D vertex constraint. Note DoPVConstraint needs to be set to true to use this option. If DoBSConstraint vertex position will be constrained to the BS" );
111 std::vector<std::string> defaultInterestedVertexContainers;
112 defaultInterestedVertexContainers.emplace_back(
"PrimaryVertices");
126 ATH_MSG_INFO(
"BeamspotVertexPreProcessor::initialize()");
140 return StatusCode::FAILURE;
148 return StatusCode::FAILURE;
156 return StatusCode::FAILURE;
164 return StatusCode::FAILURE;
175 msg(
MSG::FATAL) <<
"Requested BeamSpot track selection but Track Selector not configured"<<
endmsg;
176 return StatusCode::FAILURE;
180 return StatusCode::FAILURE;
189 return StatusCode::FAILURE;
195 return StatusCode::FAILURE;
200 ATH_MSG_INFO(
"************************************************************************");
202 ATH_MSG_INFO(
"* You have requested the Full Vertex Constraint option. *");
203 ATH_MSG_INFO(
"* It is your duty to assure that all detector elements *");
204 ATH_MSG_INFO(
"* used for track fitting are also loaded in the alignment framework!!! *");
206 ATH_MSG_INFO(
"* Also make sure the accurate track covariance matrix *");
207 ATH_MSG_INFO(
"* is returned by the GlobalChi2Fitter! *");
209 ATH_MSG_INFO(
"************************************************************************");
213 return StatusCode::SUCCESS;
221 if(!linkToTrackParticle)
return false;
228 if(
m_method.find(
"compareAddress") != std::string::npos){
234 if(
m_method.find(
"comparePerigee") != std::string::npos){
237 if(! (measPer1 && measPer2 ))
equal =
false;
239 float diff = std::abs(std::numeric_limits<float>::epsilon());
240 if( ( std::abs(measPer1->parameters()[
Trk::d0] - measPer2->parameters()[
Trk::d0]) >
diff)
241 || ( std::abs(measPer1->parameters()[
Trk::z0] - measPer2->parameters()[
Trk::z0]) >
diff)
257 ATH_MSG_DEBUG(
"this primary vertex has been rejected as type dummy");
261 ATH_MSG_WARNING(
" VERY STRANGE!!!, this primary vertex has been rejected as non-positive DoF "<< vtx->
numberDoF() <<
" the type of this vertex: "<< vtx->
vertexType() );
275 ATH_MSG_WARNING(
" VERY STRANGE!!! , the updated vertex has been rejected as non-positive DoF: "<< vtx->
numberDoF() <<
" the type of this vertex:"<< vtx->
vertexType() );
284 if ((vtx->covariancePosition())(0,0)<=0 ||
285 (vtx->covariancePosition())(1,1)<=0 ||
286 (vtx->covariancePosition())(2,2)<=0){
287 ATH_MSG_WARNING(
" VERY STRANGE!!! , this updated vertex has been rejected as negative diagonal error matrix ");
302 for ( ; vtxIter != vtxEnd && (*vtxIter)->vertexType() == 1; ++vtxIter ){
315 std::vector<VxTrackAtVertex > vertexTracks =
vertex->vxTrackAtVertex();
318 std::vector<VxTrackAtVertex >::const_iterator iVxTrackBegin = vertexTracks.begin();
319 std::vector<VxTrackAtVertex >::const_iterator iVxTrackEnd = vertexTracks.end();
321 std::vector<VxTrackAtVertex>::const_iterator findResult = std::find_if(iVxTrackBegin, iVxTrackEnd, thisCompare);
323 return findResult != iVxTrackEnd;
336 for(; strs_iter != strs_end; ++strs_iter){
338 if (
evtStore()->contains<xAOD::VertexContainer>(*strs_iter)) {
340 ATH_MSG_DEBUG (
"Could not retrieve xAOD vertex container with key "+(*strs_iter));
348 for(; vtxIter != vtxEnd; ++vtxIter){
350 ATH_MSG_DEBUG(
"this vertex did not pass the primary vertex selection...");
354 if ((*vtxIter)->vxTrackAtVertexAvailable()){
356 std::vector<VxTrackAtVertex> vtxTracks = (*vtxIter)->vxTrackAtVertex();
360 ATH_MSG_DEBUG(
"this vertex did not pass the vxTrackAtVertexAvailable() call...");
376 std::vector< std::pair< const xAOD::Vertex*, std::vector<VxTrackAtVertex> > >::const_iterator iter =
m_allTracksVector.begin();
377 std::vector< std::pair< const xAOD::Vertex*, std::vector<VxTrackAtVertex> > >::const_iterator iterEnd =
m_allTracksVector.end();
379 for(; iter != iterEnd; ++iter){
380 std::pair< const xAOD::Vertex*, std::vector<VxTrackAtVertex> > thisPair = *iter;
389 if(findResult != iVxTrackEnd){
391 findVxCandidate = thisPair.first;
400 return findVxCandidate;
406 const EventContext& ctx = Gaudi::Hive::currentContext();
415 if (!(
nullptr==findVtx) ) {
434 ATH_MSG_DEBUG(
" updated Vertex by KalmanVertexUpdator: "<<updatedVtx);
440 const Perigee* perigee =
nullptr;
441 std::unique_ptr<const Trk::TrackParameters>
tmp =
445 perigee =
static_cast<const Perigee*
> (
tmp.release());
448 const Perigee * trackPerigee =
track->perigeeParameters();
450 perigee = trackPerigee->
clone();
455 if (updatedVtx!= tmpVtx)
delete updatedVtx;
467 double ptInv = 1./perigee->momentum().perp();
468 Jacobian(0,0) = -ptInv*perigee->momentum().y();
469 Jacobian(0,1) = ptInv*perigee->momentum().x();
472 ATH_MSG_DEBUG(
" Jacobian matrix from Cartesian to Perigee: "<< Jacobian);
474 AmgSymMatrix(3) vtxCov = updatedVtx->covariancePosition();
484 tmpCov(0,0) = 1.e-10 ;
485 tmpCov(1,1) = 1.e-10;
486 tmpCov(2,2) = 1.e-10;
487 errorMatrix =
Amg::MatrixX( tmpCov.similarity(Jacobian) );
489 errorMatrix =
Amg::MatrixX( vtxCov.similarity(Jacobian) );
497 if (tmpVtx != updatedVtx){
507 vot =
new VertexOnTrack(std::move(localParams), std::move(errorMatrix), surface);
508 ATH_MSG_DEBUG(
"the VertexOnTrack created from vertex: "<<*vot);
519 const EventContext& ctx = Gaudi::Hive::currentContext();
524 float beamSpotX = bpos.x();
525 float beamSpotY = bpos.y();
526 float beamSpotZ = bpos.z();
527 float beamTiltX = beamSpotHandle->beamTilt(0);
528 float beamTiltY = beamSpotHandle->beamTilt(1);
537 float beamX = beamSpotX +
tan(beamTiltX) * (
z0-beamSpotZ);
538 float beamY = beamSpotY +
tan(beamTiltY) * (
z0-beamSpotZ);
540 ATH_MSG_DEBUG(
"constructing beam point (x,y,z) = ( "<<beamX<<
" , "<<beamY<<
" , "<<
z0<<
" )");
541 std::optional<PerigeeSurface> surface = std::nullopt;
547 beamSpotCov.setZero();
548 beamSpotCov(0,0) = beamSigmaX * beamSigmaX;
549 beamSpotCov(1,1) = beamSigmaY * beamSigmaY;
554 surface.emplace(globPos);
561 const Perigee* perigee =
nullptr;
562 std::unique_ptr<const Trk::TrackParameters>
tmp =
566 perigee =
static_cast<const Perigee*
>(
tmp.release());
570 const Perigee * trackPerigee =
track->perigeeParameters();
572 perigee = trackPerigee->
clone();
581 Eigen::Matrix<double,1,2> jacobian;
584 double ptInv = 1./perigee->momentum().perp();
585 jacobian(0,0) = -ptInv * perigee->momentum().y();
586 jacobian(0,1) = ptInv * perigee->momentum().x();
589 errorMatrix =
Amg::MatrixX( jacobian*(beamSpotCov*jacobian.transpose()));
590 if( errorMatrix.cols() != 1 )
596 std::move(errorMatrix),
602 ATH_MSG_DEBUG(
" the VertexOnTrack objects created from BeamSpot are " << *vot);
614 float beamSpotX = bpos.x();
615 float beamSpotY = bpos.y();
616 float beamSpotZ = bpos.z();
617 float beamTiltX = beamSpotHandle->beamTilt(0);
618 float beamTiltY = beamSpotHandle->beamTilt(1);
624 float z0 =
b->originalPosition()->z();
625 (*v)(0) = beamSpotX +
tan(beamTiltX) * (
z0-beamSpotZ);
626 (*v)(1) = beamSpotY +
tan(beamTiltY) * (
z0-beamSpotZ);
628 (*q)(0,0) = beamSigmaX*beamSigmaX;
629 (*q)(1,1) = beamSigmaY*beamSigmaY;
630 (*q)(2,2) = beamSigmaZ*beamSigmaZ;
632 ATH_MSG_DEBUG(
"VTX constraint point (x,y,z) = ( "<< (*
v)[0] <<
" , "<< (*
v)[1] <<
" , "<< (*
v)[2] <<
" )");
633 ATH_MSG_DEBUG(
"VTX constraint size (x,y,z) = ( "<< beamSigmaX <<
" , "<< beamSigmaY <<
" , "<< beamSigmaZ <<
" )");
638 ToolHandle<Trk::IGlobalTrackFitter>&
fitter,
643 const EventContext& ctx = Gaudi::Hive::currentContext();
644 const Track* newTrack =
nullptr;
648 std::vector<const MeasurementBase *> measurementCollection;
649 measurementCollection.push_back(vot);
653 for ( ; imeas != imeas_end ; ++imeas) measurementCollection.push_back(*imeas);
658 ATH_MSG_DEBUG(
" Track reference surface will be: " << surface);
662 newTrack = (
fitter->
fit(ctx, measurementCollection,
667 measurementCollection, *(
track->trackParameters()->front()),
680 bool haveVertex =
false;
691 ATH_MSG_DEBUG(
"Primary vertex collection for this event has "<<vertices->
size()<<
" vertices");
692 if (vertices->
size()<2){
693 ATH_MSG_DEBUG(
"Only Dummy vertex present, no Primary vertices.");
700 ATH_MSG_DEBUG(
"Could not retrieve primary vertex collection from the StoreGate");
715 const double qoverP = perigee->parameters()[
Trk::qOverP] * 1000.;
723 ATH_MSG_DEBUG(
"this track passes the beamspot track selection, will do beamspot constraint on it ");
733 const Track* newTrack =
nullptr;
751 if( !vot )
ATH_MSG_INFO(
"VoT not found for this track! ");
752 if( !vtx )
ATH_MSG_INFO(
"VTX pointer not found for this track! ");
759 msg(MSG::ERROR)<<
"VertexConstraint track refit failed! "<<
endmsg;
772 msg(MSG::ERROR)<<
"BSConstraint track refit failed! "<<
endmsg;
804 msg(MSG::ERROR)<<
"Normal track refit failed! "<<
endmsg;
842 if( (ivtx->originalVertex())==vtx ) {
852 ATH_MSG_DEBUG(
" The Beam Spot constraint will be added to the vertex.." );
856 (qtemp)(2,2) = 1000000.0;
881 ATH_MSG_DEBUG(
"BeamspotVertexPreProcessor::processTrackCollection()");
883 if( !tracks || (tracks->
empty()) )
903 for ( ; itr != itr_end; ++itr, ++
index) {
907 if (not
track)
continue;
924 if( !(alignTrack->
getVtx()) ) {
933 ATH_MSG_DEBUG(
"No Track refit for track " <<
index <<
" --> building new aligntrack");
939 if (alignTrack) newTrks->
push_back(alignTrack);
942 ATH_MSG_INFO(
"Processing of input track collection completed (size: " << tracks->
size() <<
"). Size of the alignTrack collection: " << newTrks->
size() );
944 if (newTrks->
empty()) {
961 ATH_MSG_DEBUG(
"This alignTrack is not associated to any vertex -> return. ");
969 const std::vector<AlignModuleDerivatives> * ptrDerivs = alignTrack->
derivatives();
972 if (!ptrWeights || !ptrWeightsFD || !ptrResiduals || !ptrDerivs) {
973 msg(MSG::ERROR)<<
"something missing from alignTrack!"<<
endmsg;
974 if (!ptrWeights)
msg(MSG::ERROR)<<
"no weights!"<<
endmsg;
975 if (!ptrWeightsFD)
msg(MSG::ERROR)<<
"no weights for first deriv!"<<
endmsg;
976 if (!ptrResiduals)
msg(MSG::ERROR)<<
"no residuals!"<<
endmsg;
977 if (!ptrDerivs)
msg(MSG::ERROR)<<
"no derivatives!"<<
endmsg;
983 std::vector<AlignModuleDerivatives> derivatives = *ptrDerivs;
992 ATH_MSG_DEBUG(
"accumulateVTX: The derivative vector size is " << derivatives.size() );
996 std::vector<Amg::VectorX*> allDerivatives[3];
999 const int WSize(weights.cols());
1001 std::vector<AlignModuleVertexDerivatives> derivX;
1003 for ( ; derivIt!=derivIt_end ; ++derivIt) {
1012 std::vector<Amg::VectorX>& deriv_vec = derivIt->second;
1013 ATH_MSG_VERBOSE(
"accumulateVTX: The deriv_vec size is " << deriv_vec.size() );
1015 int nModPars = alignPars->
size();
1016 if ((nModPars+3) != (
int)deriv_vec.size() ) {
1017 ATH_MSG_ERROR(
"accumulateVTX: Derivatives w.r.t. the vertex seem to be missing");
1020 for (
int i=0;
i<3;
i++) {
1021 allDerivatives[
i].push_back(&deriv_vec[nModPars+
i]);
1022 for (
int j=0;j<WSize;j++) {
1023 F(
i,j) = deriv_vec[nModPars+
i][j];
1031 ATH_MSG_ERROR(
"accumulateVTX: Derivatives do not have a valid pointer to the module.");
1038 derivIt = derivatives.begin();
1039 for ( ; derivIt!=derivIt_end ; ++derivIt) {
1047 std::vector<Amg::VectorX>& deriv_vec = derivIt->second;
1048 std::vector<Amg::VectorX> drdaWF;
1050 << deriv_vec.size());
1052 int nModPars = alignPars->
size();
1053 if ((nModPars + 3) != (
int)deriv_vec.size()) {
1055 "accumulateVTX: Derivatives w.r.t. the vertex seem to be missing");
1058 drdaWF.reserve(nModPars);
1059 for (
int i = 0;
i < nModPars;
i++) {
1060 drdaWF.emplace_back(2.0 * (WF)*deriv_vec[
i]);
1062 ATH_MSG_DEBUG(
"accumulateVTX: derivX incremented by: " << drdaWF);
1064 derivX.emplace_back(
module,std::move(drdaWF));
1067 ATH_MSG_ERROR(
"accumulateVTX: Derivatives do not have a valid pointer to the module.");
1075 int nmodules = allDerivatives[0].size();
1077 for(
int ii=0; ii<3; ++ii ) {
1078 VTXDerivatives[ii] = (*(allDerivatives[ii])[0]);
1079 for(
int jj=1; jj<nmodules; ++jj ) {
1080 VTXDerivatives[ii] += (*(allDerivatives[ii])[jj]);
1091 for (
int ipar=0;ipar<3;ipar++) {
1095 Amg::MatrixX derivativesT = (VTXDerivatives[ipar]).transpose();
1096 ATH_MSG_DEBUG(
"derivativesT (size "<<derivativesT.cols()<<
"): "<<derivativesT);
1099 vtxV[ipar] = tempV(0,0);
1101 for (
int jpar=ipar;jpar<3;jpar++) {
1107 vtxM(ipar,jpar) = tempM(0,0);
1129 if( ivtx->Ntracks()>1 ) {
1132 msg(MSG::WARNING) <<
"This vertex contains " << ivtx->Ntracks() <<
" tracks. No solution possible." <<
endmsg;
1135 ATH_MSG_DEBUG(
"This vertex contains " << ivtx->Ntracks() <<
" tracks.");
1146 *
m_logStream<<
"*************************************************************"<<std::endl;
1147 *
m_logStream<<
"****** BeamspotVertexPreProcessor summary ******"<<std::endl;
1151 *
m_logStream<<
"* --------------------------------------------"<<std::endl;
1168 ATH_MSG_INFO(
"BeamspotVertexPreProcessor::finalize()");
1170 return StatusCode::SUCCESS;