29 #include <St_base/StMessMgr.h>
35 #include "TObjArray.h"
37 #include <tables/St_g2t_vertex_Table.h>
39 #include "StGenericVertexMaker/StiPPVertex/StPPVertexFinder.h"
40 #include "StGenericVertexMaker/StGenericVertexMaker.h"
41 #include "StGenericVertexMaker/Minuit/St_VertexCutsC.h"
42 #include "StEvent/StDcaGeometry.h"
43 #include "StEvent/StEventTypes.h"
45 #include "StEvent/StTrack.h"
46 #include "StMuDSTMaker/COMMON/StMuBTofHit.h"
47 #include "StMuDSTMaker/COMMON/StMuDst.h"
48 #include "StMuDSTMaker/COMMON/StMuTrack.h"
49 #include "StMuDSTMaker/COMMON/StMuEmcCollection.h"
50 #include "StMuDSTMaker/COMMON/StMuEmcUtil.h"
54 #include <Sti/StiKalmanTrackNode.h>
55 #include <Sti/StiTrackContainer.h>
56 #include "Sti/StiTrack.h"
58 #include <St_db_Maker/St_db_Maker.h>
59 #include <StIOMaker/StIOMaker.h>
60 #include <StBFChain/StBFChain.h>
62 #include "StGenericVertexMaker/StiPPVertex/BtofHitList.h"
63 #include "StGenericVertexMaker/StiPPVertex/CtbHitList.h"
64 #include "StGenericVertexMaker/StiPPVertex/BemcHitList.h"
65 #include "StGenericVertexMaker/StiPPVertex/EemcHitList.h"
67 #include "StEvent/StEmcCollection.h"
68 #include "StEvent/StBTofCollection.h"
69 #include "StBTofUtil/StBTofGeometry.h"
74 StPPVertexFinder::StPPVertexFinder(VertexFit_t fitMode) :
76 mTrackData(), mVertexData(),
77 mTotEve(0), eveID(0), nBadVertex(0),
78 mAlgoSwitches(kSwitchOneHighPT),
79 hA{}, hACorr(
nullptr), hL(
nullptr), hM(
nullptr), hW(
nullptr),
92 mFitPossWeighting(
false),
93 mDropPostCrossingTrack(
true),
94 mStoreUnqualifiedVertex(5),
96 mUseBTOFmatchOnly(
false),
112 hL =
new TH1D(
"ppvL",
"Vertex likelyhood; Z /cm", nb, -zRange, zRange);
114 hM =
new TH1D(
"ppvM",
"cumulative track multiplicity; Z /cm", nb, -zRange, zRange);
115 hW =
new TH1D(
"ppvW",
"cumulative track weight; Z /cm", nb, -zRange, zRange);
121 void StPPVertexFinder::Init()
124 LOG_INFO << Form(
"PPV-algo switches=0x%0x, following cuts have been activated:",mAlgoSwitches)<<endm;
127 mToolkit = StiToolkit::instance();
132 if (mUseBtof && !btofList) {
136 if (mUseCtb && !ctbList) {
140 LOG_INFO <<
"Finished Init" << endm;
145 void StPPVertexFinder::InitRun(
int run_number,
const St_db_Maker* db_maker)
147 StGenericVertexFinder::InitRun(run_number, db_maker);
149 int dateY = db_maker->GetDateTime().GetYear();
156 if (run_number >= 6000000 && run_number < 13000000) {
159 LOG_INFO <<
"PPV InitRun() using old, hardwired cuts" << endm;
167 mMaxTrkDcaRxy = vtxCuts->RImpactMax();
168 mMinTrkPt = vtxCuts->MinTrackPt();
169 mMinFitPfrac = vtxCuts->MinFracOfPossFitPointsOnTrack();
170 mMaxZradius = vtxCuts->DcaZMax();
171 mMinMatchTr = vtxCuts->MinTrack();
172 mFitPossWeighting =
true;
184 if (mUseBtof) btofList->initRun(st_db_maker);
185 if (mUseCtb) ctbList->initRun();
187 bemcList->initRun(st_db_maker);
188 eemcList->initRun(st_db_maker);
190 LOG_INFO <<
"PPV::cuts "
191 <<
"\n MinNumberOfFitPointsOnTrack = unused"
192 <<
"\n MinFitPfrac=nFit/nPos = " << mMinFitPfrac
193 <<
"\n MaxTrkDcaRxy/cm= " << mMaxTrkDcaRxy
194 <<
"\n MinTrkPt GeV/c = " << mMinTrkPt
195 <<
"\n MinMatchTr of prim tracks = " << mMinMatchTr
196 <<
"\n MaxZrange (cm)for glob tracks = " << mMaxZrange
197 <<
"\n MaxZradius (cm) for prim tracks &Likelihood = " << mMaxZradius
198 <<
"\n Min/Max Z position for BTOF hit = " << mMinZBtof <<
" " << mMaxZBtof
199 <<
"\n MinAdcBemc for MIP = " << mMinAdcBemc
200 <<
"\n MinAdcEemc for MIP = " << mMinAdcEemc
201 <<
"\n bool useCtb = " << mUseCtb
202 <<
"\n bool useBtof = " << mUseBtof
203 <<
"\n bool useBTOFmatchOnly = " << mUseBTOFmatchOnly
204 <<
"\n bool nFit/nPoss weighting = " << mFitPossWeighting
205 <<
"\n bool DropPostCrossingTrack = " << mDropPostCrossingTrack
206 <<
"\n Store # of UnqualifiedVertex = " << mStoreUnqualifiedVertex
207 <<
"\n Store=" << (mAlgoSwitches & kSwitchOneHighPT)
208 <<
" oneTrack-vertex if track PT/GeV>" << mCut_oneTrackPT << endm;
214 void StPPVertexFinder::initHisto()
216 hA[0]=
new TH1F(
"ppvStat",
"event types; 1=inp, 2=trg, 3=-, 4=w/trk, 5=anyMch, 6=Bmch 7=Emch 8=anyV, 9=mulV",10,0.5,10.5);
217 hA[1]=
new TH1F(
"ch1",
"chi2/Dof, ppv pool tracks",100,0,10);
218 hA[2]=
new TH1F(
"nP",
"No. of fit points, ppv pool tracks",30,-.5,59.5);
219 hA[3]=
new TH1F(
"zV",
"reconstructed vertices ; Z (cm)",100,-200,200);
220 hA[4]=
new TH1F(
"nV",
"No. of vertices per eve",20,-0.5,19.5);
222 hA[5]=
new TH1F(
"rxyDca",
"Rxy to beam @ DCA ; (cm)",40,-0.1,3.9);
223 hA[6]=
new TH1F(
"nTpcM",
"No. tracks: tpcMatch /eve ",60,-.5,59.5);
224 hA[7]=
new TH1F(
"nTpcV",
"No. tracks: tpcVeto /eve ",60,-.5,59.5);
228 hA[9]=
new TH1F(
"zDca",
"Z DCA for all accepted tracks; Z (cm)",100,-200,200);
230 hA[10]=
new TH1F(
"zCtb",
"Z @CTB for all accepted tracks; Z (cm)",50,-250,250);
231 hA[11]=
new TH1F(
"zBemc",
"Z @Bemc for all accepted tracks; Z (cm)",100,-400,400);
232 hA[12]=
new TH1F(
"dzVerTr",
"zVerGeant - zDca of tracks used by any vertex ; (cm)",100,-5,5);
233 hA[13]=
new TH1F(
"dzVerVer",
"zVerGeant - best reco vertex ; (cm)",100,-5,5);
235 hA[14]=
new TH1F(
"EzDca",
"Error of Z DCA for all accepted tracks; Z (cm)",100,-0.,4);
236 hA[15]=
new TH1F(
"nTpcT",
"No. tracks: accepted Dca /eve ",201,-.5,200.5);
237 hA[16]=
new TH1F(
"ptTr",
"pT, ppv pool tracks; pT (GeV/c) ",50,0.,10.);
238 hA[17]=
new TH1F(
"vRL",
"PPV Vertex rank, 'funny' X-axis; X=Log10(rank-1e6)+offset", 150, -11,25);
240 hACorr=
new TH2F(
"BTOFvsBEMC",
"BTOF vs BEMC", 5,-2.5,2.5,5,-2.5,2.5);
242 for (
int i=0; i<mxH; i++)
if(hA[i]) HList.Add(hA[i]);
248 void StPPVertexFinder::findSeeds_TSpectrum()
254 for (
double vertexZ : vertexZs)
258 mVertexData.push_back(
vertex );
273 void StPPVertexFinder::findSeeds_PPVLikelihood()
275 const float par_rankOffset = 1e6;
281 if ( !buildLikelihoodZ() )
break;
285 if ( !findVertexZ(
vertex) )
break;
287 bool trigV = evalVertexZ(
vertex);
290 if (
vertex.nAnyMatch >= mMinMatchTr)
vertex.Lmax += par_rankOffset;
294 if (nBadVertex >= mStoreUnqualifiedVertex)
continue;
298 vertex.Lmax -= par_rankOffset;
301 mVertexData.push_back(
vertex);
308 void StPPVertexFinder::Clear()
310 LOG_INFO <<
"StPPVertexFinder::Clear(): Finished event " << mTotEve
311 <<
": Found " << mVertexData.size()-nBadVertex <<
" \"good\" and "
312 << nBadVertex <<
" \"bad\" vertices" << endm;
314 StGenericVertexFinder::Clear();
316 if (btofList) btofList->clear();
317 if (ctbList) ctbList->clear();
337 void StPPVertexFinder::printInfo(ostream& os)
const
340 << Form(
"PPV:: # of input track = %d\n", ntrk[0])
341 << Form(
"PPV:: dropped due to flag/dummy = %d\n", ntrk[1])
342 << Form(
"PPV:: dropped due to pt = %d\n", ntrk[2])
343 << Form(
"PPV:: dropped due to PCT check = %d\n", ntrk[3])
344 << Form(
"PPV:: dropped due to DCA check = %d\n", ntrk[4])
345 << Form(
"PPV:: dropped due to NHit check = %d\n", ntrk[5])
346 << Form(
"PPV:: dropped due to TOF check = %d\n", ntrk[6])
347 << Form(
"PPV:: # of track after all cuts = %d", ntrk[7]) << endm;
349 if(mUseBtof) btofList->print();
350 if(mUseCtb) ctbList->print();
356 os <<
"StPPVertexFinder ver=1 - Fit Statistics:\n"
357 <<
"StPPVertexFinder::result " << mVertexData.size() <<
" vertices found" << std::endl;
359 int nTpcM=0, nTpcV=0;
362 if(
track.mTpc>0) nTpcM++;
363 else if (
track.mTpc<0) nTpcV++;
364 if(
track.vertexID<=0)
continue;
367 << Form(
"%d track@z0=%.2f +/- %.2f gPt=%.3f vertID=%d match: bin,Fired,Track:\n",
370 if (mUseBtof) { LOG_DEBUG
371 << Form(
" Btof %3d,%d,%d",
track.btofBin,btofList->getFired(
track.btofBin),btofList->getTrack(
track.btofBin));
374 if (mUseCtb) { LOG_DEBUG
375 << Form(
" CTB %3d,%d,%d",
track.ctbBin,ctbList->getFired(
track.ctbBin),ctbList->getTrack(
track.ctbBin));
379 << Form(
" Bemc %3d,%d,%d",
track.bemcBin,bemcList->getFired(
track.bemcBin),bemcList->getTrack(
track.bemcBin))
380 << Form(
" Eemc %3d,%d,%d",
track.eemcBin,eemcList->getFired(
track.eemcBin),eemcList->getTrack(
track.eemcBin))
381 << Form(
" TPC %d",
track.mTpc)
385 LOG_INFO << Form(
"PPVend eveID=%d, list of found %d vertices from pool of %d tracks\n",
386 eveID, mVertexData.size(), mTrackData.size()) << endm;
395 int StPPVertexFinder::fit(
StEvent* event)
400 LOG_INFO <<
"***** START FIT\n"
401 <<
" @@@@@@ PPVertex::Fit START nEve=" << mTotEve
402 <<
" eveID=" << eveID << endm;
404 hL->SetTitle(
"Vertex likelihood, eveID=" + TString(eveID) );
410 LOG_WARN <<
"no btofCollection, continue THE SAME eve" << endm;
412 btofList->build(btofColl);
419 ctbList->buildFromData(trgD);
425 LOG_WARN <<
"No StEmcCollection found, continue with this event" << endm;
429 LOG_WARN <<
"No BEMC found in StEmcCollection, continue with this event" << endm;
431 bemcList->build(btow, mMinAdcBemc);
436 LOG_WARN <<
"No EEMC found in StEmcCollection, continue with this event" << endm;
438 eemcList->build(etow, mMinAdcEemc);
446 LOG_WARN <<
"No Sti tracks found, skipping this event" << endm;
451 int kBtof=0,kCtb=0,kBemc=0, kEemc=0,kTpc=0;
452 int nTracksMatchingAnyFastDetector=0;
454 for (
const StiTrack* stiTrack : *stiTracks)
462 if (stiKalmanTrack->getFlag() <0) { ntrk[1]++;
continue; }
463 if (stiKalmanTrack->
getPt() < mMinTrkPt) { ntrk[2]++;
continue; }
464 if (mDropPostCrossingTrack &&
465 isPostCrossingTrack(stiKalmanTrack)) { ntrk[3]++;
continue; }
466 if (!examinTrackDca(stiKalmanTrack,
track)) { ntrk[4]++;
continue; }
467 if (!matchTrack2Membrane(
track)) { ntrk[5]++;
continue; }
471 if (mUseBtof) matchTrack2BTOF(stiKalmanTrack,
track);
472 if (mUseBTOFmatchOnly && (
track.mBtof <= 0)) { ntrk[6]++;
continue; }
474 if (mUseCtb) matchTrack2CTB(stiKalmanTrack,
track);
475 matchTrack2BEMC(
track);
476 matchTrack2EEMC(
track);
481 mTrackData.push_back(
track);
484 if (
track.mBtof > 0) kBtof++;
485 if (
track.mCtb > 0) kCtb++;
486 if (
track.mBemc > 0) kBemc++;
487 if (
track.mEemc > 0) kEemc++;
488 if (
track.mTpc > 0) kTpc++;
491 nTracksMatchingAnyFastDetector++;
494 LOG_INFO << Form(
"PPV::TpcList size=%d nMatched=%d\n\n",mTrackData.size(),kTpc)
495 <<
"PPV::fit() nEve=" << mTotEve <<
" , "
496 << nTracksMatchingAnyFastDetector <<
" traks with good DCA, matching: BTOF="
497 << kBtof <<
" CTB=" << kCtb <<
" BEMC=" << kBemc <<
" EEMC=" << kEemc << endm;
499 if (nTracksMatchingAnyFastDetector >= mMinMatchTr || mStoreUnqualifiedVertex > 0)
503 LOG_INFO <<
"StPPVertexFinder::fit() nEve=" << mTotEve <<
" Quit, to few matched tracks" << endm;
510 int StPPVertexFinder::fit(
const StMuDst& muDst)
524 bemcList->build(btow, mMinAdcBemc);
527 eemcList->build(etow, mMinAdcEemc);
537 TClonesArray* covGlobTracks = muDst.covGlobTrack();
540 for (
const TObject* obj : *globalTracks)
546 if (stMuTrack.
pt() < mMinTrkPt) { ntrk[2]++;
continue; }
549 if ( (stMuTrack.flagExtension() & kPostXTrack) != 0 ) { ntrk[3]++;
continue; }
552 if (stMuTrack.index2Cov() < 0) { ntrk[4]++;
continue; }
556 if ( std::fabs(dca->z()) > mMaxZrange ) { ntrk[4]++;
continue; }
557 if ( std::fabs(dca->impact()) > mMaxTrkDcaRxy) { ntrk[4]++;
continue; }
560 double fracFit2PossHits =
static_cast<double>(stMuTrack.
nHitsFit(kTpcId)) / stMuTrack.
nHitsPoss(kTpcId);
561 if (fracFit2PossHits < mMinFitPfrac) { ntrk[5]++;
continue; }
564 if (mUseBTOFmatchOnly && (stMuTrack.tofHit() == 0)) { ntrk[6]++;
continue; }
571 matchTrack2BEMC(
track);
572 matchTrack2EEMC(
track);
573 matchTrack2Membrane(
track);
575 mTrackData.push_back(
track);
584 void StPPVertexFinder::seed_fit_export()
591 case SeedFinder_t::TSpectrum:
592 findSeeds_TSpectrum();
595 case SeedFinder_t::PPVLikelihood:
597 findSeeds_PPVLikelihood();
608 const double& z =
vertex.r.Z();
614 size_t n_seeds = mVertexData.size();
617 mVertexData.erase( std::remove_if(mVertexData.begin(), mVertexData.end(), cannot_fit), mVertexData.end() );
620 nBadVertex -= n_seeds - mVertexData.size();
625 if (mDebugLevel) printInfo();
631 bool StPPVertexFinder::buildLikelihoodZ()
637 float dzMax2 = mMaxZradius*mMaxZradius;
639 int nt=mTrackData.size();
640 LOG_DEBUG<< Form(
"PPV::buildLikelihood() pool of nTracks=%d",nt)<<endm;
641 if(nt<=0)
return false;
643 int nTracksMatchingAnyFastDetector = 0;
645 double *La = hL->GetArray();
646 double *Ma = hM->GetArray();
647 double *Wa = hW->GetArray();
653 if (
track.vertexID != 0)
continue;
655 if (
track.anyMatch) nTracksMatchingAnyFastDetector++;
657 float z0 =
track.zDca;
658 float ez =
track.ezDca;
660 int j1 = hL->FindBin(z0-mMaxZradius-.1);
661 int j2 = hL->FindBin(z0+mMaxZradius+.1);
662 float base = dzMax2/2/ez2;
663 float totW =
track.weight;
665 for (
int j=j1; j<=j2; j++)
667 float z = hL->GetBinCenter(j);
669 float xx = base - dz*dz/2/ez2;
670 if (xx <= 0)
continue;
677 LOG_DEBUG << Form(
"PPV::buildLikelihood() %d tracks w/ matched @ Lmax=%f", nTracksMatchingAnyFastDetector, hL->GetMaximum()) << endm;
679 return (nTracksMatchingAnyFastDetector >= mMinMatchTr) || (mStoreUnqualifiedVertex > 0);
686 if(hL->GetMaximum()<=0)
return false;
688 int iMax = hL->GetMaximumBin();
689 float z0 = hL->GetBinCenter(iMax);
690 float Lmax = hL->GetBinContent(iMax);
691 float accM = hM->GetBinContent(iMax);
692 float accW = hW->GetBinContent(iMax);
694 float avrW = accW/accM;
697 float Llow = 0.9* Lmax;
698 if ((Lmax-Llow) < 8*avrW ) Llow = Lmax - 8*avrW;
700 double *L = hL->GetArray();
702 int iLow = -1, iHigh = -1;
703 for(
int i=iMax; i<=hL->GetNbinsX(); i++) {
704 if(L[i] > Llow)
continue;
708 for(
int i=iMax; i>=1; i--) {
709 if(L[i] > Llow)
continue;
714 float zLow = hL->GetBinCenter(iLow);
715 float zHigh = hL->GetBinCenter(iHigh);
717 float kSig = std::sqrt(2*(Lmax-Llow)/avrW);
718 float sigZ = (zHigh-zLow)/2/kSig;
720 LOG_DEBUG << Form(
"PPV:: iLow/iMax/iHigh=%d/%d/%d\n",iLow,iMax,iHigh)
721 << Form(
" accM=%f accW=%f avrW=%f\n",accM,accW,avrW)
722 << Form(
" Z low/max/high=%f %f %f, kSig=%f, sig=%f\n",zLow,z0,zHigh,kSig,sigZ)
723 << Form(
" found PPVertex(ID=%d,neve=%d) z0 =%.2f +/- %.2f\n",vertex.id,mTotEve,z0,sigZ)<<endm;
725 if (sigZ < 0.1) sigZ = 0.1;
730 vertex.r = TVector3(0, 0, z0);
731 vertex.er = TVector3(0.1, 0.1, sigZ);
739 bool StPPVertexFinder::evalVertexZ(
VertexData &vertex)
747 if (
track.vertexID != 0)
continue;
751 if ( !
track.matchVertex(vertex, mMaxZradius) )
continue;
754 track.vertexID = vertex.id;
755 vertex.gPtSum +=
track.gPt;
758 if(
track.gPt>mCut_oneTrackPT && (
track.mBemc>0||
track.mEemc>0) ) nHiPt++;
760 if(
track.mTpc>0) vertex.nTpc++;
761 else if (
track.mTpc<0) vertex.nTpcV++;
763 if(
track.mBtof>0) vertex.nBtof++;
764 else if (
track.mBtof<0) vertex.nBtofV++;
766 if(
track.mCtb>0) vertex.nCtb++;
767 else if (
track.mCtb<0) vertex.nCtbV++;
769 if(
track.mBemc>0) vertex.nBemc++;
770 else if (
track.mBemc<0) vertex.nBemcV++;
772 if(
track.mEemc>0) vertex.nEemc++;
773 else if (
track.mEemc<0) vertex.nEemcV++;
775 if(
track.anyMatch) vertex.nAnyMatch++;
776 else if (
track.anyVeto) vertex.nAnyVeto++;
779 vertex.
isTriggered = (vertex.nAnyMatch >= mMinMatchTr) || ( (mAlgoSwitches & kSwitchOneHighPT) && nHiPt>0 );
783 LOG_DEBUG <<
"StPPVertexFinder::evalVertex Vid="<<vertex.id<<
" rejected"<<endm;
785 if(
track.vertexID!=vertex.id)
continue;
786 track.vertexID=-vertex.id;
791 LOG_INFO <<
"StPPVertexFinder::evalVertex Vid=" << vertex.id
792 <<
" accepted, nAnyMatch=" << vertex.nAnyMatch
793 <<
" nAnyVeto=" << vertex.nAnyVeto << endm;
807 void StPPVertexFinder::createTrackDcas(
const VertexData &vertex)
816 if ( std::fabs(
track.vertexID) != vertex.id)
continue;
831 if ( std::fabs(
track.vertexID) != vertex.id)
continue;
832 if (!
track.mother)
continue;
838 if (!tNode)
continue;
842 float alfa = tNode->getAlpha();
843 float setp[7] = {(float)pars.y(), (float)pars.z(), (float)pars.phi(),
844 (float)pars.ptin(), (float)pars.tanl(), (float)pars.curv(), (float)pars.hz()};
848 for (
int i=1, li=1, jj=0; i<kNPars; li += ++i) {
849 for (
int j=1;j<=i;j++) {
850 sete[jj++] = errs.G()[li+j];
855 dca->set(setp, sete);
856 mDCAs.push_back(dca);
870 int StPPVertexFinder::fitTracksToVertex(
VertexData &vertex)
872 createTrackDcas(vertex);
874 bool fitRequiresBeamline = star_vertex::requiresBeamline(
mVertexFitMode);
876 bool prerequisites =
mDCAs.size() > 1 || (
mDCAs.size() > 0 && fitRequiresBeamline);
878 if ( !prerequisites )
880 LOG_WARN <<
"StPPVertexFinder::fitTracksToVertex: At least two tracks required "
881 <<
"OR one with beam line. This vertex (id = " << vertex.id
882 <<
") coordinates will not be updated" << endm;
890 if ( fitRequiresBeamline )
892 vertexSeed.setX(
beamX(vertexSeed.z()) );
893 vertexSeed.setY(
beamY(vertexSeed.z()) );
901 mMinuit->mnexcm(
"clear", 0, 0, minuitStatus);
903 static double step[3] = {0.01, 0.01, 0.01};
905 double x_lo = vertexSeed.x() - mMaxTrkDcaRxy;
906 double y_lo = vertexSeed.y() - mMaxTrkDcaRxy;
907 double z_lo = vertexSeed.z() - mMaxZradius;
909 double x_hi = vertexSeed.x() + mMaxTrkDcaRxy;
910 double y_hi = vertexSeed.y() + mMaxTrkDcaRxy;
911 double z_hi = vertexSeed.z() + mMaxZradius;
915 mMinuit->mnparm(0,
"z", vertexSeed.z(), step[2], z_lo, z_hi, minuitStatus);
917 mMinuit->mnparm(0,
"x", vertexSeed.x(), step[0], x_lo, x_hi, minuitStatus);
918 mMinuit->mnparm(1,
"y", vertexSeed.y(), step[1], y_lo, y_hi, minuitStatus);
919 mMinuit->mnparm(2,
"z", vertexSeed.z(), step[2], z_lo, z_hi, minuitStatus);
922 mMinuit->mnexcm(
"minimize", 0, 0, minuitStatus);
926 LOG_WARN <<
"StPPVertexFinder::fitTracksToVertex: Fit did not converge. "
927 <<
"Check TMinuit::mnexcm() status flag: " << minuitStatus <<
". "
928 <<
"This vertex (id = " << vertex.id <<
") coordinates will not be updated" << endm;
932 if ( fitRequiresBeamline ) {
933 const double& z = vertex.r.Z();
941 double chisquare, fedm, errdef;
944 mMinuit->mnstat(chisquare, fedm, errdef, npari, nparx, minuitStatus);
952 mMinuit->mnemat(emat, 3);
956 const double& z = mMinuit->fU[0];
960 vertex.r.SetXYZ(mMinuit->fU[0], mMinuit->fU[1], mMinuit->fU[2]);
961 vertex.er.SetXYZ( std::sqrt(emat[0]), std::sqrt(emat[4]), std::sqrt(emat[8]) );
972 void StPPVertexFinder::exportVertices()
980 cov[0] = vertex.er.x() * vertex.er.x();
981 cov[2] = vertex.er.y() * vertex.er.y();
982 cov[5] = vertex.er.z() * vertex.er.z();
985 primV.setPosition(r);
986 primV.setCovariantMatrix(cov);
987 primV.setVertexFinderId(mUseCtb ? ppvVertexFinder : ppvNoCtbVertexFinder);
988 primV.setNumTracksUsedInFinder(vertex.nUsedTrack);
989 primV.setNumMatchesWithBTOF(vertex.nBtof);
990 primV.setNumMatchesWithCTB(vertex.nCtb);
991 primV.setNumMatchesWithBEMC(vertex.nBemc);
992 primV.setNumMatchesWithEEMC(vertex.nEemc);
993 primV.setNumTracksCrossingCentralMembrane(vertex.nTpc);
994 primV.setSumOfTrackPt(vertex.gPtSum);
995 primV.setRanking(vertex.Lmax);
1002 StThreeVectorF v_position(vertex.r.x(), vertex.r.y(), vertex.r.z());
1006 float total_err_perp = std::sqrt( vertex.er.Perp2() +
track.dca->errMatrix()[0] );
1007 float total_err_z = std::sqrt( vertex.er.z()*vertex.er.z() +
track.dca->errMatrix()[2] );
1009 bool is_daughter = (
track.vertexID == vertex.id ||
1010 (std::fabs(dist.perp())/total_err_perp < 3 && std::fabs(dist.z())/total_err_z < 3) );
1012 if ( !is_daughter )
continue;
1014 track.vertexID = vertex.id;
1017 stMuTrack->setType(primary);
1021 primV.addDaughter(primTrack);
1025 vertex.mIdTruth = primV.idTruth();
1028 while ( !primV.daughters().empty() )
1029 delete primV.daughters().back(), primV.daughters().pop_back();
1039 void StPPVertexFinder::Finish()
1041 LOG_INFO <<
"StPPVertexFinder::Finish() done, seen eve=" << mTotEve << endm;
1046 void StPPVertexFinder::saveHisto(TString fname)
1048 TString outName = fname +
".hist.root";
1049 TFile f(outName,
"recreate");
1051 printf(
"%d histos are written to '%s' ...\n", HList.GetEntries(), outName.Data());
1062 int in=0,nh=0,nTpc=0;
1063 float zL=999, zH=-999;
1064 for (it=track->
begin();it!=track->
end();it++,in++) {
1066 if(!ktn.isValid())
continue;
1067 if(ktn.getHit() && ktn.getChi2() >1000)
continue;
1069 assert(!(ktn.x()) || det);
1070 float rxy=ktn.getX();
1071 bool actv= !det || det->isActive(ktn.getY(), ktn.getZ());
1072 if(!det || (rxy>58 && rxy < 190)){
1078 if(ktn.getHit()) nh++;
1083 TString tagPlp=
" ";
if((nTpc-nh)>10) tagPlp=
" plp";
1084 TString tagMemb=
" ";
if(zH*zL<0) tagMemb=
" memb";
1087 <<
"\n#e dumpKalmanNodes nNodes="<<nn<<
" actv: nTPC="<<nTpc<<
" nHit="<<nh
1088 <<
" zL="<<zL<<
" zH="<<zH <<tagPlp<<tagMemb
1094 LOG_INFO <<
"#e @InnerMostNode x:"<< inNode->x_g()<<
" y:"<< inNode->y_g()<<
" z:"<< inNode->z_g()<<
" Eta="<<inNode->getEta()<<
" |P|="<<inNode->
getP() << endm;
1096 LOG_INFO <<
"#e @OuterMostNode g x:"<< ouNode->x_g()<<
" y:"<< ouNode->y_g()<<
" z:"<< ouNode->z_g()<<
" Eta="<<ouNode->getEta()<<
" |P|="<<ouNode->
getP() << endm;
1099 for (it=track->
begin();it!=track->
end();it++,in++) {
1102 if(!ktn.isValid())
continue;
1103 if(ktn.getHit() && ktn.getChi2() >1000)
continue;
1104 float sy = std::sqrt(ktn.getCyy());
1105 float sz = std::sqrt(ktn.getCzz());
1107 assert(!(ktn.x()) || det);
1109 LOG_INFO <<
"#e in="<<in<<
" |P|="<<ktn.
getP()<<
" Local: x="<<ktn.getX()<<
" y="<<ktn.getY()<<
" +/- "<<sy<<
" z="<<ktn.getZ()<<
" +/- "<<sz;
1111 if(ktn.getHit()) {LOG_INFO <<
" hit=1";}
1112 else {LOG_INFO <<
" hit=0";}
1114 if(det==0) {LOG_INFO <<
" noDet ";}
1115 else {LOG_INFO <<
" detActv="<<(!det || det->isActive(ktn.getY(), ktn.getZ()));}
1126 if (!bmNode)
return 0;
1127 if (!bmNode->isDca())
return 0;
1129 float rxy = std::sqrt(bmNode->x_g()*bmNode->x_g() + bmNode->y_g()*bmNode->y_g());
1131 if(rxy>mMaxTrkDcaRxy)
return false;
1132 if( std::fabs(bmNode->z_g())> mMaxZrange )
return false ;
1134 track.zDca = bmNode->getZ();
1135 track.ezDca = std::sqrt(bmNode->getCzz());
1137 track.gPt = bmNode->
getPt();
1154 ou.rotateZ(ouNode->getAlpha());
1156 ouNode->getDipAngle(),
1159 ouNode->getHelicity());
1166 for(
size_t i=0;i<idVec.size();i++) {
1167 int itray, imodule, icell;
1168 geom->DecodeCellId(idVec[i], icell, imodule, itray);
1170 Double_t local[3], global[3];
1171 for(
int j=0;j<3;j++) local[j] = 0;
1172 global[0] = crossVec[i].x();
1173 global[1] = crossVec[i].y();
1174 global[2] = crossVec[i].z();
1177 LOG_WARN <<
"no sensitive module in this projection??? - weird" << endm;
1180 sensor->Master2Local(&global[0],&local[0]);
1181 if(local[2]<mMinZBtof||local[2]>mMaxZBtof)
continue;
1182 int iBin = btofList->cell2bin(itray, imodule, icell);
1183 iBinVec.push_back(iBin);
1184 btofList->addBtofTrack(itray, imodule, icell);
1185 LOG_DEBUG <<
" !!! Push to the list ...tray/module/cell " << itray <<
"/" << imodule <<
"/" << icell << endm;
1189 bool btofMatch=btofList->isMatched(iBinVec);
1190 bool btofVeto =btofList->isVetoed(iBinVec);
1191 float btofW =btofList->getWeight(iBinVec);
1192 btofList->addBtofMatch(iBinVec);
1194 LOG_DEBUG <<
" ** BTOF ** match/veto/weight = " << btofMatch <<
" " << btofVeto <<
" " << btofW << endm;
1196 track.updateAnyMatch(btofMatch,btofVeto,track.mBtof);
1197 track.weight*=btofW;
1198 track.btofBin= iBinVec.size() ? iBinVec[0] : -1;
1205 const double Rctb=213.6;
1215 in.rotateZ(inNode->getAlpha());
1217 inNode->getDipAngle(),
1220 inNode->getHelicity());
1224 if(d2.first>=0 || d2.second<=0) {
1225 LOG_DEBUG <<Form(
"WARN MatchTrk , unexpected solution for track crossing CTB\n")<<
1226 Form(
" d2.firts=%f, second=%f, try first", d2.first, d2.second)<<endm;
1229 posCTB = phys_helix.at(path);
1238 LOG_INFO <<
"#e @ctbNode NULL"<<endm;
1239 LOG_INFO <<
"#e @track dump"<< *stiTrack << endm;
1240 LOG_INFO <<
"#e @OuterMostNode dump"<< *ouNode <<endm;
1244 posCTB=
StThreeVectorD( ctbNode->x_g(),ctbNode->y_g(),ctbNode->z_g());
1247 float phi=atan2(posCTB.y(),posCTB.x());
1248 if(phi<0) phi+=2*M_PI;
1249 float eta=posCTB.pseudoRapidity();
1251 int iBin=ctbList->addTrack(eta,phi);
1253 bool ctbMatch=ctbList->isMatched(iBin);
1254 bool ctbVeto =ctbList->isVetoed(iBin);
1255 float ctbW =ctbList->getWeight(iBin);
1257 track.updateAnyMatch(ctbMatch,ctbVeto,track.mCtb);
1272 ou.rotateZ(ouNode->getAlpha());
1274 ouNode->getDipAngle(),
1277 ouNode->getHelicity());
1279 matchTrack2BEMC(phys_helix, track);
1285 const StMuTrack& muTrack = *track.getMother();
1286 matchTrack2BEMC(muTrack.
outerHelix(), track);
1292 const double Rxy = 242.;
1296 float path = d2.second;
1298 if(d2.first>=0 || d2.second<=0) {
1299 LOG_DEBUG <<Form(
"WARN MatchTrk , unexpected solution for track crossing BEMC Cyl\n")<<
1300 Form(
" d2.firts=%f, second=%f, try first\n", d2.first, d2.second)<<endm;
1306 float phi = atan2(posCyl.y(), posCyl.x());
1307 if (phi < 0) phi += 2*M_PI;
1308 float eta = posCyl.pseudoRapidity();
1310 int iBin = bemcList->addTrack(eta, phi);
1311 bool bemcMatch = bemcList->isMatched(iBin);
1312 bool bemcVeto = bemcList->isVetoed(iBin);
1313 float bemcW = bemcList->getWeight(iBin);
1315 track.updateAnyMatch(bemcMatch, bemcVeto, track.mBemc);
1316 track.weight *= bemcW;
1317 track.bemcBin = iBin;
1327 const double minEta=0.7 ;
1333 if(inNode->getZ()> ouNode->getZ())
return;
1339 ou.rotateZ(ouNode->getAlpha());
1341 ouNode->getDipAngle(),ouNode->
getPhase(),
1342 ou,ouNode->getHelicity());
1348 matchTrack2EEMC(phys_helix, track);
1354 const StMuTrack& muTrack = *track.getMother();
1356 const double minEta = 0.7;
1362 if(muTrack.
eta() < minEta)
return;
1364 matchTrack2EEMC(muTrack.
outerHelix(), track);
1370 const double eemc_z_position = 288.;
1371 const double maxPath=200 ;
1377 if(path>maxPath)
return;
1380 double periodL=phys_helix. period();
1382 if(periodL<2*path) {
1383 LOG_DEBUG <<Form(
" Warn, long path fac=%.1f ",path/periodL)<<
1384 Form(
" punchEEMC1 x,y,z=%.1f, %.1f, %.1f path=%.1f period=%.1f\n",r.x(),r.y(),r.z(),path,periodL)<<endm;
1387 double phi=atan2(r.y(),r.x());
1388 if(phi<0) phi+=2*M_PI;
1389 double eta=r.pseudoRapidity();
1391 int iBin=eemcList->addTrack(eta,phi);
1392 bool eemcMatch=eemcList->isMatched(iBin);
1393 bool eemcVeto =eemcList->isVetoed(iBin);
1394 float eemcW =eemcList->getWeight(iBin);
1396 track.updateAnyMatch(eemcMatch,eemcVeto,track.mEemc);
1397 track.weight*=eemcW;
1409 const double RxyMin=59, RxyMax=199, zMax=200;
1410 const double zMembraneDepth=1;
1413 std::vector<int> hitPatt;
1416 double lastRxy=9999;
1421 for (it=stiTrack->
begin();it!=stiTrack->
end();it++) {
1423 if(!ktnp->isValid())
continue;
1425 double rxy = std::sqrt(ktnp->x_g()*ktnp->x_g() + ktnp->y_g()*ktnp->y_g());
1426 double z=ktnp->z_g();
1427 if(rxy<RxyMin)
continue;
1428 if(rxy>RxyMax)
continue;
1429 if(std::fabs(z)>zMax)
continue;
1432 LOG_WARN <<
"StPPVertexFinder::matchTrack2Membrane() \n the "<<in<<
" node of the kalmanTrack below is out of order and is ignorred in (some) of vertex finder analysis"<<
"\n Z="<<z<<
" rXY="<<rxy<<
" last_rxy="<<lastRxy<<endm;
1438 if(fabsf(z)>zMembraneDepth) {
1441 LOG_WARN <<
"StPPVertexFinder::matchTrack2Membrane() \n the "<<in<<
" node of the kalmanTrack crosses Z=0 for the 2nd time, this track has a strange list of nodes - continue"<<endm;
1444 jz0 = hitPatt.size();
1449 assert(!(ktnp->x()) || det);
1450 bool active = !det || det->isActive(ktnp->getY(), ktnp->getZ());
1451 int hit = ktnp->getHit() ? 1 : 0;
1453 hitPatt.push_back(hit);
1455 if(hit && ktnp->getChi2() <=1000 ) nFit++;
1459 if (nFit < mMinFitPfrac * nPos)
return false;
1461 if( mFitPossWeighting)
1462 track.weight *= 1.*nFit/nPos;
1464 track.scanNodes(hitPatt, jz0);
1473 const StMuTrack& muTrack = *track.getMother();
1476 if (mFitPossWeighting) {
1477 double fracFit2PossHits =
static_cast<double>(muTrack.
nHitsFit(kTpcId)) / muTrack.
nHitsPoss(kTpcId);
1478 track.weight *= fracFit2PossHits;
1485 const float RxyMin = 59, RxyMax = 199, zMax = 200;
1487 bool isTrackInside = firstPoint.perp() < RxyMin || lastPoint.perp() < RxyMin ||
1488 firstPoint.perp() > RxyMax || lastPoint.perp() > RxyMax ||
1489 std::fabs(firstPoint.z()) > zMax ||
1490 std::fabs(lastPoint.z()) > zMax;
1493 bool crossMembrane = firstPoint.z() * lastPoint.z() < 0;
1495 if ( !isTrackInside || !crossMembrane)
return;
1498 double t = firstPoint.z() / (firstPoint.z() - lastPoint.z());
1500 double intersect_x = firstPoint.x() + t * (lastPoint.x() - firstPoint.x());
1501 double intersect_y = firstPoint.y() + t * (lastPoint.y() - firstPoint.y());
1504 double intersect_r = std::sqrt(intersect_x*intersect_x + intersect_y*intersect_y);
1507 const std::array<double, 45> padrow_radii
1509 60.0, 64.8, 69.6, 74.4, 79.2, 84.0, 88.8, 93.6, 98.8, 104.0,
1510 109.2, 114.4, 119.6, 127.195, 129.195, 131.195, 133.195, 135.195, 137.195, 139.195,
1511 141.195, 143.195, 145.195, 147.195, 149.195, 151.195, 153.195, 155.195, 157.195, 159.195,
1512 161.195, 163.195, 165.195, 167.195, 169.195, 171.195, 173.195, 175.195, 177.195, 179.195,
1513 181.195, 183.195, 185.195, 187.195, 189.195
1516 std::vector<int> hitPatt;
1519 for (
auto padrow_r : padrow_radii)
1521 int curr_padrow_index = hitPatt.size();
1523 if (intersect_r > padrow_r)
1524 jz0 = curr_padrow_index;
1526 int hit = muTrack.
topologyMap().hasHitInRow(kTpcId, curr_padrow_index+1) ? 1 : 0;
1528 hitPatt.push_back(hit);
1531 track.scanNodes(hitPatt, jz0);
1538 bool StPPVertexFinder::isPostCrossingTrack(
const StiKalmanTrack* stiTrack)
1540 const float RxyMin=59, RxyMax=199, zMax=200;
1541 const float zMembraneDepth=1.0;
1542 const int nWrongZHitCut=2;
1545 for (it=stiTrack->
begin();it!=stiTrack->
end();it++)
1548 if(!ktnp->isValid() || ktnp->getChi2()>1000 )
continue;
1550 StiHit* stihit=ktnp->getHit();
1552 if (!stihit)
continue;
1556 if (!sthit)
continue;
1557 if (sthit->detector() != kTpcId)
continue;
1560 float r=hit->position().perp();
1561 if (r < RxyMin)
continue;
1562 if (r > RxyMax)
continue;
1564 float z=hit->position().z();
1565 if (std::fabs(z) > zMax)
continue;
1567 if ((z < -zMembraneDepth && hit->sector() <= 12) ||
1568 (z > zMembraneDepth && hit->sector() > 12))
1571 if (nWrongZHit >= nWrongZHitCut) {
return true;}
Bool_t HelixCrossCellIds(const StHelixD &helix, IntVec &idVec, DoubleVec &pathVec, PointVec &crossVec) const
static TObjArray * globalTracks()
returns pointer to the global tracks list
Definition of Kalman Track.
double getP() const
Calculates and returns the momentum of the track at this node.
bool isTriggered
Indicates whether the vertex potentially belongs to triggered event.
Double_t pt() const
Returns pT at point of dca to primary vertex.
Abstract definition of a Track.
SeedFinder_t mSeedFinderType
The type of vertex seed finder to use in derived concrete implementation.
double beamX(double z) const
StiKalmanTrackNode * getOuterMostNode(int qua=0) const
Accessor method returns the outer most node associated with the track.
double beamY(double z) const
double getP() const
Calculates and returns the momentum of the track at the inner most node.
pair< double, double > pathLength(double r) const
path length at given r (cylindrical r)
UShort_t nHitsFit() const
Return total number of hits used in fit.
int getFitPointCount(int detectorId=0) const
Returns the number of hits associated and used in the fit of this track.
std::vector< double > FindSeeds_TSpectrum()
double getPt() const
Calculates and returns the transverse momentum of the track at this node.
StiKalmanTrackNode * getInnerMostNode(int qua=0) const
Accessor method returns the inner most node associated with the track.
StThreeVectorD CalcVertexSeed(const StDcaList &trackDcas)
Double_t eta() const
Returns pseudo rapidity at point of dca to primary vertex.
Definition of Kalman Track.
const StThreeVectorF & firstPoint() const
Returns positions of first measured point.
double getPseudoRapidity() const
Return the pseudorapidity of the track.
StiKalmanTrackNode * extrapolateToBeam()
UShort_t nHitsPoss() const
Return number of possible hits on track.
static StMuEmcCollection * muEmcCollection()
returns pointer to current StMuEmcCollection
VertexFit_t mVertexFitMode
The type of vertex fit to use in derived concrete implementation.
static StTrack * createStTrack(const StMuTrack *)
creates a StTrack from an StMuTrack and return pointer to it
const StThreeVectorF & lastPoint() const
Returns positions of last measured point.
const StiKTNBidirectionalIterator & end() const
double getCurvature() const
Calculates and returns the tangent of the track pitch angle at this node.
static StGenericVertexFinder * sSelf
By default point to invalid object.
const StMeasuredPoint * stHit() const
StPhysicalHelixD outerHelix() const
Returns outer helix (last measured point)
StTrackTopologyMap topologyMap() const
Returns topology map.
StiKTNBidirectionalIterator begin() const
double getPt() const
Calculates and returns the transverse momentum of the track at the inner most node.