StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StPPVertexFinder.cxx
1 /************************************************************
2  *
3  * $Id: StPPVertexFinder.cxx,v 1.15 2018/03/16 18:38:49 genevb Exp $
4  *
5  * Author: Jan Balewski
6  ************************************************************
7  *
8  * Description: does not fear any pileup
9  *
10  ************************************************************/
11 
12 #include "StMessMgr.h"
13 #include "TGraphErrors.h"
14 #include "TF1.h"
15 #include "TH2.h"
16 #include "TFile.h"
17 #include "TLine.h"
18 
19 #include "tables/St_g2t_vertex_Table.h" // tmp for Dz(vertex)
20 
21 #include "StPPVertexFinder.h"
22 #include <StEventTypes.h>
23 #include "TrackData.h"
24 #include "VertexData.h"
25 #include "Vertex3D.h"
26 #include "StGenericVertexMaker.h"
27 #include "St_VertexCutsC.h"
28 
29 #include "StEventToolkit.h"
30 #include "StEvent/StGlobalTrack.h"
31 #include "StEvent/StContainers.h"
32 #include "StEvent/StEnumerations.h"
33 #include "St_db_Maker/St_db_Maker.h"
34 #include "StIOMaker/StIOMaker.h" // to save local histos
35 #include "StBFChain/StBFChain.h"
36 
37 #include "TGeoManager.h"
38 
39 #define xL(t) (t->getX())
40 #define yL(t) (t->getY())
41 #define eyL(t) sqrt(t->getCyy())
42 #define zL(t) (t->getZ())
43 #define ezL(t) sqrt(t->getCzz())
44 #define rxyL(t) sqrt(xL(t)*xL(t) + yL(t)*yL(t))
45 #define xG(t) (t->x_g())
46 #define yG(t) (t->y_g())
47 #define zG(t) (t->z_g())
48 #define rxyG(t) sqrt(xG(t)*xG(t) + yG(t)*yG(t))
49 
50 #include "StEEmcUtil/database/StEEmcDb.h"
51 #include "StEEmcUtil/database/EEmcDbItem.h"
52 #include "StEEmcUtil/database/cstructs/eemcConstDB.hh"
53 #include "StEEmcUtil/EEmcGeom/EEmcGeomSimple.h"
54 
55 #include "BtofHitList.h"
56 #include "CtbHitList.h"
57 #include "BemcHitList.h"
58 #include "EemcHitList.h"
59 
60 #include "StEmcCollection.h"
61 #include "StBTofCollection.h"
62 #include "StBTofUtil/StBTofGeometry.h"
63 #include "TObjectSet.h"
64 
65 enum { kImpImp=0, kZZ = 2 ,kPsiImp=3, kPsiPsi=5 };
66 enum { RxyMin=59, RxyMax=199, zMax=200,zMembraneDepth=1,nWrongZHitCut=2};
67 
68 Float_t mImpImp;
69  Float_t mZImp, mZZ;
70  Float_t mPsiImp, mPsiZ, mPsiPsi;
71  Float_t mPtiImp, mPtiZ, mPtiPsi, mPtiPti;
72  Float_t mTanImp, mTanZ, mTanPsi, mTanPti, mTanTan;
73  Char_t mEnd[1];
74 
75 namespace StEvPPV {
76 //==========================================================
77 //==========================================================
78 StPPVertexFinder::StPPVertexFinder()
79 {
80  mTotEve = 0;
81  HList=0;
82  mToolkit =0;
83  memset(hA,0,sizeof(hA));
84 
85  UseCTB(false); // default CTB is off
86  UseBTOF(false); // default BTOF is off
87  setDropPostCrossingTrack(true); // default PCT rejection on
88  mVertexOrderMethod = orderByRanking; // change ordering by ranking
89 
90  mAlgoSwitches=0; // default, as for 2008 pp data production
91 
92  //........... tune for W-boson reco
93  mAlgoSwitches|=kSwitchOneHighPT;
94  mCut_oneTrackPT=10; // GeV, used only if coresponding algoSwitch switch is ON.
95  mBeamLineTracks=0; // expert only, activation via BFC
96 
97  // special histogram for finding the vertex, not to be saved
98  int nb=5000;
99  float zRange=250;// (cm)
100  hL=new TH1D("ppvL","Vertex likelyhood; Z /cm",nb,-zRange,zRange);
101  // needed only for better errZ calculation
102  hM=new TH1D("ppvM","cumulative track multiplicity; Z /cm",nb,-zRange,zRange);
103  hW=new TH1D("ppvW","cumulative track weight; Z /cm",nb,-zRange,zRange);
104 
105 }
106 
107 
108 //==========================================================
109 //==========================================================
110 void StPPVertexFinder::Init()
111 {
112  assert(mTotEve==0); // can't be called twice
113  LOG_INFO << Form("PPV-algo switches=0x%0x, following cuts have been activated:",mAlgoSwitches)<<endm;
114  //.. set various params
115  mStoreUnqualifiedVertex=5; // extension requested by Akio, October 2008, set to 0 do disable it
116  mFitPossWeighting=false; // default prior to 2012
117 
118  //get pointer to Sti toolkit
119  mToolkit = StEventToolkit::instance();
120  assert(mToolkit); // internal error of Sti
121 
122  ctbList = new CtbHitList;
123  bemcList = new BemcHitList;
124  btofList = new BtofHitList;
125  vertex3D = 0; // default
126 
127 
128  // access EEMC-DB
129  eeDb = (StEEmcDb*)StMaker::GetChain()->GetDataSet("StEEmcDb");
130  assert(eeDb); // eemcDB must be in the chain, fix it,JB
131  LOG_INFO << "eeDb done" <<endm;
132  geomE= new EEmcGeomSimple();
133  // choose which 'stat' bits are fatal for mip detection
134  unsigned int killStatEEmc=EEMCSTAT_ONLPED | EEMCSTAT_STKBT| EEMCSTAT_HOTHT | EEMCSTAT_HOTJP | EEMCSTAT_JUMPED ;
135  eemcList =new EemcHitList(eeDb, killStatEEmc,geomE);
136 
137  HList=new TObjArray(0);
138  initHisto();
139  LOG_INFO << "initiated histos" << endm;
140  if (mUseBtof)
141  btofList->initHisto( HList);
142  ctbList->initHisto( HList);
143  bemcList->initHisto( HList);
144  eemcList->initHisto( HList);
145  LOG_INFO << "Finished Init" << endm;
146 }
147 
148 //==========================================================
149 //==========================================================
150 void StPPVertexFinder::InitRun(int runnumber)
151 {
152  LOG_INFO << "PPV InitRun() runNo="<<runnumber<<endm;
153  St_db_Maker* mydb = (St_db_Maker*) StMaker::GetChain()->GetMaker("db");
154  int dateY=mydb->GetDateTime().GetYear();
155 
156  // Initialize BTOF geometry
157  if (mUseBtof){ // only add btof if it is required
158  btofGeom = 0;
159  TObjectSet *geom = (TObjectSet *) mydb->GetDataSet("btofGeometry");
160  if (geom) btofGeom = (StBTofGeometry *) geom->GetObject();
161  if (btofGeom) {
162  LOG_INFO << " Found btofGeometry ... " << endm;
163  } else {
164  btofGeom = new StBTofGeometry("btofGeometry","btofGeometry in VertexFinder");
165  geom = new TObjectSet("btofGeometry",btofGeom);
166  LOG_INFO << " Create a new btofGeometry ... " << endm;
167  mydb->AddConst(geom);
168  }
169  if(btofGeom && !btofGeom->IsInitDone()) {
170  LOG_INFO << " BTofGeometry initialization ... " << endm;
171  TVolume *starHall = gGeoManager ? nullptr : (TVolume *) (mydb->GetDataSet("HALL"));
172  btofGeom->Init(mydb, starHall, gGeoManager);
173  }
174  }
175 
176  //.. set various params
177  // It is not clear why one would hard code cuts for any specific run or
178  // a period since they can be set in the database. Here we'll assume that for
179  // Runs 5 to 12 the PPV cuts are optimized and there is no need to access the
180  // values from the database.
181  if (runnumber >= 6000000 && runnumber < 13000000) {
182  // old defaults, pre-Run12
183  // (important if we want to reprocess old data with different cuts!)
184  LOG_INFO << "PPV InitRun() using old, hardwired cuts" << endm;
185  mMaxTrkDcaRxy = 3.0; // cm
186  mMinTrkPt = 0.20; // GeV/c //was 0.2 in 2005 prod
187  mMinFitPfrac = 0.7; // nFit /nPossible points on the track
188  mMaxZradius = 3.0; //+sigTrack, to match tracks to Zvertex
189  mMinMatchTr = 2; // required to accept vertex
190  } else {
191  St_VertexCutsC* vtxCuts = St_VertexCutsC::instance();
192  mMaxTrkDcaRxy = vtxCuts->RImpactMax();
193  mMinTrkPt = vtxCuts->MinTrackPt();
194  mMinFitPfrac = vtxCuts->MinFracOfPossFitPointsOnTrack();
195  mMaxZradius = vtxCuts->DcaZMax(); //+sigTrack, to match tracks to Zvertex
196  mMinMatchTr = vtxCuts->MinTrack(); // required to accept vertex
197  mFitPossWeighting = true;
198  }
199  mMaxZrange = 200; // to accept Z_DCA of a track
200  mDyBtof = 1.5; // |dy|<1.5 cm for local position - not used now
201  mMinZBtof = -3.0; //
202  mMaxZBtof = 3.0; // -3.0<zLocal<3.0
203  mMinAdcEemc = 5; // chan, MIP @ 6-18 ADC depending on eta
204 
205  //assert(dateY<2008); // who knows what 2007 setup will be, crash it just in case
206 
207  if(dateY<2006) {
208  mMinAdcBemc = 15; // BTOW used calibration of maxt Et @ ~27Gev
209  } else {
210  mMinAdcBemc = 8; // BTOW used calibration of maxt Et @ ~60Gev
211  }
212  if (mUseBtof)
213  btofList->initRun();
214  ctbList->initRun();
215  bemcList->initRun();
216  eemcList->initRun();
217 
218  if(mBeamLineTracks){
219  assert(vertex3D==0); // crash means initRun was called twice - not foreseen,Jan B.
220  vertex3D=new Vertex3D;
221  vertex3D->setCuts(0.8,8.0, 3.3,5); // pT1(GeV), pT2, sigY(cm), nTr
222  vertex3D->initHisto( HList);
223  vertex3D->initRun();
224  }
225 
226  //gMessMgr->Message("","I")
227  LOG_INFO
228  << "PPV::cuts "
229  <<"\n MinNumberOfFitPointsOnTrack = unused"
230  <<"\n MinFitPfrac=nFit/nPos = " << mMinFitPfrac
231  <<"\n MaxTrkDcaRxy/cm= " << mMaxTrkDcaRxy
232  <<"\n MinTrkPt GeV/c = " << mMinTrkPt
233  <<"\n MinMatchTr of prim tracks = " << mMinMatchTr
234  <<"\n MaxZrange (cm)for glob tracks = " << mMaxZrange
235  <<"\n MaxZradius (cm) for prim tracks &Likelihood = " << mMaxZradius
236  <<"\n DeltaY (cm) for BTOF local posision = "<< mDyBtof
237  <<"\n Min/Max Z position for BTOF hit = " << mMinZBtof<<" "<<mMaxZBtof
238  <<"\n MinAdcBemc for MIP = " << mMinAdcBemc
239  <<"\n MinAdcEemc for MIP = " << mMinAdcEemc
240  <<"\n bool useCtb = " << mUseCtb
241  <<"\n bool useBtof = " << mUseBtof
242  <<"\n bool nFit/nPoss weighting = " << mFitPossWeighting
243  <<"\n bool DropPostCrossingTrack = " << mDropPostCrossingTrack
244  <<"\n Store # of UnqualifiedVertex = " << mStoreUnqualifiedVertex
245  <<"\n Store="<<(mAlgoSwitches & kSwitchOneHighPT) <<
246  " oneTrack-vertex if track PT/GeV>"<< mCut_oneTrackPT
247  <<"\n dump tracks for beamLine study = " << mBeamLineTracks
248  <<"\n"
249  <<endm;
250 
251 }
252 
253 
254 //==========================================================
255 //==========================================================
256 void StPPVertexFinder::initHisto()
257 {
258  assert(HList);
259  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);
260  hA[1]=new TH1F("ch1","chi2/Dof, ppv pool tracks",100,0,10);
261  hA[2]=new TH1F("nP","No. of fit points, ppv pool tracks",30,-.5,59.5);
262  hA[3]=new TH1F("zV","reconstructed vertices ; Z (cm)",100,-200,200);
263  hA[4]=new TH1F("nV","No. of vertices per eve",20,-0.5,19.5);
264 
265  hA[5]=new TH1F("rxyDca","Rxy to beam @ DCA ; (cm)",40,-0.1,3.9);
266  hA[6]=new TH1F("nTpcM","No. tracks: tpcMatch /eve ",60,-.5,59.5);
267  hA[7]=new TH1F("nTpcV","No. tracks: tpcVeto /eve ",60,-.5,59.5);
268 
269  hA[8]=0; // (TH1F*) new TH2F ("xyE","Y vs. X of match tracks in EEMC; X (cm); Y(cm)",200,-250.,250,200,-250,250);
270 
271  hA[9]=new TH1F("zDca","Z DCA for all accepted tracks; Z (cm)",100,-200,200);
272 
273  hA[10]=new TH1F("zCtb","Z @CTB for all accepted tracks; Z (cm)",50,-250,250);
274  hA[11]=new TH1F("zBemc","Z @Bemc for all accepted tracks; Z (cm)",100,-400,400);
275  hA[12]=new TH1F("dzVerTr","zVerGeant - zDca of tracks used by any vertex ; (cm)",100,-5,5);
276  hA[13]=new TH1F("dzVerVer","zVerGeant - best reco vertex ; (cm)",100,-5,5);
277 
278  hA[14]=new TH1F("EzDca","Error of Z DCA for all accepted tracks; Z (cm)",100,-0.,4);
279  hA[15]=new TH1F("nTpcT","No. tracks: accepted Dca /eve ",201,-.5,200.5);
280  hA[16]=new TH1F("ptTr","pT, ppv pool tracks; pT (GeV/c) ",50,0.,10.);
281  hA[17]=new TH1F("vRL","PPV Vertex rank, 'funny' X-axis; X=Log10(rank-1e6)+offset", 150, -11,25);
282 
283  hACorr=new TH2F("BTOFvsBEMC","BTOF vs BEMC", 5,-2.5,2.5,5,-2.5,2.5);
284 
285  int i;
286  for(i=0;i<mxH; i++) if(hA[i]) HList->Add(hA[i]);
287  HList->Add(hACorr);
288 }
289 
290 //==========================================================
291 //==========================================================
292 void StPPVertexFinder::Clear()
293 {
294  LOG_DEBUG << "PPVertex::Clear nEve="<<mTotEve<< endm;
295  StGenericVertexFinder::Clear();
296  btofList->clear();
297  ctbList->clear();
298  bemcList->clear();
299  eemcList->clear();
300  mTrackData.clear();
301  mVertexData.clear();
302  eveID=-1;
303 
304  // the clear below is not needed but cleans up stale result
305  hL->Reset();
306  hM->Reset();
307  hW->Reset();
308 
309 
310 }
311 
312 
313 //==========================================================
314 //==========================================================
315 StPPVertexFinder::~StPPVertexFinder()
316 {
317  //x delete mTrackData;
318  //x delete mVertexData;
319  delete geomE;
320  //yf if(btofGeom) delete btofGeom;
321 }
322 
323 //======================================================
324 //======================================================
325 void StPPVertexFinder::printInfo(ostream& os) const
326 {
327  os << "StPPVertexFinder ver=1 - Fit Statistics:" << endl;
328 
329  os << "StPPVertexFinder::result "<<mVertexData.size()<<" vertices found\n" << endl;
330 
331  int nTpcM=0, nTpcV=0;
332  unsigned int i;
333  int k=0;
334  for(i=0;i<mTrackData.size();i++) {
335  const TrackData *t=&mTrackData[i];
336  if( t->mTpc>0) nTpcM++;
337  else if ( t->mTpc<0) nTpcV++;
338  hA[9]->Fill(t->zDca);
339  hA[14]->Fill(t->ezDca);
340  if(t->vertexID<=0) continue; // skip not used or pileup vertex
341  k++;
342  LOG_DEBUG
343  <<
344  Form("%d track@z0=%.2f +/- %.2f gPt=%.3f vertID=%d match: bin,Fired,Track:\n",
345  k,t->zDca,t->ezDca,t->gPt,t->vertexID)
346  << Form(" Btof %3d,%d,%d",t->btofBin,btofList->getFired(t->btofBin),btofList->getTrack(t->btofBin))
347  << Form(" CTB %3d,%d,%d",t->ctbBin,ctbList->getFired(t->ctbBin),ctbList->getTrack(t->ctbBin))
348  << Form(" Bemc %3d,%d,%d",t->bemcBin,bemcList->getFired(t->bemcBin),bemcList->getTrack(t->bemcBin))
349  << Form(" Eemc %3d,%d,%d",t->eemcBin,eemcList->getFired(t->eemcBin),bemcList->getTrack(t->bemcBin))
350  << Form(" TPC %d",t->mTpc)
351  <<endm;
352  }
353  hA[6]->Fill(nTpcM);
354  hA[7]->Fill(nTpcV);
355  hA[15]->Fill(mTrackData.size());
356 
357  LOG_INFO<< Form("PPVend eveID=%d, list of found %d vertices from pool of %d tracks\n",eveID,mVertexData.size(),mTrackData.size())<<endm;
358  for(i=0;i<mVertexData.size();i++) {
359  const VertexData *V=& mVertexData[i];
360  V->print(os);
361  }
362 
363  LOG_DEBUG<< Form("---- end of PPVertex Info\n")<<endm;
364 
365 }
366 
367 
368 //==========================================================
369 //==========================================================
370 int StPPVertexFinder::fit(StEvent* event) {
371  LOG_INFO << "***** START FIT" << endm;
372  if(mBeamLineTracks) vertex3D->clearEvent();
373 
374  hA[0]->Fill(1);
375 assert(event);
376  StEventToolkit::instance()->SetEvent(event);
377  mTotEve++;
378  eveID=event->id();
379  LOG_INFO << "\n @@@@@@ PPVertex::Fit START nEve="<<mTotEve<<" eveID="<<eveID<< endm;
380 
381  TString tt="Vertex likelyhood, eveID=";
382  tt+=eveID;
383  hL->SetTitle(tt);
384 
385  hA[0]->Fill(2);
386 
387  if(mToolkit==0) {
388  LOG_WARN <<"no Sti tool kit, PPV is OFF"<<endm;
389  return 0;
390  }
391 
392  // get BTOF info
393 
394  if(mUseBtof) {
395  StBTofCollection *btofColl = (StBTofCollection*)event->btofCollection();
396  if(btofColl==0) {
397  LOG_WARN << "no btofCollection , continue THE SAME eve"<<endm;
398  } else {
399  btofList->build(btofColl);
400  }
401  }
402 
403  // get CTB info, does not work for embeding
404  if(mUseCtb) {// CTB could be off since 2006
405  StTriggerData *trgD=event->triggerData ();
406  ctbList->buildFromData(trgD); // use real data
407  }
408 
409 
410  StEmcCollection* emcC =(StEmcCollection*)event->emcCollection();
411  if(emcC==0) {
412  LOG_WARN <<"no emcCollection , continue THE SAME eve"<<endm;
413  } else {
414  assert(emcC);
415  StEmcDetector* btow = emcC->detector( kBarrelEmcTowerId);
416  if(btow==0) {
417  LOG_WARN <<"no BEMC in emcColl , continue THE SAME eve"<<endm;
418  } else {
419  assert(btow);
420  bemcList->build(btow, mMinAdcBemc);
421  }
422 
423  StEmcDetector* etow = emcC->detector(kEndcapEmcTowerId);
424  if(etow==0) {
425  LOG_WARN <<"no EEMC in emcColl , continue THE SAME eve"<<endm;
426  } else {
427  assert(etow);
428  eemcList->build(etow, mMinAdcEemc);
429  }
430  }
431 
432  //get the Sti track container...
433  const StSPtrVecTrackNode* tracks = mToolkit->getTrackContainer();
434  if(tracks==0) {
435  LOG_WARN <<"no STi tracks , skip eve"<<endm;
436  printInfo();
437  return 0 ;
438  }
439 
440  hA[0]->Fill(4);
441 
442  //select reasonable tracks and add them to my list
443  int k=0;
444  int kBtof=0,kCtb=0,kBemc=0, kEemc=0,kTpc=0;
445  int nmAny=0;
446 
447  int ntrk[7]; for(int i=0; i<7; i++) ntrk[i]=0;
448 
449  int nTk = tracks->size();
450  for (int it=0; it<nTk; ++it)
451  {
452  k++;
453  const StGlobalTrack* track = (const StGlobalTrack*)(*tracks)[it]->track(global);
454  if (!track->dcaGeometry()) continue;
455  TrackData t;
456 
457  ntrk[0]++;
458  if(track->flag()<0) {ntrk[1]++; continue;}
459 
460  double myPt = track->dcaGeometry()->pt();
461  if(myPt<mMinTrkPt) {ntrk[2]++; continue;}
462  if(mDropPostCrossingTrack){
463  if(isPostCrossingTrack(track)) {ntrk[3]++; continue;} // kill if it has hits in wrong z
464  }
465  if(!examinTrackDca(track,t)) {ntrk[4]++; continue;} // drop from DCA
466  if(!matchTrack2Membrane(track,t)) {ntrk[5]++; continue;} // kill if nFitP too small
467  ntrk[6]++;
468 
469  //cout <<"\n#e itr="<<k<<" gPt="<<track->getPt()<<" gEta="<<track->getPseudoRapidity()<<" nFitP="<<track->getFitPointCount()<<" of "<<track->getMaxPointCount()<<" poolSize="<< mTrackData->size()<<" myW="<<t.weight<<endl;
470  //printf(" t.weight AA=%f\n", t.weight);
471 
472  hA[ 1]->Fill(track->fitTraits().chi2());
473  hA[ 2]->Fill(track->fitTraits().numberOfFitPoints());
474  hA[16]->Fill(myPt);
475  // dumpKalmanNodes(track);
476 
477  // ......... matcho various detectors ....................
478  if(mUseBtof) matchTrack2BTOF(track,t,btofGeom); // matching track to btofGeometry
479  if(mUseCtb) matchTrack2CTB(track,t);
480  matchTrack2BEMC(track,t,242); // middle of tower in Rxy
481  matchTrack2EEMC(track,t,288); // middle of tower in Z
482  //.... all test done on this track .........
483  t.mother=track;
484  mTrackData.push_back(t);
485 
486  hA[5]->Fill(t.rxyDca);
487 
488  if( t.mBtof>0 ) kBtof++;
489  if( t.mCtb>0 ) kCtb++;
490  if( t.mBemc>0) kBemc++;
491  if( t.mEemc>0) kEemc++;
492  if( t.mTpc>0 ) kTpc++;
493 
494  if(t.mBtof>0 || t.mCtb>0 || t.mBemc>0 || t.mEemc>0 || t.mTpc>0 ) nmAny++ ;
495 
496  hACorr->Fill(t.mBtof, t.mBemc);
497  // t.print();
498  }
499 
500  LOG_INFO<< Form("PPV:: # of input track = %d",ntrk[0])<<endm;
501  LOG_INFO<< Form("PPV:: dropped due to flag = %d",ntrk[1])<<endm;
502  LOG_INFO<< Form("PPV:: dropped due to pt = %d",ntrk[2])<<endm;
503  LOG_INFO<< Form("PPV:: dropped due to PCT check = %d",ntrk[3])<<endm;
504  LOG_INFO<< Form("PPV:: dropped due to DCA check = %d",ntrk[4])<<endm;
505  LOG_INFO<< Form("PPV:: dropped due to NHit check = %d",ntrk[5])<<endm;
506  LOG_INFO<< Form("PPV:: # of track after all cuts = %d",ntrk[6])<<endm;
507 
508  if(mUseCtb) {
509  ctbList ->print();
510  ctbList ->doHisto();
511  }
512 
513  if(mUseBtof) {
514  btofList->print();
515  btofList->doHisto();
516  }
517 
518  bemcList->print();
519  eemcList->print();
520  LOG_INFO<< Form("PPV::TpcList size=%d nMatched=%d\n\n",mTrackData.size(),kTpc)<<endm;
521 
522  bemcList->doHisto();
523  eemcList->doHisto();
524 
525  LOG_INFO << "PPV::fit() nEve="<<mTotEve<<" , "<<nmAny<<" traks with good DCA, matching: BTOF="<<kBtof<<" CTB="<<kCtb<<" BEMC="<<kBemc<<" EEMC="<<kEemc<<endm;
526 
527 
528  if(nmAny<mMinMatchTr && mStoreUnqualifiedVertex<=0){
529  LOG_INFO << "StPPVertexFinder::fit() nEve="<<mTotEve<<" Quit, to few matched tracks"<<endm;
530  printInfo();
531  return 0;
532  }
533  hA[0]->Fill(5);
534 
535  if(kBemc) hA[0]->Fill(6);
536  if(kEemc) hA[0]->Fill(7);
537 
538  //............................................................
539  // ...................... search for multiple vertices
540  //............................................................
541 
542  const float par_rankOffset=1e6; // to separate class of vertices (approximately)
543 
544  int nBadVertex=0;
545  int vertexID=0;
546  while(1) {
547  if(! buildLikelihoodZ() ) break;
548  VertexData V;
549  V.id=++vertexID;
550  if(! findVertexZ(V)) break;
551 
552  bool trigV=evalVertexZ(V); // V.print();
553  //bump up rank of 2+ track all vertices
554  if(V.nAnyMatch>=mMinMatchTr) V.Lmax+=par_rankOffset;
555  if(!trigV) {
556  if( nBadVertex>=mStoreUnqualifiedVertex) continue; // drop this vertex
557  /* preserve this unqalified vertex for Akio
558  and deposit 1 cent on Jan's bank account (optional)
559  */
560  nBadVertex++;
561  //bump down rank of sub-prime vertices
562  V.Lmax-=par_rankOffset;
563  }
564 
565  {// ... more rank QA ...
566  float rank=V.Lmax;
567  if(rank>1e6) hA[17]->Fill(log(rank-1e6)+10);
568  else if(rank>0) hA[17]->Fill(log(rank));
569  else hA[17]->Fill(log(rank+1e6)-10);
570  }
571 
572  mVertexData.push_back(V);
573  if(trigV && mBeamLineTracks) vertex3D->study(V.r,eveID);
574  }
575 
576  LOG_INFO << "StPPVertexFinder::fit(totEve="<<mTotEve<<") "<<mVertexData.size()<<" vertices found, nBadVertex=" <<nBadVertex<< endm;
577 
578  if(mVertexData.size()>0) hA[0]->Fill(8);
579  if(mVertexData.size()>1) hA[0]->Fill(9);
580 
581  exportVertices();
582  printInfo();
583 
584  hA[4]->Fill(mVertexData.size());
585  unsigned int i;
586  for(i=0;i<mVertexData.size();i++) {
587  VertexData *V=&mVertexData[i];
588  hA[3]->Fill(V->r.z());
589  }
590 
591  if(mVertexData.size()<=0) {
592  return 0; // no vertex
593  }
594 
595  return size();
596 }
597 
598 
599 //==========================================================
600 //==========================================================
601 bool StPPVertexFinder::buildLikelihoodZ()
602 {
603  hL->Reset();
604  hM->Reset();
605  hW->Reset();
606 
607  float dzMax2=mMaxZradius*mMaxZradius;
608 
609  int nt=mTrackData.size();
610  LOG_DEBUG<< Form("PPV::buildLikelihood() pool of nTracks=%d",nt)<<endm;
611  if(nt<=0) return false;
612 
613  int n1=0;
614  int i;
615 
616  double *La=hL->GetArray(); // PPV main likelyhood histogram
617  double *Ma=hM->GetArray(); // track multiplicity histogram
618  double *Wa=hW->GetArray(); // track weight histogram
619 
620  for(i=0;i<nt;i++) {
621  const TrackData *t=&mTrackData[i];
622  if(t->vertexID!=0) continue; // track already used
623  if(t->anyMatch) n1++;
624  // t->print();
625  float z0=t->zDca;
626  float ez=t->ezDca;
627  float ez2=ez*ez;
628  int j1=hL->FindBin(z0-mMaxZradius-.1);
629  int j2=hL->FindBin(z0+mMaxZradius+.1);
630  float base=dzMax2/2/ez2;
631  float totW=t->weight;
632  // printf("i=%d Z0=%f ez=%f j1=%d j2=%d base=%f gPt/GeV=%.3f ctbW=%.3f\n",i,z0,ez,j1,j2,base,t->gPt,ctbW);
633 
634  int j;
635  for(j=j1;j<=j2;j++) {
636  float z=hL->GetBinCenter(j);
637  float dz=z-z0;
638  float xx=base-dz*dz/2/ez2;
639  if(xx<=0) continue;
640  La[j]+=xx*totW;
641  Ma[j]+=1.;
642  Wa[j]+=totW;
643  // printf("z=%f dz=%f xx=%f\n",z,dz,xx);
644  }
645  // break; // tmp , to get only one track
646  }
647 
648  LOG_DEBUG<< Form("PPV::buildLikelihood() %d tracks w/ matched @ Lmax=%f",n1,hL->GetMaximum())<<endm;
649 
650 
651  return (n1>=mMinMatchTr) || (mStoreUnqualifiedVertex>0 );
652 }
653 
654 //==========================================================
655 //==========================================================
656 bool StPPVertexFinder::findVertexZ(VertexData &V) {
657 
658  if(hL->GetMaximum()<=0) return false; // no more tracks left
659 
660  int iMax=hL-> GetMaximumBin();
661  float z0=hL-> GetBinCenter(iMax);
662  float Lmax=hL-> GetBinContent(iMax);
663  float accM=hM-> GetBinContent(iMax);
664  float accW=hW-> GetBinContent(iMax);
665  assert(accM>0);
666  float avrW=accW/accM;
667 
668  // search for sigma of the vertex
669  float Llow=0.9* Lmax;
670  if((Lmax-Llow)<8*avrW ) Llow=Lmax-8*avrW; // to be at least 4 sigma
671  int i;
672  double *L=hL->GetArray(); // likelyhood
673 
674  int iLow=-1, iHigh=-1;
675  for(i=iMax;i<=hL->GetNbinsX();i++) {
676  if(L[i] >Llow) continue;
677  iHigh=i;
678  break;
679  }
680  for(i=iMax;i>=1;i--) {
681  if(L[i] >Llow) continue;
682  iLow=i;
683  break;
684  }
685 
686  float zLow=hL-> GetBinCenter(iLow);
687  float zHigh=hL-> GetBinCenter(iHigh);
688 
689  float kSig= sqrt(2*(Lmax-Llow)/avrW);
690  float sigZ= (zHigh-zLow)/2/kSig;
691  LOG_DEBUG<< Form("PPV:: iLow/iMax/iHigh=%d/%d/%d\n",iLow,iMax,iHigh)
692  <<Form(" accM=%f accW=%f avrW=%f\n",accM,accW,avrW)
693  <<Form(" Z low/max/high=%f %f %f, kSig=%f, sig=%f\n",zLow,z0,zHigh,kSig,sigZ)
694  <<Form(" found PPVertex(ID=%d,neve=%d) z0 =%.2f +/- %.2f\n",V.id,mTotEve,z0,sigZ)<<endm;
695  if(sigZ<0.1) sigZ=0.1; // tmp, make it not smaller than the bin size
696 
697  // take x,y from beam line equation, TMP
698  V.r=TVector3(beamX(z0), beamY(z0), z0);
699  V.er=TVector3(0.1,0.1,sigZ); //tmp
700  V.Lmax=Lmax;
701 
702  return true;
703 }
704 
705 //==========================================================
706 //==========================================================
707 bool StPPVertexFinder::evalVertexZ(VertexData &V) { // and tag used tracks
708  // returns true if vertex is accepted accepted
709  if(mBeamLineTracks) vertex3D->clearTracks();
710  int nt=mTrackData.size();
711  LOG_DEBUG << "StPPVertexFinder::evalVertex Vid="<<V.id<<" start ..."<<endm;
712  int n1=0, nHiPt=0;
713  int i;
714 
715  for(i=0;i<nt;i++) {
716  TrackData *t=&mTrackData[i];
717  if(t->vertexID!=0) continue;
718  if(! t->matchVertex(V,mMaxZradius)) continue; // track to far
719  // this track belongs to this vertex
720  n1++;
721  t->vertexID=V.id;
722  V.gPtSum+=t->gPt;
723  if(mBeamLineTracks) vertex3D->addTrack(t);
724  if( t->gPt>mCut_oneTrackPT && ( t->mBemc>0|| t->mEemc>0) ) nHiPt++;
725 
726  if( t->mTpc>0) V.nTpc++;
727  else if ( t->mTpc<0) V.nTpcV++;
728 
729  if( t->mBtof>0) V.nBtof++;
730  else if ( t->mBtof<0) V.nBtofV++;
731 
732  if( t->mCtb>0) V.nCtb++;
733  else if ( t->mCtb<0) V.nCtbV++;
734 
735  if( t->mBemc>0) V.nBemc++;
736  else if ( t->mBemc<0) V.nBemcV++;
737 
738  if( t->mEemc>0) V.nEemc++;
739  else if ( t->mEemc<0) V.nEemcV++;
740 
741  if( t->anyMatch) V.nAnyMatch++;
742  else if (t->anyVeto) V.nAnyVeto++;
743  }
744  V.nUsedTrack=n1;
745 
746  bool validVertex = V.nAnyMatch>=mMinMatchTr;
747  if((mAlgoSwitches & kSwitchOneHighPT) && ( nHiPt>0)) {
748  validVertex|=1;
749  }
750 
751  if(!validVertex) { // discrad vertex
752  //no match tracks in this vertex, tag vertex ID in tracks differently
753  //V.print(cout);
754  LOG_DEBUG << "StPPVertexFinder::evalVertex Vid="<<V.id<<" rejected"<<endm;
755  for(i=0;i<nt;i++) {
756  TrackData *t=&mTrackData[i];
757  if(t->vertexID!=V.id) continue;
758  t->vertexID=-V.id;
759  }
760  return false;
761  }
762 
763  LOG_INFO << "StPPVertexFinder::evalVertex Vid="<<V.id<<" accepted, nAnyMatch="<<V.nAnyMatch<<" nAnyVeto="<<V.nAnyVeto<<endm;
764  return true;
765 }
766 
767 
768 //-------------------------------------------------
769 //-------------------------------------------------
770 void StPPVertexFinder::exportVertices(){
771  if ( ! mVertexConstrain ){
772  // code is not ready for reco w/o beamLine
773  LOG_FATAL << "StPPVertexFinder code is not ready for reco w/o beamLine" << endm;
774  assert(mVertexConstrain);
775  }
776  unsigned int i;
777  for(i=0;i<mVertexData.size();i++) {
778  VertexData *V=&mVertexData[i];
779  StThreeVectorD r(V->r.x(),V->r.y(),V->r.z());
780 
781  Float_t cov[6];
782  memset(cov,0,sizeof(cov));
783  cov[0]=V->er.x()*V->er.x();
784  cov[2]=V->er.y()*V->er.y();
785  cov[5]=V->er.z()*V->er.z(); // [5] is correct,JB
786 
787  StPrimaryVertex primV;
788  primV.setPosition(r);
789  primV.setCovariantMatrix(cov);
790 
791  if(mUseCtb) primV.setVertexFinderId(ppvVertexFinder);
792  else primV.setVertexFinderId(ppvNoCtbVertexFinder);
793 
794  primV.setNumTracksUsedInFinder(V->nUsedTrack);
795  primV.setNumMatchesWithBTOF(V->nBtof);
796  primV.setNumMatchesWithCTB(V->nCtb);
797  primV.setNumMatchesWithBEMC(V->nBemc);
798  primV.setNumMatchesWithEEMC(V->nEemc);
799  primV.setNumTracksCrossingCentralMembrane(V->nTpc);
800  primV.setSumOfTrackPt(V->gPtSum);
801  primV.setRanking(V->Lmax);
802  primV.setFlag(1); //??? is it a right value?
803 
804  //..... add vertex to the list
805  addVertex(primV);
806  }
807  LOG_DEBUG << "StPPVertexFinder::exportVertices(), size="<<size()<<endm;
808 }
809 
810 //-------------------------------------------------
811 //-------------------------------------------------
812 void StPPVertexFinder::Finish()
813 {
814 
815  if(mBeamLineTracks) { // save local histo w/ PPV monitoring
816  StIOMaker *ioMk=(StIOMaker*)StMaker::GetChain()->GetMaker("inputStream");
817 
818  TString tt="ppv";
819  if(ioMk) {
820  assert(ioMk);
821  const char *fname=ioMk->GetFileName();
822  tt=strstr(fname,"st_");
823  tt.ReplaceAll(".daq",".ppv");
824  } else {
825  tt= ((StBFChain*)StMaker::GetChain())->GetFileOut() ;
826  tt.ReplaceAll(".root",".ppv");
827  }
828  LOG_INFO << "PPV save local histo="<<tt<<endm;
829  saveHisto(tt.Data());
830  }
831 
832  LOG_INFO << "StPPVertexFinder::Finish() done, seen eve=" <<mTotEve<< endm;
833  // TString fileIn = ((StBFChain*)StMaker::GetChain())->GetFileIn() ;
834  // LOG_INFO << "in="<<fileIn<< endm;
835 }
836 
837 //-------------------------------------------------
838 //-------------------------------------------------
839 void StPPVertexFinder::saveHisto(TString fname){
840  TString outName=fname+".hist.root";
841  TFile f( outName,"recreate");
842  assert(f.IsOpen());
843  printf("%d histos are written to '%s' ...\n",HList->GetEntries(),outName.Data());
844  HList->ls();
845  HList->Write();
846  f.Close();
847 }
848 
849 //==========================================================
850 //==========================================================
851 void StPPVertexFinder::dumpKalmanNodes(const StGlobalTrack*)
852 {
853  assert(0 && "dumpKalmanNodes");
854 }
855 
856 //==========================================================
857 //==========================================================
858 bool StPPVertexFinder::examinTrackDca(const StGlobalTrack *track,TrackData &t)
859 {
860 
861  //1 StGlobalTrackNode* inNode=track->getInnerMostNode();
862  //1 cout <<"#e track->getPseudoRapidity()="<<track->getPseudoRapidity()<<" track->getFitPointCount()="<<track->getFitPointCount()<<endl;
863 
864  // .......... test DCA to beam .............
865  const StDcaGeometry *dcaGeo = track->dcaGeometry();
866  if (!dcaGeo) return false;
867 
868  double rxy=dcaGeo->impact();
869 
870  //1 cout<<"#e @beam global DCA x:"<< bmNode->x_g()<<" y:"<< bmNode->y_g()<<" z:"<< bmNode->z_g()<<" Rxy="<< rxy <<endl;
871  if(fabs(rxy) > mMaxTrkDcaRxy) return false;
872  if(fabs(dcaGeo->z()) > mMaxZrange ) return false ;
873 
874  const float *dcaErr = dcaGeo->errMatrix();
875  double impimp = dcaErr[kImpImp];
876  double psipsi = dcaErr[kPsiPsi];
877  double xyErr = (0.5*(impimp + rxy*rxy*psipsi));
878 
879  //1 cout<<"#e inBeam |P|="<<bmNode->getP()<<" pT="<<bmNode->getPt()<<" local x="<<xL(bmNode)<<" y="<<yL(bmNode)<<" +/- "<<eyL(bmNode)<<" z="<<zL(bmNode)<<" +/- "<<ezL(bmNode)<<endl;
880 
881  t.zDca=dcaGeo->z();
882  t.ezDca=sqrt(dcaErr[kZZ]);
883  t.rxyDca=rxy;
884  t.gPt=dcaGeo->pt();
885  //...... record more detals for 3D vertex reco
886  StThreeVectorF myXYZ(dcaGeo->origin());
887  t.dcaTrack.R.SetXYZ(myXYZ.x(),myXYZ.y(),myXYZ.z());
888  // approximation below: use sigX=sigY, I do not want to deal wih rotations in X-Y plane, Jan B.
889 
890 
891  t.dcaTrack.sigYloc=sqrt(xyErr);
892  t.dcaTrack.sigZ=t.ezDca;
893 
894  StThreeVectorF const globP3=dcaGeo->momentum();
895  t.dcaTrack.gP.SetXYZ(globP3.x(),globP3.y(),globP3.z());
896 //VP t.dcaTrack.fitErr=bmNode->fitErrs();
897  t.dcaTrack.gChi2=track->fitTraits().chi2();
898  t.dcaTrack.nFitPoint=track->fitTraits().numberOfFitPoints();
899  // t.dcaTrack.print();
900 
901  return true;
902 }
903 
904 
905 //==========================================================
906 //==========================================================
907 void StPPVertexFinder::matchTrack2BTOF(const StGlobalTrack* track,TrackData &t,StBTofGeometry* geom)
908 {
909 
910  StPhysicalHelixD hlx(track->outerGeometry()->helix());
911 
912  IntVec idVec;
913  DoubleVec pathVec;
914  PointVec crossVec;
915 
916  IntVec iBinVec;
917  if(geom->HelixCrossCellIds(hlx,idVec,pathVec,crossVec)) {
918  for(size_t i=0;i<idVec.size();i++) {
919  int itray, imodule, icell;
920  geom->DecodeCellId(idVec[i], icell, imodule, itray);
921 
922  Double_t local[3], global[3];
923  for(int j=0;j<3;j++) local[j] = 0;
924  global[0] = crossVec[i].x();
925  global[1] = crossVec[i].y();
926  global[2] = crossVec[i].z();
927  StBTofGeomSensor *sensor = geom->GetGeomSensor(imodule,itray);
928  if(!sensor) {
929  LOG_WARN << "no sensitive module in this projection??? - weird" << endm;
930  continue;
931  }
932  sensor->Master2Local(&global[0],&local[0]);
933 // LOG_INFO << " Hit the TOF cell " << itray << " " << imodule << " " << icell << endm;
934 // LOG_INFO << " position " << local[0] << " " << local[1] << " " << local[2] << endm;
935 // float yCenter = (icell-1-2.5)*3.45; // cell center position;
936 // if(fabs(local[1]-yCenter)>mDyBtof) continue;
937 // if(icell==1||icell==6) continue;
938  if(local[2]<mMinZBtof||local[2]>mMaxZBtof) continue;
939  int iBin = btofList->cell2bin(itray, imodule, icell);
940  iBinVec.push_back(iBin);
941  btofList->addBtofTrack(itray, imodule, icell);
942  LOG_DEBUG << " !!! Push to the list ...tray/module/cell " << itray << "/" << imodule << "/" << icell << endm;
943  }
944  }
945 
946  bool btofMatch=btofList->isMatched(iBinVec);
947  bool btofVeto =btofList->isVetoed(iBinVec);
948  float btofW =btofList->getWeight(iBinVec);
949  btofList->addBtofMatch(iBinVec); // update the nMatch statistics
950 
951  LOG_DEBUG << " ** BTOF ** match/veto/weight = " << btofMatch << " " << btofVeto << " " << btofW << endm;
952 
953  t.updateAnyMatch(btofMatch,btofVeto,t.mBtof);
954  t.weight*=btofW;
955  t.btofBin= iBinVec.size() ? iBinVec[0] : -1;
956 }
957 
958 //==========================================================
959 //==========================================================
960 void StPPVertexFinder::matchTrack2CTB(const StGlobalTrack* track,TrackData &t)
961 {
962  const double Rctb=213.6; // (cm) radius of the CTB
963  StPhysicalHelixD hlx(track->outerGeometry()->helix());
964 
965  StThreeVectorD posCTB;
966  float path=-1;
967  pairD d2;
968  d2 = hlx.pathLength(Rctb);
969  path=d2.second;
970  if(d2.first>=0 || d2.second<=0) {
971  LOG_DEBUG <<Form("WARN MatchTrk , unexpected solution for track crossing CTB\n")<<
972  Form(" d2.firts=%f, second=%f, try first", d2.first, d2.second)<<endm;
973  path=d2.first;
974  }
975  posCTB = hlx.at(path);
976  // printf(" punch Cylinder x,y,z=%.1f, %.1f, %.1f path.second=%.1f\n",posCTB.x(),posCTB.y(),posCTB.z(),path);
977 
978  // official Sti node extrapolation
979 
980  float phi=posCTB.phi();
981  if(phi<0) phi+=2*M_PI;// now phi is [0,2Pi] as for CTB slats
982  float eta=posCTB.pseudoRapidity();
983  //1 cout<<"#e @ctbNode xyz="<<posCTB<<" eta="<<eta<<" phi/deg="<<phi/3.1416*180<<" path/cm="<<path<<endl;
984  if(fabs(eta)<1) hA[10]->Fill(posCTB.z());
985 
986  int iBin=ctbList->addTrack(eta,phi);
987 
988  bool ctbMatch=ctbList->isMatched(iBin);
989  bool ctbVeto =ctbList->isVetoed(iBin);
990  float ctbW =ctbList->getWeight(iBin);
991 
992  t.updateAnyMatch(ctbMatch,ctbVeto,t.mCtb);
993  t.weight*=ctbW;
994  t.ctbBin=iBin;
995 }
996 
997 //==========================================================
998 //==========================================================
999 void StPPVertexFinder::matchTrack2BEMC(const StGlobalTrack* track,TrackData &t, float Rxy)
1000 {
1001 
1002  StPhysicalHelixD hlx(track->outerGeometry()->helix());
1003  StThreeVectorD posCyl;
1004  float path=-1;
1005  pairD d2;
1006  d2 = hlx.pathLength(Rxy);
1007  path=d2.second;
1008  if(d2.first>=0 || d2.second<=0) {
1009  LOG_DEBUG <<Form("WARN MatchTrk , unexpected solution for track crossing BEMC Cyl\n")<<
1010  Form(" d2.firts=%f, second=%f, try first\n", d2.first, d2.second)<<endm;
1011  path=d2.first;
1012  }
1013  posCyl = hlx.at(path);
1014  // printf(" punch Cylinder x,y,z=%.1f, %.1f, %.1f path.second=%.1f\n",posCyl.x(),posCyl.y(),posCyl.z(),path);
1015 
1016 
1017  float phi=posCyl.phi();
1018  if(phi<0) phi+=2*M_PI;// now phi is [0,2Pi] as for Cyl slats
1019  float eta=posCyl.pseudoRapidity();
1020 
1021  // cout<<"#e @bemcNode xyz="<<posCyl<<" etaDet="<<eta<<" phi/deg="<<phi/3.1416*180<<" path/cm="<<path<<endl;
1022 
1023  if(fabs(eta)<1) hA[11]->Fill(posCyl.z());
1024 
1025  int iBin=bemcList->addTrack(eta,phi);
1026  bool bemcMatch=bemcList->isMatched(iBin);
1027  bool bemcVeto =bemcList->isVetoed(iBin);
1028  float bemcW =bemcList->getWeight(iBin);
1029 
1030  t.updateAnyMatch(bemcMatch,bemcVeto,t.mBemc);
1031  t.weight*=bemcW;
1032  t.bemcBin=iBin;
1033 
1034 }
1035 
1036 
1037 //==========================================================
1038 //==========================================================
1039 void StPPVertexFinder::matchTrack2EEMC(const StGlobalTrack* track,TrackData &t,float z)
1040 {
1041 
1042  const float minEta=0.7 ;// tmp cut
1043  const float maxPath=200 ;// tmp, cut too long extrapolation
1044 
1045  const StTrackGeometry* outGeo = track->outerGeometry();
1046  const StDcaGeometry* dcaGeo = track->dcaGeometry();
1047  StPhysicalHelixD hlx(outGeo->helix());
1048 
1049  //direction of extrapolation must be toward West (Z+ axis)
1050  if(dcaGeo->z() > outGeo->origin().z()) return;
1051 
1052  // droop too steep tracks
1053  if(dcaGeo->momentum().pseudoRapidity() < minEta) return;
1054 
1055  StThreeVectorD rSmd=StThreeVectorD(0,0,z);
1056  StThreeVectorD n=StThreeVectorD(0,0,1);
1057 
1058  double path = hlx.pathLength(rSmd,n);
1059  //cout<<" EEMC match: path="<<path<<endl;
1060  if(path>maxPath) return; // too long extrapolation
1061 
1062  StThreeVectorD r = hlx.at(path);
1063  float periodL=hlx. period();
1064 
1065  if(periodL<2*path) {
1066  LOG_DEBUG <<Form(" Warn, long path fac=%.1f ",path/periodL)<<
1067  Form(" punchEEMC1 x,y,z=%.1f, %.1f, %.1f path=%.1f period=%.1f\n",r.x(),r.y(),r.z(),path,periodL)<<endm;
1068  }
1069 
1070  float phi=r.phi();
1071  if(phi<0) phi+=2*M_PI;// now phi is [0,2Pi] as for Cyl slats
1072  float eta=r.pseudoRapidity();
1073 
1074  int iBin=eemcList->addTrack(eta,phi);
1075  bool eemcMatch=eemcList->isMatched(iBin);
1076  bool eemcVeto =eemcList->isVetoed(iBin);
1077  float eemcW =eemcList->getWeight(iBin);
1078 
1079  t.updateAnyMatch(eemcMatch,eemcVeto,t.mEemc);
1080  t.weight*=eemcW;
1081  t.eemcBin=iBin;
1082 
1083 }
1084 
1085 //==========================================================
1086 //==========================================================
1087 bool StPPVertexFinder::matchTrack2Membrane(const StGlobalTrack* track,TrackData &t)
1088 {
1089  //generate bitt pattern for TPC nodes with hits
1090  int nPos=0,nFit=0,jz0=0;
1091  const StDcaGeometry* dcaGeo = track->dcaGeometry();
1092  if (!dcaGeo) return 0;
1093  float rxy=fabs(dcaGeo->impact());
1094  float z=dcaGeo->z();
1095  if(rxy >RxyMax) return 0;
1096  if(fabs(z)>zMax) return 0;
1097 
1098  vector<int> hitPatt; hitPatt.resize(200);
1099 const StPtrVecHit& hits = track->detectorInfo()->hits();
1100  int nHits = hits.size();
1101  const StHit *hit = hits[0];
1102  int zignOld = (hit->position().z()<0)? -1:1;
1103  int rowMin=999,rowMax=-999;
1104 
1105  for (int it=0;it<nHits;it++) {//loop over hits
1106  hit = hits[it];
1107  if (!hit) continue;
1108  if (hit->detector()!=kTpcId) continue;
1109  float z = hit->position().z();
1110  if(fabs(z)>zMax) continue;
1111  if (hit->position().perp()<RxyMin) continue;
1112  if (hit->position().perp()>RxyMax) continue;
1113  if(fabs(z)<zMembraneDepth ) continue; //ignore hits too close to z=0
1114  const StTpcHit* tpcHit = (const StTpcHit*)hit;
1115  int row = tpcHit->padrow();
1116  if (rowMin>row) rowMin=row;
1117  if (rowMax<row) rowMax=row;
1118  hitPatt[row-1]=1; nFit++;
1119  if (!jz0) {// jz0 is not yet defined
1120  int zignNow = (z<0)? -1:1;
1121  if (zignNow!=zignOld) jz0 = row;
1122  }
1123  }//end loop over hits
1124  if (rowMax<0) return 0;
1125 
1126  for (int jl=0,jr=rowMin-1;jr<rowMax;jl++,jr++) { //remove leading & trailing zeros
1127  hitPatt[jl]=hitPatt[jr];
1128  }
1129  jz0-= rowMin-1; nPos = rowMax-rowMin+1;
1130  hitPatt.resize(nPos);
1131 
1132  if(nFit< mMinFitPfrac * nPos) return false; // too short fragment of a track
1133 
1134  if( mFitPossWeighting)
1135  t.weight*=double(nFit)/nPos;// introduced in 2012 for pp510 to differentiate between global track quality, together with lowering the overall threshold from 0.7 to 0.51, Jan
1136 
1137  t.scanNodes(hitPatt,jz0); // if central membrane is crossed, scale weight inside
1138 
1139  return true;
1140 }
1141 
1142 //==========================================================
1143 //==========================================================
1144 
1145 bool StPPVertexFinder::isPostCrossingTrack(const StGlobalTrack* track)
1146 {
1147  int nWrongZHit=0;
1148 
1149  const StPtrVecHit& hits = track->detectorInfo()->hits();
1150  int nHits = hits.size();
1151  for (int it=0; it<nHits;it++)
1152  {
1153  const StTpcHit* hit=(const StTpcHit*)hits[it];
1154  if(hit->detector()!=kTpcId) continue;
1155  float r=hit->position().perp();
1156  if (r < RxyMin) continue;
1157  if (r > RxyMax) continue;
1158  float z=hit->position().z();
1159  if (fabs(z) > zMax) continue;
1160  if ((z < -zMembraneDepth && hit->sector() <= 12) ||
1161  (z > zMembraneDepth && hit->sector() > 12)) {
1162  nWrongZHit++;
1163  if(nWrongZHit>=nWrongZHitCut) {return true;}
1164  }
1165  }
1166  return false;
1167 }
1168 
1169 /**************************************************************************
1170  **************************************************************************
1171  * $Log: StPPVertexFinder.cxx,v $
1172  * Revision 1.15 2018/03/16 18:38:49 genevb
1173  * Use TGeo initializer for BTof geometry
1174  *
1175  * Revision 1.14 2017/05/10 23:16:42 smirnovd
1176  * Some minor refactoring changes:
1177  *
1178  * See commits 6fb592df..07da3bdf on master branch
1179  *
1180  * StPPVertexFinder: Get rid of a temporary variable
1181  *
1182  * StPPVertexFinder: Get rid of extra return
1183  * Zero vertices returned for unqualified event anyway
1184  *
1185  * StGenericVertexFinder: Removed deprecated CalibBeamLine()
1186  *
1187  * Revision 1.13 2017/02/14 22:00:41 smirnovd
1188  * Squashed commit of the following clean-up changes:
1189  *
1190  * See master branch for details.
1191  *
1192  * - Remove commented code for debugging
1193  * - Removed extra validation; it is done at construction
1194  * - No need to include header for apple OS
1195  * - Removed pointless assert
1196  * - Use standard portable type name
1197  * - Remove unused header math_constants.h
1198  * - StMinuitVertexFinder: Remove abandoned member function
1199  *
1200  * Revision 1.12 2017/01/06 21:01:49 smirnovd
1201  * Use pi constant from standard library, s/C_PI/M_PI/
1202  *
1203  * Revision 1.11 2017/01/03 22:17:37 smirnovd
1204  * [Stylistic] Changed public addVertex() to accept references
1205  *
1206  * Avoid unnecessary gymnastics with pointers
1207  *
1208  * Revision 1.10 2016/12/12 18:44:21 smirnovd
1209  * Removed unused local variable
1210  *
1211  * Revision 1.9 2016/12/12 17:17:00 smirnovd
1212  * Removed unused #include "TCanvas.h"
1213  *
1214  * Revision 1.8 2016/12/12 16:42:30 smirnovd
1215  * Removed special treatment for MC data in PPV vertex finder
1216  *
1217  * Removed mIsMC flag in order to treat the simulated and real data in the same
1218  * manner during vertex reconstruction. The flag caused confusion rather than being
1219  * helpful in any way for the main VF task. As an additional benefit the users will
1220  * not have to worry about setting the flag when running on simulated data.
1221  *
1222  * Revision 1.7 2016/11/07 21:19:28 smirnovd
1223  * Added and reworded some doxygen and other comments
1224  *
1225  * Also cleaned up not-so-useful comments
1226  *
1227  * Revision 1.6 2016/11/07 21:19:14 smirnovd
1228  * Moved log print statements out of constructors
1229  *
1230  * Revision 1.5 2016/08/18 17:46:15 smirnovd
1231  * Squashed commit of the following refactoring changes:
1232  *
1233  * Date: Wed Jul 27 18:31:18 2016 -0400
1234  *
1235  * Removed unused arguments in UseVertexConstraint()
1236  *
1237  * In StiPPVertexFinder and StvPPVertexFinder this method does nothing
1238  *
1239  * Date: Wed Jul 27 16:47:58 2016 -0400
1240  *
1241  * Make old UseVertexConstraint private virtual and call it from its public replacement in the base class
1242  *
1243  * also mark methods as private explicitly
1244  *
1245  * Date: Wed Jul 27 16:52:02 2016 -0400
1246  *
1247  * Removed unused private data member mWeight
1248  *
1249  * Date: Wed Jul 27 16:50:42 2016 -0400
1250  *
1251  * Prefer base class static beamline parameters rather than this class private members
1252  *
1253  * Date: Wed Jul 27 16:21:49 2016 -0400
1254  *
1255  * StPPVertexFinder: Got rid of unused private beamline parameters
1256  *
1257  * The equivalent measurements are available from the base class
1258  * StGenericVertexFinder
1259  *
1260  * Date: Wed Jul 27 16:19:19 2016 -0400
1261  *
1262  * StPPVertexFinder: For beamline position use equivalent static methods from parent class
1263  *
1264  * Date: Wed Jul 27 16:05:50 2016 -0400
1265  *
1266  * StGenericVertexMaker: Assigning once is enough
1267  *
1268  * Date: Mon Aug 15 10:43:49 2016 -0400
1269  *
1270  * StGenericVertexFinder: Print out beamline parameters
1271  *
1272  * Print beamline values as extracted from the database before any modification.
1273  *
1274  * Date: Wed Jul 6 15:33:02 2016 -0400
1275  *
1276  * Stylistic changes and minor refactoring
1277  *
1278  * Whitespace and comments for improved readability
1279  * s/track/stiKalmanTrack/
1280  *
1281  * Date: Wed Jul 6 15:28:16 2016 -0400
1282  *
1283  * StPPVertexFinder: Switched to cleaner c++11 range loop syntax
1284  *
1285  * Date: Wed Jul 6 15:22:14 2016 -0400
1286  *
1287  * StPPVertexFinder: Minor c++ refactoring
1288  *
1289  * - Removed unused counter
1290  * - c-style array to std::array
1291  *
1292  * Date: Wed Jul 6 15:20:11 2016 -0400
1293  *
1294  * Deleted commented out code
1295  *
1296  * Removed unused #include's StMinuitVertexFinder
1297  *
1298  * Revision 1.4 2016/03/08 15:54:19 smirnovd
1299  * Removed pointless remnants of past debugging
1300  *
1301  * Revision 1.3 2016/02/29 22:58:23 jwebb
1302  * Moved include of StEventTypes from header of generic class to implementation files of generic and concrete classes.
1303  *
1304  * Revision 1.2 2013/08/19 21:27:32 perev
1305  * Check for Dca geo added
1306  *
1307  * Revision 1.1 2013/08/16 22:19:56 perev
1308  * PPV with only StEvent dependency
1309  *
1310  * Revision 1.44 2013/04/09 22:37:56 genevb
1311  * Remove boostEfficiency codes: DB usage implemented
1312  *
1313  * Revision 1.43 2013/04/09 21:11:58 genevb
1314  * Use database table for track selection cuts
1315  *
1316  * Revision 1.42 2013/04/05 21:00:02 jeromel
1317  * Implemented and merged back to source the boostEfficiency (i.e. change of
1318  * nFit /nPossible points on the track fract to consider). No DB imp yet.
1319  *
1320  * Fixed boostEfficiency()
1321  *
1322  * Changed cout to LOG_INFO
1323  *
1324  * Revision 1.41 2012/11/06 20:58:04 fisyak
1325  * Remove second addition of btofGeom to db maker
1326  *
1327  * Revision 1.40 2012/05/25 20:19:40 balewski
1328  * convert many LOG_INFO to LOG_DEBUG to make PPV more silent. No intencional change of PPV logic.
1329  *
1330  * Revision 1.39 2012/05/07 15:55:30 fisyak
1331  * Proper handing of btofGeometry
1332  *
1333  * Revision 1.38 2010/09/16 04:18:55 rjreed
1334  * Moved intialized of btof from init to initrun and changed it so that the btof class is not utilized if mUseBtof is false
1335  *
1336  * Revision 1.37 2010/09/10 21:08:35 rjreed
1337  * Added function UseBOTF and bool mUseBtof to switch the use of the TOF on and off in vertex finding. Default value is off (false).
1338  * Added functions, and variables necessary to use the TOF in PPV for vertex finding. Includes matching tracks to the TOF and changing the track weight based on its matched status with the TOF.
1339  *
1340  * Revision 1.36 2009/11/20 18:54:08 genevb
1341  * Avoid compiler warning about operator order precedence
1342  *
1343  * Revision 1.35 2009/11/05 21:40:08 rjreed
1344  * Last line of matchTrack2Membrane was deleted between version 1.29 and 1.30. This line checks
1345  * tracks to determine whether they've crossed the TPC CM. This rev reinstates the line.
1346  *
1347  * Revision 1.34 2009/07/09 21:29:03 balewski
1348  * allow export of prim tracks for 3D beam line fit (use VtxSeedCalG option),
1349  * oneTrack vertex thresholds was lowered form 15 to 10 GeV/c
1350  *
1351  * Revision 1.33 2009/02/05 21:43:59 balewski
1352  * Oleksandr renamed StEEmcDbMaker to StEEmcDb and requested this set of code corrections
1353  *
1354  * Revision 1.32 2008/12/02 14:35:05 balewski
1355  * I forgot to require EMC hit for highPT track, now it is in
1356  *
1357  * Revision 1.31 2008/12/01 22:57:39 balewski
1358  * Added capability to reco 1 high pT track vertices with positive rank. 2+ match vertices will have rank above 1e6. Sub-prime vertices (for Akio) have negative rank. More details is given at:
1359  * http://drupal.star.bnl.gov/STAR/comp/reco/vf/ppv-vertex/2009-algo-upgrade-1
1360  *
1361  * Revision 1.30 2008/10/21 19:23:05 balewski
1362  * store unqualified vertices on Akio's request
1363  *
1364  * Revision 1.29 2008/08/21 22:09:31 balewski
1365  * - In matchTrack2Membrane()
1366  * - Cut on hit max R chanegd from 190 to 199cm
1367  * - Fixed logic failure of counting possible hits
1368  * - Fixed logic failure of crossing CM for certain pattern of hits
1369  * - Added a new function bool isPostCrossingTrack()
1370  * - it returns true if track have 2 or more hits in wrong z
1371  * - Use isPostCrossingTrack() in fit()
1372  * - Added switch setDropPostCrossingTrack(bool), defaulted to true
1373  * All changes tested & implemented by Akio in preparation for 2008 pp production.
1374  * The key change (removing PostCrossingTrack) is in response to the change of the TPC cluster finder
1375  * - now we use the on-line version which allows for longer range of TPC time buckets to be used.
1376  *
1377  * Revision 1.28 2008/04/03 16:24:31 fisyak
1378  * replace sti->getToolkit() by StEventToolkit::instance()
1379  *
1380  * Revision 1.27 2008/02/12 17:51:20 jeromel
1381  * Assert of Year number removed. Assert on beamLine left but added an explaination (so we won't have to rediscover this).
1382  *
1383  * Revision 1.26 2007/03/22 08:42:05 balewski
1384  * extend validity of PPV for 2007 data taking
1385  *
1386  * Revision 1.25 2006/10/17 13:38:03 fisyak
1387  * Remove dependencies from dead classes
1388  *
1389  * Revision 1.24 2006/07/31 17:57:54 balewski
1390  * cleanup before 2006 prod, no changes in algo, CTB stays out all the time
1391  *
1392  * Revision 1.23 2006/06/02 20:46:55 perev
1393  * Accoun DCA node added
1394  *
1395  * Revision 1.22 2006/05/04 20:01:31 jeromel
1396  * Switched to logger
1397  *
1398  * Revision 1.21 2006/04/26 15:37:04 jeromel
1399  * mVertexOrderMethod (To be tested)
1400  *
1401  * Revision 1.20 2006/03/12 18:47:29 balewski
1402  * small corrections of histograms and printouts
1403  *
1404  * Revision 1.19 2006/03/12 17:01:01 jeromel
1405  * Minor change + use ppvNoCtbVertexFinder
1406  *
1407  * Revision 1.18 2006/03/11 04:12:49 balewski
1408  * 2 changes in preparation for 2006 data processing:
1409  * - CTB matching ON/OFF switch activated by m_Mode 0x8 or 0x10
1410  * - vertex enum extension depending on CTB usage - hack in the moment,
1411  * Jerome needs to provide actual new enum
1412  * - BTOW calibration wil change for 2006+ from maxt eT of ~27 --> 60 GeV
1413  * NOTE : this new code was NOT executed - it is late, I want to get it in CVS
1414  * Tomorrow I'll do some tests
1415  * Jan
1416  *
1417  * Revision 1.17 2006/01/24 17:53:39 balewski
1418  * small fix
1419  *
1420  * Revision 1.16 2006/01/24 17:26:06 balewski
1421  * drop hardcoded mask of BTOW lower East, now it takes BTOW mask & ped+sigPed from DB
1422  * Watch the DB time stamp !
1423  *
1424  * Revision 1.15 2005/09/03 16:41:53 balewski
1425  * bug fix: <<endm replaced with <<endl
1426  *
1427  * Revision 1.14 2005/08/30 22:08:43 balewski
1428  * drop '*' from declaration of mTrackData & mVertexData
1429  *
1430  * Revision 1.13 2005/08/17 15:07:39 balewski
1431  * cleanup, irrelevant for pp200 production
1432  *
1433  * Revision 1.12 2005/08/15 13:04:08 balewski
1434  * Z-range +/- 250 cm
1435  *
1436  * Revision 1.11 2005/08/14 23:49:55 balewski
1437  * smaller bins for Z-likelihood, limit siZ >=1 mm
1438  *
1439  * Revision 1.10 2005/08/12 18:35:27 balewski
1440  * more accurate calculation of Z-vertex error
1441  * by accounting for average weight of tracks contributing to the likelihood,
1442  * Now errZ is of 0.5-1.5 mm, was ~2x smaller
1443  *
1444  * Revision 1.9 2005/07/28 20:57:14 balewski
1445  * extand zMax range to 200cm, call it PPV-2
1446  *
1447  * Revision 1.8 2005/07/27 06:08:19 balewski
1448  * tuning PPV cuts
1449  *
1450  * Revision 1.7 2005/07/26 02:49:08 balewski
1451  * more flexible for node pathologies
1452  *
1453  * Revision 1.6 2005/07/22 21:02:08 balewski
1454  * bug fix & cleanup
1455  *
1456  * Revision 1.5 2005/07/20 05:34:16 balewski
1457  * cleanup
1458  *
1459  * Revision 1.4 2005/07/19 22:01:24 perev
1460  * MultiVertex
1461  *
1462  * Revision 1.3 2005/07/15 20:53:25 balewski
1463  * cleanup
1464  *
1465  * Revision 1.2 2005/07/14 15:39:25 balewski
1466  * nothing, to force recompilation of this code by Autobuild
1467  *
1468  * Revision 1.1 2005/07/11 20:38:12 balewski
1469  * PPV added for real
1470  *
1471  *
1472  **************************************************************************
1473  **************************************************************************
1474  **************************************************************************/
1475 
1476 }// end namespace StEvPPV
Bool_t HelixCrossCellIds(const StHelixD &helix, IntVec &idVec, DoubleVec &pathVec, PointVec &crossVec) const
const void * mother
Pointer to original track.
Definition: TrackData.h:45
Definition: StHit.h:125
double beamX(double z) const
double beamY(double z) const
pair< double, double > pathLength(double r) const
path length at given r (cylindrical r)
Definition: StHelix.cc:351
EEMC simple geometry.
virtual TObject * GetObject() const
The depricated method (left here for the sake of the backward compatibility)
Definition: TObjectSet.h:56
int vertexID
Definition: TrackData.h:42