12 #include "StV0FinderMaker.h"
13 #include "StMessMgr.h"
14 #include "StEvent/StEventTypes.h"
17 #include "tables/St_V0FinderParameters_Table.h"
21 #include "StEvent/StTrack.h"
22 #include "StMuDSTMaker/COMMON/StMuTypes.hh"
25 #include "math_constants.h"
26 #include "phys_constants.h"
27 #include "SystemOfUnits.h"
29 static const int BLOCK=1024;
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)
60 gMessMgr->Warning() <<
"(" << name <<
61 ") : MORE THAN ONE INSTANCE!" << endm;
62 else mInstance =
this;
79 StV0FinderMaker::~StV0FinderMaker() {
96 TDataSet* dbDataSet = GetDataBase(
"Calibrations/tracker");
99 "Init() : could not find Calibrations/tracker database.");
102 v0pars = (St_V0FinderParameters*) (dbDataSet->FindObject(
"V0FinderParameters"));
105 "Init() : could not find V0FinderParameters in database.");
124 Int_t StV0FinderMaker::Init()
127 if ((useTracker!=kTrackerUseTPT) && (useTracker!=kTrackerUseITTF) && (useTracker!=kTrackerUseBOTH))
128 {gMessMgr->Error(
"Init() : wrong TrackerUsage parameter set.");
131 if ((useSVT!=kNoSVT) && (useSVT!=kUseSVT))
132 {gMessMgr->Error(
"Init() : wrong SVTUsage parameter set.");
135 if ((useEventModel!=kUseStEvent) && (useEventModel!=kUseMuDst))
136 {gMessMgr->Error(
"Init() : wrong EventModelUsage parameter set.");
139 if ((useLikesign!=kLikesignUseStandard) && (useLikesign!=kLikesignUseLikesign))
140 {gMessMgr->Error(
"Init() : wrong LikesignUsage parameter set.");
143 if ((useRotating!=kRotatingUseStandard) && (useRotating!=kRotatingUseRotating) && (useRotating!=kRotatingUseSymmetry) && (useRotating!=kRotatingUseRotatingAndSymmetry))
144 {gMessMgr->Error(
"Init() : wrong RotatingUsage parameter set.");
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;
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);
168 {
case kLanguageUseOldRun : gMessMgr->Info()<<
"Fortran run."<<endm;
170 case kLanguageUseRun : gMessMgr->Info()<<
"C++ run."<<endm;
171 gMessMgr->Info()<<
"BE CAREFUL : you are NOT running the XiFinder !"<<endm;
173 case kLanguageUseTestV0Finder : gMessMgr->Info()<<
"Test V0Finder."<<endm;
175 case kLanguageUseTestXiFinder : gMessMgr->Info()<<
"Test XiFinder."<<endm;
176 gMessMgr->Info()<<
"BE CAREFUL : you are NOT running the XiFinder !"<<endm;
178 case kLanguageUseTestBothFinders : gMessMgr->Info()<<
"Test V0Finder and XiFinder."<<endm;
179 gMessMgr->Info()<<
"BE CAREFUL : you are NOT running the XiFinder !"<<endm;
181 case kLanguageUseSpecial :
break;
182 default : gMessMgr->Error(
"Init() : wrong LanguageUsage parameter set.");
185 if ((useV0Language!=kV0LanguageUseFortran) && (useV0Language!=kV0LanguageUseCpp) && (useV0Language!=kV0LanguageUseBoth))
186 {gMessMgr->Error(
"Init() : wrong V0LanguageUsage parameter set.");
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;
197 if(!mMuDstMaker) gMessMgr->Warning(
"Init can't find a valid MuDst");
200 return StMaker::Init();
205 if (prepared)
return kStOk;
207 unsigned short i,j,nNodes,nTrksEstimate;
212 ITTFflag=kITKalmanFitId;
213 TPTflag=kHelix3DIdentifier;
218 if(GetEventUsage()==kUseStEvent){
219 event = (
StEvent*) GetInputDS(
"StEvent");
222 else if(GetEventUsage()==kUseMuDst){
224 if(mu) cout<<
"V0Finder :: found a MuDst"<<endl;
225 if(mu->
event())cout<<
"see a muEvent ... "<<endl;
229 if(event)cout<<
"see a recreated StEvent!"<<endl;
231 Int_t nV0s = mu->GetNV0();
232 cout<<
"the number of existing v0's is "<<nV0s<<endl;
238 {gMessMgr->Warning(
"no StEvent ; skipping event.");
245 {gMessMgr->Warning(
"no primary vertex ; skipping event.");
248 mainv = pvert->position();
250 StSPtrVecTrackNode& theNodes =
event->trackNodes();
251 nNodes = theNodes.size();
254 nTrksEstimate = (
unsigned int) (nNodes*trkNodeRatio);
255 if (nTrksEstimate > trk.size()) ExpandVectors(nTrksEstimate);
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++) {
265 StTrack* tri = theNodes[i]->track(global,j);
269 StTrack* svtTrack = theNodes[i]->track(estGlobal,j);
281 (tri->fittingMethod() != ITTFflag && (GetTrackerUsage() == kTrackerUseITTF)) ||
282 (tri->fittingMethod() == ITTFflag && (GetTrackerUsage() == kTrackerUseTPT)))
continue;
285 if (tri->flag() <= 0)
continue;
288 if (trks >= trk.size()) ExpandVectors(trks+1);
292 Bool_t tpcHit = map.hasHitInDetector(kTpcId);
293 Bool_t silHit = map.hasHitInDetector(kSvtId) ||
294 map.hasHitInDetector(kSsdId);
309 if(!triGeom)
continue;
311 heli[trks] = triGeom->helix();
313 p = triGeom->momentum();
316 ptot[trks] = p.mag();
317 trkID[trks]=tri->key();
320 hits[trks] = map.numberOfHits(kTpcId) +
321 map.numberOfHits(kSvtId) +
322 map.numberOfHits(kSsdId);
324 pars2 = v0pars->GetTable(detId[trks]-1);
325 if (hits[trks] < pars2->n_point)
continue;
328 if (nBfieldRunning<1e2) {
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();
341 if (fabs(Bfield)<1.e-20)
return kStWarn;
342 Bfield = TMath::Sign(Bfield,-1.0*triGeom->charge()*triGeom->helicity());
344 BfieldRunning += Bfield;
347 if (triGeom->charge() > 0) ptrk.push_back(trks);
348 else if (triGeom->charge() < 0) ntrk.push_back(trks);
352 if (nBfieldRunning>0) Bfield = BfieldRunning/nBfieldRunning;
356 if (trks < (trk.size()/2)) {
357 if (trks > trkmax) trkmax = trks;
360 ExpandVectors(trkmax);
368 trkNodeRatio = ((trkNodeRatio*trkNodeRatioCnt)+((
float) trks)/((
float) nNodes)) /
369 (trkNodeRatioCnt + 1.);
372 gMessMgr->Info() <<
"No. of nodes is : "
374 gMessMgr->Info() <<
"No. of tracks is : "
397 TVector2 ri,rj,xci,xcj,tmp2V;
398 double rad_i,rad_j,separation,solution,dxc;
399 double dca_ij,dca_ij1,rmin,dlen,pperpsq,ppmag;
400 double alpha,ptArm_sq,pPosAlongV0,pNegAlongV0;
401 double cosij,sin2ij,t1,t2;
402 unsigned short i,j,ii,jj;
403 pairD paths,paths1,path2;
405 Bool_t doSecond, isPrimaryV0, usedV0;
409 if (! (2&useV0Language))
return kStOk;
411 gMessMgr->Info(
"Make() : Starting...");
415 if (iRes !=
kStOk)
return iRes;
418 StSPtrVecV0Vertex& v0Vertices =
event->v0Vertices();
419 gMessMgr->Info()<<
"coming in I have "<<v0Vertices.size()<<
" V0s."<<endm;
421 if (!(1&useV0Language)) {
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;
436 int nii = ptrk.size();
437 for (ii=0; ii<nii; ii++) {
440 xci.Set(heli[i].xcenter(),heli[i].ycenter());
441 ri.Set(heli[i].origin().x(),heli[i].origin().y());
446 int njj = ntrk.size();
447 for (jj=0; jj<njj; jj++) {
450 if (GetTrackerUsage() == kTrackerUseBOTH)
453 if ((trk[i]->fittingMethod() == ITTFflag) && (trk[j]->fittingMethod() != ITTFflag))
continue;
455 if ((trk[i]->fittingMethod() != ITTFflag) && (trk[j]->fittingMethod() == ITTFflag))
continue;
459 det_id_v0 = TMath::Max(detId[i],detId[j]);
462 pars = v0pars->GetTable(det_id_v0+2);
464 pars2 = v0pars->GetTable(det_id_v0-1);
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;
479 xcj.Set(heli[j].xcenter(),heli[j].ycenter());
480 rj.Set(heli[j].origin().x(),heli[j].origin().y());
486 separation = dxc - (rad_i + rad_j);
494 if (dxc < TMath::Abs(rad_i - rad_j))
continue;
499 path2 = heli[i].pathLength(rad_j,xcj.X(),xcj.Y());
501 if (!std::isnan(path2.first))
502 {solution = path2.first;
503 if ((!std::isnan(path2.second)) && (path2.second != path2.first))
506 goto ProcessSolution;
508 else if (std::isnan(path2.second))
514 solution = path2.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);
525 else if (separation < pars2->dca)
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);
539 dca_ij = xi.z() - xj.z();
548 if ((dca_ij1 != -9999) &&
549 (TMath::Abs(dca_ij1) < TMath::Abs(dca_ij))) {
559 pi = heli[i].momentumAt(paths.first ,Bfield);
560 pj = heli[j].momentumAt(paths.second,Bfield);
563 if ((pi.dot(xi-mainv) < 0.0) ||
564 (pj.dot(xj-mainv) < 0.0))
continue;
580 cosij = pi1.dot(pj1);
581 sin2ij = 1.0 - cosij*cosij;
583 temp = dca_ij/sin2ij;
584 t1 = (-pi1.z()+pj1.z()*cosij)*temp;
585 t2 = ( pj1.z()-pi1.z()*cosij)*temp;
587 temp = rad_i*(ptot[i]/pt[i]);
588 temp *= sin(t1/temp);
589 xi1 = xi + pi1.pseudoProduct(temp,temp,t1);
591 temp = rad_j*(ptot[j]/pt[j]);
592 temp *= sin(t2/temp);
593 xj1 = xj + pj1.pseudoProduct(temp,temp,t2);
595 dca_ij1 = (xi1 - xj1).mag2();
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) {
609 pi = heli[i].momentumAt(paths.first ,Bfield);
610 pj = heli[j].momentumAt(paths.second,Bfield);
637 if (dca_ij >= (pars2->dca*pars2->dca))
continue;
640 pperpsq = pp.perp2();
643 if ((pperpsq < pars2->dcapn_pt * pars2->dcapn_pt) &&
644 ((trk[i]->impactParameter() <= pars2->dcapnmin) ||
645 (trk[j]->impactParameter() <= pars2->dcapnmin)))
continue;
647 xpp = (xi + xj) * 0.5;
648 impact = xpp - mainv;
649 dlen = impact.mag2();
652 if (dlen <= (pars2->dlen*pars2->dlen))
continue;
655 if (pp.dot(impact) < 0.0)
continue;
657 ppmag = pperpsq + pp.z()*pp.z();
658 rmin = impact.cross(pp).mag2()/ppmag;
661 if (rmin >= (pars2->dcav0*pars2->dcav0))
continue;
663 tmp3V = pp/::sqrt(ppmag);
664 pPosAlongV0 = pi.dot(tmp3V);
665 pNegAlongV0 = pj.dot(tmp3V);
666 alpha = (pPosAlongV0-pNegAlongV0) /
667 (pPosAlongV0+pNegAlongV0);
670 if (TMath::Abs(alpha) > pars2->alpha_max)
continue;
672 ptArm_sq = ptot[i]*ptot[i] - pPosAlongV0*pPosAlongV0;
675 if (ptArm_sq > (pars2->ptarm_max*pars2->ptarm_max))
continue;
678 dca_ij = ::sqrt(dca_ij);
679 if (trk[i]->fittingMethod() == ITTFflag) dca_ij=-dca_ij;
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);
703 keepTrack |=((long)1 << 4);
705 {keepTrack |=((long)1 << 3);
707 if (detId[i]==2 || detId[i]==3){
708 keepTrack |=((long)1 << 2);
710 if(detId[j]==2 || detId[j]==3){
711 keepTrack |=((long)1 << 1);
715 v0Vertex->setChiSquared((
float)keepTrack);
720 (rmin < pars->dcav0) &&
721 ((pperpsq >= pars->dcapn_pt * pars->dcapn_pt) ||
722 ((trk[i]->impactParameter() > pars->dcapnmin) &&
723 (trk[j]->impactParameter() > pars->dcapnmin)));
729 if (usedV0 && !isPrimaryV0)
730 v0Vertex->setDcaParentToPrimaryVertex(-rmin);
733 if (usedV0 || isPrimaryV0) {
734 v0Vertices.push_back(v0Vertex);
743 gMessMgr->Info()<<
"now I have "<<v0Vertices.size()<<
" V0s."<<endm;
744 gMessMgr->Info()<<
"using magnetic field : "<<Bfield/tesla<<
" T."<<endm;
788 void StV0FinderMaker::Trim() {
791 gMessMgr->Info() <<
"Trim() : Starting..." << endm;
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--) {
799 v0Vertex = v0Vertices[i];
802 (v0Vertex->dcaParentToPrimaryVertex() >= 0) &&
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();
813 gMessMgr->Info() <<
"Trim() : saving " << iV0s <<
814 " V0 candidates" << endm;
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;
826 hits.resize(newsize);
827 detId.resize(newsize);
829 ptot.resize(newsize);
830 heli.resize(newsize);
831 trkID.resize(newsize);
virtual void Clear(Option_t *option="")
User defined functions.
virtual void AddData(TDataSet *data, const char *dir=".data")
User methods.
static StMuEvent * event()
returns pointer to current StMuEvent (class holding the event wise information, e.g. event number, run number)
virtual const char * GetName() const
special overload
StEvent * createStEvent()
creates a StEvent from the StMuDst (this) and returns a pointer to it. (This function is not yet fini...