13 #include "TGeant3TGeo.h"
16 #include "TDatabasePDG.h"
17 #include "TGeoTorus.h"
18 #include "TMatrixFSym.h"
19 #include "TVirtualMC.h"
30 : TNamed(
"Geane",
"Propagate Tracks"),
34 fdbPDG(TDatabasePDG::Instance()),
41 fpoint(TVector3(0., 0., 0.)),
42 fwire1(TVector3(0., 0., 0.)),
43 fwire2(TVector3(0., 0., 0.)),
47 fvpf(TVector3(0., 0., 0.)),
48 fvwi(TVector3(0., 0., 0.)),
55 std::cerr<<
"FairGeanePro::TGeant3 has not been initialized! ABORTING!"<<std::endl;
81 for(
int i = 0; i < 5; i++)
for(
int j = 0; j < 5; j++) {
trpmat[i][j] = 0.; }
86 for(
int i = 0; i < 15; i++) {
137 Double_t fCov[15], fCovOut[15];
141 Double_t Q = TParam->
GetQ();
142 if (fabs(Q)>1.E-8) { ch= int (Q/TMath::Abs(Q)); }
145 for(Int_t i=0; i<15; i++) {
158 }
else if(
fPCA != 0) {
164 Double_t maxdistance = 0;
167 Double_t distance1, distance2;
170 if(distance1 < distance2) { maxdistance = distance2; }
171 else { maxdistance = distance1; }
176 Int_t findpca =
FindPCA(
fPCA, PDG,
fpoint,
fwire1,
fwire2, maxdistance,
fRad,
fvpf,
fvwi,
fDi,
ftrklength);
177 if(findpca != 0) {
return kFALSE; }
185 cout <<
"Propagate Helix parameter to Plane is not implimented yet" << endl;
189 if(
Propagate(PDG)==kFALSE) {
return kFALSE; }
191 for(Int_t i=0; i<15; i++) {
193 if(i == 0) { fCovOut[i] = fCovOut[i] * ch * ch; }
194 if(i > 0 && i < 5) { fCovOut[i] = fCovOut[i] * ch; }
198 if(fabs(
p2[0]) < 1
e-9 && fabs(
p2[1]) < 1
e-9 && fabs(
p2[2]) < 1
e-9) {
return kFALSE; }
206 cout <<
"FairGeanePro::Propagate(FairTrackParP *TParam, FairTrackParH &TEnd, Int_t PDG) : (not used nor implemented)" << endl;
214 Double_t fCov[15], fCovOut[15];
220 Double_t Q = TStart->
GetQ() ;
221 if (Q!=0) { ch= int (Q/TMath::Abs(Q)); }
224 cout <<
"Propagate Parabola parameter to Volume is not implimented yet" << endl;
228 for(Int_t i=0; i<15; i++) {
235 if(
fPCA == 0) { cout <<
"Propagate Parabola to Parabola in Length not yet implemented" << endl; }
242 Double_t maxdistance = 0;
245 Double_t distance1, distance2;
248 if(distance1 < distance2) { maxdistance = distance2; }
249 else { maxdistance = distance1; }
254 Int_t findpca =
FindPCA(
fPCA, PDG,
fpoint,
fwire1,
fwire2, maxdistance,
fRad,
fvpf,
fvwi,
fDi,
ftrklength);
256 if(findpca != 0) {
return kFALSE; }
264 TVector3 fromwiretoextr =
fvpf -
fvwi;
265 fromwiretoextr.SetMag(1.);
266 if(fabs(fromwiretoextr.Mag()-1)>1E-4) {
267 std::cerr<<
"fromwire.Mag()!=1"<<std::endl;
276 wiredirection=
mom.Cross(fromwiretoextr);
278 wiredirection.SetMag(1.);
280 if(fabs(fromwiretoextr * wiredirection) > 1
e-3) {
286 TVector3 jver = TStart->
GetJVer();;
287 TVector3 kver = TStart->
GetKVer();
288 Bool_t backtracking = kFALSE;
289 if(
fPropOption.Contains(
"B")) { backtracking = kTRUE; }
300 if(
Propagate(PDG)==kFALSE) {
return kFALSE; }
303 for(Int_t i=0; i<15; i++) {
305 if(i == 0) { fCovOut[i] = fCovOut[i] * ch * ch; }
306 if(i > 0 && i < 5) { fCovOut[i] = fCovOut[i] * ch; }
316 if(fabs(
p2[0]) < 1
e-9 && fabs(
p2[1]) < 1
e-9 && fabs(
p2[2]) < 1
e-9) {
return kFALSE; }
318 TEnd->
SetTrackPar(
x2[0],
x2[1],
x2[2],
p2[0],
p2[1],
p2[2], ch ,fCovOut, origin, di, dj, dk);
328 cout <<
"FairGeanePro::Propagate(FairTrackParH *TParam, FairTrackParP &TEnd, Int_t PDG) not implemented" << endl;
340 if(X2[0]<-1.E29) {
return kFALSE; }
341 if(
gMC3->IsTrackOut()) {
return kFALSE; }
354 if(
x2[0]<-1.E29) {
return kFALSE; }
356 if(
gMC3->IsTrackOut()) {
return kFALSE; }
362 for(
int i = 0; i < 25; i++) {
392 TVector3 v1u=v1.Unit();
393 TVector3 v2u=v2.Unit();
408 TVector3 v1u=v1.Unit();
409 TVector3 v2u=v2.Unit();
423 TVector3
v3=v1u.Cross(v2u);
437 for(Int_t i=0; i<15; i++) {
ein[i]=0.00; }
440 if(option==1) {
VEnter=kTRUE; }
487 fvpf = TVector3(0.,0.,0.);
488 fvwi = TVector3(0.,0.,0.);
498 else { cout <<
"FairGeanePro::PropagateToPCA(int, int) ERROR: no direction set" << endl; }
504 fvpf = TVector3(0.,0.,0.);
505 fvwi = TVector3(0.,0.,0.);
516 else { cout <<
"FairGeanePro::ActualFindPCA ERROR: no direction set" << endl; }
522 fvpf = TVector3(0.,0.,0.);
523 fvwi = TVector3(0.,0.,0.);
525 for(Int_t i=0; i<15; i++) {
ein[i]=0.00; }
538 fvpf = TVector3(0.,0.,0.);
539 fvwi = TVector3(0.,0.,0.);
553 fvpf = TVector3(0.,0.,0.);
554 fvwi = TVector3(0.,0.,0.);
568 fvpf = TVector3(0.,0.,0.);
569 fvwi = TVector3(0.,0.,0.);
576 int FairGeanePro::FindPCA(Int_t pca, Int_t PDGCode, TVector3
point, TVector3 wire1, TVector3 wire2, Double_t maxdistance, Double_t& Rad, TVector3& vpf, TVector3& vwi, Double_t& Di, Float_t& trklength)
595 Float_t pf[3] = {point.X(), point.Y(), point.Z()};
596 Float_t w1[3] = {wire1.X(), wire1.Y(), wire1.Z()};
597 Float_t w2[3] = {wire2.X(), wire2.Y(), wire2.Z()};
609 Float_t po1[3],po2[3],po3[3];
616 Double_t dist1,dist2;
635 gMC3->SetClose(pca,pf,dst,w1,w2,po1,po2,po3,cl);
640 Float_t stdlength[1] = {maxdistance};
642 gMC3->Eufill(1,
ein, stdlength);
646 if(
x2[0]<-1.E29) {
return 1; }
647 if(
gMC3->IsTrackOut()) {
return 1; }
648 gMC3->GetClose(po1,po2,po3,clen);
654 if(clen[0] == 0 && clen[1] == 0) {
661 if((po1[0] == po2[0] && po1[1] == po2[1] && po1[2] == po2[2])
662 || (po2[0] == po3[0] && po2[1] == po3[1] && po2[2] == po3[2])) {
664 Track2ToPoint(TVector3(po1),TVector3(po3),TVector3(pf),vpf,Di,Le,quitFlag);
665 if(quitFlag!=0) {std::cerr<<
"ABORT"<<std::endl;
return 1;}
667 Track3ToPoint(TVector3(po1),TVector3(po2),TVector3(po3),TVector3(pf),vpf,flg,Di,Le,Rad);
670 Track2ToPoint(TVector3(po1),TVector3(po3),TVector3(pf),vpf,Di,Le,quitFlag);
671 if(quitFlag!=0) {std::cerr<<
"ABORT"<<std::endl;
return 1;}
672 }
else if(flg==2) {std::cerr<<
"ABORT"<<std::endl;
return 1;}
677 }
else if(pca == 2) {
678 if((po1[0] == po2[0] && po1[1] == po2[1] && po1[2] == po2[2])
679 || (po2[0] == po3[0] && po2[1] == po3[1] && po2[2] == po3[2])) {
681 TVector3(w2),vpf,vwi,flg,Di,Le);
683 dist1 = (vwi-TVector3(w1)).Mag();
684 dist2 = (vwi-TVector3(w2)).Mag();
686 dist1<dist2?
Track2ToPoint(TVector3(po1),TVector3(po3),TVector3(w1),vpf,Di,Le,quitFlag):
687 Track2ToPoint(TVector3(po1),TVector3(po3),TVector3(w2),vpf,Di,Le,quitFlag);
688 if(quitFlag!=0) {std::cerr<<
"ABORT"<<std::endl;
return 1;}
690 std::cerr<<
"ABORT"<<std::endl;
695 TVector3(w1),TVector3(w2),vpf,vwi,flg,Di,Le,Rad);
698 TVector3(w2),vpf,vwi,flg,Di,Le);
700 dist1 = (vwi-TVector3(w1)).Mag();
701 dist2 = (vwi-TVector3(w2)).Mag();
703 dist1<dist2?
Track2ToPoint(TVector3(po1),TVector3(po3),TVector3(w1),vpf,Di,Le,quitFlag):
704 Track2ToPoint(TVector3(po1),TVector3(po3),TVector3(w2),vpf,Di,Le,quitFlag);
705 if(quitFlag!=0) {std::cerr<<
"ABORT"<<std::endl;
return 1;}
707 std::cerr<<
"ABORT"<<std::endl;
711 dist1 = (vwi-TVector3(w1)).Mag();
712 dist2 = (vwi-TVector3(w2)).Mag();
714 dist1<dist2?
Track3ToPoint(TVector3(po1),TVector3(po2),TVector3(po3),TVector3(w1),vpf,flg,Di,Le,Rad):
715 Track3ToPoint(TVector3(po1),TVector3(po2),TVector3(po3),TVector3(w2),vpf,flg,Di,Le,Rad);
716 if(flg==2) {std::cerr<<
"ABORT"<<std::endl;
return 1;}
718 dist1 = (vwi-TVector3(w1)).Mag();
719 dist2 = (vwi-TVector3(w2)).Mag();
721 dist1<dist2?
Track2ToPoint(TVector3(po1),TVector3(po3),TVector3(w1),vpf,Di,Le,quitFlag):
722 Track2ToPoint(TVector3(po1),TVector3(po3),TVector3(w2),vpf,Di,Le,quitFlag);
723 if(quitFlag!=0) {std::cerr<<
"ABORT"<<std::endl;
return 1;}
726 TVector3(w2),vpf,vwi,flg,Di,Le);
728 std::cerr<<
"ABORT"<<std::endl;
738 trklength = clen[0]+Le;
741 if(trklength<0) {
return 1; }
749 TVector3 w2, TVector3& Pfinal, TVector3& Pwire,
750 Int_t& Iflag, Double_t& Dist, Double_t& Length)
780 TVector3 x21, x32, w21;
783 Double_t a1, b1,
c1, d1, e1,
t1,
s1;
786 Double_t Eps = 1.E-08;
803 Delta1 = a1*c1-b1*b1;
806 t1 = (a1*e1-b1*d1)/Delta1;
807 s1 = (b1*e1-c1*d1)/Delta1;
809 Pfinal = (X1 + x21*
s1);
810 Pwire = (w1 + w21*
t1);
811 Length = s1*x21.Mag();
812 Dist= (Pfinal-Pwire).Mag();
816 Pfinal.SetXYZ(0.,0.,0.);
817 Pwire.SetXYZ(0.,0.,0.);
824 if((((Pwire[0]<w1[0] && Pwire[0]<w2[0]) || (w2[0]<Pwire[0] && w1[0]<Pwire[0]))
825 && (fabs(Pwire[0]-w1[0]) > 1
e-11 && fabs(Pwire[0]- w2[0]) > 1
e-11))
826 || (((Pwire[1]<w1[1] && Pwire[1]<w2[1]) || (w2[1]<Pwire[1] && w1[1]<Pwire[1]))
827 && (fabs(Pwire[1]-w1[1]) > 1
e-11 && fabs(Pwire[1]- w2[1]) > 1
e-11))
828 || (((Pwire[2]<w1[2] && Pwire[2]<w2[2]) || (w2[2]<Pwire[2] && w1[2]<Pwire[2]))
829 && (fabs(Pwire[2]-w1[2]) > 1
e-11 && fabs(Pwire[2]- w2[2]) > 1
e-11))) {
837 Double_t& Dist, Double_t& Length, Int_t& quitFlag)
863 Double_t
d=(X2-X1).Mag();
870 u21 = (X2-X1).Unit();
873 Dist= ((w1-X1).Cross(u21)).Mag();
874 t1 = a*(w1-X1).Dot(u21);
875 Pfinal = (X2-X1)*t1 + X1;
876 Length = (X2-X1).Mag()*
t1;
881 TVector3 w1, TVector3 w2,
883 TVector3& Pfinal, TVector3&
Wire,
884 Int_t& Iflag, Double_t& Dist,
885 Double_t& Length, Double_t& Radius)
923 TVector3 xp1, xp2, xp3, xp32;
925 TVector3 e1, e2, e3, aperp;
926 TVector3 Ppfinal, Pwire;
927 TVector3 wp1, wp2, wpt, xR, xpR;
931 Double_t
T[3][3], TM1[3][3];
933 TVector3
N,
M, D, B, Pointw;
934 Double_t a0, a1, b0, b1, c0,
c1,
c2;
935 Double_t d0, d1, d2, d3, d4, sol4[4], dmin;
953 if(e3.Mag() < 1
e-8) {
969 for(Int_t i=0; i<3; i++) {
976 for(Int_t i=0; i<3; i++) {
978 for(Int_t j=0; j<3; j++) {
980 xp2[i] += T[i][j] * (X2[j]-X1[j]);
981 xp3[i] += T[i][j] * (X3[j]-X1[j]);
982 wp1[i] += T[i][j] * (w1[j]-X1[j]);
983 wp2[i] += T[i][j] * (w2[j]-X1[j]);
991 if(fabs(xp3[1])<1.E-8) {
995 xpR[1] = 0.5*(xp32[0]*xp3[0]/xp3[1]+ xp3[1]);
997 Radius = sqrt(pow(xpR[0]-xp1[0],2)+pow(xpR[1]-xp1[1],2));
1008 b0 = M.Dot(D) -(N.Dot(M))*(N.Dot(D));
1009 b1 = M.Dot(M) -(N.Dot(M))*(N.Dot(M));
1010 c0 = D.Dot(D) -(N.Dot(D))*(N.Dot(D));
1014 d0 = a0*a0*c0 -b0*b0*Radius*Radius;
1015 d1 = 2.*(a0*a1*c0+a0*a0*c1-b0*b1*Radius*Radius);
1016 d2 = a1*a1*c0+4.*a0*a1*c1+a0*a0*c2-b1*b1*Radius*Radius;
1017 d3 = 2.*(a1*a1*c1+a0*a1*
c2);
1021 for(Int_t
k=0;
k<4;
k++) {
1024 if(fabs(d4) < 1.E-12) {
1030 it = t.SolveQuartic(d3/d4,d2/d4,d1/d4,d0/d4,sol4);
1040 for(Int_t j=0; j<
it; j++) {
1041 Pointw[0] = B[0] + sol4[j]*M[0];
1042 Pointw[1] = B[1] + sol4[j]*M[1];
1043 Pointw[2] = B[2] + sol4[j]*M[2];
1044 Track3ToPoint(xp1,xp2,xp3, Pointw, px, Iflag, dx, Length, Radius);
1056 Pwire[0] = B[0] + sol4[imin]*M[0];
1057 Pwire[1] = B[1] + sol4[imin]*M[1];
1058 Pwire[2] = B[2] + sol4[imin]*M[2];
1059 Track3ToPoint(xp1,xp2,xp3, Pwire, px, Iflag, dx, Length, Radius);
1084 for(Int_t i=0; i<3; i++) {
1085 for(Int_t j=0; j<3; j++) {
1086 Pfinal[i] += TM1[i][j] * Ppfinal[j];
1087 Wire[i] += TM1[i][j] * Pwire[j];
1088 xR[i] += TM1[i][j] * xpR[j];
1095 double dx1=(X1-xR).Mag();
1096 double dx2=(Pfinal-xR).Mag();
1097 double dx12=dx1*dx2;
1098 if(fabs(dx12)<1.E-8) {
1104 Angle = TMath::ACos((X1-xR).Dot(Pfinal-xR)/(dx12));
1105 Length = Radius*Angle;
1106 if((X2-X1).Dot(Pfinal-X1) < 0.) { Length = -Length; }
1110 if(Radius>1E-8) { epsi = Radius*(1.-TMath::Cos(0.5*(X3-X1).Mag()/Radius)); }
1111 if(epsi < 0.0020) { Iflag=1; }
1114 if((((Wire[0]<w1[0] && Wire[0]<w2[0]) || (w2[0]<Wire[0] && w1[0]<Wire[0]))
1115 && (fabs(Wire[0]-w1[0]) > 1
e-11 && fabs(Wire[0]- w2[0]) > 1
e-11))
1116 || (((Wire[1]<w1[1] && Wire[1]<w2[1]) || (w2[1]<Wire[1] && w1[1]<Wire[1]))
1117 && (fabs(Wire[1]-w1[1]) > 1
e-11 && fabs(Wire[1]- w2[1]) > 1
e-11))
1118 || (((Wire[2]<w1[2] && Wire[2]<w2[2]) || (w2[2]<Wire[2] && w1[2]<Wire[2]))
1119 && (fabs(Wire[2]-w1[2]) > 1
e-11 && fabs(Wire[2]- w2[2]) > 1
e-11))) {
1126 TVector3& Pfinal, Int_t& Iflag,
1127 Double_t& Dist, Double_t& Length, Double_t& Radius)
1155 TVector3 xp1, xp2, xp3, xp32;
1157 TVector3 e1, e2, e3;
1158 TVector3 Ppfinal, x32;
1159 TVector3 wp1, wpt, xR, xpR;
1162 TVector3 xc1, xc2, xc3, wc1;
1164 Double_t m1,
m3, Rt;
1165 Double_t
T[3][3], TM1[3][3];
1177 Double_t x21mag=x21.Mag();
1193 if(e3.Mag() < 1
e-8) {
1210 for(Int_t i=0; i<3; i++) {
1216 for(Int_t i=0; i<3; i++) {
1217 for(Int_t j=0; j<3; j++) {
1218 TM1[i][j] = T[j][i];
1220 xp2[i] += T[i][j] * (X2[j]-X1[j]);
1221 xp3[i] += T[i][j] * (X3[j]-X1[j]);
1222 wp1[i] += T[i][j] * (w1[j]-X1[j]);
1229 xpR[0] = 0.5*xp2[0];
1230 if(fabs(xp3[1])<1.E-8) {
1234 xpR[1] = 0.5*(xp32[0]*xp3[0]/xp3[1]+ xp3[1]);
1237 Radius = sqrt( pow(xpR[0]-xp1[0],2) + pow(xpR[1]-xp1[1],2) );
1243 Double_t dwp=(wpt-xpR).Mag();
1244 if(fabs(dwp)<1.E-8) {
1249 Ppfinal = (wpt-xpR)*Rt + xpR;
1250 Dist = (wp1-Ppfinal).Mag();
1261 for(Int_t i=0; i<3; i++) {
1262 for(Int_t j=0; j<3; j++) {
1263 Pfinal[i] += TM1[i][j] * Ppfinal[j];
1264 xR[i] += TM1[i][j] * xpR[j];
1271 double dx1=(X1-xR).Mag();
1272 double dx2=(Pfinal-xR).Mag();
1273 double dx12=dx1*dx2;
1274 if(fabs(dx12)<1.E-8) {
1279 Angle = TMath::ACos((X1-xR).Dot(Pfinal-xR)/(dx12));
1280 Length = Radius*Angle;
1284 if(Radius>1E-8) { epsi = Radius*(1.-TMath::Cos(0.5*(X3-X1).Mag()/Radius)); }
1285 if(epsi < 0.0020) { Iflag=1; }
1290 for(
int i = 0; i < 5; i++)
for(
int j = 0; j < 5; j++) { trm[i][j] =
trpmat[i][j]; }