5 #include <phfield/PHFieldUtility.h>
6 #include <phfield/PHFieldConfig_v3.h>
7 #include <phfield/PHField.h>
9 #include <GenFit/FieldManager.h>
10 #include <GenFit/MaterialEffects.h>
11 #include <GenFit/TGeoMaterialInterface.h>
12 #include <GenFit/MeasuredStateOnPlane.h>
13 #include <GenFit/SharedPlanePtr.h>
14 #include <GenFit/RKTrackRep.h>
17 #include <TGeoManager.h>
31 static bool inited =
false;
34 static int NSTEPS_TARGET = 100;
35 static int NSTEPS_SHIELDING = 50;
36 static int NSTEPS_FMAG = 100;
38 static double FMAG_LENGTH;
39 static double Z_UPSTREAM;
42 void initGlobalVariables()
50 NSTEPS_SHIELDING = rc->
get_IntFlag(
"NSTEPS_SHIELDING");
59 static const double c_light = 2.99792458e+8 * m/
s;
64 pos_i(TVector3()), mom_i(TVector3()), cov_i(TMatrixDSym(5)),
65 pos_f(TVector3()), mom_f(TVector3()), cov_f(TMatrixDSym(5)),
66 jac_sd2sc(TMatrixD(5,5)), jac_sc2sd(TMatrixD(5,5))
68 initGlobalVariables();
80 genfit::FieldManager::getInstance()->init(fieldMap);
82 _tgeo_manager =
const_cast<TGeoManager*
>(geom);
88 double p[4] = {0, 0, z_test*cm, 0};
89 double B[3] = {0, 0, 0};
91 cout <<
"PHField (CLHEP) at Z = " << z_test << endl;
92 cout << B[0] <<
", " << B[1] <<
", " << B[2] << endl;
95 genfit::AbsBField *f = genfit::FieldManager::getInstance()->getField();
96 TVector3 H = f->get(TVector3(0,0,z_test));
98 cout <<
"genfit::AbsBField (tesla) at Z = " << z_test << endl;
102 H = f->get(TVector3(0,0,z_test));
103 H *= kilogauss/tesla;
104 cout <<
"genfit::AbsBField (tesla) at Z = " << z_test << endl;
109 _tgeo_manager->Export(
"GenFitExtrapolatorGeom.root");
111 genfit::MaterialEffects::getInstance()->init(
new genfit::TGeoMaterialInterface());
122 LogInfo(
"z_in: ") << z_in << endl;
129 if(state_in[0][0] > 0)
138 TMatrixD cov_sd(5, 5);
139 for(
int i = 0; i < 5; i++)
141 for(
int j = 0; j < 5; j++)
143 cov_sd[i][j] = cov_in[i][j];
145 if(i == 0) cov_sd[i][j] = double(iParType)*cov_sd[i][j];
146 if(j == 0) cov_sd[i][j] = double(iParType)*cov_sd[i][j];
151 TRSDSC(iParType, mom_i, pos_i);
152 TMatrixD jac_sd2sc_T = jac_sd2sc;
155 TMatrixD cov_sc = jac_sd2sc*cov_sd*jac_sd2sc_T;
156 for(
int i = 0; i < 5; i++)
158 for(
int j = 0; j < 5; j++)
160 cov_i[i][j] = cov_sc[i][j];
172 TMatrixD cov_sc(5, 5);
173 for(
int i = 0; i < 5; i++)
175 for(
int j = 0; j < 5; j++)
177 cov_sc[i][j] = cov_f[i][j];
179 if(direction == GenFitExtrapolator::Backward)
181 if(i == 1) cov_sc[i][j] = -cov_sc[i][j];
182 if(j == 1) cov_sc[i][j] = -cov_sc[i][j];
183 if(i == 3) cov_sc[i][j] = -cov_sc[i][j];
184 if(j == 3) cov_sc[i][j] = -cov_sc[i][j];
190 TRSCSD(iParType, mom_f, pos_f);
191 TMatrixD jac_sc2sd_T = jac_sc2sd;
194 cov_out = jac_sc2sd*cov_sc*jac_sc2sd_T;
196 for(
int i = 0; i < 5; i++)
198 for(
int j = 0; j < 5; j++)
200 if(i == 0) cov_out[i][j] = double(iParType)*cov_out[i][j];
201 if(j == 0) cov_out[i][j] = double(iParType)*cov_out[i][j];
237 if(pos_i[2] > 2400 || pos_i[2] < -600 || z_out > 2400 || z_out < -600)
243 if(fabs(pos_i[2] - z_out) < 1E-3)
252 int pid = iParType > 0 ? -13 : 13;
255 <<
"extrapolateToPlane: "
256 <<
"From: " << pos_i.Z()
261 auto up_rep = std::unique_ptr<genfit::AbsTrackRep> (
new genfit::RKTrackRep(pid));
262 auto rep = up_rep.get();
264 genfit::SharedPlanePtr destPlane(
new genfit::DetPlane(TVector3(0, 0, z_out), TVector3(0, 0, 1)));
266 std::unique_ptr<genfit::MeasuredStateOnPlane> currentState = std::unique_ptr < genfit::MeasuredStateOnPlane > (
new genfit::MeasuredStateOnPlane(rep));
268 currentState->setPosMom(pos_i, mom_i);
269 currentState->setCov(cov_i);
272 travelLength = rep->extrapolateToPlane(*currentState, destPlane);
275 cout <<
"extrapolateToPlane failed!" << endl;
280 currentState->getPosMom(pos_f, mom_f);
281 cov_f = currentState->getCov();
295 TVector3 mom[NSTEPS_FMAG + NSTEPS_TARGET + 1];
296 TVector3 pos[NSTEPS_FMAG + NSTEPS_TARGET + 1];
300 double step_fmag = FMAG_LENGTH/NSTEPS_FMAG;
301 double step_target = fabs(Z_UPSTREAM)/NSTEPS_TARGET;
310 for(; iStep <= NSTEPS_FMAG; ++iStep)
312 pos_i = pos[iStep-1];
313 mom_i = mom[iStep-1];
321 for(; iStep < NSTEPS_FMAG+NSTEPS_TARGET+1; ++iStep)
323 pos_i = pos[iStep-1];
324 mom_i = mom[iStep-1];
333 double dca_min = 1E6;
334 for(
int i = 0; i < NSTEPS_FMAG+NSTEPS_TARGET+1; ++i)
336 double dca = sqrt(pos[i][0]*pos[i][0] + pos[i][1]*pos[i][1]);
344 return pos[iStep][2];
348 double p = fabs(1. / state[0][0]);
349 double pz = p / sqrt(1. + state[1][0] * state[1][0] + state[2][0] * state[2][0]);
350 double px = pz * state[1][0];
351 double py = pz * state[2][0];
353 double x = state[3][0];
354 double y = state[4][0];
357 mom.SetXYZ(px, py, pz);
361 TVector3 mom_gev = mom;
362 TVector3 pos_cm = pos;
364 state[0][0] = double(iParType) / mom_gev.Mag();
365 state[1][0] = mom_gev.x() / mom_gev.z();
366 state[2][0] = mom_gev.y() / mom_gev.z();
368 state[3][0] = pos_cm.x();
369 state[4][0] = pos_cm.y();
375 TVector3 mom(mom_input[0], mom_input[1], mom_input[2]);
376 TVector3 pos(pos_input[0], pos_input[1], pos_input[2]);
379 TVector3 DJ(1., 0., 0.);
380 TVector3 DK(0., 1., 0.);
381 TVector3 DI = DJ.Cross(DK);
384 double p_inv = 1./mom.Mag();
385 double vp = mom.Dot(DJ)/mom.Dot(DI);
386 double wp = mom.Dot(DK)/mom.Dot(DI);
387 double lambda = TMath::Pi()/2. - mom.Theta();
391 TVW.SetX(1./sqrt(1. + vp*vp + wp*wp));
392 TVW.SetY(vp*TVW.X());
393 TVW.SetZ(wp*TVW.X());
396 for(
int i = 0; i < 3; i++)
398 TN[i] = TVW[0]*DI[i] + TVW[1]*DJ[i] + TVW[2]*DK[i];
401 double cosl = cos(lambda);
402 double cosl1 = 1./cosl;
404 TVector3 UN(-TN.Y()*cosl1, TN.X()*cosl1, 0.);
405 TVector3 VN(-TN.Z()*UN.Y(), TN.Z()*UN.X(), cosl);
407 double UJ = UN.Dot(DJ);
408 double UK = UN.Dot(DK);
409 double VJ = VN.Dot(DJ);
410 double VK = VN.Dot(DK);
413 jac_sd2sc[0][0] = 1.;
414 jac_sd2sc[1][1] = TVW[0]*VJ;
415 jac_sd2sc[1][2] = TVW[0]*VK;
416 jac_sd2sc[2][1] = TVW[0]*UJ*cosl1;
417 jac_sd2sc[2][2] = TVW[0]*UK*cosl1;
418 jac_sd2sc[3][3] = UJ;
419 jac_sd2sc[3][4] = UK;
420 jac_sd2sc[4][3] = VJ;
421 jac_sd2sc[4][4] = VK;
424 genfit::AbsBField *field = genfit::FieldManager::getInstance()->getField();
426 if(charge != 0 && field)
428 TVector3 H = field->get(pos);
429 H *= kilogauss/tesla;
436 double HAM = HA*p_inv*tesla*GeV;
447 double Q = -HAM*c_light/(km/ns);
448 double sinz = -H.Dot(UN)*HM;
449 double cosz = H.Dot(VN)*HM;
451 jac_sd2sc[1][3] = -Q*TVW[1]*sinz;
452 jac_sd2sc[1][4] = -Q*TVW[2]*sinz;
453 jac_sd2sc[2][3] = -Q*TVW[1]*cosz*cosl1;
454 jac_sd2sc[2][4] = -Q*TVW[2]*cosz*cosl1;
461 TVector3 mom(mom_input[0], mom_input[1], mom_input[2]);
462 TVector3 pos(pos_input[0], pos_input[1], pos_input[2]);
465 TVector3 DJ(1., 0., 0.);
466 TVector3 DK(0., 1., 0.);
467 TVector3 DI = DJ.Cross(DK);
470 double p_inv = 1./mom.Mag();
473 double lambda = TMath::Pi()/2. - mom.Theta();
474 double phi = mom.Phi();
476 double cosl = cos(lambda);
477 double sinp = sin(phi);
478 double cosp = cos(phi);
480 TVector3 TN(cosl*cosp, cosl*sinp, sin(lambda));
482 TVW.SetX(TN.Dot(DI));
483 TVW.SetY(TN.Dot(DJ));
484 TVW.SetZ(TN.Dot(DK));
486 double T1R = 1./TVW[0];
487 double T2R = T1R*T1R;
488 TVector3 UN(-sinp, cosp, 0.);
489 TVector3 VN(-TN.Z()*UN.Y(), TN.Z()*UN.X(), cosl);
491 double UJ = UN.Dot(DJ);
492 double UK = UN.Dot(DK);
493 double VJ = VN.Dot(DJ);
494 double VK = VN.Dot(DK);
495 double UI = UN.Dot(DI);
496 double VI = VN.Dot(DI);
499 jac_sc2sd[0][0] = 1.;
500 jac_sc2sd[1][1] = -UK*T2R;
501 jac_sc2sd[1][2] = VK*cosl*T2R;
502 jac_sc2sd[2][1] = UJ*T2R;
503 jac_sc2sd[2][2] = -VJ*cosl*T2R;
504 jac_sc2sd[3][3] = VK*T1R;
505 jac_sc2sd[3][4] = -UK*T1R;
506 jac_sc2sd[4][3] = -VJ*T1R;
507 jac_sc2sd[4][4] = UJ*T1R;
509 genfit::AbsBField *field = genfit::FieldManager::getInstance()->getField();
510 if(charge != 0 && field)
512 TVector3 H = field->get(pos);
513 H *= kilogauss/tesla;
516 double HAM = HA*p_inv;
527 double Q = -HAM*c_light/(km/ns);
528 double sinz = -H.Dot(UN)*HM;
529 double cosz = H.Dot(VN)*HM;
530 double T3R = Q*T1R*T1R*T1R;
532 jac_sc2sd[1][3] = -UI*(VK*cosz - UK*sinz)*T3R;
533 jac_sc2sd[1][4] = -VI*(VK*cosz - UK*sinz)*T3R;
534 jac_sc2sd[2][3] = UI*(VJ*cosz - UJ*sinz)*T3R;
535 jac_sc2sd[2][4] = VI*(VJ*cosz - UJ*sinz)*T3R;
540 cout <<
"Propagating " << iParType <<
":" << endl;
542 <<
"(" << pos_i.X() <<
", " << pos_i.Y() <<
", "<< pos_i.Z() <<
") "
544 <<
"(" << pos_f.X() <<
", " << pos_f.Y() <<
", "<< pos_f.Z() <<
") "
547 cout <<
"Momentum change: From "
548 <<
"(" << mom_i.X() <<
", " << mom_i.Y() <<
", "<< mom_i.Z() <<
") "
550 <<
"(" << mom_f.X() <<
", " << mom_f.Y() <<
", "<< mom_f.Z() <<
") "
553 cout <<
"Initial error matrix: " << endl;
554 for(
int i = 0; i < 5; i++)
556 for(
int j = 0; j < 5; j++)
558 cout << cov_i[i][j] <<
" ";
563 cout <<
"Final error matrix: " << endl;
564 for(
int i = 0; i < 5; i++)
566 for(
int j = 0; j < 5; j++)
568 cout << cov_f[i][j] <<
" ";
virtual double get_DoubleFlag(const std::string &name) const
transient DST object for field storage and access
static recoConsts * instance()
virtual void GetFieldValue(const double Point[4], double *Bfield) const =0
virtual int get_IntFlag(const std::string &name) const