13 #include "TDatabasePDG.h"
15 #include "TMathBase.h"
18 #include <TGenericClassInfo.h>
19 #include <TParticlePDG.h>
20 #include <fairlogger/Logger.h>
28 FairRKPropagator::FairRKPropagator(
FairField* field)
32 , fPropagationFlag(
NONE)
36 , fPCAPropagationType(0)
37 , fPCAPropagationDir(1)
38 , fPCAPropagationPar(nullptr)
49 double FairRKPropagator::GetChargeFromPDG(
int pdg)
51 TDatabasePDG* pdgDB = TDatabasePDG::Instance();
52 return pdgDB->GetParticle(pdg)->Charge() / 3.;
57 if (fPropagationFlag ==
TOPLANE) {
58 float x1[3] = {(float)TStart->
GetX(), (float)TStart->
GetY(), (float)TStart->
GetZ()};
59 float p1[3] = {(float)TStart->
GetPx(), (float)TStart->
GetPy(), (float)TStart->
GetPz()};
60 float x2[3] = {0., 0., 0.};
61 float p2[3] = {0., 0., 0.};
62 bool ret =
Propagate(x1, p1, x2, p2, PDG);
71 TEnd->
SetQp(GetChargeFromPDG(PDG) / sqrt(p2[0] * p2[0] + p2[1] * p2[1] + p2[2] * p2[2]));
80 LOG(warning) <<
"FairRKPropagator::Propagate not implemented yet or plane to propagate not set";
86 if (fPropagationFlag ==
TOPLANE) {
87 float x1[3] = {(float)TStart->
GetX(), (float)TStart->
GetY(), (float)TStart->
GetZ()};
88 float p1[3] = {(float)TStart->
GetPx(), (float)TStart->
GetPy(), (float)TStart->
GetPz()};
89 float x2[3] = {0., 0., 0.};
90 float p2[3] = {0., 0., 0.};
91 bool ret =
Propagate(x1, p1, x2, p2, PDG);
100 TEnd->
SetQp(GetChargeFromPDG(PDG) / sqrt(p2[0] * p2[0] + p2[1] * p2[1] + p2[2] * p2[2]));
109 LOG(warning) <<
"FairRKPropagator::Propagate not implemented yet or plane to propagate not set";
115 if (fPropagationFlag ==
TOPLANE) {
116 float x1[3] = {(float)TStart->
GetX(), (float)TStart->
GetY(), (float)TStart->
GetZ()};
117 float p1[3] = {(float)TStart->
GetPx(), (float)TStart->
GetPy(), (float)TStart->
GetPz()};
118 float x2[3] = {0., 0., 0.};
119 float p2[3] = {0., 0., 0.};
120 bool ret =
Propagate(x1, p1, x2, p2, PDG);
129 TEnd->
SetQp(GetChargeFromPDG(PDG) / sqrt(p2[0] * p2[0] + p2[1] * p2[1] + p2[2] * p2[2]));
138 LOG(warning) <<
"FairRKPropagator::Propagate not implemented yet or plane to propagate not set";
144 if (fPropagationFlag ==
TOPLANE) {
145 float x1[3] = {(float)TStart->
GetX(), (float)TStart->
GetY(), (float)TStart->
GetZ()};
146 float p1[3] = {(float)TStart->
GetPx(), (float)TStart->
GetPy(), (float)TStart->
GetPz()};
147 float x2[3] = {0., 0., 0.};
148 float p2[3] = {0., 0., 0.};
149 bool ret =
Propagate(x1, p1, x2, p2, PDG);
158 TEnd->
SetQp(GetChargeFromPDG(PDG) / sqrt(p2[0] * p2[0] + p2[1] * p2[1] + p2[2] * p2[2]));
167 LOG(warning) <<
"FairRKPropagator::Propagate not implemented yet";
173 double charge = GetChargeFromPDG(PDG);
174 double momIn = TMath::Sqrt(p1[0] * p1[0] + p1[1] * p1[1] + p1[2] * p1[2]);
177 double vecIn[7] = {x1[0], x1[1], x1[2], p1[0] / momIn, p1[1] / momIn, p1[2] / momIn, momIn};
179 double vec1[3] = {fDefPlaneV1.X(), fDefPlaneV1.Y(), fDefPlaneV1.Z()};
180 double vec2[3] = {fDefPlaneV2.X(), fDefPlaneV2.Y(), fDefPlaneV2.Z()};
181 double vec3[3] = {fDefPlaneV0.X(), fDefPlaneV0.Y(), fDefPlaneV0.Z()};
186 p2[0] = vecOut[3] * vecOut[6];
187 p2[1] = vecOut[4] * vecOut[6];
188 p2[2] = vecOut[5] * vecOut[6];
203 LOG(warning) <<
"FairRKPropagator::SetLengthToPropagateTo not implemented yet";
208 [[gnu::unused]]
int copyNo,
209 [[gnu::unused]]
int option)
211 LOG(warning) <<
"FairRKPropagator::SetDestinationVolume not implemented yet";
217 LOG(warning) <<
"FairRKPropagator::SetDestinationLength not implemented yet";
225 LOG(warning) <<
"Set PCA dir to +1 or -1.";
228 fPCAPropagationType = pca;
229 fPCAPropagationDir = dir;
230 fPCAPropagationPar =
par;
240 [[gnu::unused]]
double MaxDistance)
244 if (PCA != 1 && PCA != 2) {
245 LOG(info) <<
"FairRKPropagator::FindPCA implemented for point (pca=1) and wire (pca=2) only";
248 double charge = GetChargeFromPDG(PDGCode);
249 double momIn = fPCAPropagationDir *
250 TMath::Sqrt(fPCAPropagationPar->
GetPx() * fPCAPropagationPar->
GetPx()
251 + fPCAPropagationPar->
GetPy() * fPCAPropagationPar->
GetPy()
252 + fPCAPropagationPar->
GetPz() * fPCAPropagationPar->
GetPz());
255 double vecIn[7] = {fPCAPropagationPar->
GetX(),
256 fPCAPropagationPar->
GetY(),
257 fPCAPropagationPar->
GetZ(),
258 fPCAPropagationPar->
GetPx() / momIn,
259 fPCAPropagationPar->
GetPy() / momIn,
260 fPCAPropagationPar->
GetPz() / momIn,
265 diff = sqrt((vecIn[0] - Point.X()) * (vecIn[0] - Point.X()) + (vecIn[1] - Point.Y()) * (vecIn[1] - Point.Y())
266 + (vecIn[2] - Point.Z()) * (vecIn[2] - Point.Z()));
268 diff = CalculatePointToWireDistance(
269 TVector3(fPCAPropagationPar->
GetX(), fPCAPropagationPar->
GetY(), fPCAPropagationPar->
GetZ()),
274 fMaxStep = diff / 25;
275 double res_old = diff;
279 for (
int i = 0; i < 7; i++) {
288 double stepLength =
Step(charge, vecIn, vecOut);
291 newDiff = sqrt((vecOut[0] - Point.X()) * (vecOut[0] - Point.X())
292 + (vecOut[1] - Point.Y()) * (vecOut[1] - Point.Y())
293 + (vecOut[2] - Point.Z()) * (vecOut[2] - Point.Z()));
295 newDiff = CalculatePointToWireDistance(
296 TVector3(vecOut[0], vecOut[1], vecOut[2]), Wire1, Wire2, pcastruct.
OnWirePCA);
298 res = newDiff / diff;
299 if (TMath::Abs(res) < 0.01 || res > res_old) {
302 for (
int i = 0; i < 7; i++) {
303 vecOutT[i] = vecOut[i];
304 vecIn[i] = vecOut[i];
309 if (nIter++ > 1000) {
314 for (
int k = 0; k < 7; k++) {
315 vecOut[k] = vecOutT[k];
324 sqrt((vecOut[0] - Point.X()) * (vecOut[0] - Point.X()) + (vecOut[1] - Point.Y()) * (vecOut[1] - Point.Y())
325 + (vecOut[2] - Point.Z()) * (vecOut[2] - Point.Z()));
328 CalculatePointToWireDistance(TVector3(vecOut[0], vecOut[1], vecOut[2]), Wire1, Wire2, pcastruct.
OnWirePCA);
335 double FairRKPropagator::CalculatePointToWireDistance(TVector3 point, TVector3 wire1, TVector3 wire2, TVector3& vwi)
337 TVector3 ab = wire2 - wire1;
338 TVector3 av = point - wire1;
340 if (av.Dot(ab) <= 0.0) {
345 TVector3 bv = point - wire2;
347 if (bv.Dot(ab) >= 0.0) {
352 vwi = (ab.Dot(av) / ab.Mag() / ab.Mag()) * ab;
354 return (ab.Cross(av)).Mag() / ab.Mag();
376 for (
int i = 0; i < 7; i++) {
380 Norm[0] = vec1[1] * vec2[2] - vec2[2] * vec2[1];
381 Norm[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
382 Norm[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
384 Mag = TMath::Sqrt(Norm[0] * Norm[0] + Norm[1] * Norm[1] + Norm[2] * Norm[2]);
388 Norm[0] = Norm[0] / Mag;
389 Norm[1] = Norm[1] / Mag;
390 Norm[2] = Norm[2] / Mag;
393 dist[0] = vecRKIn[0] - vec3[0];
394 dist[1] = vecRKIn[1] - vec3[1];
395 dist[2] = vecRKIn[2] - vec3[2];
397 distance[0] = Norm[0] * dist[0];
398 distance[1] = Norm[1] * dist[1];
399 distance[2] = Norm[2] * dist[2];
401 double diff = TMath::Abs(distance[0] + distance[1] + distance[2]);
404 double res_old = 100.0;
413 Step(Charge, vecRKIn, vecRKOut);
414 dist[0] = (vecRKOut[0] - vec3[0]) * Norm[0];
415 dist[1] = (vecRKOut[1] - vec3[1]) * Norm[1];
416 dist[2] = (vecRKOut[2] - vec3[2]) * Norm[2];
417 fMaxStep = TMath::Sqrt(dist[0] * dist[0] + dist[1] * dist[1] + dist[2] * dist[2]);
418 res = TMath::Abs(fMaxStep / diff);
420 if (res < 0.001 || res > res_old) {
423 for (
int i = 0; i < 7; i++) {
424 vecRKIn[i] = vecRKOut[i];
425 vecRKoutT[i] = vecRKOut[i];
429 if (nIter++ > 1000) {
435 for (
int i = 0; i < 7; i++) {
437 vecOut[i] = vecRKoutT[i];
439 vecOut[i] = vecRKOut[i];
446 double diff = Pos[2] - vecRKIn[2];
447 fMaxStep = diff / 25;
448 double res_old = diff;
452 for (
int i = 0; i < 7; i++) {
459 Step(Charge, vecRKIn, vecRKOut);
460 res = (vecRKOut[2] - Pos[2]) / diff;
461 if (TMath::Abs(res) < 0.01 || res > res_old) {
464 for (
int i = 0; i < 7; i++) {
465 vecRKOutT[i] = vecRKOut[i];
466 vecRKIn[i] = vecRKOut[i];
469 if (nIter++ > 1000) {
474 for (
int k = 0; k < 7; k++) {
475 vecRKOut[k] = vecRKOutT[k];
477 for (
int k = 0; k < 3; k++) {
478 printf(
" vecRKOut[%i] =%f ", k, vecRKOut[k]);
487 for (
int i = 0; i < 7; i++) {
494 vecOut[0] = vecRKOut[0];
495 vecOut[1] = vecRKOut[1];
496 vecOut[2] = vecRKOut[2];
497 vecOut[6] = vecRKOut[6];
498 vecOut[3] = vecRKOut[3];
499 vecOut[4] = vecRKOut[4];
500 vecOut[5] = vecRKOut[5];
535 double secxs[4], secys[4], seczs[4];
539 double track_length = 0.;
544 const double hmin = 1e-4;
545 const double kdlt = 1e-6;
546 const double kdlt32 = kdlt / 32.;
547 const double kthird = 1. / 3.;
548 const double khalf = 0.5;
549 const double kec = 2.99792458e-4;
550 const double kpisqua = 9.86960440109;
565 for (
int j = 0; j < 7; j++) {
569 double pinv = kec * charge / vect[6];
574 double rest = step - tl;
576 if (TMath::Abs(h) > TMath::Abs(rest)) {
590 double h2 = khalf * h;
591 double h4 = khalf * h2;
592 double ph = pinv * h;
593 double ph2 = khalf * ph;
597 secxs[0] = (b * f[2] - c * f[1]) * ph2;
598 secys[0] = (c * f[0] - a * f[2]) * ph2;
599 seczs[0] = (a * f[1] - b * f[0]) * ph2;
600 double ang2 = (secxs[0] * secxs[0] + secys[0] * secys[0] + seczs[0] * seczs[0]);
601 if (ang2 > kpisqua) {
605 double dxt = h2 * a + h4 * secxs[0];
606 double dyt = h2 * b + h4 * secys[0];
607 double dzt = h2 * c + h4 * seczs[0];
614 double est = TMath::Abs(dxt) + TMath::Abs(dyt) + TMath::Abs(dzt);
616 if (ncut++ > maxcut) {
629 double at = a + secxs[0];
630 double bt = b + secys[0];
631 double ct = c + seczs[0];
633 secxs[1] = (bt * f[2] - ct * f[1]) * ph2;
634 secys[1] = (ct * f[0] - at * f[2]) * ph2;
635 seczs[1] = (at * f[1] - bt * f[0]) * ph2;
639 secxs[2] = (bt * f[2] - ct * f[1]) * ph2;
640 secys[2] = (ct * f[0] - at * f[2]) * ph2;
641 seczs[2] = (at * f[1] - bt * f[0]) * ph2;
642 dxt = h * (a + secxs[2]);
643 dyt = h * (b + secys[2]);
644 dzt = h * (c + seczs[2]);
648 at = a + 2. * secxs[2];
649 bt = b + 2. * secys[2];
650 ct = c + 2. * seczs[2];
653 est = TMath::Abs(dxt) + TMath::Abs(dyt) + TMath::Abs(dzt);
654 if (est > 2. * TMath::Abs(h)) {
655 if (ncut++ > maxcut) {
668 z = z + (c + (seczs[0] + seczs[1] + seczs[2]) * kthird) * h;
669 y = y + (b + (secys[0] + secys[1] + secys[2]) * kthird) * h;
670 x = x + (a + (secxs[0] + secxs[1] + secxs[2]) * kthird) * h;
672 secxs[3] = (bt * f[2] - ct * f[1]) * ph2;
673 secys[3] = (ct * f[0] - at * f[2]) * ph2;
674 seczs[3] = (at * f[1] - bt * f[0]) * ph2;
675 a = a + (secxs[0] + secxs[3] + 2. * (secxs[1] + secxs[2])) * kthird;
676 b = b + (secys[0] + secys[3] + 2. * (secys[1] + secys[2])) * kthird;
677 c = c + (seczs[0] + seczs[3] + 2. * (seczs[1] + seczs[2])) * kthird;
679 est = TMath::Abs(secxs[0] + secxs[3] - (secxs[1] + secxs[2]))
680 + TMath::Abs(secys[0] + secys[3] - (secys[1] + secys[2]))
681 + TMath::Abs(seczs[0] + seczs[3] - (seczs[1] + seczs[2]));
683 if (est > kdlt && TMath::Abs(h) > hmin) {
684 if (ncut++ > maxcut) {
693 if (iter++ > maxit) {
701 double cba = 1. / TMath::Sqrt(a * a + b * b + c * c);
716 if (rest < 1.e-5 * TMath::Abs(step)) {
virtual Double_t GetPz() const
virtual bool SetDestinationPlane(const TVector3 &v0, const TVector3 &v1, const TVector3 &v2)
virtual PCAOutputStruct FindPCA(int PCA, int PDGCode, TVector3 Point, TVector3 Wire1, TVector3 Wire2, double MaxDistance)
virtual void SetDPy(Double_t dpy)
double Step(double Charge, double *vecRKIn, double *vecOut)
virtual void SetDPz(Double_t dpz)
virtual bool SetDestinationVolume(std::string volName, int copyNo, int option)
virtual void SetPy(Double_t py)
ClassImp(FairEventBuilder)
void Propagate(double Charge, double *vecRKIn, double *Pos)
virtual void SetY(Double_t y)
virtual bool SetPCAPropagation(int pca, int dir=1, FairTrackParP *par=nullptr)
virtual void SetZ(Double_t z)
virtual Double_t GetPx() const
virtual void SetDPx(Double_t dpx)
double OneStepRungeKutta(double charge, double step, double *vect, double *vout)
FairMQExParamsParOne * par
virtual void SetPz(Double_t pz)
virtual void SetPx(Double_t px)
virtual void GetFieldValue(const Double_t point[3], Double_t *bField)
virtual Double_t GetPy() const
virtual void SetX(Double_t x)
virtual void SetDY(Double_t dy)
virtual bool SetDestinationLength(float length)
virtual void SetDX(Double_t dx)
virtual bool SetOriginPlane(const TVector3 &v0, const TVector3 &v1)
virtual void SetDZ(Double_t dz)
virtual ~FairRKPropagator()
void PropagateToPlane(double Charge, double *vecRKIn, double *vec1, double *vec2, double *vec3, double *vecOut)