StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StppLMVVertexFinder.cxx
1 /************************************************************
2  *
3  * $Id: StppLMVVertexFinder.cxx,v 1.32 2017/02/15 15:30:18 smirnovd Exp $
4  *
5  * Author: Jan Balewski
6  ************************************************************
7  *
8  * Description:
9  *
10  ************************************************************/
11 
12 #include <cmath>
13 
14 #include "StChain/StMaker.h"
15 #include "StEvent/StEvent.h"
16 #include "StEvent/StRunInfo.h"
17 #include "StEvent/StTrack.h"
18 #include "StEvent/StTrackDetectorInfo.h"
19 #include "StEvent/StTrackGeometry.h"
20 #include "StEvent/StTrackNode.h"
21 #include "StGenericVertexMaker/StppLMVVertexFinder.h"
22 #include "St_base/StMessMgr.h"
23 #include "StarClassLibrary/StThreeVectorD.hh"
24 #include "tables/St_g2t_vertex_Table.h"
25 
26 
27 //==========================================================
28 //==========================================================
29 StppLMVVertexFinder::StppLMVVertexFinder() {
30  LOG_INFO << "StppLMVVertexFinder::StppLMVVertexFinder is in use." << endm;
31  mBeamHelix = 0;
32  mVertexConstrain = false;
33  mTotEve = 0;
34  mMode = 1;
35 }
36 
37 //==========================================================
38 //==========================================================
39 void
40 StppLMVVertexFinder::Init() {
41 
42  //jan default cuts
43  if (mMode==0){
44  LOG_INFO << "The ppLMV4 cuts have been activated" << endm;
45  mMaxTrkDcaRxy = 3.9;
46  mMinTrkPt = 0.2;
47  mMinNumberOfFitPointsOnTrack = 15; // a typo (=10) was here before , JB
48  mMaxZrange = 180; // for tracks; typo (=250) was here before , JB
49  mDVtxMax = 4.0; // max sigma multipl between tracks and current vertex, used for tracks rejection
50  mMinMatchTr = 1; // minimal # of tracks matched to CTB
51  mBLequivNtr = 100; // equivalent # of tracks for BeamLine
52  mMatchCtbMax_eta = mCtbEtaSeg/2.+0.02;
53  mMatchCtbMax_phi = mCtbPhiSeg/2.+M_PI*1./180.;
54  } else {
55  LOG_INFO << "The ppLMV5 cuts have been activated" << endm;
56  mMaxTrkDcaRxy = 2.0;
57  mMinTrkPt = 0.2;
58  mMinNumberOfFitPointsOnTrack = 15;
59  mMaxZrange = 150;
60  mDVtxMax = 4.0;
61  mMinMatchTr = 2;
62  mBLequivNtr = 20;
63  mMatchCtbMax_eta = mCtbEtaSeg/2.+0.02;
64  mMatchCtbMax_phi = mCtbPhiSeg/2.+M_PI*0./180.;
65  }
66 }
67 
68 //==========================================================
69 //==========================================================
70 void
71 StppLMVVertexFinder::Clear(){ // Reset vertex
72  StGenericVertexFinder::Clear();
73  mCtbHits.clear();
74  mPrimCand.clear();
75  LOG_INFO << "StppLMVVertexFinder::Clear() ..." << endm;
76 }
77 
78 //==========================================================
79 //==========================================================
80 void
81 StppLMVVertexFinder::addFakeVerex(float z){
82  StPrimaryVertex primV;
83  Float_t cov[6] = {1,0.0,2,0.0,0.0,3 };
84  StThreeVectorD XVertex(0.1,0.2,z);
85  primV.setPosition(XVertex);
86  primV.setCovariantMatrix(cov);
87  primV.setVertexFinderId(pplmvVertexFinder);
88  primV.setFlag(1);
89  primV.setRanking(444);
90  //..... add vertex to the list
91  addVertex(primV);
92 }
93 
94 //==========================================================
95 //==========================================================
96 StppLMVVertexFinder::~StppLMVVertexFinder() {
97  delete mBeamHelix;mBeamHelix=0;
98 }
99 
100 //==========================================================
101 //==========================================================
102 int
103 StppLMVVertexFinder::fit(StEvent* event) {
104  LOG_INFO << "StppLMVVertexFinder::fit() START ..." << endm;
105  //
106 
107  n1=0,n2=0,n3=0, n4=0,n5=0,n6=0;
108  // mStatus = -888;
109 
110  mTotEve++;
111  eveID=event->id();
112 
113  mBfield = event->runInfo()->magneticField();
114  LOG_INFO << Form("ppLMV5:: mBfield[Tesla]=%e ",mBfield)<<endm;
115 
116 
117  gMessMgr->Message("","I") << "ppLMV5::cuts"
118  <<"\n CtbThres_ch (real)="<<mCtbThres_ch
119  <<"\n CtbThres_mev (M-C)="<<mCtbThres_mev
120  <<"\n MinNumberOfFitPointsOnTrack="<<mMinNumberOfFitPointsOnTrack
121  <<"\n MaxTrkDcaRxy/cm="<<mMaxTrkDcaRxy
122  <<"\n MinTrkPt GeV/c ="<<mMinTrkPt
123  <<"\n MatchCtbMax_eta="<<mMatchCtbMax_eta
124  <<"\n MatchCtbMax_phi/deg="<<mMatchCtbMax_phi/3.1416*180
125  <<"\n BeamLequivNtr="<<mBLequivNtr
126  <<"\n DVtxMax (dz/sig)="<<mDVtxMax
127  <<"\n MinMatchTr ="<< mMinMatchTr
128  <<"\n MaxZrange (cm) ="<< mMaxZrange
129  <<"\n VertexConstrain="<<mVertexConstrain
130  // <<"\n ="<<
131  <<endm;
132 
133  // get CTB info, does not work for embeding
134  if(event->runId()<100000){
135  St_DataSet *gds=StMaker::GetChain()->GetDataSet("geant");
136  collectCTBhitsMC(gds); // use M-C
137  } else {
138  StTriggerData *trgD=event->triggerData ();
139  collectCTBhitsData(trgD); // use real data
140  }
141  // printCtb(); //4ppv
142 
143  if(mCtbHits.size()<=0){
144  LOG_WARN << "StppLMVVertexFinder::fit() no valid CTB hits found, quit" << endm;
145  return 0;
146  }
147 
148  // Loop all global tracks (TPC) and store the
149  // refering helices and their estimated DCA
150  // resolution in vectors.
151 
152  StSPtrVecTrackNode& nodes = event->trackNodes();
153  for (unsigned int k=0; k<nodes.size(); k++) {
154  StTrack* g = nodes[k]->track(global);
155  float sigma=0;
156  if( !matchTrack2CTB(g,sigma)) continue;;
157  JHelix x;
158  x.helix=g->geometry()->helix();
159  x.sigma=sigma;
160  mPrimCand.push_back(x);
161  // printf("added tr %d w/ sigma=%f\n",mPrimCand.size(),sigma);
162 
163  } // end of track selection
164 
165  // printf(", now n1=%d n2=%d n3=%d n4=%d n6=%d\n",n1,n2,n3,n4,n6); //tmp
166  LOG_DEBUG << ", now n1=" << n1 << " n2=" << n2 << " n3=" << n3 << " n4=" << n4 << "n6=" << n6 << endm;
167 
168 
169  //
170  // In case there are no tracks left we better quit
171  //
172  if (mPrimCand.size() < mMinMatchTr){
173  LOG_WARN << "StppLMVVertexFinder::fit() only "<< mPrimCand.size() << "tracks to fit - too few, quit ppLMV" << endm;
174  return 0;
175  }
176  LOG_INFO << "StppLMVVertexFinder::fit() size of helix vector: " << mPrimCand.size() << endm;
177 
178  // use beam line constraint or not
179  if(mVertexConstrain ) {
180 
181  float sigMin=100000; // pick large weight for this track
182  for( unsigned int j=0;j<mPrimCand.size();j++) {
183  float sig=mPrimCand[j].sigma;
184  if(sigMin>sig) sigMin=sig;
185  }
186  float sigma=sigMin/::sqrt(mBLequivNtr); //<== assigne relative weight
187  JHelix x;
188  x.helix=*mBeamHelix;
189  x.sigma=sigma;
190  mPrimCand.push_back(x);
191  //printf("WARN ppLMV: nominal beam line added with sigma=%f, now nTrack=%d \n",sigma, mPrimCand.size());
192  LOG_WARN << "ppLMV: nominal beam line added with sigma=" << sigma
193  << ", now nTrack=" << mPrimCand.size() << endm;
194 
195  } // end of beamLine
196 
197 
198  //printf("PrimCand before ppLMV for eveID=%d tracks at first point\n",eveID);
199  LOG_DEBUG << "PrimCand before ppLMV for eveID=" << eveID << "tracks at first point" << endm;
200 
201  //tmp - lits all matched tracks
202  for( unsigned int j=0;j<mPrimCand.size();j++) {
203  StThreeVectorD p=mPrimCand[j].helix.momentum(mBfield*tesla);
204  printf("j=%d sig=%f pT=%f eta=%f phi/deg=%f\n",j,mPrimCand[j].sigma,p.perp(),p.pseudoRapidity(), p.phi()/M_PI*180);
205  }
206 
207  // ---------- D O F I N D V E R T E X
208  int ret=ppLMV5();
209  if(ret==false) {
210  LOG_DEBUG << "ppLMV did not found vertex"<< endm;
211  return 0;
212  }
213 
214 
215  LOG_INFO << "Prim tr used by ppLMV for eveID=" << eveID
216  << ", tracks at vertex=" << mPrimCand.size()<<endm;
217 
218  assert(size());
219  for( unsigned int j=0;j<mPrimCand.size();j++) {
220  double spath = mPrimCand[j].helix.pathLength( getVertex(0)->position().x(),getVertex(0)->position().y());
221  StThreeVectorD p=mPrimCand[j].helix.momentumAt(spath,mBfield*tesla);
222  // printf("j=%d sig=%f pT=%f eta=%f phi/deg=%f cur=%f p=%f charg=%d spath=%f\n",j,mPrimCand[j].sigma,p.perp(),p.pseudoRapidity(), p.phi()/M_PI*180,mPrimCand[j].helix.curvature(), p.mag(),mPrimCand[j].helix.charge(mBfield*tesla),spath);
223  }
224 
225  gMessMgr->Message("","I") << "Prim ppLMV Vertex at " << getVertex(0)->position()<<endm;
226  return size();
227 }
228 
229 
230 //======================================================
231 //======================================================
232 void
233 StppLMVVertexFinder::printInfo(ostream& os) const
234 {
235  os << "StppLMVVertexFinder - Fit Statistics:" << endl;
236  os << "found prim vertices ................ " <<size() << endl;
237  os << "no more info printed at the moment, Jan"<<endl;
238  }
239 
240 
241 //======================================================
242 //======================================================
243 void
244 StppLMVVertexFinder::UseVertexConstraint() {
245  mVertexConstrain = true;
246  double mX0 = mBeamline.x0;
247  double mY0 = mBeamline.y0;
248  double mdxdz = mBeamline.dxdz;
249  double mdydz = mBeamline.dydz;
250  LOG_INFO << "StppLMVVertexFinder::Using Constrained Vertex" << endm;
251  StThreeVectorD origin(mX0,mY0,0.0);
252  double pt = 88889999;
253  double nxy=::sqrt(mdxdz*mdxdz + mdydz*mdydz);
254  if(nxy<1.e-5){ // beam line _MUST_ be tilted
255  LOG_WARN << "StppLMVVertexFinder:: Beam line must be tilted!" << endm;
256  nxy=mdxdz=1.e-5;
257  }
258  double p0=pt/nxy;
259  double px = p0*mdxdz;
260  double py = p0*mdydz;
261  double pz = p0; // approximation: nx,ny<<0
262  StThreeVectorD MomFstPt(px*GeV, py*GeV, pz*GeV);
263  delete mBeamHelix;
264  mBeamHelix = new StPhysicalHelixD(MomFstPt,origin,0.5*tesla,1.);
265 }
266 
267 
268 
269 
270 //==========================================================
271 //==========================================================
272 bool
273 StppLMVVertexFinder::matchTrack2CTB (StTrack* track, float & sigma) {
274  /* upgrade:
275  - used dE/dX for strag
276  - use track length
277  - make clear()
278  - check for total energy per slat for geant
279  */
280 
281  sigma=0;
282  const double Rctb=213.6; // (cm) radius of the CTB
283  unsigned int nFitP=0;
284 
285  if (!track) return false; // it should never happen
286  if(!finite(track->geometry()->helix().curvature())){
287  LOG_WARN << "StppLMVVertexFinder::matchTrack2CTB: helix.curvature not finite, fix tracker, ppLMV aborting" << endm;
288  mCtbHits.clear();
289  mPrimCand.clear();
290  return false;
291  }
292 
293  if( track->flag()<0) return false;
294  if( track->topologyMap().trackFtpc() )return false;
295 
296  n1++;
297 
298  StPhysicalHelixD TrkHlxIn=track->geometry()->helix();
299 
300  // check Rxy_min condition close to beam
301  double spath = TrkHlxIn.pathLength(mBeamline.x0, mBeamline.y0);
302  StThreeVectorD posDCA = TrkHlxIn.at(spath);
303  // cout<<" DCA Position: "<<posDCA<<endl;
304  double x_m = posDCA.x(), y_m = posDCA.y();
305  double dmin = ::sqrt(x_m*x_m + y_m*y_m);
306  if( dmin > mMaxTrkDcaRxy ) return false;
307  if (fabs(posDCA.z()) >mMaxZrange) return false;
308  n2++;
309 
310  nFitP = track->detectorInfo()->numberOfPoints(kTpcId);
311 
312  if( nFitP <= mMinNumberOfFitPointsOnTrack) return false;
313  n3++;
314 
315  if(track->geometry()->momentum().perp() <mMinTrkPt ) return false;
316  n4++;
317 
318  //cout<<"\n\n DCA to beam at xy=00: "<<posDCA<<endl;
319 
320  //Find momentum direction at vertex point
321  StThreeVectorD pmom = TrkHlxIn.momentumAt(spath,mBfield*tesla );
322  double beta = pmom.mag()/::sqrt(pmom.mag()*pmom.mag()+0.139*0.139); //Assume pion
323 
324  // old formula from TPT chain
325  // float strag=0.0136/beta/pmom.mag()*fabs(spath);
326 
327  // ppLMV face-lift : attenuated weights
328  float pmomM=pmom.mag();
329  float spathL=fabs(spath); // reduce advantage of SVT matched tracks
330 
331  if(mMode ==1){
332  // This is mode 1 (ppLMV5)
333  if (pmomM >4 ) pmomM=4; //inhibit domination of high pT tracks
334  if( spathL<40) spathL=40;
335  } else {
336  // This is mode 0 (ppLMV4)
337  // ignore SVT contribution , ~aproximately
338  if( spathL<60) spathL=60;
339  }
340 
341  float strag=0.0136/beta/pmomM*spathL;
342  if(fabs(mBfield)<0.01) strag=0.0136*spathL; // no field case, pT makes no sense
343 
344  // printf("stragling=%f %f p=%f %f nFp=%d nPp=%d\n",strag,beta,pmom.mag(),spath, track->fitTraits().numberOfFitPoints(), track->numberOfPossiblePoints(kTpcId) );
345 
346 
347  if ( !track->outerGeometry() ) return false;
348  StPhysicalHelixD TrkHlxOut=track->outerGeometry()->helix();
349  pairD d2 = TrkHlxOut.pathLength(Rctb);
350  // printf(" path 1=%f, 2=%f, period=%f, R=%f\n",d2.first ,d2.second,TrkHlx.period(),1./TrkHlxOut.curvature());
351 
352  // assert(d2.first<0); // propagate backwards
353  //assert(d2.second>0); // propagate forwards
354 
355  if(d2.first>=0 || d2.second<=0) {
356  n5++;
357  gMessMgr->Message("","W") << "ppLMV::matchTrack2CTB ()"
358  " unexpected solution for track crossing CTB, TrkHlxOut="<< TrkHlxOut<<endm;
359  return false;
360  }
361 
362 
363  StThreeVectorD posCTB = TrkHlxOut.at(d2.second);
364  // double xmagn = ::sqrt( posCTB.x()*posCTB.x() + posCTB.y()*posCTB.y() );//tmp, out
365  // printf(" punch2 x,y,z=%.1f, %.1f, %.1f, Rxy=%.1f\n",posCTB.x(),posCTB.y(),posCTB.z(),xmagn);
366 
367  float phi=atan2(posCTB.y(),posCTB.x());
368  if(phi<0) phi+=2*M_PI;// now phi is [0,2Pi] as for CTB slats
369 
370  // printf("posCTB.z()=%f posDCA.z()=%f\n",posCTB.z(),posDCA.z());
371 
372  unsigned int ih;
373  for(ih=0;ih<mCtbHits.size();ih++) {// loop over CTB hits
374 
375  // match to CTB slats in phi
376  float del_phi=phi-mCtbHits[ih].phi;
377  if(del_phi>M_PI) del_phi-=2*M_PI;
378  if(del_phi<-M_PI) del_phi+=2*M_PI;
379  //printf("phiRad trk=%f CTB=%f del=%f\n",phi,mCtbHits[ih].phi,del_phi);
380  //printf("match ih=%d del_phi=%f/deg\n",ih, del_phi/M_PI*180);
381  if(fabs(del_phi) >mMatchCtbMax_phi) continue;
382 
383  // match to CTB slats in eta
384  float eta=posCTB.pseudoRapidity();
385  float del_eta=eta-mCtbHits[ih].eta;
386  //printf(" match ih=%d del_eta=%f\n",ih, del_eta);
387  if(fabs(del_eta) >mMatchCtbMax_eta) continue;
388 
389  // printf(" CTB match OK: del_eta=%.2f, del_phi/deg=%.1f \n", del_eta,del_phi/M_PI*180);
390  sigma=strag;
391  n6++;
392  // printf("add tr %d w/ sigma=%f p/GeV=%f spath/cm=%f nFitP=%d nSVT=%d\n",mPrimCand.size(),sigma,pmom.mag(),spath,nFitP, track->detectorInfo()->numberOfPoints(kSvtId) );
393 
394  return true;
395  }
396 
397  // match not found
398  return false;
399 }
400 
401 //==========================================================
402 //==========================================================
403 bool
404 StppLMVVertexFinder::ppLMV5() {
405  // ---------- D O F I N D V E R T E X
406  if(mMode == 0) LOG_WARN<<"ppLMV4 cuts have been activated"<<endm;
407 
408  int totTr=mPrimCand.size();
409  unsigned int minTr=mMinMatchTr;
410  if(mVertexConstrain) minTr++;
411  //printf("passed %d tracks match to CTB, BeamLine=%d\n",totTr,mVertexConstrain );
412  LOG_DEBUG << "passed " << totTr << " tracks match to CTB, BeamLine=" << mVertexConstrain << endm;
413 
414  double xo = mBeamline.x0;
415  double yo = mBeamline.y0;
416 
417  //Do the actual vertex fitting, continue until good
418  double A11=0.0,A12=0.0,A13=0.0;
419  double A21=0.0,A22=0.0,A23=0.0;
420  double A31=0.0,A32=0.0,A33=0.0; // Matrix Elements
421 
422  double C11=0.0,C12=0.0,C13=0.0;
423  double C21=0.0,C22=0.0,C23=0.0;
424  double C31=0.0,C32=0.0,C33=0.0; // C = A^-1
425 
426  int done = 0;
427  int vertIter=0;
428  double chi2=0;
429  StThreeVectorD XVertex(999.,888.,777.);
430  while( done != 1 ){
431  vertIter++;
432  // Check that there at least are 2 tracks
433  if( mPrimCand.size() < minTr ){
434  LOG_WARN << "ppLMV5: below "<<minTr<<" track remains. No vertex found." << endm;
435  return false;
436  }
437 
438  // Begin by doing a fit
439  A11=0.0,A12=0.0,A13=0.0;
440  A21=0.0,A22=0.0,A23=0.0;
441  A31=0.0,A32=0.0,A33=0.0; // Matrix Elements
442 
443  C11=0.0,C12=0.0,C13=0.0;
444  C21=0.0,C22=0.0,C23=0.0;
445  C31=0.0,C32=0.0,C33=0.0; // C = A^-1
446 
447  double b1=0.0,b2=0.0,b3=0.0;
448 
449  // Compute matrix A and vector b
450  for(unsigned int itr=0; itr < mPrimCand.size(); itr++){
451 
452  double spath = mPrimCand[itr].helix.pathLength(xo,yo);
453  StThreeVectorD XClosest = mPrimCand[itr].helix.at(spath);
454  StThreeVectorD XMomAtClosest = mPrimCand[itr].helix.momentumAt(spath,mBfield*tesla );
455 
456  double xp = XClosest.x(); double yp= XClosest.y(); double zp= XClosest.z();
457  // printf("itr=%d DCA x=%f y=%f z=%f sig=%f\n",itr,xp,yp,zp,mPrimCand[itr].sigma);
458 
459  double xhat = XMomAtClosest.x()/XMomAtClosest.mag();
460  double yhat = XMomAtClosest.y()/XMomAtClosest.mag();
461  double zhat = XMomAtClosest.z()/XMomAtClosest.mag();
462  float sig=mPrimCand[itr].sigma;
463  A11=A11+(yhat*yhat+zhat*zhat)/sig;
464  A12=A12-(xhat*yhat)/sig;
465  A13=A13-(xhat*zhat)/sig;
466  A22=A22+(xhat*xhat+zhat*zhat)/sig;
467  A23=A23-(yhat*zhat)/sig;
468  A33=A33+(xhat*xhat+yhat*yhat)/sig;
469  b1=b1 + ( (yhat*yhat+zhat*zhat)*xp - xhat*yhat*yp - xhat*zhat*zp )/sig;
470  b2=b2 + ( (xhat*xhat+zhat*zhat)*yp - xhat*yhat*xp - yhat*zhat*zp )/sig;
471  b3=b3 + ( (xhat*xhat+yhat*yhat)*zp - xhat*zhat*xp - yhat*zhat*yp )/sig;
472  }
473  A21 = A12; A31=A13; A32=A23;
474 
475  // Invert A
476  double detA = A11*A22*A33 + A12*A23*A31 + A13*A21*A32;
477  detA = detA - A31*A22*A13 - A32*A23*A11 - A33*A21*A12;
478  // cout<<"Determinant= "<<detA<<endl;
479  // cout<<"A11,A12,A13: "<<A11<<" "<<A12<<" "<<A13<<endl;
480  // cout<<"A21,A22,A23: "<<A21<<" "<<A22<<" "<<A23<<endl;
481  // cout<<"A31,A32,A33: "<<A31<<" "<<A32<<" "<<A33<<endl;
482  // cout<<"b1,b2,b3 "<<b1<<" "<<b2<<" "<<b3<<endl;
483  C11=(A22*A33-A23*A32)/detA; C12=(A13*A32-A12*A33)/detA; C13=(A12*A23-A13*A22)/detA;
484  C21=C12; C22=(A11*A33-A13*A31)/detA; C23=(A13*A21-A11*A23)/detA;
485  C31=C13; C32=C23; C33=(A11*A22-A12*A21)/detA;
486 
487  // Find Vertex Position
488  double Xv = C11*b1 + C12*b2 + C13*b3;
489  double Yv = C21*b1 + C22*b2 + C23*b3;
490  double Zv = C31*b1 + C32*b2 + C33*b3;
491  XVertex.setX(Xv); XVertex.setY(Yv); XVertex.setZ(Zv);
492  LOG_DEBUG <<vertIter<<" Vertex Position : "<<XVertex.x()<<" "<<XVertex.y()<<" "<<XVertex.z()<<endm;
493  LOG_DEBUG <<"Error in Position : "<<::sqrt(C11)<<" "<<::sqrt(C22)<<" "<<::sqrt(C33)<<endm;
494 
495 
496  // Check if the fit is any good
497  // Loop over tracks again to get Chi2 and check each track's deviation
498 
499  double dmax=0.0;
500  vector<JHelix>::iterator itehlx, end, ikeep;
501  end=mPrimCand.end();
502  if(mVertexConstrain )end--; // to preserve beamL
503 
504  for( itehlx=mPrimCand.begin(); itehlx <end; itehlx++) {
505  StPhysicalHelixD hlx = (*itehlx).helix;
506  double sig = (*itehlx).sigma;
507  double spath = hlx.pathLength(XVertex.x(),XVertex.y());
508  StThreeVectorD XHel = hlx.at(spath);
509  double d=(XHel.x()-XVertex.x())*(XHel.x()-XVertex.x());
510  d = d+(XHel.y()-XVertex.y())*(XHel.y()-XVertex.y());
511  d = d+(XHel.z()-XVertex.z())*(XHel.z()-XVertex.z());
512  d = ::sqrt(d);
513  chi2 = chi2 + (d*d)/(sig*sig);
514  double drel = d; // do not use sig during track rejection ??? JB
515  //printf(" DCA x=%f y=%f z=%f d=%f drel=%f dmax=%f sig=%f\n",XHel.x(),XHel.y(),XHel.z(),d,drel,dmax,sig);
516  if( drel > dmax ){// save track that deviates the most from vertex to be discarded later
517  dmax = drel;
518  ikeep = itehlx;
519  }
520  }
521 
522  if( dmax > mDVtxMax ){
523  LOG_INFO << "Removing a track! dmax=" << dmax << endm;
524  mPrimCand.erase(ikeep);
525  done=0;
526  }
527  else{
528  done=1;
529  }
530  } // End While Loop
531 
532  // double chi2pdof = chi2/(mPrimCand.size()-1);
533 
534  StPrimaryVertex primV; // Initial comment - cxx,?,cyy,?,?,czz
535  Float_t cov[6] = {(Float_t) C11, 0.0, // m(1,1) m(1,2)==m(2,1)
536  (Float_t) C22, 0.0, // m(2,2) m(1,3)==m(3,1)
537  0.0, (Float_t) C33 }; // m(2,3)==m(3,2) m(3,3)
538 
539  primV.setPosition(XVertex);
540  primV.setCovariantMatrix(cov);
541  primV.setVertexFinderId(pplmvVertexFinder);
542  primV.setNumTracksUsedInFinder(mPrimCand.size());
543  primV.setNumMatchesWithCTB(mPrimCand.size());// the same, only matched tracks are used
544 
545  /* I do not understand if this elaborate scheme is applicable to multiple prim vertices for pp
546  http://www.star.bnl.gov/STAR/html/all_l/html/dst_vertex_flags.html
547  provide '1' as was
548  */
549  primV.setFlag(1);
550  primV.setRanking(555);
551 
552  //..... add vertex to the list
553  addVertex(primV);
554 
555 #if 0
556  /*
557  The fake vertex will never take precedence over the real one in
558  the muDst analysi since its rank is lower (if default ranking is used).
559  But may pick a random match if luminosity (i.e. pileup is high).
560  Unless the true vertex is not found. Then we would have a fake
561  vertex w/o prim tracks.
562  Jan B.
563  */
564  if(eveID%2) addFakeVerex(XVertex.z()+20);
565 #endif
566 
567 #if 0
568  mFitResult=XVertex;
569  mFitError.setX(sqrt(C11)); mFitError.setY(sqrt(C22)); mFitError.setZ(sqrt(C33));
570 #endif
571 
572 
573  LOG_DEBUG <<"ppLMV5: Primary Vertex found!\nVert position: "<<XVertex<<", accepted tracks "<<mPrimCand.size()<<" of "<<totTr<<" eveID="<<eveID<<endm;
574  printf("##V %6d %d %f %f %f %d %d %d\n",eveID,mTotEve,XVertex.x(),XVertex.y(),XVertex.z(),mCtbHits.size(),n1,NCtbMatches());
575 
576 
577  // get geant vertex
578  St_DataSet *gds=StMaker::GetChain()->GetDataSet("geant");
579  if(gds) {
580  St_g2t_vertex *g2t_ver=( St_g2t_vertex *)gds->Find("g2t_vertex");
581  if(g2t_ver) {
582  // -------------- A C C E S S G E A N T V E R T E X (for histo)
583  g2t_vertex_st *GVER= g2t_ver->GetTable();
584  // printf("GVER add=%d\n",GVER);
585  // hPiFi[10]->Fill(GVER->ge_x[2]-rZver);
586  // hPiFi[11]->Fill(GVER->ge_x[0]-rXver);
587  // hPiFi[12]->Fill(GVER->ge_x[1]-rYver);
588  printf("Z Geant-found=%.2f, dx=%.2f, dy=%.2f nCtbSl=%d n1=%d eveID=%d\n",GVER->ge_x[2]-XVertex.z(),GVER->ge_x[0]-XVertex.x(),GVER->ge_x[1]-XVertex.y(),mCtbHits.size(),n1,eveID);
589  printf("##G %6d %d %f %f %d %d %d\n",eveID,mTotEve,GVER->ge_x[2],XVertex.z(),mCtbHits.size(),n1,NCtbMatches());
590 
591  }
592  }
593 
594  LOG_DEBUG << "StppLMVVertexFinder::ppLMV5() ends" << endm;
595  return true;
596 }
597 
598 
599 //==========================================================
600 //==========================================================
601 int StppLMVVertexFinder::NCtbMatches() {
602  int nTr=mPrimCand.size();
603  if(mVertexConstrain ) nTr--; // drop beam line
604  return nTr;
605 }
606 
607 
608 /*
609  * $Log: StppLMVVertexFinder.cxx,v $
610  * Revision 1.32 2017/02/15 15:30:18 smirnovd
611  * Refactoring design flaws by getting rid of static members
612  *
613  * For details see commits on master branch edbe287d..8166aa1e
614  *
615  * - StMinuitVertexFinder: Move static fit functions to base class
616  * - StMinuitVertexFinder: Use equivalent base class fit function for Beamline3D fits
617  * - StMinuitVertexFinder: Get rid of static mWidthScale
618  * in favor of equivalent local variables.
619  * To do: The scale should come from the database where it is actually already
620  * defined. See Calibrations::rhic::vertexSeed::weight in DB
621  * - Converted functions from static to member + adjustments
622  * - Introduced self static pointer to vertex finder implementations
623  * - This is required by TMinuit relying on static fit functions.
624  * - StMinuitVertexFinder: Use common fit function type
625  * - Renamed Chi2AtVertex to virtual CalcChi2DCAs
626  * The virtuality allows to keep backward compatibility with the previous
627  * implementation of 1D fit with (forced) beamline in StMinuitVertexFinder.
628  * - Convert static sDCAs to mDCAs
629  * - Convert static sBeamline to mBeamline
630  *
631  * Revision 1.31 2017/02/14 22:00:40 smirnovd
632  * Squashed commit of the following clean-up changes:
633  *
634  * See master branch for details.
635  *
636  * - Remove commented code for debugging
637  * - Removed extra validation; it is done at construction
638  * - No need to include header for apple OS
639  * - Removed pointless assert
640  * - Use standard portable type name
641  * - Remove unused header math_constants.h
642  * - StMinuitVertexFinder: Remove abandoned member function
643  *
644  * Revision 1.30 2017/01/06 21:01:48 smirnovd
645  * Use pi constant from standard library, s/C_PI/M_PI/
646  *
647  * Revision 1.29 2017/01/03 22:17:36 smirnovd
648  * [Stylistic] Changed public addVertex() to accept references
649  *
650  * Avoid unnecessary gymnastics with pointers
651  *
652  * Revision 1.28 2016/08/18 17:46:14 smirnovd
653  * Squashed commit of the following refactoring changes:
654  *
655  * Date: Wed Jul 27 18:31:18 2016 -0400
656  *
657  * Removed unused arguments in UseVertexConstraint()
658  *
659  * In StiPPVertexFinder and StvPPVertexFinder this method does nothing
660  *
661  * Date: Wed Jul 27 16:47:58 2016 -0400
662  *
663  * Make old UseVertexConstraint private virtual and call it from its public replacement in the base class
664  *
665  * also mark methods as private explicitly
666  *
667  * Date: Wed Jul 27 16:52:02 2016 -0400
668  *
669  * Removed unused private data member mWeight
670  *
671  * Date: Wed Jul 27 16:50:42 2016 -0400
672  *
673  * Prefer base class static beamline parameters rather than this class private members
674  *
675  * Date: Wed Jul 27 16:21:49 2016 -0400
676  *
677  * StPPVertexFinder: Got rid of unused private beamline parameters
678  *
679  * The equivalent measurements are available from the base class
680  * StGenericVertexFinder
681  *
682  * Date: Wed Jul 27 16:19:19 2016 -0400
683  *
684  * StPPVertexFinder: For beamline position use equivalent static methods from parent class
685  *
686  * Date: Wed Jul 27 16:05:50 2016 -0400
687  *
688  * StGenericVertexMaker: Assigning once is enough
689  *
690  * Date: Mon Aug 15 10:43:49 2016 -0400
691  *
692  * StGenericVertexFinder: Print out beamline parameters
693  *
694  * Print beamline values as extracted from the database before any modification.
695  *
696  * Date: Wed Jul 6 15:33:02 2016 -0400
697  *
698  * Stylistic changes and minor refactoring
699  *
700  * Whitespace and comments for improved readability
701  * s/track/stiKalmanTrack/
702  *
703  * Date: Wed Jul 6 15:28:16 2016 -0400
704  *
705  * StPPVertexFinder: Switched to cleaner c++11 range loop syntax
706  *
707  * Date: Wed Jul 6 15:22:14 2016 -0400
708  *
709  * StPPVertexFinder: Minor c++ refactoring
710  *
711  * - Removed unused counter
712  * - c-style array to std::array
713  *
714  * Date: Wed Jul 6 15:20:11 2016 -0400
715  *
716  * Deleted commented out code
717  *
718  * Removed unused #include's StMinuitVertexFinder
719  *
720  * Revision 1.27 2016/04/28 18:17:38 smirnovd
721  * [Cosmetic] Whitespace, doxygen, comments, and readability changes only
722  *
723  * Revision 1.26 2016/04/15 19:24:14 smirnovd
724  * Got rid of unused variables reported by compiler
725  *
726  * Revision 1.25 2014/07/28 18:07:59 jeromel
727  * Cst for C++11 and added comment for cov elements as per StVertex
728  *
729  * Revision 1.24 2010/01/26 21:01:49 fisyak
730  * Clean up, switch from bit mask to attributes
731  *
732  * Revision 1.23 2006/05/05 18:35:39 balewski
733  * block the fake second prim vertex
734  *
735  * Revision 1.22 2006/05/04 20:01:30 jeromel
736  * Switched to logger
737  *
738  * Revision 1.21 2006/05/02 13:49:21 balewski
739  * replace gufld() with mBfield = event->runInfo()->magneticField();
740  *
741  * Revision 1.20 2005/07/19 21:56:58 perev
742  * MultiVertex
743  *
744  * Revision 1.19 2005/06/21 02:16:36 balewski
745  * multiple prim vertices are stored in StEvent
746  *
747  * Revision 1.18 2005/03/11 22:23:53 balewski
748  * towards PPV
749  *
750  * Revision 1.17 2005/03/09 19:24:18 balewski
751  * preparation for PPV vertex finder
752  *
753  * Revision 1.16 2004/12/16 17:01:36 balewski
754  * 2 cuts in ppLMV4 were slightly off what was in the TPT version
755  *
756  * Revision 1.15 2004/12/13 20:39:58 fisyak
757  * Add initaition of StGenericVertexFinder variables, replace mDumMaker by StMaker::GetChain() method
758  *
759  * Revision 1.14 2004/09/13 15:41:31 balewski
760  * fix bug in ppLMV4/5 switch
761  *
762  * Revision 1.13 2004/09/03 14:24:15 jeromel
763  * Fixed inverted comment
764  *
765  * Revision 1.12 2004/09/03 00:09:08 jeromel
766  * Modified code to Implement Init() and SetMode() and allow passing a switch
767  * to chose the vertex finder from within the same code implementation. Was
768  * needed for ppLMV (one implementation, two algorithm)
769  *
770  * Revision 1.11 2004/09/01 18:45:01 balewski
771  * ppLMV5/4 switch added
772  *
773  * Revision 1.10 2004/08/25 15:20:30 balewski
774  * Z-vertex range increased to +/- 150 cm
775  *
776  * Revision 1.9 2004/08/18 20:08:04 balewski
777  * outerGeometry()->helix() used by ppLMV for extrapolation to CTB
778  *
779  * Revision 1.8 2004/08/06 21:00:01 balewski
780  * now should be fine for 2004 pp200 data,
781  * high pT & small path cat-off included
782  * still no nFit/nPoss cut
783  *
784  * Revision 1.7 2004/08/06 04:49:14 balewski
785  * that would be it
786  *
787  * Revision 1.6 2004/08/05 22:08:04 balewski
788  * toward working point
789  *
790  * Revision 1.5 2004/08/04 21:57:56 balewski
791  * toward smarter ppLMV5
792  *
793  * Revision 1.4 2004/07/29 00:44:30 balewski
794  * ppLMV() returns false on error
795  *
796  * Revision 1.3 2004/07/24 02:57:40 balewski
797  * clean up of ppLMV, CTB-util separated
798  *
799  * Revision 1.2 2004/07/23 01:01:33 jeromel
800  * See .h + changed printf() / cout to gMessMgr + removed a ew asserts
801  *
802  * Revision 1.1 2004/07/21 01:53:18 balewski
803  * first
804  *
805  **************************************************************************/
806 
float mCtbThres_mev
Definition: StCtbUtility.h:23
pair< double, double > pathLength(double r) const
path length at given r (cylindrical r)
Definition: StHelix.cc:351
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362