StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StV0FinderMaker.cxx
1 //
7 // Cuts can be found in the code by comments beginning with "Cut:"
8 //
9 //
10 
11 
12 #include "StV0FinderMaker.h"
13 #include "StMessMgr.h"
14 #include "StEvent/StEventTypes.h"
15 #include "TMath.h"
16 #include "TVector2.h"
17 #include "tables/St_V0FinderParameters_Table.h"
18 
21 #include "StEvent/StTrack.h"
22 #include "StMuDSTMaker/COMMON/StMuTypes.hh"
24 
25 #include "math_constants.h"
26 #include "phys_constants.h"
27 #include "SystemOfUnits.h"
28 
29 static const int BLOCK=1024;
30 
31 
32 StV0FinderMaker* StV0FinderMaker::mInstance = 0;
33 
34 
35 //_____________________________________________________________________________
36  StV0FinderMaker::StV0FinderMaker(const char *name):StMaker(name),
37  v0pars(0),pars(0),pars2(0),event(0),v0Vertex(0),
38  prepared(kFALSE),useExistingV0s(kFALSE),dontZapV0s(kFALSE),
39  useTracker(kTrackerUseBOTH),useSVT(kNoSVT),useEventModel(kUseStEvent),
40  useV0Language(kV0LanguageUseCpp),useXiLanguage(kXiLanguageUseCppOnCppV0),
41  useLanguage(kLanguageUseRun),useLikesign(kLikesignUseStandard),
42  useRotating(kRotatingUseStandard)
43 {
44  // Initializes everything that wasn't yet :
45  trks = 0;
46  det_id_v0 = 0;
47  ITTFflag = 0;
48  TPTflag = 0;
49  mainv.setX(0.);
50  mainv.setY(0.);
51  mainv.setZ(0.);
52 
53  trkcnt = 0;
54  trkmax = BLOCK;
55  trkNodeRatio = 1.;
56  trkNodeRatioCnt = 0.;
57 
58  // Check for multiple instances
59  if (mInstance != 0)
60  gMessMgr->Warning() << "(" << name <<
61  ") : MORE THAN ONE INSTANCE!" << endm;
62  else mInstance = this;
63 
64  Bfield = 1.e-10; //Random value for initialisation.
65  //If it isn't changed to correct value in
66  // Prepare() then something has gone wrong!
67 }
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 //_____________________________________________________________________________
79 StV0FinderMaker::~StV0FinderMaker() {
80 }
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 //_____________________________________________________________________________
95 {
96  TDataSet* dbDataSet = GetDataBase("Calibrations/tracker");
97  if (!dbDataSet) {
98  gMessMgr->Error(
99  "Init() : could not find Calibrations/tracker database.");
100  return;
101  }
102  v0pars = (St_V0FinderParameters*) (dbDataSet->FindObject("V0FinderParameters"));
103  if (!v0pars) {
104  gMessMgr->Error(
105  "Init() : could not find V0FinderParameters in database.");
106  return;
107  }
109 }
110 
111 
112 
113 
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 //_____________________________________________________________________________
124 Int_t StV0FinderMaker::Init()
125 {bool a,b,c;
126 
127  if ((useTracker!=kTrackerUseTPT) && (useTracker!=kTrackerUseITTF) && (useTracker!=kTrackerUseBOTH))
128  {gMessMgr->Error("Init() : wrong TrackerUsage parameter set.");
129  return kStErr;
130  }
131  if ((useSVT!=kNoSVT) && (useSVT!=kUseSVT))
132  {gMessMgr->Error("Init() : wrong SVTUsage parameter set.");
133  return kStErr;
134  }
135  if ((useEventModel!=kUseStEvent) && (useEventModel!=kUseMuDst))
136  {gMessMgr->Error("Init() : wrong EventModelUsage parameter set.");
137  return kStErr;
138  }
139  if ((useLikesign!=kLikesignUseStandard) && (useLikesign!=kLikesignUseLikesign))
140  {gMessMgr->Error("Init() : wrong LikesignUsage parameter set.");
141  return kStErr;
142  }
143  if ((useRotating!=kRotatingUseStandard) && (useRotating!=kRotatingUseRotating) && (useRotating!=kRotatingUseSymmetry) && (useRotating!=kRotatingUseRotatingAndSymmetry))
144  {gMessMgr->Error("Init() : wrong RotatingUsage parameter set.");
145  return kStErr;
146  }
147 
148  if (useTracker == kTrackerUseTPT) gMessMgr->Info()<<"use TPT tracks."<<endm;
149  if (useTracker == kTrackerUseITTF) gMessMgr->Info()<<"use ITTF tracks."<<endm;
150  if (useTracker == kTrackerUseBOTH) gMessMgr->Info()<<"use TPT *and* ITTF tracks."<<endm;
151  if (useSVT == kUseSVT) gMessMgr->Info()<<"use SVT points if possible."<<endm;
152  if (useSVT == kNoSVT) gMessMgr->Info()<<"do not use SVT points."<<endm;
153  if (useEventModel == kUseStEvent) gMessMgr->Info()<<"expect StEvent files in input."<<endm;
154  if (useEventModel == kUseMuDst) gMessMgr->Info()<<"expect MuDst files in input."<<endm;
155  if (useLikesign == kLikesignUseLikesign) gMessMgr->Info()<<"does like-sign finding."<<endm;
156  if (useRotating == kRotatingUseRotating) gMessMgr->Info()<<"does rotating finding."<<endm;
157  if (useRotating == kRotatingUseSymmetry) gMessMgr->Info()<<"does symmetry finding."<<endm;
158  if (useRotating == kRotatingUseRotatingAndSymmetry) gMessMgr->Info()<<"does rotating + symmetry finding."<<endm;
159 
160  if (useLanguage != kLanguageUseSpecial)
161  {a=(bool)(1&(useLanguage>>2));
162  b=(bool)(1&(useLanguage>>1));
163  c=(bool)(1&useLanguage);
164  useV0Language=2*(!(a^c))+(a|c);
165  useXiLanguage=4*(b&(!(a^c)))+2*(a&b&(!c))+(a|c);
166  }
167  switch (useLanguage)
168  {case kLanguageUseOldRun : gMessMgr->Info()<<"Fortran run."<<endm;
169  break;
170  case kLanguageUseRun : gMessMgr->Info()<<"C++ run."<<endm;
171  gMessMgr->Info()<<"BE CAREFUL : you are NOT running the XiFinder !"<<endm;
172  break;
173  case kLanguageUseTestV0Finder : gMessMgr->Info()<<"Test V0Finder."<<endm;
174  break;
175  case kLanguageUseTestXiFinder : gMessMgr->Info()<<"Test XiFinder."<<endm;
176  gMessMgr->Info()<<"BE CAREFUL : you are NOT running the XiFinder !"<<endm;
177  break;
178  case kLanguageUseTestBothFinders : gMessMgr->Info()<<"Test V0Finder and XiFinder."<<endm;
179  gMessMgr->Info()<<"BE CAREFUL : you are NOT running the XiFinder !"<<endm;
180  break;
181  case kLanguageUseSpecial : break;
182  default : gMessMgr->Error("Init() : wrong LanguageUsage parameter set.");
183  return kStErr;
184  }
185  if ((useV0Language!=kV0LanguageUseFortran) && (useV0Language!=kV0LanguageUseCpp) && (useV0Language!=kV0LanguageUseBoth))
186  {gMessMgr->Error("Init() : wrong V0LanguageUsage parameter set.");
187  return kStErr;
188  }
189  if (1&useV0Language) gMessMgr->Info()<<" Will store Fortran V0."<<endm;
190  if (2&useV0Language) gMessMgr->Info()<<" Will store C++ V0."<<endm;
191  if (1&useXiLanguage) gMessMgr->Info()<<" Will store Fortran Xi."<<endm;
192  if (2&useXiLanguage) gMessMgr->Info()<<" BE CAREFUL : will NOT store C++ Xi, although asked."<<endm;
193  if (4&useXiLanguage) gMessMgr->Info()<<" BE CAREFUL : will NOT store C++ Xi, although asked."<<endm;
194 
195  if (useEventModel) { //initialize mMuDstMaker
196  mMuDstMaker = (StMuDstMaker*)GetMaker("myMuDstMaker");
197  if(!mMuDstMaker) gMessMgr->Warning("Init can't find a valid MuDst");
198  }
199 
200  return StMaker::Init();
201 }
202 //_____________________________________________________________________________
204 
205  if (prepared) return kStOk;
206 
207  unsigned short i,j,nNodes,nTrksEstimate;
208  StThreeVectorD p;
209 
210  // Get pars
211  GetPars();
212  ITTFflag=kITKalmanFitId;
213  TPTflag=kHelix3DIdentifier;
214 
215  // Get event
216 
218  if(GetEventUsage()==kUseStEvent){
219  event = (StEvent*) GetInputDS("StEvent");
220  }
222  else if(GetEventUsage()==kUseMuDst){
223  StMuDst* mu = mMuDstMaker->muDst();
224  if(mu) cout<<"V0Finder :: found a MuDst"<<endl;
225  if(mu->event())cout<<"see a muEvent ... "<<endl;
226  if(mu) event = mu->createStEvent();
227 
228  if(event) AddData(event);
229  if(event)cout<<"see a recreated StEvent!"<<endl;
230 #if 0
231  Int_t nV0s = mu->GetNV0();
232  cout<<"the number of existing v0's is "<<nV0s<<endl;
233 #endif
234  }
236 
237  if (!event)
238  {gMessMgr->Warning("no StEvent ; skipping event.");
239  return kStWarn;
240  }
241 
242  // Get Primary Vertex Position
243  StPrimaryVertex* pvert = event->primaryVertex();
244  if (!pvert)
245  {gMessMgr->Warning("no primary vertex ; skipping event.");
246  return kStWarn;
247  }
248  mainv = pvert->position();
249 
250  StSPtrVecTrackNode& theNodes = event->trackNodes();
251  nNodes = theNodes.size();
252 
253  // Initial estimate of needed vector sizes
254  nTrksEstimate = (unsigned int) (nNodes*trkNodeRatio);
255  if (nTrksEstimate > trk.size()) ExpandVectors(nTrksEstimate);
256 
257  // Find which global tracks to use
258  trks=0;
259  double BfieldRunning = 0;
260  double nBfieldRunning = 0;
261  for (i=0; i<nNodes; i++) {
262  int nj = theNodes[i]->entries(global);
263  for (j=0; j<nj; j++) {
264 
265  StTrack* tri = theNodes[i]->track(global,j);
267  //if there is a track that uses an SVT point, set the track to estGlobal
268  if(useSVT){
269  StTrack* svtTrack = theNodes[i]->track(estGlobal,j);
270  if (svtTrack){
271  tri=svtTrack;
272  }
273  }
275 
276  //Cut: track type
277  //cout << "i,j" << i << "," << j << " fittingMethod = " << tri->fittingMethod() << endl;
278 
279  if (
280  //(tri->fittingMethod() == TPTflag && (GetTrackerUsage() == kTrackerUseITTF)) ||
281  (tri->fittingMethod() != ITTFflag && (GetTrackerUsage() == kTrackerUseITTF)) ||
282  (tri->fittingMethod() == ITTFflag && (GetTrackerUsage() == kTrackerUseTPT))) continue;
283 
284  //Cut: track flag
285  if (tri->flag() <= 0) continue;
286 
287  // Expand vectors if needed
288  if (trks >= trk.size()) ExpandVectors(trks+1);
289 
290  // Determine detector id of track i
291  const StTrackTopologyMap& map = tri->topologyMap();
292  Bool_t tpcHit = map.hasHitInDetector(kTpcId);
293  Bool_t silHit = map.hasHitInDetector(kSvtId) ||
294  map.hasHitInDetector(kSsdId);
295  if (tpcHit) {
296  if (silHit)
297  detId[trks] = 3; //SVT+TPC
298  else
299  detId[trks] = 1; //TPC-only
300  } else if (silHit)
301  detId[trks] = 2; //SVT-only
302  else
303  //ignore this track
304  continue;
305 
306  trk[trks] = tri;
307 
308  StTrackGeometry* triGeom = tri->geometry();
309  if(!triGeom) continue; //ignore the track if it has no geometry
310 
311  heli[trks] = triGeom->helix();
312 
313  p = triGeom->momentum();
314 
315  pt[trks] = p.perp();
316  ptot[trks] = p.mag();
317  trkID[trks]=tri->key();
318 
319  // Determine number of hits (in SVT+TPC)
320  hits[trks] = map.numberOfHits(kTpcId) +
321  map.numberOfHits(kSvtId) +
322  map.numberOfHits(kSsdId);
323  //Cut: number of hits
324  pars2 = v0pars->GetTable(detId[trks]-1);
325  if (hits[trks] < pars2->n_point) continue;
326 
327  //if (!trks)
328  if (nBfieldRunning<1e2) {
329  StThreeVectorD p1 = triGeom->momentum();
330  StThreeVectorD p2 = heli[trks].momentum(Bfield);
331 
332  if (fabs(p2.x()) > fabs(p2.y())) Bfield *= p1.x()/p2.x();
333  else if (fabs(p2.y()) > 1.e-20) Bfield *= p1.y()/p2.y();
334  else continue;
335  // This method appears to only be accurate to about 1 part in 1000 for
336  // single tracks. We can do better by using information from multiple
337  // tracks. But Bfield is only used in momentum determination, which
338  // is not likely to be that accurate anyhow, so no need to push too far.
339  // (Bfield is not used in helix extrapolation for now.)
340 
341  if (fabs(Bfield)<1.e-20) return kStWarn;
342  Bfield = TMath::Sign(Bfield,-1.0*triGeom->charge()*triGeom->helicity());
343 
344  BfieldRunning += Bfield;
345  nBfieldRunning += 1;
346  }
347  if (triGeom->charge() > 0) ptrk.push_back(trks);
348  else if (triGeom->charge() < 0) ntrk.push_back(trks);
349  trks++;
350  }
351  }
352  if (nBfieldRunning>0) Bfield = BfieldRunning/nBfieldRunning;
353 
354  // Manage vector memory usage
355  // If maximum needed is less than half allocated for 10 events, resize
356  if (trks < (trk.size()/2)) {
357  if (trks > trkmax) trkmax = trks;
358  trkcnt++;
359  if (trkcnt >= 10) {
360  ExpandVectors(trkmax);
361  trkcnt = 0;
362  trkmax = BLOCK;
363  }
364  } else {
365  trkcnt = 0;
366  trkmax = BLOCK;
367  }
368  trkNodeRatio = ((trkNodeRatio*trkNodeRatioCnt)+((float) trks)/((float) nNodes)) /
369  (trkNodeRatioCnt + 1.);
370  trkNodeRatioCnt++;
371 
372  gMessMgr->Info() << "No. of nodes is : "
373  << nNodes << endm;
374  gMessMgr->Info() << "No. of tracks is : "
375  << trks << endm;
376 
377  prepared = kTRUE;
378  return kStOk;
379 }
380 
381 
382 
383 
384 
385 
386 
387 
388 
389 
390 
391 //_____________________________________________________________________________
393 
394  // Variables:
395  StThreeVectorD xi,xj,pi,pj,xpp,pp,impact; // 3D vectors of the V0
396  StThreeVectorD xi1,xj1,pi1,pj1,tmp3V; // temporary 3D vectors
397  TVector2 ri,rj,xci,xcj,tmp2V; // 2D vectors of the tracks
398  double rad_i,rad_j,separation,solution,dxc; // helix circle params
399  double dca_ij,dca_ij1,rmin,dlen,pperpsq,ppmag; // V0 params
400  double alpha,ptArm_sq,pPosAlongV0,pNegAlongV0; // Armenteros params
401  double cosij,sin2ij,t1,t2; // 3D dca calculation vars
402  unsigned short i,j,ii,jj; // track iteration vars
403  pairD paths,paths1,path2; // helix pathLength vars
404  double temp;
405  Bool_t doSecond, isPrimaryV0, usedV0;
406  Int_t iRes;
407  long keepTrack;
408 
409  if (! (2&useV0Language)) return kStOk;
410 
411  gMessMgr->Info("Make() : Starting...");
412 
413  // Prepare event and track variables
414  iRes = Prepare();
415  if (iRes != kStOk) return iRes;
416 
417 
418  StSPtrVecV0Vertex& v0Vertices = event->v0Vertices();
419  gMessMgr->Info()<<"coming in I have "<<v0Vertices.size()<<" V0s."<<endm;
420 
421  if (!(1&useV0Language)) {
422  //Erase existing V0s and Xis
423  // (must do Xis too as they point to the V0s!)
424  gMessMgr->Info()<<"pre-existing V0s and Xis deleted."<<endm;
425  StSPtrVecV0Vertex v0Vertices2;
426  v0Vertices = v0Vertices2;
427  StSPtrVecXiVertex& xiVertices = event->xiVertices();
428  StSPtrVecXiVertex xiVertices2;
429  xiVertices = xiVertices2;
430  }
431 
432 
433  // Loop over track pairs to find V0s
434 
435  //i track is positive
436  int nii = ptrk.size();
437  for (ii=0; ii<nii; ii++) {
438  i = ptrk[ii];
439 
440  xci.Set(heli[i].xcenter(),heli[i].ycenter());
441  ri.Set(heli[i].origin().x(),heli[i].origin().y());
442  ri -= xci;
443  rad_i = ri.Mod();
444 
445  //j track is negative
446  int njj = ntrk.size();
447  for (jj=0; jj<njj; jj++) {
448  j = ntrk[jj];
449 
450  if (GetTrackerUsage() == kTrackerUseBOTH)
451  {
452  //if ((trk[i]->fittingMethod() == ITTFflag) && (trk[j]->fittingMethod() == TPTflag)) continue;
453  if ((trk[i]->fittingMethod() == ITTFflag) && (trk[j]->fittingMethod() != ITTFflag)) continue;
454  //if ((trk[i]->fittingMethod() == TPTflag) && (trk[j]->fittingMethod() == ITTFflag)) continue;
455  if ((trk[i]->fittingMethod() != ITTFflag) && (trk[j]->fittingMethod() == ITTFflag)) continue;
456  }
457 
458  // Determine detector id of V0 for pars
459  det_id_v0 = TMath::Max(detId[i],detId[j]);
460 
461  // Primary V0 cut parameters
462  pars = v0pars->GetTable(det_id_v0+2);
463  // Primary and secondary V0 cut parameters
464  pars2 = v0pars->GetTable(det_id_v0-1);
465 
466  //Cut: number of hits
467  //Now cut directly when filling the table of tracks in Prepare().
468 // if ((hits[i] < pars2->n_point) ||
469 // (hits[j] < pars2->n_point)) continue;
470 
471  //Cut: Initial cut on dca of tracks to primary vertex
472  // (perform as early as possible)
473  // V0 can't have pt larger than sum of pts of daughters
474  temp = pt[i] + pt[j];
475  if ((temp < 0.99 * pars2->dcapn_pt) &&
476  ((trk[i]->impactParameter() <= pars2->dcapnmin) ||
477  (trk[j]->impactParameter() <= pars2->dcapnmin))) continue;
478 
479  xcj.Set(heli[j].xcenter(),heli[j].ycenter());
480  rj.Set(heli[j].origin().x(),heli[j].origin().y());
481  rj -= xcj;
482  rad_j = rj.Mod();
483 
484  tmp2V = xci - xcj;
485  dxc = tmp2V.Mod();
486  separation = dxc - (rad_i + rad_j);
487  doSecond = kFALSE;
488  dca_ij1 = -9999;
489 
490 
491  // ********************* START OF DETERMINATION OF V0 GEOMETRY
492  if (separation < 0)
493  {// Check for one helix circle completely inside the other
494  if (dxc < TMath::Abs(rad_i - rad_j)) continue;
495  // Helix circles are overlapping
496  //FULL 3D ITERATIVE METHOD (VERY SLOW, ONE SOLUTION)
497  // paths = heli[i].pathLengths(heli[j]);
498  //2D+ METHOD (GETS 3D APPROXIMATION AFTER TWO 2D SOLUTIONS)
499  path2 = heli[i].pathLength(rad_j,xcj.X(),xcj.Y());
500  // Two possible solutions: process ones that aren't nans
501  if (!std::isnan(path2.first))
502  {solution = path2.first;
503  if ((!std::isnan(path2.second)) && (path2.second != path2.first))
504  {doSecond = kTRUE;
505  }
506  goto ProcessSolution;
507  }
508  else if (std::isnan(path2.second))
509  {// no solutions
510  continue;
511  }
512  //else run only with the second solution
513  SecondSolution:
514  solution = path2.second;
515  doSecond = kFALSE;
516  ProcessSolution:
517  // paths contains the pathlengths for this solution with
518  // that for track i stored in first, and track j stored
519  // in second.
520  paths.first = solution;
521  xi = heli[i].at(paths.first );
522  paths.second = heli[j].pathLength(xi.x(),xi.y());
523  xj = heli[j].at(paths.second);
524  }
525  else if (separation < pars2->dca)
526  {// Helix circles are close, but not overlapping,
527  // find dca to point halfway between circle centers
528  tmp2V = (xci + xcj) * 0.5;
529  paths.first = heli[i].pathLength(tmp2V.X(),tmp2V.Y());
530  paths.second = heli[j].pathLength(tmp2V.X(),tmp2V.Y());
531  xi = heli[i].at(paths.first );
532  xj = heli[j].at(paths.second);
533  }
534  else
535  {// Helix circles are too far apart
536  continue;
537  }
538 
539  dca_ij = xi.z() - xj.z();
540  if (doSecond) {
541  // If we have two solutions, save this one and compare
542  dca_ij1 = dca_ij;
543  xi1=xi;
544  xj1=xj;
545  paths1=paths;
546  goto SecondSolution;
547  }
548  if ((dca_ij1 != -9999) &&
549  (TMath::Abs(dca_ij1) < TMath::Abs(dca_ij))) {
550  // First solution was better
551  dca_ij = dca_ij1;
552  xi=xi1;
553  xj=xj1;
554  paths=paths1;
555  }
556  // At this point, dca_ij is *signed* for use in 3D calc
557  // ********************* END OF DETERMINATION OF V0 GEOMETRY
558 
559  pi = heli[i].momentumAt(paths.first ,Bfield);
560  pj = heli[j].momentumAt(paths.second,Bfield);
561 
562  //Cut: check if tracks points away from prim vtx
563  if ((pi.dot(xi-mainv) < 0.0) ||
564  (pj.dot(xj-mainv) < 0.0)) continue;
565 
567  //Cut: check if the first point of either track is after v0vertex
568  // Commented out by helen 4/13/04 because it hurts SVT Xis try
569  // to find a more elegant soultion later
570  // if ((pi.dot(heli[i].origin() - xi) < 0.0) || //if pV0 * r <0, cut
571  // (pj.dot(heli[j].origin() - xj) < 0.0)) continue;
573 
574 
575  // ********************* START OF DETERMINATION OF 3D DCA
576  // dca_ij will be an approximation of the 3D dca
577  pi1 = pi/ptot[i];
578  pj1 = pj/ptot[j];
579 
580  cosij = pi1.dot(pj1);
581  sin2ij = 1.0 - cosij*cosij;
582  if (sin2ij) {
583  temp = dca_ij/sin2ij;
584  t1 = (-pi1.z()+pj1.z()*cosij)*temp;
585  t2 = ( pj1.z()-pi1.z()*cosij)*temp;
586 
587  temp = rad_i*(ptot[i]/pt[i]);
588  temp *= sin(t1/temp);
589  xi1 = xi + pi1.pseudoProduct(temp,temp,t1);
590 
591  temp = rad_j*(ptot[j]/pt[j]);
592  temp *= sin(t2/temp);
593  xj1 = xj + pj1.pseudoProduct(temp,temp,t2);
594 
595  dca_ij1 = (xi1 - xj1).mag2();
596  dca_ij *= dca_ij;
597 
598  if (dca_ij1 < dca_ij) {
599  paths.first = heli[i].pathLength(xi1.x(),xi1.y());
600  paths.second = heli[j].pathLength(xj1.x(),xj1.y());
603  xi1 = heli[i].at(paths.first);
604  xj1 = heli[j].at(paths.second);
605  dca_ij1 = (xi1 - xj1).mag2();
606  if (dca_ij1 < dca_ij) {
607  xi = xi1;
608  xj = xj1;
609  pi = heli[i].momentumAt(paths.first ,Bfield);
610  pj = heli[j].momentumAt(paths.second,Bfield);
611  dca_ij = dca_ij1;
612  }
613  }
614  //This code is the new one.
615 
616  /*if (dca_ij1 < dca_ij) {
617  paths.first = heli[i].pathLength(xi1.x(),xi1.y());
618  paths.second = heli[j].pathLength(xj1.x(),xj1.y());
619  xi = xi1;
620  xj = xj1;
621  pi = heli[i].momentumAt(paths.first ,Bfield);
622  pj = heli[j].momentumAt(paths.second,Bfield);
623  dca_ij = dca_ij1;
624  }*/
625  //And this one is the old one (comparison with Fortran).
626 
627 
628  }
629  // ********************* END OF DETERMINATION OF 3D DCA
630 
631 
632  // Now we have the positions and momenta of our tracks
633  // at the V0 vertex determined. Ready to make cuts on
634  // the V0 itself.
635 
636  //Cut: dca between tracks
637  if (dca_ij >= (pars2->dca*pars2->dca)) continue;
638 
639  pp = pi + pj;
640  pperpsq = pp.perp2();
641 
642  //Cut: dca of tracks to primary vertex (early as possible)
643  if ((pperpsq < pars2->dcapn_pt * pars2->dcapn_pt) &&
644  ((trk[i]->impactParameter() <= pars2->dcapnmin) ||
645  (trk[j]->impactParameter() <= pars2->dcapnmin))) continue;
646 
647  xpp = (xi + xj) * 0.5;
648  impact = xpp - mainv;
649  dlen = impact.mag2();
650 
651  //Cut: decay length from prim vtx
652  if (dlen <= (pars2->dlen*pars2->dlen)) continue;
653 
654  //Cut: V0 momentum should be away from prim vtx
655  if (pp.dot(impact) < 0.0) continue;
656 
657  ppmag = pperpsq + pp.z()*pp.z();
658  rmin = impact.cross(pp).mag2()/ppmag;
659 
660  //Cut: dca of V0 to prim vtx
661  if (rmin >= (pars2->dcav0*pars2->dcav0)) continue;
662 
663  tmp3V = pp/::sqrt(ppmag);
664  pPosAlongV0 = pi.dot(tmp3V);
665  pNegAlongV0 = pj.dot(tmp3V);
666  alpha = (pPosAlongV0-pNegAlongV0) /
667  (pPosAlongV0+pNegAlongV0);
668 
669  //Cut: Armenteros alpha
670  if (TMath::Abs(alpha) > pars2->alpha_max) continue;
671 
672  ptArm_sq = ptot[i]*ptot[i] - pPosAlongV0*pPosAlongV0;
673 
674  //Cut: Armenteros pt
675  if (ptArm_sq > (pars2->ptarm_max*pars2->ptarm_max)) continue;
676 
677  rmin = ::sqrt(rmin);
678  dca_ij = ::sqrt(dca_ij);
679  if (trk[i]->fittingMethod() == ITTFflag) dca_ij=-dca_ij;
680 
681  // Fill an StV0Vertex
682  v0Vertex = new StV0Vertex();
683  v0Vertex->setPosition(xpp);
684  v0Vertex->addDaughter(trk[i]);
685  v0Vertex->addDaughter(trk[j]);
686  v0Vertex->setDcaDaughterToPrimaryVertex(positive,trk[i]->impactParameter());
687  v0Vertex->setDcaDaughterToPrimaryVertex(negative,trk[j]->impactParameter());
689  v0Vertex->setMomentumOfDaughter(positive,pi);
690  v0Vertex->setMomentumOfDaughter(negative,pj);
691  v0Vertex->setDcaDaughters(dca_ij);
692  v0Vertex->setDcaParentToPrimaryVertex(rmin);
693 
695  /*Set bits 0000 0000 -> 1001 0000 if C++ used
696  if SVT ran in tracking, 1001 1000;
697  SVT and +: 1001 1100
698  SVT, + and -: 1001 1110;
699  SVT, - only: 1001 1010*/
700 
702  keepTrack=0;
703  keepTrack |=((long)1 << 4); // c++ v0 finder ran
704  if (useSVT)
705  {keepTrack |=((long)1 << 3); //sets to one the fourth digit if SVT was used
706  }
707  if (detId[i]==2 || detId[i]==3){
708  keepTrack |=((long)1 << 2); //sets 3rd bit to 1 if + track came from SVT
709  }
710  if(detId[j]==2 || detId[j]==3){
711  keepTrack |=((long)1 << 1); //sets 2nd bit to 1 if - track came from SVT
712  }
713 
714  keepTrack *= -1; //sets to negative the last digit
715  v0Vertex->setChiSquared((float)keepTrack);
717 
718  // Use primary V0 cut parameters
719  isPrimaryV0 =
720  (rmin < pars->dcav0) &&
721  ((pperpsq >= pars->dcapn_pt * pars->dcapn_pt) ||
722  ((trk[i]->impactParameter() > pars->dcapnmin) &&
723  (trk[j]->impactParameter() > pars->dcapnmin)));
724 
725  // Call secondary usage of V0 (such as for Xis)
726  usedV0 = UseV0();
727 
728  // Tag used V0s to indicate if they aren't primary
729  if (usedV0 && !isPrimaryV0)
730  v0Vertex->setDcaParentToPrimaryVertex(-rmin);
731 
732  // If used or primary, keep it
733  if (usedV0 || isPrimaryV0) {
734  v0Vertices.push_back(v0Vertex);
735  } else {
736  delete v0Vertex;
737  v0Vertex = 0;
738  }
739 
740  } // j-Loop
741  } // i-Loop
742 
743  gMessMgr->Info()<<"now I have "<<v0Vertices.size()<<" V0s."<<endm;
744  gMessMgr->Info()<<"using magnetic field : "<<Bfield/tesla<<" T."<<endm;
745 
746  // Any cleanup involved for using KeepV0()
747 
748  return kStOk;
749 }
750 
751 
752 
753 
754 
755 
756 
757 
758 
759 
760 //____________________________________________________________________________
761 
762 void StV0FinderMaker::Clear(Option_t *option){
763  prepared = kFALSE;
764  ptrk.clear();
765  ntrk.clear();
766  if(useEventModel){
767  if(mMuDstMaker){
768  if(event){
769  delete event;
770  event=0;
771  }
772  }
773  }
774 }
775 
776 
777 
778 
779 
780 
781 
782 
783 
784 
785 
786 
787 //_____________________________________________________________________________
788 void StV0FinderMaker::Trim() {
789  // Loop over V0s and remove those that don't satisfy the tight V0 cuts
790 
791  gMessMgr->Info() << "Trim() : Starting..." << endm;
792 
793  event = (StEvent*) GetInputDS("StEvent");
794  pars = v0pars->GetTable(3);
795  StSPtrVecV0Vertex& v0Vertices = event->v0Vertices();
796  int iV0s = v0Vertices.size();
797  for (int i=iV0s-1; i>=0; i--) {
798 
799  v0Vertex = v0Vertices[i];
800  if ((v0Vertex) &&
801  // Is it not a seconday V0?
802  (v0Vertex->dcaParentToPrimaryVertex() >= 0) &&
803  // Is it not a primary V0?
804  ! ((v0Vertex->dcaParentToPrimaryVertex() < pars->dcav0) &&
805  ((v0Vertex->momentum().perp2() >= pars->dcapn_pt * pars->dcapn_pt) ||
806  ((v0Vertex->dcaDaughterToPrimaryVertex(positive) > pars->dcapnmin) &&
807  (v0Vertex->dcaDaughterToPrimaryVertex(negative) > pars->dcapnmin))))) {
808  v0Vertex->makeZombie();
809  iV0s--;
810  }
811  } // V0 loop
812 
813  gMessMgr->Info() << "Trim() : saving " << iV0s <<
814  " V0 candidates" << endm;
815 }
816 //_____________________________________________________________________________
817 void StV0FinderMaker::ExpandVectors(unsigned short size) {
818  unsigned int oldsize = trk.size();
819  unsigned int newsize = oldsize;
820  if (newsize > size) newsize = BLOCK;
821  while (newsize <= size) newsize += BLOCK;
822  if (newsize == oldsize) return;
823  gMessMgr->Info() << IsA()->GetName() << "::ExpandVectors(" << newsize
824  << ") for " << GetName() << endm;
825  trk.resize(newsize);
826  hits.resize(newsize);
827  detId.resize(newsize);
828  pt.resize(newsize);
829  ptot.resize(newsize);
830  heli.resize(newsize);
831  trkID.resize(newsize);
832 }
833 //_____________________________________________________________________________
834 // $Id: StV0FinderMaker.cxx,v 1.36 2016/12/12 17:18:04 smirnovd Exp $
835 // $Log: StV0FinderMaker.cxx,v $
836 // Revision 1.36 2016/12/12 17:18:04 smirnovd
837 // Removed outdated ClassImp ROOT macro
838 //
839 // Revision 1.35 2015/07/20 18:03:15 genevb
840 // isnan => std::isnan
841 //
842 // Revision 1.34 2013/02/22 18:37:39 perev
843 // Cleanu
844 //
845 // Revision 1.33 2013/02/22 17:06:10 fisyak
846 // Remove reference to gufld, which is not used
847 //
848 // Revision 1.32 2008/03/05 04:20:18 genevb
849 // Change to DB table of V0FinderParameters, reduce logger output, improve Bfield calc
850 //
851 // Revision 1.31 2006/06/12 15:17:48 caines
852 // Fix chisq flagging so chisq set for SVT even when sti and v02 flags are used
853 //
854 // Revision 1.30 2005/02/10 02:51:09 jeromel
855 // Correct Zero field protection (broke V0/kink)
856 //
857 // Revision 1.29 2005/02/09 21:10:01 perev
858 // test for zero field fixed
859 //
860 // Revision 1.28 2005/02/05 01:10:16 perev
861 // Zero field check
862 //
863 // Revision 1.27 2004/09/17 03:14:06 perev
864 // LeakOff+cleanup
865 //
866 // Revision 1.26 2004/08/27 05:37:28 genevb
867 // Slightly modify parameters of vector memory control
868 //
869 // Revision 1.25 2004/08/26 03:00:46 genevb
870 // Improved vector size management
871 //
872 // Revision 1.24 2004/08/23 23:14:53 genevb
873 // Use resize() for vectors, and allow downsizing.
874 //
875 // Revision 1.23 2004/08/11 21:26:38 genevb
876 // Trade static arrays for vectors
877 //
878 // Revision 1.22 2004/04/15 19:41:35 jeromel
879 // Mainly undo recent patch which is logically right (but over-estimate actual coding standards)
880 //
881 // Revision 1.21 2004/04/13 19:50:38 caines
882 // Remove cut on v0 being before hit as thsi hurts vos from xi in svt
883 //
884 // Revision 1.20 2004/04/06 14:05:16 faivre
885 // Change default options to : do not use SVT.
886 //
887 // Revision 1.19 2004/04/02 08:57:23 faivre
888 // Use actual TPT flag rather than "not ITTF" for TPT tracks. Minor changes.
889 //
890 // Revision 1.18 2004/03/04 18:31:03 faivre
891 // Add cut number of hits for Xi's bachelors.
892 //
893 // Revision 1.17 2004/02/16 16:18:39 betya
894 // added a check on (!triGeom) in V0Finder::Prepare()
895 //
896 // Revision 1.16 2004/02/03 09:52:45 faivre
897 // Update user-friendliness ; default options now use SVT and ITTF+TPT ; remove warning.
898 //
899 // Revision 1.15 2004/01/27 17:56:05 betya
900 //
901 // added EventModelUsage so that the V0Finder and XiFinder can no run on
902 // MuDst as well as on StEvent. Note that the output is still in the StEvent
903 // format. Added Clear() in StV0FinderMaker.cxx to accomodate this addition.
904 //
905 // Revision 1.14 2003/11/08 18:25:54 faivre
906 // Bfield + consistency int/short
907 //
908 // Revision 1.13 2003/09/17 12:00:31 faivre
909 // RH8 : initialize everything in constructor.
910 //
911 // Revision 1.12 2003/09/07 03:49:04 perev
912 // gcc 3.2 + WarnOff
913 //
914 // Revision 1.11 2003/09/02 17:58:59 perev
915 // gcc 3.2 updates + WarnOff
916 //
917 // Revision 1.10 2003/08/22 17:47:14 caines
918 // Get sign AND magnitude of mag field correctly for Xi and V0 finder
919 //
920 // Revision 1.9 2003/07/17 17:01:10 faivre
921 // Add one causality check. Exhaustive listing of cuts. Tab->spaces.
922 //
923 // Revision 1.8 2003/07/15 17:40:36 faivre
924 // Fixed charge of Bfield (used for print, and XiFinder since now).
925 //
926 // Revision 1.7 2003/07/04 17:52:54 faivre
927 // Use SVT cuts if any dg has a SVT hit.
928 //
929 // Revision 1.6 2003/06/24 16:20:01 faivre
930 // Uses SVT tracks. Fixed bool calculations. Exits when bad param. Reshaping.
931 //
932 // Revision 1.5 2003/05/14 19:15:03 faivre
933 // Fancy choices Fortran/C++ V0's and Xi's. SVT tracks.
934 //
935 // Revision 1.4 2003/05/02 21:21:08 lbarnby
936 // Now identify ITTF tracks by fittingMethod() equal to kITKalmanFitId
937 //
938 // Revision 1.3 2003/04/30 20:38:22 perev
939 // Warnings cleanup. Modified lines marked VP
940 //
941 // Revision 1.2 2003/04/30 19:14:27 faivre
942 // ITTF vs TPT V0s
943 //
944 //
virtual void Clear(Option_t *option="")
User defined functions.
virtual Int_t Prepare()
StMuDst * muDst()
Definition: StMuDstMaker.h:425
virtual void AddData(TDataSet *data, const char *dir=".data")
User methods.
Definition: StMaker.cxx:332
virtual Int_t Make()
static StMuEvent * event()
returns pointer to current StMuEvent (class holding the event wise information, e.g. event number, run number)
Definition: StMuDst.h:320
virtual const char * GetName() const
special overload
Definition: StMaker.cxx:237
Definition: Stypes.h:42
StEvent * createStEvent()
creates a StEvent from the StMuDst (this) and returns a pointer to it. (This function is not yet fini...
Definition: StMuDst.cxx:702
virtual void GetPars()
Definition: Stypes.h:44
Definition: Stypes.h:41