3 #if ROOT_VERSION_CODE < 331013
13 #include "StDcaGeometry.h"
14 #include "KFParticle.h"
19 #include "StAnneling.h"
20 #include "StKFEvent.h"
21 #include "StKFTrack.h"
22 #include "StKFVertex.h"
23 #include "StKFVerticesCollection.h"
24 #include "StVertexP.h"
25 #include "StVertexT.h"
26 #include "TDirectory.h"
27 #include "StEventTypes.h"
29 #include "SystemOfUnits.h"
30 #include "StKFVertexMaker.h"
31 #include "StDetectorDbMaker/St_vertexSeedC.h"
32 #include "Sti/StiHit.h"
34 #include "Sti/StiKalmanTrackNode.h"
35 #include "StiStEventFiller.h"
37 #include "TRSymMatrix.h"
43 StKFVertexMaker::~StKFVertexMaker() {
45 for (Int_t pass = 0; pass < fNPasses; pass++) {
46 SafeDelete(fVtxKs[pass]);
47 SafeDelete(fVtxKs[pass]);
49 SafeDelete(fSpectrum);
51 SafeDelete(fminBrent);
52 delete [] fVerticesPass; fVerticesPass = 0;
53 SafeDelete(fParticles);
57 for (Int_t pass = 0; pass < fNPasses; pass++) {
58 fVtxKs[pass]->Reset();
59 fVtxKs[pass]->SetMaximum();
61 fVtxs[pass]->SetMaximum();
66 fParticles->Clear(
"C");
69 StKFVertexMaker::StKFVertexMaker(
const char *name) :
StMaker(name),
70 fNzBins(2500), fNPasses(2), fSpectrum(0), fzWindow(2),
71 fVtxM(0), fVerticesPass(0), fTempLog(2), fminBrent(0), func(0),
72 mBeamLine(kFALSE), fc1(0)
78 for (Int_t pass = 0; pass < fNPasses; pass++) {
79 fVtxs[pass] =
new TH1F(Form(
"Vtx%1i",pass),Form(
"z-dca distribution for pass = %1i",pass),fNzBins,zmin,zmax);
80 fVtxs[pass]->SetDirectory(0);
81 if (pass) fVtxs[pass]->SetLineColor(5);
82 fVtxs[pass]->SetDefaultSumw2();
83 fVtxs[pass]->SetStats(0);
84 fVtxKs[pass] =
new TH1K(Form(
"VtxK%1i",pass),Form(
"z-dca distribution for pass = %1i",pass),fNzBins,zmin,zmax);
85 fVtxKs[pass]->SetDirectory(0);
86 fVtxKs[pass]->SetStats(0);
87 fVtxKs[pass]->SetLineColor(2);
89 fVtxM =
new TH1F(
"VtxM",
"MuDst reconstructed multiplicities versus Z",fNzBins,zmin,zmax);
90 fVtxM->SetDirectory(0);
91 fSpectrum =
new TSpectrum(2*npeaks);
92 func =
new ROOT::Math::Functor1D(&StKFVertexMaker::AnnelingFcn);
93 fminBrent =
new ROOT::Math::GSLMinimizer1D();
96 fParticles =
new TObjArray();
97 fParticles->SetOwner(kTRUE);
101 Int_t StKFVertexMaker::Init(){
102 mBeamLine = IAttr(
"beamLine");
103 return StMaker::Init();
106 Int_t StKFVertexMaker::InitRun(Int_t runumber){
107 return StMaker::InitRun(runumber);
113 LOG_WARN <<
"StKFVertexMaker::fit: no StEvent " << endm;
117 if (pEvent->runInfo()) bField = pEvent->runInfo()->magneticField();
121 Double_t x0 = vSeed->x0() ; Double_t err_x0 = vSeed->err_x0();
122 Double_t y0 = vSeed->y0() ; Double_t err_y0 = vSeed->err_y0();
123 Double_t dxdz = vSeed->dxdz(); Double_t err_dxdz = vSeed->err_dxdz();
124 Double_t dydz = vSeed->dydz(); Double_t err_dydz = vSeed->err_dydz();
125 Double_t weight = vSeed->weight();
126 if (err_x0 < 0.010) err_x0 = 0.010;
127 if (err_y0 < 0.010) err_y0 = 0.010;
128 static Bool_t firstTime = kTRUE;
131 LOG_INFO <<
"BeamLine Constraint: weight = " << weight << endm;
132 LOG_INFO <<
"x(z) = (" << x0 <<
" +- " << err_x0 <<
") + (" << dxdz <<
" +- " << err_dxdz <<
") * z" << endm;
133 LOG_INFO <<
"y(z) = (" << y0 <<
" +- " << err_y0 <<
") + (" << dydz <<
" +- " << err_dydz <<
") * z" << endm;
135 static Double_t pZ = 1000;
137 Double_t xyzP[6] = { x0, y0, 0.,
138 pZ*dxdz, pZ*dydz, pZ};
139 Double_t CovXyzP[21] = {
143 0 ,0 , 0, (err_dxdz*pZ)*(err_dxdz*pZ),
144 0 ,0 , 0, 0, (err_dydz*pZ)*(err_dydz*pZ)
146 track.SetParameters(xyzP);
147 track.SetCovarianceMatrix(CovXyzP);
152 fParticles->AddAt(beam, 0);
154 StSPtrVecTrackNode& trackNode = pEvent->trackNodes();
155 UInt_t nTracks = trackNode.size();
157 Int_t NGoodGlobals = 0;
158 map<Int_t,StTrackNode*> TrackNodeMap;
159 for (UInt_t i=0; i < nTracks; i++) {
163 if (! gTrack)
continue;
166 if (gTrack->flag() < 0)
continue;
167 if (gTrack->flag() > 700)
continue;
168 if (gTrack->flag()%100 == 11)
continue;
169 if ((gTrack->isWestTpcOnly() || gTrack->isEastTpcOnly()) && gTrack->isPostXTrack())
continue;
170 Int_t kg = gTrack->key();
171 TrackNodeMap[kg] = node;
174 if (Debug() > 2) {LOG_INFO << Form(
"particle: %4i/%4i ",NGoodGlobals,kg) << *particle << endm;}
175 LOG_INFO <<
"Add to map[" << kg <<
"] node = " << TrackNodeMap[kg] << endm;
179 if (NGoodGlobals < 2)
return 0;
181 if (! Vertices())
return 0;
185 StSPtrVecTrackDetectorInfo& detInfoVec = pEvent->trackDetectorInfo();
186 Int_t Nvtx = Vertices()->NoVertices();
187 for (Int_t l = 0; l < Nvtx; l++) {
190 if (Debug() > 2) V->PrintW();
194 primV->setPosition(XVertex);
195 primV->setChiSquared(V->Vertex().Chi2()/V->Vertex().GetNDF());
196 primV->setProbChiSquared(TMath::Prob(V->Vertex().GetChi2(),V->Vertex().GetNDF()));
198 TCL::ucopy(&V->Vertex().Covariance(0),cov,6);
199 primV->setCovariantMatrix(cov);
200 primV->setVertexFinderId(KFVertexFinder);
202 primV->setRanking(333);
203 primV->setNumTracksUsedInFinder(V->NoTracks());
204 Bool_t
beam = kFALSE;
206 TCL::ucopy(&V->Vertex().X(), Pars, 6);
208 TCL::ucopy(&V->Vertex().Covariance(0), Cov, 21);
210 Vertex->
setGlobal(0, 0, V->Vertex().X(), V->Vertex().Y(), V->Vertex().Z(), 0);
211 Vertex->setError(cov);
212 Int_t NoTracks = V->NoTracks();
213 TArrayI indexT(NoTracks); Int_t *indexes = indexT.GetArray();
214 TArrayI IdT(NoTracks); Int_t *Ids = IdT.GetArray();
215 for (Int_t itk = 0; itk < NoTracks; itk++) {
218 if (! track)
continue;
220 Int_t kg = P.GetID()%100000;
223 TMath::Sort(NoTracks,Ids,indexes,0);
224 for (Int_t i = 0; i < NoTracks; i++) {
225 Int_t itk = indexes[i];
227 if (! track)
continue;
229 Int_t kg = P.GetID()%100000;
238 for (Int_t m = 0; m < 2; m++) {
239 if (! m) cout <<
"Original";
240 else cout <<
"Fitted ";
241 static const Char_t *names[6] = {
"x",
"y",
"z",
"px",
"py",
"pz"};
242 for (Int_t j = 0; j < 6; j++) {
243 cout << Form(
" %2s: %8.3f +/- %8.3f",names[j],
244 PS[m]->GetParameter(j),
245 PS[m]->GetCovariance(j,j) > 0 ? TMath::Sqrt(PS[m]->GetCovariance(j,j)) : -13);
250 node = TrackNodeMap[kg];
252 LOG_INFO <<
"Missing node in map[" << kg <<
"] node = " << TrackNodeMap[kg] << endm;
255 StiKalmanTrack* kTrack = (*StiStEventFiller::Node2TrackMap())[node];
262 if (! tNode->isDca())
continue;
266 tNode->
rotate(-tNode->getAlpha());
270 tNode->setHit(Vertex);
271 tNode->setDetector(0);
280 FP.eta() = Phi - tNode->getAlpha();
281 FP.ptin() = - P.GetQ()/pT;
282 FP.tanl() = P.GetPz()/pT;
286 Double_t pzpT3 = - P.GetPz()/(pT*pT*pT);
292 0, 0, 0, P.GetPy()/(pT*pT), -P.GetPx()/(pT*pT), 0,
293 0, 0, 0, -FP.ptin()*P.GetPx()/(pT*pT), -FP.ptin()*P.GetPy()/(pT*pT), 0,
294 0, 0, 0, pzpT3*P.GetPx(), pzpT3*P.GetPy(), 1./pT};
295 TRMatrix F(6,6,f);
if (Debug()) {LOG_INFO <<
"F\t" << F << endm;}
296 TRSymMatrix CovP(6,&((
KFParticle *)&P)->Covariance(0));
if (Debug()) {LOG_INFO <<
"CovP\t" << CovP << endm;}
297 TRSymMatrix Covi(F,TRArray::kAxSxAT,CovP);
if (Debug()) {LOG_INFO <<
"Covi\t" << Covi << endm;}
299 TCL::ucopy(Covi.GetArray(), FE.A, 21);
304 assert(test == tNode);
306 Int_t status = kTrack->fit(kInsideOut);
307 if (status)
continue;
309 kTrack->setPrimary(l+1);
313 kTrack->
add(extended,kOutsideIn);
314 if (extended && !extended->isValid()) extended=0;
315 if (extended && extended->getChi2()>1000) extended=0;
318 if (! extended)
continue;
320 kTrack->setPrimary(l+1);
321 extended->setUntouched();
322 Int_t ifail = kTrack->
refit();
327 kTrack->removeLastNode();
328 kTrack->setPrimary(0);
337 node->addTrack(pTrack);
338 pTrack->setKey( gTrack->key());
339 pTrack->setFlagExtension( gTrack->flagExtension());
340 StiStEventFiller::instance()->fillTrack(pTrack,kTrack, detInfo);
342 detInfoVec.push_back(detInfo);
343 primV->addDaughter(pTrack);
346 if (beam ) primV->setBeamConstrained();
348 if (primV->numberOfDaughters() < 1) {
351 primV->setTrackNumbers();
352 calculateRank(primV);
362 Float_t rank = primV->probChiSquared();
363 static Float_t Wveto = 1;
364 static Float_t Wmatch = 4;
365 if (primV->isBeamConstrained()) rank += Wmatch;
366 rank -= Wveto*primV->numPostXTracks();
367 rank += Wmatch*primV->numTracksWithPromptHit();
368 rank += Wmatch*primV->numTracksCrossingCentralMembrane();
369 rank += Wmatch*primV->numMatchesWithCTB()
370 - Wveto*primV->numNotMatchesWithCTB();
371 rank += Wmatch*primV->numMatchesWithBTOF()
372 - Wveto*primV->numNotMatchesWithBTOF();
373 rank += Wmatch*(primV->numMatchesWithBEMC() + primV->numMatchesWithEEMC());
378 if (primV->numTracksTpcWestOnly() > 0 && primV->numTracksTpcEastOnly() > 0)
379 rank += Wmatch*TMath::Min(primV->numTracksTpcWestOnly(),primV->numTracksTpcEastOnly());
380 primV->setRanking(rank);
381 if (Debug()) primV->Print();
385 fParticles->AddAtAndExpand (0,kg);
387 Double_t xyzp[6], CovXyzp[21];
388 dca->GetXYZ(xyzp,CovXyzp);
390 track.SetParameters(xyzp);
391 track.SetCovarianceMatrix(CovXyzp);
397 if (dca->charge() < 0) {
404 fParticles->AddAt(particle,kg);
408 void StKFVertexMaker::Fit() {
409 if (Debug() != 2) StKFVertex::SetDebug(Debug());
411 for (Int_t i = 0; i < fNPasses+1; i++) {
412 SafeDelete(fVerticesPass[i]);
414 Int_t NGoodGlobals = Particles().GetLast();
416 Double_t TempLog = fTempLog;
417 for (Int_t pass = 0; pass < fNPasses; pass++) {
419 Double_t dZ = fVtxs[pass]->GetBinWidth(1);
420 for (Int_t k = 0; k < NGoodGlobals; k++) {
422 if (! particle)
continue;
425 particle->GetPt(pT,dpT);
426 Double_t offset = 0.5*particle->GetPz()/pT;
427 Double_t SigmaZ = TMath::Sqrt(particle->Covariance(2,2) + offset*offset);
429 Double_t Z = particle->GetZ();
430 fVtxKs[pass]->Fill(Z);
431 Int_t bin1 = fVtxs[pass]->FindBin(Z - 5*SigmaZ);
432 if (bin1 < 1) bin1 = 1;
433 Int_t bin2 = fVtxs[pass]->FindBin(Z + 5*SigmaZ);
434 if (bin2 > fNzBins) bin2 = fNzBins;
435 Double_t z = fVtxs[pass]->GetBinCenter(bin1);
436 for (Int_t bin = bin1; bin <= bin2; bin++, z += dZ) {
437 fVtxs[pass]->Fill(z,(TMath::Erfc((z - Z - fzWindow)/SigmaZ) - TMath::Erfc((z - Z + fzWindow)/SigmaZ))/2.);
441 Double_t F = fVtxKs[pass]->GetEntries();
443 fVtxKs[pass]->SetNormFactor(F/dZ);
446 if (! Canvas()) opt =
"goff";
447 Int_t nfound = fSpectrum->Search(fVtx,3,opt,TMath::Min(0.1,5./NGoodGlobals));
448 if (! nfound)
continue;
451 fVtxs[0]->Draw(); fVtxKs[0]->Draw(
"same");
453 if (pass) fVtx->Draw(
"same");
456 if (StKFVertex::Debug() > 1) {
457 LOG_INFO <<
"Found " << nfound
458 <<
" candidate peaks to fit with " << NGoodGlobals
459 <<
" good globals from with " << nAccepted <<
" accepted" << endm;
461 Double_t *zOfPeaks =
new Double_t[nfound];
463 #if ROOT_VERSION_CODE > 336641
464 Double_t *xpeaks = fSpectrum->GetPositionX();
466 Float_t *xpeaks = fSpectrum->GetPositionX();
468 for (Int_t p = 0; p < nfound; p++) {
469 #if ROOT_VERSION_CODE > 336641
470 Double_t xp = xpeaks[p];
472 Float_t xp = xpeaks[p];
474 Int_t bin = fVtx->GetXaxis()->FindBin(xp);
475 Double_t yp = fVtx->GetBinContent(bin);
476 Double_t ep = fVtx->GetBinError(bin);
477 if (yp-1.25*ep < 0)
continue;
478 zOfPeaks[npeaks] = xp;
481 if (StKFVertex::Debug() > 1) {
482 LOG_INFO <<
"Found " << npeaks <<
" useful peaks to fit" << endm;
484 if (! npeaks) {
delete [] zOfPeaks;
break; }
485 if (fVerticesPass[pass]) {
delete fVerticesPass[pass]; fVerticesPass[pass] = 0;}
488 fcVertices = fVerticesPass[pass];
489 fcVertices->DoTrack2VertexAssociation(Particles());
490 if (! fcVertices->NoVertices())
continue;
491 if (AnnelingFcn(TMath::Exp(-TempLog)) <= 0)
continue;
492 if (! fcVertices->NoVertices())
continue;
493 fcVertices->UniqueTracks2VertexAssociation();
498 if (! fVerticesPass[0])
return;
499 if (fNPasses > 1 && Canvas()) {
501 fVtxs[1]->Draw(
"same");
504 Int_t N1 = fVerticesPass[0]->NoVertices();
506 if (fVerticesPass[1]) {
507 *fVerticesPass[0] += *fVerticesPass[1];
509 fcVertices = fVerticesPass[0];
510 fcVertices->MergeDuplicatedVertices();
511 if (! fcVertices->NoVertices())
return;
514 Double_t Temperature = TMath::Exp(TempLog);
517 Int_t pass = fNPasses;
518 if (fVerticesPass[pass]) {
delete fVerticesPass[pass]; fVerticesPass[pass] = 0;}
520 fcVertices = fVerticesPass[pass];
521 StAnneling::SetTemperature(Temperature);
522 for (Int_t k = 1; k < NGoodGlobals; k++) {
524 if (! particleK)
continue;
525 if (particleK->GetID() > 100000)
continue;
527 for (Int_t l = k+1; l < NGoodGlobals; l++) {
529 if (! particleL)
continue;
530 if (particleL->GetID() > 100000)
continue;
531 Double_t dist = particleK->GetDistanceFromParticle(*particleL);
532 if (dist > 5.0)
continue;
534 vtx =
new StKFVertex(fcVertices->NoVertices() + 1);
535 vtx->AddTrack(
new StKFTrack(k,particleK));
537 vtx->AddTrack(
new StKFTrack(l,particleL));
541 Int_t N = vtx->NoTracks();
542 if (! N) {
delete vtx; vtx = 0;
continue;}
543 Double_t X = vtx->Vertex().X();
544 Double_t Y = vtx->Vertex().Y();
545 Double_t R = TMath::Sqrt(X*X + Y*Y);
546 if (R > 200 ) {
delete vtx; vtx = 0;
continue;}
547 Double_t prob = TMath::Prob(vtx->Vertex().GetChi2(),vtx->Vertex().GetNDF());
548 if (N > 2 || prob > 1.e-3) {
549 for (Int_t i = 0; i < N; i++) {
550 KFParticle *particle = vtx->Track(i)->OrigParticle();;
551 Int_t
ID = particle->GetID()%100000 + 100000*vtx->ID();;
555 fcVertices->AddVertex(vtx);
557 if (StKFVertex::Debug() > 1) {
558 LOG_INFO <<
"Candidate for secondary vertices: " << fcVertices->NoVertices() << endm;
560 if ( fcVertices->NoVertices() ) {
564 *fVerticesPass[0] += *fVerticesPass[fNPasses];
568 fcVertices = fVerticesPass[0];
569 fcVertices->Compress();
570 if (! fcVertices->NoVertices())
return;
571 fcVertices->MergeDuplicatedVertices();
572 fminBrent->SetFunction(*func,TMath::Exp(-0.5*(TempLog)),TMath::Exp(-TempLog),1);
573 if (! fminBrent->Minimize(10,0.1,0.1)) {
574 LOG_WARN <<
"Temperature fit has failed" << endm;
577 Temperature = 1./fminBrent->XMinimum();
579 StAnneling::SetTemperature(Temperature);
580 fcVertices->UniqueTracks2VertexAssociation();
581 fcVertices->Fit(29,Canvas(),fVtx);
582 if (Canvas()) Canvas()->Update();
585 Double_t StKFVertexMaker::AnnelingFcn(Double_t TInv) {
586 if (! fcVertices)
return 0;
587 Double_t Temperature = 1./TInv;
588 StAnneling::SetTemperature(Temperature);
589 Double_t Chi2 = fcVertices->Fit();
590 if (StKFVertex::Debug())
591 LOG_INFO <<
"StKFVertexMaker::AnnelingFcn\tTemperature = " << Temperature <<
" Chi2 = " << Chi2 << endm;
void Clear(Option_t *option="")
User defined functions.
StiKalmanTrackNode * getInnerMostHitNode(int qua=0) const
Accessor method returns the inner most hit node associated with the track.
Definition of Kalman Track.
void setGlobal(const StiDetector *detector, const StMeasuredPoint *stHit, Float_t x, Float_t y, Float_t z, Float_t energy)
StiTrackNode * extendToVertex(StiHit *vertex)
virtual Abstract * getInstance()=0
Get a pointer to instance of objects served by this factory.
StiKalmanTrackNode * getInnerMostNode(int qua=0) const
Accessor method returns the inner most node associated with the track.
Definition of Kalman Track.
virtual void add(StiTrackNode *node, int direction, StiTrackNode *near=0)
static void SetField(Double_t Bz)
void fillDetectorInfo(StTrackDetectorInfo *detInfo, StiKalmanTrack *kTrack, bool refCountIncr)