17 const std::string &
name,
18 const std::string &
type,
23 declareInterface<Prompt::IVertexMergingTool>(
this);
32 ATH_CHECK(makeHist(m_histNvtx2TrkInit,
"nvtx_2trk_init", 25, -0.5, 24.5));
33 ATH_CHECK(makeHist(m_histNvtx2TrkPass,
"nvtx_2trk_pass", 25, -0.5, 24.5));
34 ATH_CHECK(makeHist(m_histNvtx2TrkUnmerged,
"nvtx_2trk_unmerged", 25, -0.5, 24.5));
35 ATH_CHECK(makeHist(m_histNvtxMerged,
"nvtx_merged", 25, -0.5, 24.5));
37 ATH_CHECK(makeHist(m_histNewVtxFitChi2,
"newVtxFit_chi2", 100, 0.0, 50.0));
38 ATH_CHECK(makeHist(m_histNewVtxFitProb,
"newVtxFit_prob", 100, 0.0, 1.0));
40 ATH_CHECK(makeHist(m_histNewVtxFitDistToCurr,
"newVtxFit_dist_toCurr", 100, 0.0, 10.0));
41 ATH_CHECK(makeHist(m_histNewVtxFitDistToSeed,
"newVtxFit_dist_toSeed", 100, 0.0, 10.0));
42 ATH_CHECK(makeHist(m_histNewVtxFitDistToSeedPass,
"newVtxFit_dist_toSeed_pass", 100, 0.0, 10.0));
43 ATH_CHECK(makeHist(m_histNewVtxFitDistToSeedFail,
"newVtxFit_dist_toSeed_fail", 100, 0.0, 10.0));
45 ATH_CHECK(makeHist(m_histNewVtxFitProbCandOverSeed,
"newVtxFit_prob_candOverSeed", 100, 0.0, 4.0));
46 ATH_CHECK(makeHist(m_histNewVtxFitProbCandOverSeedPass,
"newVtxFit_prob_candOverSeed_pass", 100, 0.0, 4.0));
47 ATH_CHECK(makeHist(m_histNewVtxFitProbCandOverSeedFail,
"newVtxFit_prob_candOverSeed_fail", 100, 0.0, 4.0));
48 ATH_CHECK(makeHist(m_histNewVtxFitProbCandOverSeed3Trk,
"newVtxFit_prob_candOverSeed_3trk", 100, 0.0, 4.0));
49 ATH_CHECK(makeHist(m_histNewVtxFitProbCandOverSeed3TrkPass,
"newVtxFit_prob_candOverSeed_3trk_pass", 100, 0.0, 4.0));
51 ATH_CHECK(makeHist(m_histVtx2TrkPairDist,
"Vtx2trkPair_dist", 100, 0.0, 100.0));
52 ATH_CHECK(makeHist(m_histVtx2trkPairDistZoom,
"Vtx2trkPair_dist_zoom", 100, 0.0, 10.0));
53 ATH_CHECK(makeHist(m_histVtx2TrkPairSig1,
"Vtx2trkPair_sig1", 100, 0.0, 20.0));
54 ATH_CHECK(makeHist(m_histVtx2TrkPairSig2,
"Vtx2trkPair_sig2", 100, 0.0, 20.0));
56 ATH_CHECK(makeHist(m_histSelectedTrackCountAll,
"selectedTrack_CountAll", 25, -0.5, 24.5));
57 ATH_CHECK(makeHist(m_histSelectedTrackCountMatch2Vtx ,
"selectedTrack_CountMatch2Vtx", 25, -0.5, 24.5));
58 ATH_CHECK(makeHist(m_histSelectedTrackCountWithout2Vtx,
"selectedTrack_CountWithout2Vtx", 25, -0.5, 24.5));
60 ATH_CHECK(makeHist(m_histVtxWithoutLepton2TrkNTrack,
"vtxWithoutLepton2trk_NTrack", 25, -0.5, 24.5));
61 ATH_CHECK(makeHist(m_histVtxWithoutLepton2TrkNPass,
"vtxWithoutLepton2trk_NPass", 25, -0.5, 24.5));
62 ATH_CHECK(makeHist(m_histVtxWithoutLepton2TrkNPassUnmerged,
"vtxWithoutLepton2trk_NPassUnmerged", 25, -0.5, 24.5));
63 ATH_CHECK(makeHist(m_histVtxWithoutLepton2TrkNMerged,
"vtxWithoutLepton2trk_NMerged", 25, -0.5, 24.5));
65 return StatusCode::SUCCESS;
71 std::vector<std::unique_ptr<xAOD::Vertex>> &initVtxs,
72 const std::vector<const xAOD::TrackParticle *> &selectedTracks
79 ATH_MSG_DEBUG(
"===========================================================================" << std::endl
80 <<
name() <<
"::mergeInitVertices - start processing");
88 std::vector<std::unique_ptr<xAOD::Vertex>> vtxsInitPassed;
90 for(std::unique_ptr<xAOD::Vertex> &vtx: initVtxs) {
91 if(passVertexSelection(vtx.get())) {
93 result.vtxsInitPassed.push_back(vtx.get());
94 vtxsInitPassed.push_back(std::move(vtx));
98 const unsigned nvtxInit = initVtxs.size();
99 const unsigned nvtxPass =
result.vtxsInitPassed.size();
101 fillTH1(m_histNvtx2TrkInit, nvtxInit);
106 ATH_MSG_DEBUG(
name() <<
"::mergeInitVertices - processes vertexes without lepton");
108 std::vector<const xAOD::TrackParticle *> tracksWithoutVertex = getTracksWithoutVertex(
109 result.vtxsInitPassed, selectedTracks
114 if(tracksWithoutVertex.size() > m_maxExtraTracks) {
115 ATH_MSG_DEBUG(
" number of tracks without good lepton+track vertex: " << tracksWithoutVertex.size() << std::endl
116 <<
" will only keep the top " << m_maxExtraTracks <<
" tracks");
120 tracksWithoutVertex.erase(tracksWithoutVertex.begin() + m_maxExtraTracks, tracksWithoutVertex.end());
128 name() <<
"::mergeInitVertices - will merge vertexes without lepton" << std::endl
129 <<
" number of selected tracks without good lepton+track vertex: "
130 << tracksWithoutVertex .
size() << std::endl
131 <<
" number of 2-track vertexes without lepton: "
144 fillTH1(m_histVtxWithoutLepton2TrkNTrack, tracksWithoutVertex.size());
150 ATH_MSG_DEBUG(
name() <<
"::mergeInitVertices - finished merging vertexes without lepton" << std::endl
151 <<
" number of tracks without good lepton+track vertex: " << tracksWithoutVertex.size() << std::endl
152 <<
" number of 2-track vertexes without lepton: " << resultExtra.
vtxsInitPassed.size() << std::endl
153 <<
" number of unmerged 2-track vertexes without lepton: " << resultExtra.
vtxsInitPassedNotMerged.size() << std::endl
154 <<
" number of merged vertexes without lepton: " << resultExtra.
vtxsNewMerged.size());
159 ATH_MSG_DEBUG(
"===========================================================================" << std::endl
160 <<
name() <<
"::mergeInitVertices - process 2-track vertexes with lepton" << std::endl
161 <<
" lepton track pT=" << tracklep->
pt() << std::endl
162 <<
" number of initial 2-track vertices: " << initVtxs.size() << std::endl
163 <<
" number of selected 2-track vertices: " <<
result.vtxsInitPassed.size() << std::endl
164 <<
" number of selected ID tracks: " << selectedTracks.size() );
171 if(
result.vtxsInitPassed.size() > 1) {
175 fillTH1(m_histNvtx2TrkPass, nvtxPass);
176 fillTH1(m_histNvtx2TrkUnmerged,
result.vtxsInitPassedNotMerged.size());
188 result.vtxsInitPassedNotMerged.insert(
189 result.vtxsInitPassedNotMerged.end(),
194 result.vtxsNewMerged.insert(
195 result.vtxsNewMerged.end(),
200 ATH_MSG_DEBUG(
"==========================================" << std::endl
201 <<
"mergeInitVertices report" << std::endl
202 <<
" \tnumber of initial 2-track vertices: "
203 << initVtxs.size() << std::endl
204 <<
"\tnumber of passed 2-track vertices: "
205 <<
result.vtxsInitPassed.size() << std::endl
206 <<
"\tnumber of unmerged 2-track vertices: "
207 <<
result.vtxsInitPassedNotMerged.size() << std::endl
208 <<
"\tnumber of merged vertices: "
209 <<
result.vtxsNewMerged.size() << std::endl
211 <<
"\tnumber of tracks without good lepton+track vertex: "
212 << tracksWithoutVertex.size() << std::endl
213 <<
"\tnumber of 2-track vertexes without lepton: "
215 <<
"\tnumber of unmerged 2-track vertexes without lepton: "
217 <<
"\tnumber of merged vertexes without lepton: "
219 <<
name() <<
"::mergeInitVertices - ALL DONE" << std::endl
220 <<
"=========================================="
229 std::vector<std::unique_ptr<xAOD::Vertex>> &initVtxs,
249 if(
result.vtxsInitPassed.size() < 2) {
250 result.vtxsInitPassedNotMerged = std::move(initVtxs);
252 ATH_MSG_DEBUG(
name() <<
"::mergeIteratively2TrackVtxs - too few vertexes: nothing more to do");
260 std::vector<TwoTrackVtx> vtxs2Track;
262 for(std::unique_ptr<xAOD::Vertex> &vtx: initVtxs) {
263 if(vtx->nTrackParticles() != 2) {
264 ATH_MSG_WARNING(
"mergeIteratively2TrackVtxs - wrong number of tracks: " << vtx->nTrackParticles());
268 if(vtx->nTrackParticles() !=2 ) {
269 ATH_MSG_WARNING(
"mergeIteratively2TrackVtxs - vertex does not contain 2 TrackParticles: ntrack=" << vtx->nTrackParticles());
274 vtx2track.
trackId0 = vtx->trackParticle(0);
275 vtx2track.
trackId1 = vtx->trackParticle(1);
278 ATH_MSG_WARNING(
"mergeIteratively2TrackVtxs - failed to find TrackParticles for 2-track vertex");
282 vtx2track.
vertex = vtx.get();
286 vtxs2Track.push_back(vtx2track);
289 ATH_MSG_DEBUG(
name() <<
"::mergeIteratively2TrackVtxs - start processing with " << vtxs2Track.size() <<
" input vertexes ");
291 if(vtxs2Track.size() < 2) {
292 ATH_MSG_WARNING(
"mergeIteratively2TrackVtxs - logic error: found only " << vtxs2Track.size() <<
" 2-track vertex");
301 ATH_MSG_DEBUG(
name() <<
"::mergeIteratively2TrackVtxs - number of 2 track passed vertexes=" << vtxs2Track.size());
304 ATH_MSG_DEBUG(
"Input vertex with 2 tracks sum pT=" << vtx.sumTrackPt <<
"\n " <<
vtxAsStr(vtx.vertex,
true));
310 plotVertexDistances(vtxs2Track);
321 while(currVit != vtxs2Track.end()) {
329 std::unique_ptr<xAOD::Vertex> newMergedVtx =
nullptr;
331 seedVtx, newMergedVtx,
input, currVit, vtxs2Track, vtxType
338 removeMerged2TrackVertexes(newMergedVtx.get(), vtxs2Track);
341 currVit = vtxs2Track.begin();
346 result.vtxsNewMerged.push_back(std::move(newMergedVtx));
361 for(std::unique_ptr<xAOD::Vertex> &vtxUniquePtr: initVtxs) {
363 if (vtxUniquePtr.get() == vtx.vertex){
364 result.vtxsInitPassedNotMerged.push_back(std::move(vtxUniquePtr));
371 ATH_MSG_DEBUG(
name() <<
"::mergeIteratively2TrackVtxs - finished processing:" << std::endl
372 <<
" number of unmerged 2-track vertexes=" << vtxs2Track .
size() << std::endl
373 <<
" number of merged vertexes=" <<
result.vtxsNewMerged.size() );
379 for(
const std::unique_ptr<xAOD::Vertex>& vtx:
result.vtxsNewMerged) {
388 std::unique_ptr<xAOD::Vertex> &newMergedVtx,
391 std::vector<TwoTrackVtx> &vtxs2Track,
395 std::vector<TwoTrackVtx> others;
399 others.push_back(*vit);
408 input, seedVtx, vtxType, others
420 if (mergedVtx == seedVtx){
421 newMergedVtx.reset(
nullptr);
423 newMergedVtx.reset(mergedVtx);
432 std::vector<TwoTrackVtx> &others
451 ATH_MSG_WARNING(
"VertexIterativeFitMergingTool::fitSeedVertexCluster - current vertex is null pointer");
458 others.erase(others.begin());
463 std::unique_ptr<xAOD::Vertex> candVtx =fitSeedPlusOtherVertex(
464 input, seedVtx, currVtx, vtxType
472 ATH_MSG_DEBUG(
"fitSeedVertexCluster - NEW MERGED VERTEX FIT FAILED" << std::endl
473 <<
"---------------------------------------------------------------------------");
475 return fitSeedVertexCluster(
input, std::move(seedVtx), vtxType, others);
481 double probCandOverSeed = -1.0;
484 probCandOverSeed = probCand/probSeed;
487 const double distToSeed =
getDistance(seedVtx, candVtx.get());
488 const double distToCurr =
getDistance(currVtx, candVtx.get());
491 fillTH1(m_histNewVtxFitProb, probCand);
493 fillTH1(m_histNewVtxFitDistToSeed, distToSeed);
494 fillTH1(m_histNewVtxFitDistToCurr, distToCurr);
495 fillTH1(m_histNewVtxFitProbCandOverSeed, probCandOverSeed);
498 fillTH1(m_histNewVtxFitProbCandOverSeed3Trk, probCandOverSeed);
501 std::stringstream
str;
504 str <<
" dist to seed=" << distToSeed <<
", probCandOverSeed=" << probCandOverSeed << std::endl
505 <<
" seed: " <<
vtxAsStr(seedVtx,
false) << std::endl
506 <<
" curr: " <<
vtxAsStr(currVtx,
true)
507 <<
" cand: " <<
vtxAsStr(candVtx.get(),
true)
508 <<
"fitSeedVertexCluster - finished" << std::endl
509 <<
"---------------------------------------------------------------------------" << std::endl;
513 if(!(passVertexSelection(candVtx.get()) && probCandOverSeed > m_minCandOverSeedFitProbRatio)) {
518 ATH_MSG_DEBUG(
"fitSeedVertexCluster - FAIL NEW MERGED VERTEX\n" <<
str.str());
521 fillTH1(m_histNewVtxFitDistToSeedFail, distToSeed);
522 fillTH1(m_histNewVtxFitProbCandOverSeedFail, probCandOverSeed);
527 return fitSeedVertexCluster(
input, seedVtx, vtxType, others);
530 fillTH1(m_histNewVtxFitDistToSeedPass, distToSeed);
531 fillTH1(m_histNewVtxFitProbCandOverSeedPass, probCandOverSeed);
534 fillTH1(m_histNewVtxFitProbCandOverSeed3TrkPass, probCand/probSeed);
541 ATH_MSG_DEBUG(
"fitSeedVertexCluster - PASS NEW MERGED VERTEX" <<
str.str());
544 return fitSeedVertexCluster(
input, candVtx, vtxType, others);
552 std::unique_ptr<xAOD::Vertex> & seedVtx,
554 std::vector<TwoTrackVtx> &others
559 xAOD::Vertex* iterationResult = fitSeedVertexCluster(
input,seedVtx.get(), vtxType,others);
562 if (iterationResult == originalSeed)
return seedVtx.release();
565 else return iterationResult;
570 std::vector<TwoTrackVtx> &vtxs
573 ATH_MSG_WARNING(
"VertexIterativeFitMergingTool::removeMerged2TrackVertexes - merged vertex is null pointer");
580 while(vit != vtxs.end()) {
581 int iCountMatchedTrack = 0;
587 ATH_MSG_WARNING(
"removeMerged2TrackVertexes - merged vertex contains null TrackParticle pointer");
591 if(vit->trackId0 ==
track) { iCountMatchedTrack++; }
592 if(vit->trackId1 ==
track) { iCountMatchedTrack++; }
595 if(iCountMatchedTrack == 2) {
599 vit = vtxs.erase(vit);
602 ATH_MSG_DEBUG(
"removeMerged2TrackVertexes - removed merged 2-track vertex");
607 ATH_MSG_DEBUG(
"removeMerged2TrackVertexes - skip unmerged 2-track vertex");
612 name() <<
"::removeMerged2TrackVertexes - merged vertex ntrack=" << mergedVtx->
nTrackParticles()
613 <<
", removed " << icount <<
" merged 2-track vertexes"
621 const std::vector<TwoTrackVtx> &others
623 for(std::vector<TwoTrackVtx>::const_iterator
fit = others.begin();
fit != others.end(); ++
fit) {
624 for(std::vector<TwoTrackVtx>::const_iterator sit =
fit+1; sit != others.end(); ++sit) {
626 const double sig1 =
Prompt::getNormDist(
fit->vertex->position(), sit->vertex->position(),
fit->vertex->covariance(),
msg(MSG::WARNING));
627 const double sig2 =
Prompt::getNormDist(
fit->vertex->position(), sit->vertex->position(), sit->vertex->covariance(),
msg(MSG::WARNING));
629 fillTH1(m_histVtx2TrkPairDist, dist);
630 fillTH1(m_histVtx2trkPairDistZoom, dist);
631 fillTH1(m_histVtx2TrkPairSig1, sig1);
632 fillTH1(m_histVtx2TrkPairSig2, sig2);
639 const std::vector<xAOD::Vertex*> &passVtxs,
640 const std::vector<const xAOD::TrackParticle *> &selectedTracks
646 std::vector<const xAOD::TrackParticle *> tracksWithoutVertex;
648 unsigned iCountDoMatch = 0;
654 for(
unsigned k = 0;
k < vtx->nTrackParticles(); ++
k) {
657 if(vtxTrack ==
track) {
668 tracksWithoutVertex.push_back(
track);
672 fillTH1(m_histSelectedTrackCountAll, selectedTracks.size());
673 fillTH1(m_histSelectedTrackCountMatch2Vtx, iCountDoMatch);
674 fillTH1(m_histSelectedTrackCountWithout2Vtx, tracksWithoutVertex.size());
676 return tracksWithoutVertex;
698 return fitProb > m_minFitProb;
730 std::vector<const xAOD::TrackParticle *> tracks;
736 tracks.push_back(
track);
739 ATH_MSG_WARNING(
"fitSeedPlusOtherVertex - seed vertex contains TrackParticle null pointer");
750 tracks.push_back(
track);
753 ATH_MSG_WARNING(
"fitSeedPlusOtherVertex - other vertex contains TrackParticle null pointer");
760 std::unique_ptr<xAOD::Vertex> secVtx = m_vertexFitterTool->fitVertexWithSeed(
774 std::vector<const xAOD::TrackParticle *> &selectedTracks,
781 std::vector<std::unique_ptr<xAOD::Vertex>> passVtxs;
783 if(selectedTracks.size() < 2) {
784 ATH_MSG_DEBUG(
"fit2TrackVertexeses - 0 or 1 input tracks - nothing to do");
788 ATH_MSG_DEBUG(
name() <<
"::fit2TrackVertexes - start with " << selectedTracks.size() <<
" tracks");
793 std::sort(selectedTracks.begin(), selectedTracks.end(),
SortTracksByPt());
797 for(std::vector<const xAOD::TrackParticle *>::const_iterator
it1 = selectedTracks.begin();
it1 != selectedTracks.end(); ++
it1) {
798 for(std::vector<const xAOD::TrackParticle *>::const_iterator it2 =
it1 + 1; it2 != selectedTracks.end(); ++it2) {
802 if(!track1 || !track2) {
803 ATH_MSG_WARNING(
"fit2TrackVertexeses - logic error: TrackParticle null pointer");
807 std::vector<const xAOD::TrackParticle *> fit_tracks = {track1, track2};
812 std::unique_ptr<xAOD::Vertex> vtx = m_vertexFitterTool->fitVertexWithPrimarySeed(
813 input, fit_tracks, vtxType
823 if(passVertexSelection(vtx.get())) {
825 passVtxs.push_back(std::move(vtx));
830 ATH_MSG_DEBUG(
name() <<
"::fit2TrackVertexes - finished processing: " << std::endl
831 <<
" number of input tracks: " << selectedTracks.size() << std::endl
832 <<
" number of 2-track combinations: " << icount << std::endl
833 <<
" number of passed 2-track vertexes: " << passVtxs .size() << std::endl
834 <<
name() <<
"::fit2TrackVertexes - all is done" );
847 if(m_outputStream.empty() ||
key.empty()) {
848 return StatusCode::SUCCESS;
852 const std::string hist_key =
"/"+m_outputStream+
"/"+
hname;
857 return m_histSvc->regHist(hist_key,
h);