13 #include "StMemStat.h"
14 #include "StKinkMaker.h"
15 #include "StKinkLocalTrack.hh"
16 #include "StTrackGeometry.h"
17 #include "StV0FinderMaker.h"
18 #include "StEvent/StEventTypes.h"
22 #include "tables/St_tkf_tkfpar_Table.h"
23 #include "StMessMgr.h"
25 #include "math_constants.h"
26 #include "phys_constants.h"
28 #include "StThreeVectorF.hh"
29 #include "TObjArray.h"
30 #include "SystemOfUnits.h"
33 #if !defined(ST_NO_NAMESPACES)
34 using namespace units;
37 const double kaonMass= M_KAON_PLUS;
38 const double pionMass= M_PION_PLUS;
39 const double muonMass= M_MUON_PLUS;
40 const double pi0Mass= M_PION_0;
42 const double kaonToMuonQ= 0.236;
43 const double kaonToPionQ= 0.205;
44 const double pionToMuonQ= 0.030;
46 const int MAXNUMOFTRACKS= 10000;
47 const int SIZETRKIDCHECK= 1000;
51 StKinkMaker::StKinkMaker(
const char *name):
StMaker(name),m_tkfpar(0)
56 mParentTrackCandidate=0;
57 mDaughterTrackCandidate=0;
59 mUseTracker = kTrackerUseBOTH;
65 StKinkMaker::~StKinkMaker(){
86 return StMaker::Init();
89 Int_t StKinkMaker::InitRun(
int runumber) {
90 m_tkfpar = (St_tkf_tkfpar*) GetDataBase(
"Calibrations/tracker/tkf_tkfpar");
93 "StKinkMaker::InitRun() : could not find tkf_tkfpar in database.");
96 return StMaker::InitRun(runumber);
103 unsigned short nNodes,i,j;
106 TObjArray trackArray(MAXNUMOFTRACKS);trackArray.SetOwner();
108 tkf_tkfpar_st *tkfpar = m_tkfpar->GetTable();
109 gMessMgr->Info()<<
"StKinkMaker: impact parameter"<<tkfpar->impactCut<<endm;
114 event = (
StEvent*)GetInputDS(
"StEvent");
116 gMessMgr->Warning(
"StKinkMaker:no StEvent;skip event");
123 gMessMgr->Warning(
"StKinkMaker:no primary vertex;skip event");
126 mEventVertex = vrtx->position();
129 StSPtrVecTrackNode& theNodes =
event->trackNodes();
130 nNodes = theNodes.size();
132 for (i=0;i<nNodes;i++){
133 int nj = theNodes[i]->entries(global);
135 StTrack* trk = theNodes[i]->track(global,j);
140 if(!trkGeom)
continue;
148 if (fabs(p22.x()) > 1.e-20) mBfield *= p11.x()/p22.x();
149 else if (fabs(p22.y()) > 1.e-20) mBfield *= p11.y()/p22.y();
152 if (fabs(mBfield) < 1.e-20)
return kStWarn;
157 Float_t trkStartRadius2D = trk->geometry()->origin().perp();
158 Float_t trkEndRadius2D = trk->outerGeometry()->origin().perp();
159 if (trkStartRadius2D < tkfpar->vertexRMin2D &&
160 trkEndRadius2D > tkfpar->vertexRMax2D )
162 if (trkStartRadius2D < tkfpar->vertexRMax2D ||
163 trkEndRadius2D > tkfpar->vertexRMin2D ){
165 trackArray.Add(tempTrack);
173 StSPtrVecKinkVertex& kinkVertices =
event->kinkVertices();
178 kinkVertices.erase(kinkVertices.begin(),kinkVertices.end());
186 if (trackArray.GetEntries() > 0) trackArray.Sort();
187 Int_t kinkCandidate=0;
188 Int_t cutPPt=0,cutPImpact=0,initial=0;
190 int ni=trackArray.GetEntries();
194 mParentTrackCandidate = mTrack1->trackBack();
195 StTrackGeometry* myParentGeometry1 = mParentTrackCandidate->geometry();
196 StTrackGeometry* myParentGeometry11 = mParentTrackCandidate->outerGeometry();
198 double parentPtot = myParentGeometry11->momentum().mag();
199 double parentPt = myParentGeometry11->momentum().perp();
202 if (myParentGeometry1->momentum().perp() < tkfpar->parentPtMin )
continue;
206 mParentImpact = parentHelix.
distance(mEventVertex);
207 if (mParentImpact > tkfpar->impactCut )
continue;
209 Int_t foundDaughters = 0;
210 int nj = trackArray.GetLast()+1;
211 for (j=i+1;j<nj;j++ ){
213 mDaughterTrackCandidate = mTrack2->trackBack();
214 StTrackGeometry* myDaughterGeometry1 = mDaughterTrackCandidate->geometry();
216 double daughterPtot = myDaughterGeometry1->momentum().mag();
217 double daughterPt = myDaughterGeometry1->momentum().perp();
220 if (myParentGeometry1->charge() != myDaughterGeometry1->charge() )
continue;
223 if (myDaughterGeometry1->origin().perp() < tkfpar->vertexRMin2D )
continue;
226 mDaughterImpact = daughterHelix.
distance(mEventVertex);
227 if (mDaughterImpact < mParentImpact)
continue;
230 if (fabs(myDaughterGeometry1->origin().perp() - myParentGeometry11->origin().perp())
231 > tkfpar->parentLastDaughterStart2D )
continue;
232 if (fabs(myDaughterGeometry1->origin().z() - myParentGeometry11->origin().z())
233 > tkfpar->parentLastDaughterStartZ )
continue;
242 pairD paths,path2,paths1;
243 TVector2 r1,r2,xc1 ,xc2,tmp2V;
245 double separation,dxc;
246 double dca_12,dca_12tmp;
248 double distanceOne,distanceTwo;
252 r1.Set(parentHelix.
origin().x(),parentHelix.
origin().y());
257 r2.Set(daughterHelix.
origin().x(),daughterHelix.
origin().y());
263 separation = dxc - (rad_1+rad_2);
270 if (dxc <= TMath::Abs(rad_1-rad_2)){
271 double why = xc1.Y()-((rad_1+rad_2+dxc)*0.5 * (xc1.Y()-xc2.Y()))/dxc;
272 double ecs = xc1.X()-((rad_1+rad_2+dxc)*0.5 * (xc1.X()-xc2.X()))/dxc;
273 paths.first = parentHelix.
pathLength(ecs,why);
274 paths.second = daughterHelix.
pathLength(ecs,why);
275 x1 = parentHelix.at(paths.first);
276 x2 = daughterHelix.at(paths.second);
277 dca_12=x1.z()-x2.z();
281 path2 = parentHelix.
pathLength(rad_2,xc2.X(),xc2.Y());
282 if (!std::isnan(path2.first)){
283 paths.first = path2.first;
284 x1 = parentHelix.at(paths.first);
285 paths.second = daughterHelix.
pathLength(x1.x(),x1.y());
286 x2 = daughterHelix.at(paths.second);
287 dca_12 = x1.z()-x2.z();
288 distanceOne = (x1-myDaughterGeometry1->origin()).mag();
290 if ((!std::isnan(path2.second))&&(path2.second!=path2.first))
291 { paths1.first = path2.second;
292 x1i = parentHelix.at(paths1.first);
293 paths1.second = daughterHelix.
pathLength(x1i.x(),x1i.y());
294 x2j = daughterHelix.at(paths1.second);
295 distanceTwo = (x2j-myDaughterGeometry1->origin()).mag();
296 dca_12tmp = x1i.z()-x2j.z();
298 if( distanceTwo < distanceOne){
307 }
else if (std::isnan(path2.second))
311 }
else if(separation==0){
312 double why = xc1.Y()-(rad_1 * (xc1.Y()-xc2.Y()))/dxc;
313 double ecs = xc1.X()-(rad_1 * (xc1.X()-xc2.X()))/dxc;
314 paths.first = parentHelix.
pathLength(ecs,why);
315 paths.second = daughterHelix.
pathLength(ecs,why);
316 x1 = parentHelix.at(paths.first);
317 x2 = daughterHelix.at(paths.second);
318 dca_12=x1.z()-x2.z();
319 }
else if ((separation < tkfpar->dcaParentDaughterMax)){
322 tmp2V = (xc1 + xc2) * 0.5;
323 paths.first = parentHelix.
pathLength(tmp2V.X(),tmp2V.Y());
324 paths.second = daughterHelix.
pathLength(tmp2V.X(),tmp2V.Y());
325 x1 = parentHelix.at(paths.first);
326 x2 = daughterHelix.at(paths.second);
327 dca_12=x1.z()-x2.z();
332 if ((x1.perp() > tkfpar->vertexRMax2D)|| (x1.perp() < tkfpar->vertexRMin2D) )
continue;
333 if ((x2.perp() > tkfpar->vertexRMax2D)|| (x2.perp() < tkfpar->vertexRMin2D) )
continue;
335 if (fabs(dca_12) > tkfpar->projectPointZDiff)
continue;
343 mParentMoment = parentHelix.momentumAt(paths.first, mBfield);
344 mDaughterMoment = daughterHelix.momentumAt(paths.second, mBfield);
347 mDecayAngle = (1./degree) * mParentMoment.angle(mDaughterMoment);
348 if (mDecayAngle<tkfpar->thetaMin)
continue;
352 double cos12,sin2_12,t1,t2;
355 p1 = mParentMoment/parentPtot;
356 p2 = mDaughterMoment/daughterPtot;
359 sin2_12 = (1.0 - cos12)*(1.- cos12);
361 temp = dca_12/sin2_12;
362 t1 = (-p1.z()+p2.z()*cos12)*temp;
363 t2 = ( p2.z()-p1.z()*cos12)*temp;
365 temp = rad_1*(parentPtot/parentPt);
366 temp *= sin(t1/temp);
367 x1i = x1 + p1.pseudoProduct(temp,temp,t1);
369 temp = rad_2*(daughterPtot/daughterPt);
370 temp *= sin(t2/temp);
371 x2j = x2 + p2.pseudoProduct(temp,temp,t2);
373 dca_12tmp = (x1i - x2j).mag2();
376 if( dca_12tmp < dca_12){
377 paths.first = parentHelix.
pathLength(x1i.x(),x1i.y());
378 paths.second = daughterHelix.
pathLength(x2j.x(),x2j.y());
379 x1i = parentHelix.at(paths.first);
380 x2j = daughterHelix.at(paths.second);
381 dca_12tmp = (x1i - x2j).mag2();
382 if( dca_12tmp < dca_12){
385 mParentMoment = parentHelix.momentumAt(paths.first, mBfield);
386 mDaughterMoment = daughterHelix.momentumAt(paths.second,mBfield);
398 if (mDca>(tkfpar->dcaParentDaughterMax) )
continue;
402 mKinkVertex = (x1 + x2) * 0.5;
404 dx = mKinkVertex.x() - myParentGeometry11->origin().x();
405 dy = mKinkVertex.y() - myParentGeometry11->origin().y();
406 Float_t distanceKinkParent2D = sqrt(dx*dx+dy*dy );
407 dx = mKinkVertex.x() - myDaughterGeometry1->origin().x();
408 dy = mKinkVertex.y() - myDaughterGeometry1->origin().y();
409 Float_t distanceKinkDaughter2D = sqrt(dx*dx+dy*dy );
410 Float_t distanceKinkParentZ = mKinkVertex.z() - myParentGeometry11->origin().z();
411 Float_t distanceKinkDaughterZ = mKinkVertex.z() - myDaughterGeometry1->origin().z();
414 if (distanceKinkParent2D > tkfpar->distanceKinkParent2D )
continue;
415 if (distanceKinkDaughter2D > tkfpar->distanceKinkDaughter2D )
continue;
416 if (distanceKinkParentZ > tkfpar->distanceKinkParentZ )
continue;
417 if (distanceKinkDaughterZ > tkfpar->distanceKinkDaughterZ )
continue;
419 mDaughterTrackUnic = myDaughterGeometry1;
421 if(foundDaughters!=1)
continue;
424 FillEvent(mDaughterTrackUnic,myParentGeometry11);
425 kinkVertices.push_back(kinkVertex);
430 gMessMgr->Info() <<
"StKinkMaker:: Found " << kinkCandidate <<
" kink candidates " << endm;
438 if(kinkVertices.size()>1) Crop();
450 Float_t deltaKaonMuon = fabs(sqrt(mParentMoment.mag2() + kaonMass*kaonMass) -
451 sqrt(mDaughterMoment.mag2() + muonMass*muonMass) -
452 pMomMinusdMom.mag());
453 Float_t deltaKaonPion = fabs(sqrt(mParentMoment.mag2() + kaonMass*kaonMass) -
454 sqrt(mDaughterMoment.mag2() + pionMass*pionMass) -
455 sqrt(pMomMinusdMom.mag2() + pi0Mass*pi0Mass));
456 Float_t deltaPionMuon = fabs(sqrt(mParentMoment.mag2() + pionMass*pionMass) -
457 sqrt(mDaughterMoment.mag2() + muonMass*muonMass) -
458 pMomMinusdMom.mag());
460 if ((deltaKaonPion < deltaKaonMuon) && (deltaKaonPion < deltaPionMuon) ){
461 Float_t asinArg = (mDaughterMoment.mag() / kaonToPionQ) * sin(mDecayAngle*degree);
462 if (fabs(asinArg) < 1. ) {
463 kinkVertex->setDecayAngleCM(
float((1./degree) * asin(asinArg)));
466 kinkVertex->setDecayAngleCM(999.) ;
468 if( myParentGeometry11->charge() > 0 ){
469 kinkVertex->setGeantIdDaughter(8);
470 kinkVertex->setGeantIdParent(11);
473 kinkVertex->setGeantIdDaughter(9);
474 kinkVertex->setGeantIdParent(12);
477 else if ((deltaKaonMuon < deltaKaonPion) && (deltaKaonMuon < deltaPionMuon) ) {
478 Float_t asinArg = (mDaughterMoment.mag() / kaonToMuonQ) * sin(mDecayAngle*degree);
479 if (fabs(asinArg) < 1. ) {
480 kinkVertex->setDecayAngleCM( (1./degree) * asin(asinArg) );
483 kinkVertex->setDecayAngleCM( 999.) ;
485 if( myParentGeometry11->charge() > 0 ){
486 kinkVertex->setGeantIdDaughter(5);
487 kinkVertex->setGeantIdParent(11);
490 kinkVertex->setGeantIdDaughter(6);
491 kinkVertex->setGeantIdParent(12);
494 Float_t asinArg = (mDaughterMoment.mag() / pionToMuonQ) * sin(mDecayAngle*degree);
495 if( fabs(asinArg) < 1. ) {
496 kinkVertex->setDecayAngleCM( (1./degree) * asin(asinArg) );
499 kinkVertex->setDecayAngleCM( 999.) ;
501 if (myParentGeometry11->charge() > 0 ){
502 kinkVertex->setGeantIdDaughter(5);
503 kinkVertex->setGeantIdParent(8);
506 kinkVertex->setGeantIdDaughter(6);
507 kinkVertex->setGeantIdParent(9);
511 kinkVertex->setDcaParentDaughter(mDca);
512 kinkVertex->setDcaDaughterPrimaryVertex(mDaughterImpact);
513 kinkVertex->setDcaParentPrimaryVertex(mParentImpact);
516 kinkVertex->setHitDistanceParentDaughter( (myDaughterGeometry1->origin() - myParentGeometry11->origin()).mag() );
519 kinkVertex->setHitDistanceParentVertex(sqrt( pow(mKinkVertex.x() - myParentGeometry11->origin().x(), 2) +
520 pow(mKinkVertex.y() - myParentGeometry11->origin().y(), 2) +
521 pow(mKinkVertex.z() - myParentGeometry11->origin().z(), 2)) );
524 kinkVertex->setdE(1,deltaKaonMuon);
525 kinkVertex->setdE(2,deltaKaonPion);
526 kinkVertex->setdE(3,deltaPionMuon);
529 kinkVertex->setParentMomentum(mParentMoment);
530 kinkVertex->setDaughterMomentum(mDaughterMoment);
531 kinkVertex->setParent(mParentTrackCandidate);
534 kinkVertex->setDecayAngle(mDecayAngle);
537 kinkVertex->addDaughter(mDaughterTrackCandidate);
540 kinkVertex->setPosition(mKinkVertex);
564 if (trk->flag() <= 0)
return false;
569 ( trk->fittingMethod() != kITKalmanFitId && (mUseTracker == kTrackerUseTPT || mUseTracker == kTrackerUseBOTH) ) ||
570 ( trk->fittingMethod() == kITKalmanFitId && (mUseTracker == kTrackerUseITTF || mUseTracker == kTrackerUseBOTH) ) ){
598 gMessMgr->Info() <<
"StKinkMaker::SetTrackerUsage : Setting option to " << mUseTracker << endm;
601 void StKinkMaker::Crop(){
603 gMessMgr->Info()<<
"StKinkMaker::Crop() : Starting ...."<<endm;
604 event = (
StEvent *)GetInputDS(
"StEvent");
605 StSPtrVecKinkVertex& kinkVertices =
event->kinkVertices();
610 int iKinks = kinkVertices.size();
613 for(Int_t ikv1=0; ikv1<iKinks-1; ikv1++) {
614 kinkVtxPtr1 = kinkVertices[ikv1];
615 daughterTrk1=kinkVtxPtr1->daughter();
617 for(Int_t ikv2=ikv1+1; ikv2<iKinks; ikv2++) {
619 kinkVtxPtr2 = kinkVertices[ikv2];
620 daughterTrk2=kinkVtxPtr2->daughter();
622 if(daughterTrk1->key() == daughterTrk2->key()) {
623 float decAngKinkVtx1 = kinkVtxPtr1->decayAngle();
624 float decAngKinkVtx2 = kinkVtxPtr2->decayAngle();
625 kinkVtxPtr1->setDecayAngle(decAngKinkVtx1*100+99);
626 kinkVtxPtr2->setDecayAngle(decAngKinkVtx2*100+99);
auxiliary class for the kink finder
virtual void SetTrackerUsage(Int_t opt=0)
double distance(const StThreeVector< double > &p, bool scanPeriods=true) const
minimal distance between point and helix
pair< double, double > pathLength(double r) const
path length at given r (cylindrical r)
double ycenter() const
x-center of circle in xy-plane
void FillEvent(StTrackGeometry *myDaughterGeometry1, StTrackGeometry *myParentGeometry11)
Event filling.
const StThreeVector< double > & origin() const
-sign(q*B);
double xcenter() const
aziumth in xy-plane measured from ring center
bool acceptTrack(StTrack *)