53 noMaterialMode_ =
false;
54 noErrorPropagation_ =
false;
55 applyRadX0Correction_ =
true;
56 useMagVolumes_ =
true;
57 useIsYokeFlag_ =
true;
58 useMatVolumes_ =
true;
59 useInTeslaFromMagField_ =
false;
60 returnTangentPlane_ =
true;
61 sendLogWarning_ =
false;
62 useTuningForL2Speed_ =
false;
63 for (
int i = 0;
i <= MAX_POINTS;
i++){
65 svBuf_[
i].r3 =
Point(0,0,0);
67 svBuf_[
i].bfGradLoc =
Vector(0,0,0);
70 svBuf_[
i].isComplete =
true;
71 svBuf_[
i].isValid_ =
true;
72 svBuf_[
i].hasErrorPropagated_ = !noErrorPropagation_;
83 return propagateWithPath(ftsStart, pDest).first;
89 return propagateWithPath(ftsStart, cDest).first;
95 return propagateWithPath(ftsStart, pDest).first;
102 return propagateWithPath(ftsStart, pDest1, pDest2).first;
109 return propagateWithPath(ftsStart, beamSpot).first;
113 std::pair<TrajectoryStateOnSurface, double>
115 const Plane& pDest)
const {
119 const StateInfo& svCurrent = propagate(svBuf_[0], pDest);
121 return TsosPP(svCurrent.getStateOnSurface(pDest), svCurrent.path());
124 std::pair<TrajectoryStateOnSurface, double>
130 const StateInfo& svCurrent = propagate(svBuf_[0], cDest);
132 return TsosPP(svCurrent.getStateOnSurface(cDest, returnTangentPlane_), svCurrent.path());
136 std::pair<FreeTrajectoryState, double>
141 const StateInfo& svCurrent = propagate(svBuf_[0], pDest);
144 svCurrent.getFreeState(ftsDest);
146 return FtsPP(ftsDest, svCurrent.path());
149 std::pair<FreeTrajectoryState, double>
153 if ((pDest1-pDest2).
mag() < 1
e-10){
154 if (sendLogWarning_){
155 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: the points should be at a bigger distance"
162 const StateInfo& svCurrent = propagate(svBuf_[0], pDest1, pDest2);
165 svCurrent.getFreeState(ftsDest);
167 return FtsPP(ftsDest, svCurrent.path());
171 std::pair<FreeTrajectoryState, double>
176 pDest1.
y() + beamSpot.
dydz()*1e3,
178 return propagateWithPath(ftsStart, pDest1, pDest2);
186 if (sendLogWarning_){
187 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: invalid input state"
190 return invalidState_;
193 const Plane* pDest =
dynamic_cast<const Plane*
>(&sDest);
194 if (pDest != 0)
return propagate(sStart, *pDest);
197 if (cDest != 0)
return propagate(sStart, *cDest);
199 throw PropagationException(
"The surface is neither Cylinder nor Plane");
205 const Plane& pDest)
const {
208 if (sendLogWarning_){
209 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: invalid input state"
212 return invalidState_;
219 double pars[6] = { rPlane.x(), rPlane.y(), rPlane.z(),
220 nPlane.x(), nPlane.y(), nPlane.z() };
222 propagate(PLANE_DT, pars);
227 if (sStart.
path() < svBuf_[cIndex_(nPoints_-1)].path()) lDir = 1.;
228 if (sStart.
path() > svBuf_[cIndex_(nPoints_-1)].path()) lDir = -1.;
229 svBuf_[cIndex_(nPoints_-1)].dir = lDir;
230 return svBuf_[cIndex_(nPoints_-1)];
238 if (sendLogWarning_){
239 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: invalid input state"
242 return invalidState_;
246 double pars[6] = {0,0,0,0,0,0};
247 pars[RADIUS_P] = cDest.radius();
250 propagate(RADIUS_DT, pars);
255 if (sStart.
path() < svBuf_[cIndex_(nPoints_-1)].path()) lDir = 1.;
256 if (sStart.
path() > svBuf_[cIndex_(nPoints_-1)].path()) lDir = -1.;
257 svBuf_[cIndex_(nPoints_-1)].dir = lDir;
258 return svBuf_[cIndex_(nPoints_-1)];
266 if (sendLogWarning_){
267 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: invalid input state"
270 return invalidState_;
274 double pars[6] = {pDest.
x(), pDest.
y(), pDest.
z(), 0, 0, 0};
277 propagate(POINT_PCA_DT, pars);
279 return svBuf_[cIndex_(nPoints_-1)];
286 if ((pDest1-pDest2).
mag() < 1
e-10 || !sStart.
isValid()){
287 if (sendLogWarning_){
288 if ((pDest1-pDest2).mag() < 1
e-10)
289 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: points are too close"
292 edm::LogWarning(
"SteppingHelixPropagator")<<
"Can't propagate: invalid input state"
295 return invalidState_;
299 double pars[6] = {pDest1.
x(), pDest1.
y(), pDest1.
z(),
300 pDest2.
x(), pDest2.
y(), pDest2.
z()};
302 propagate(LINE_PCA_DT, pars);
304 return svBuf_[cIndex_(nPoints_-1)];
309 svBuf_[cIndex_(nPoints_)] = sStart;
311 svBuf_[cIndex_(nPoints_)] = sStart;
314 loadState(svBuf_[cIndex_(nPoints_)], sStart.
p3, sStart.
r3, sStart.
q,
315 propagationDirection(), sStart.
covCurv);
318 svBuf_[cIndex_(0)].hasErrorPropagated_ = sStart.
hasErrorPropagated_ & !noErrorPropagation_;
321 SteppingHelixPropagator::Result
322 SteppingHelixPropagator::propagate(SteppingHelixPropagator::DestType
type,
323 const double pars[6],
double epsilon)
const{
326 StateInfo* svCurrent = &svBuf_[cIndex_(nPoints_-1)];
332 Result
result = refToDest(type, (*svCurrent), pars, dist, tanDist, refDirection);
335 svCurrent->status_ =
result;
337 svCurrent->isValid_ =
false;
338 svCurrent->field = field_;
339 if (sendLogWarning_){
340 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
" Failed after first refToDest check with status "
348 bool makeNextStep =
true;
349 double dStep = defaultStep_;
351 dir = propagationDirection();
355 double distMag = 1e12;
356 double tanDistMag = 1e12;
358 double distMat = 1e12;
359 double tanDistMat = 1e12;
361 double tanDistNextCheck = -0.1;
362 double tanDistMagNextCheck = -0.1;
363 double tanDistMatNextCheck = -0.1;
370 bool isFirstStep =
true;
371 bool expectNewMagVolume =
false;
374 while (makeNextStep){
375 dStep = defaultStep_;
376 svCurrent = &svBuf_[cIndex_(nPoints_-1)];
377 double curZ = svCurrent->r3.z();
378 double curR = svCurrent->r3.perp();
379 if ( fabs(curZ) < 440 && curR < 260) dStep = defaultStep_*2;
383 if (useTuningForL2Speed_){
385 if (! useIsYokeFlag_ && fabs(curZ) < 667 && curR > 380 && curR < 850){
386 dStep = 5*(1+0.2*svCurrent->p3.mag());
392 tanDistNextCheck -= oldDStep;
393 tanDistMagNextCheck -= oldDStep;
394 tanDistMatNextCheck -= oldDStep;
396 if (tanDistNextCheck < 0){
398 if (! isFirstStep) refToDest(type, (*svCurrent), pars, dist, tanDist, refDirection);
400 if (fabs(tanDist) > 4.*(fabs(dist)) ) tanDist *= tanDist == 0 ? 0 :fabs(dist/tanDist*4.);
402 tanDistNextCheck = fabs(tanDist)*0.5 - 0.5;
404 if (tanDistNextCheck > defaultStep_*20. ) tanDistNextCheck = defaultStep_*20.;
405 oldRefDirection = refDirection;
407 tanDist = tanDist > 0. ? tanDist - oldDStep : tanDist + oldDStep;
408 refDirection = oldRefDirection;
409 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Skipped refToDest: guess tanDist = "<<tanDist
410 <<
" next check at "<<tanDistNextCheck<<std::endl;
413 double fastSkipDist = fabs(dist) > fabs(tanDist) ? tanDist : dist;
418 dir = propagationDirection();
419 if (fabs(tanDist)<0.1 && refDirection != dir ){
422 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"NOTE: overstepped last time: switch direction (can do it if within 1 mm)"<<std::endl;
426 if (useMagVolumes_ && ! (fabs(dist) < fabs(epsilon))){
427 if (tanDistMagNextCheck < 0){
428 resultToMag = refToMagVolume((*svCurrent), dir, distMag, tanDistMag, fabs(fastSkipDist), expectNewMagVolume, fabs(tanDist));
430 if (fabs(tanDistMag) > 4.*(fabs(distMag)) ) tanDistMag *= tanDistMag == 0 ? 0 : fabs(distMag/tanDistMag*4.);
432 tanDistMagNextCheck = fabs(tanDistMag)*0.5-0.5;
434 if (tanDistMagNextCheck > defaultStep_*20.
435 || fabs(dist) < fabs(distMag)
437 tanDistMagNextCheck = defaultStep_*20 > fabs(fastSkipDist) ? fabs(fastSkipDist) : defaultStep_*20;
442 tanDistMag = tanDistMag > 0. ? tanDistMag - oldDStep : tanDistMag + oldDStep;
443 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Skipped refToMag: guess tanDistMag = "<<tanDistMag
444 <<
" next check at "<<tanDistMagNextCheck;
448 if (useMatVolumes_ && ! (fabs(dist) < fabs(epsilon))){
449 if (tanDistMatNextCheck < 0){
450 resultToMat = refToMatVolume((*svCurrent), dir, distMat, tanDistMat, fabs(fastSkipDist));
452 if (fabs(tanDistMat) > 4.*(fabs(distMat)) ) tanDistMat *= tanDistMat == 0 ? 0 : fabs(distMat/tanDistMat*4.);
454 tanDistMatNextCheck = fabs(tanDistMat)*0.5-0.5;
456 if (tanDistMatNextCheck > defaultStep_*20.
457 || fabs(dist) < fabs(distMat)
459 tanDistMatNextCheck = defaultStep_*20 > fabs(fastSkipDist) ? fabs(fastSkipDist) : defaultStep_*20;
464 tanDistMat = tanDistMat > 0. ? tanDistMat - oldDStep : tanDistMat + oldDStep;
465 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Skipped refToMat: guess tanDistMat = "<<tanDistMat
466 <<
" next check at "<<tanDistMatNextCheck;
470 double rDotP = svCurrent->r3.dot(svCurrent->p3);
471 if ((fabs(curZ) > 1.5e3 || curR >800.)
475 dStep = fabs(tanDist) -1
e-12;
477 double tanDistMin = fabs(tanDist);
478 if (tanDistMin > fabs(tanDistMag)+0.05 &&
480 tanDistMin = fabs(tanDistMag)+0.05;
481 expectNewMagVolume =
true;
482 }
else expectNewMagVolume =
false;
485 tanDistMin = fabs(tanDistMat)+0.05;
486 if (expectNewMagVolume) expectNewMagVolume =
false;
489 if (tanDistMin*fabs(svCurrent->dEdx) > 0.5*svCurrent->p3.mag()){
490 tanDistMin = 0.5*svCurrent->p3.mag()/fabs(svCurrent->dEdx);
491 if (expectNewMagVolume) expectNewMagVolume =
false;
496 double tanDistMinLazy = fabs(tanDistMin);
497 if ((type == POINT_PCA_DT || type == LINE_PCA_DT)
498 && fabs(tanDist) < 2.*fabs(tanDistMin) ){
500 tanDistMinLazy = fabs(tanDistMin)*0.5;
503 if (fabs(tanDistMinLazy) < dStep){
504 dStep = fabs(tanDistMinLazy);
510 if (dStep > 1
e-10 && ! (fabs(dist) < fabs(epsilon))){
511 StateInfo* svNext = &svBuf_[cIndex_(nPoints_)];
512 makeAtomStep((*svCurrent), (*svNext), dStep, dir, HEL_AS_F);
525 nPoints_++; svCurrent = &svBuf_[cIndex_(nPoints_-1)];
528 tanDistNextCheck = -1;
529 tanDistMagNextCheck = -1;
530 tanDistMatNextCheck = -1;
535 if (nOsc>1 && fabs(dStep)>epsilon){
536 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Ooops"<<std::endl;
541 if ((type == POINT_PCA_DT || type == LINE_PCA_DT )
542 && fabs(dStep) < fabs(epsilon) ){
545 double nextTanDist = 0;
547 StateInfo* svNext = &svBuf_[cIndex_(nPoints_)];
548 makeAtomStep((*svCurrent), (*svNext), 1., dir, HEL_AS_F);
549 nPoints_++; svCurrent = &svBuf_[cIndex_(nPoints_-1)];
550 refToDest(type, (*svCurrent), pars, nextDist, nextTanDist, nextRefDirection);
551 if ( fabs(nextDist) > fabs(dist)){
552 nPoints_--; svCurrent = &svBuf_[cIndex_(nPoints_-1)];
555 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Found real local minimum in PCA"<<std::endl;
559 dStep = defaultStep_;
561 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Found branch point in PCA"<<std::endl;
566 if (nPoints_ > MAX_STEPS*1./defaultStep_ || loopCount > MAX_STEPS*100
571 curZ = svCurrent->r3.z();
572 curR = svCurrent->r3.perp();
576 svCurrent->status_ =
result;
578 svCurrent->field = field_;
585 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
" Propagation failed with status "
589 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
" Momentum at last point is too low (<0.1) p_last = "
590 <<svCurrent->p3.mag()
593 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
" Went too far: the last point is at "<<svCurrent->r3
596 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
" Infinite loop condidtion detected: going in cycles. Break after 6 cycles"
599 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
" Tired to go farther. Made too many steps: more than "
600 <<MAX_STEPS*1./defaultStep_
608 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to radius "<<pars[RADIUS_P]<<std::endl;
611 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to z "<<pars[Z_P]<<std::endl;
614 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to pathL "<<pars[PATHL_P]<<std::endl;
618 Point rPlane(pars[0], pars[1], pars[2]);
619 Vector nPlane(pars[3], pars[4], pars[5]);
620 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to plane r0:"<<rPlane<<
" n:"<<nPlane<<std::endl;
625 Point rDest(pars[0], pars[1], pars[2]);
626 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to PCA to point "<<rDest<<std::endl;
631 Point rDest1(pars[0], pars[1], pars[2]);
632 Point rDest2(pars[3], pars[4], pars[5]);
633 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to PCA to line "<<rDest1<<
" - "<<rDest2<<std::endl;
637 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"going to NOT IMPLEMENTED"<<std::endl;
640 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Made "<<nPoints_-1<<
" steps and stopped at(cur step) "<<svCurrent->r3<<
" nOsc "<<nOsc<<std::endl;
646 void SteppingHelixPropagator::loadState(SteppingHelixPropagator::StateInfo& svCurrent,
651 static const std::string metname =
"SteppingHelixPropagator";
659 svCurrent.radPath_ = 0;
661 GlobalPoint gPointNorZ(svCurrent.r3.x(), svCurrent.r3.y(), svCurrent.r3.z());
663 float gpmag = gPointNorZ.
mag2();
664 float pmag2 = p3.mag2();
665 if (gpmag > 1e20f ) {
666 LogTrace(metname)<<
"Initial point is too far";
667 svCurrent.isValid_ =
false;
670 if (! (gpmag == gpmag) ) {
671 LogTrace(metname)<<
"Initial point is a nan";
672 edm::LogWarning(
"SteppingHelixPropagatorNAN")<<
"Initial point is a nan";
673 svCurrent.isValid_ =
false;
676 if (! (pmag2 == pmag2) ) {
677 LogTrace(metname)<<
"Initial momentum is a nan";
678 edm::LogWarning(
"SteppingHelixPropagatorNAN")<<
"Initial momentum is a nan";
679 svCurrent.isValid_ =
false;
687 svCurrent.magVol = vbField_->findVolume(gPointNorZ);
689 double curRad = svCurrent.r3.perp();
690 if (curRad > 380 && curRad < 850 && fabs(svCurrent.r3.z()) < 667){
691 svCurrent.isYokeVol = isYokeVolume(svCurrent.magVol);
693 svCurrent.isYokeVol =
false;
697 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Failed to cast into VolumeBasedMagneticField: fall back to the default behavior"<<std::endl;
698 svCurrent.magVol = 0;
701 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Got volume at "<<svCurrent.magVol<<std::endl;
705 if (useMagVolumes_ && svCurrent.magVol != 0 && ! useInTeslaFromMagField_){
706 bf = svCurrent.magVol->inTesla(gPointNorZ);
708 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Loaded bfield float: "<<bf
709 <<
" at global float "<< gPointNorZ<<
" double "<< svCurrent.r3<<std::endl;
710 LocalPoint lPoint(svCurrent.magVol->toLocal(gPointNorZ));
711 LocalVector lbf = svCurrent.magVol->fieldInTesla(lPoint);
712 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"\t cf in local locF: "<<lbf<<
" at "<<lPoint<<std::endl;
714 svCurrent.bf.set(bf.x(), bf.y(), bf.z());
717 bf = field_->inTesla(gPoint);
718 svCurrent.bf.set(bf.x(), bf.y(), bf.z());
720 if (svCurrent.bf.mag2() < 1
e-32) svCurrent.bf.set(0., 0., 1
e-16);
722 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific
723 <<
"Loaded bfield double: "<<svCurrent.bf<<
" from float: "<<bf
724 <<
" at float "<< gPointNorZ<<
" double "<< svCurrent.r3<<std::endl;
729 double dEdXPrime = 0;
733 dEdx = getDeDx(svCurrent, dEdXPrime, radX0, rzLims);
734 svCurrent.dEdx = dEdx; svCurrent.dEdXPrime = dEdXPrime;
735 svCurrent.radX0 = radX0;
736 svCurrent.rzLims = rzLims;
738 svCurrent.covCurv =covCurv;
740 svCurrent.isComplete =
true;
741 svCurrent.isValid_ =
true;
744 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Loaded at path: "<<svCurrent.path()<<
" radPath: "<<svCurrent.radPath()
745 <<
" p3 "<<
" pt: "<<svCurrent.p3.perp()<<
" phi: "<<svCurrent.p3.phi()
746 <<
" eta: "<<svCurrent.p3.eta()
748 <<
" r3: "<<svCurrent.r3
749 <<
" bField: "<<svCurrent.bf.mag()
751 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Input Covariance in Curvilinear RF "<<covCurv<<std::endl;
755 void SteppingHelixPropagator::getNextState(
const SteppingHelixPropagator::StateInfo& svPrevious,
756 SteppingHelixPropagator::StateInfo& svNext,
760 static const std::string metname =
"SteppingHelixPropagator";
761 svNext.q = svPrevious.q;
762 svNext.dir = dS > 0.0 ? 1.: -1.;
763 svNext.p3 =
tau; svNext.p3*=(svPrevious.p3.mag() - svNext.dir*fabs(dP));
765 svNext.r3 = svPrevious.r3; svNext.r3 += drVec;
767 svNext.path_ = svPrevious.path() + dS;
768 svNext.radPath_ = svPrevious.radPath() + dX0;
770 GlobalPoint gPointNorZ(svNext.r3.x(), svNext.r3.y(), svNext.r3.z());
776 svNext.magVol = vbField_->findVolume(gPointNorZ);
778 double curRad = svNext.r3.perp();
779 if (curRad > 380 && curRad < 850 && fabs(svNext.r3.z()) < 667){
780 svNext.isYokeVol = isYokeVolume(svNext.magVol);
782 svNext.isYokeVol =
false;
786 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Failed to cast into VolumeBasedMagneticField"<<std::endl;
790 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Got volume at "<<svNext.magVol<<std::endl;
794 if (useMagVolumes_ && svNext.magVol != 0 && ! useInTeslaFromMagField_){
795 bf = svNext.magVol->inTesla(gPointNorZ);
796 svNext.bf.set(bf.x(), bf.y(), bf.z());
798 GlobalPoint gPoint(svNext.r3.x(), svNext.r3.y(), svNext.r3.z());
799 bf = field_->inTesla(gPoint);
800 svNext.bf.set(bf.x(), bf.y(), bf.z());
802 if (svNext.bf.mag2() < 1
e-32) svNext.bf.set(0., 0., 1
e-16);
805 double dEdXPrime = 0;
809 dEdx = getDeDx(svNext, dEdXPrime, radX0, rzLims);
810 svNext.dEdx = dEdx; svNext.dEdXPrime = dEdXPrime;
811 svNext.radX0 = radX0;
812 svNext.rzLims = rzLims;
815 svNext.hasErrorPropagated_ = svPrevious.hasErrorPropagated_;
816 if (svPrevious.hasErrorPropagated_){
819 ROOT::Math::AssignSym::Evaluate(svNext.covCurv, tmp*ROOT::Math::Transpose(dCovCurvTransform));
821 svNext.covCurv += svPrevious.matDCovCurv;
829 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Now at path: "<<svNext.path()<<
" radPath: "<<svNext.radPath()
830 <<
" p3 "<<
" pt: "<<svNext.p3.perp()<<
" phi: "<<svNext.p3.phi()
831 <<
" eta: "<<svNext.p3.eta()
834 <<
" dPhi: "<<acos(svNext.p3.unit().dot(svPrevious.p3.unit()))
835 <<
" bField: "<<svNext.bf.mag()
836 <<
" dedx: "<<svNext.dEdx
838 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"New Covariance "<<svNext.covCurv<<std::endl;
839 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Transf by dCovTransform "<<dCovCurvTransform<<std::endl;
843 void SteppingHelixPropagator::setRep(SteppingHelixPropagator::Basis&
rep,
847 rep.lY = zRep.cross(tau); rep.lY *= 1./tau.perp();
848 rep.lZ = rep.lX.cross(rep.lY);
851 bool SteppingHelixPropagator::makeAtomStep(SteppingHelixPropagator::StateInfo& svCurrent,
852 SteppingHelixPropagator::StateInfo& svNext,
855 SteppingHelixPropagator::Fancy fancy)
const{
856 static const std::string metname =
"SteppingHelixPropagator";
858 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Make atom step "<<svCurrent.path()<<
" with step "<<dS<<
" in direction "<<dir<<std::endl;
864 double curP = svCurrent.p3.mag();
865 Vector tau = svCurrent.p3; tau *= 1./curP;
878 double p0Inv = 1./p0;
879 double b0 = svCurrent.bf.mag();
882 double phi = (2.99792458e-3*svCurrent.q*b0*p0Inv)*dS/2.;
883 bool phiSmall = fabs(phi) < 1
e-4;
888 double oneLessCosPhi=0;
889 double oneLessCosPhiOPhi=0;
891 double phiLessSinPhiOPhi=0;
894 double phi2 = phi*
phi;
895 double phi3 = phi2*
phi;
896 double phi4 = phi3*
phi;
897 sinPhi = phi - phi3/6. + phi4*phi/120.;
898 cosPhi = 1. -phi2/2. + phi4/24.;
899 oneLessCosPhi = phi2/2. - phi4/24. + phi2*phi4/720.;
900 oneLessCosPhiOPhi = 0.5*phi - phi3/24. + phi2*phi3/720.;
901 sinPhiOPhi = 1. - phi*phi/6. + phi4/120.;
902 phiLessSinPhiOPhi = phi*phi/6. - phi4/120. + phi4*phi2/5040.;
906 oneLessCosPhi = 1.-cosPhi;
907 oneLessCosPhiOPhi = oneLessCosPhi/
phi;
908 sinPhiOPhi = sinPhi/
phi;
909 phiLessSinPhiOPhi = 1 - sinPhiOPhi;
912 Vector bHat = svCurrent.bf; bHat *= 1./b0;
915 Vector btVec(bHat.cross(tau));
916 double tauB = tau.dot(bHat);
917 Vector bbtVec(bHat*tauB - tau);
920 drVec = bbtVec*phiLessSinPhiOPhi; drVec -= btVec*oneLessCosPhiOPhi; drVec +=
tau;
923 double dEdx = svCurrent.dEdx;
924 double dEdXPrime = svCurrent.dEdXPrime;
925 radX0 = svCurrent.radX0;
929 drVec += svCurrent.r3;
932 if (useMagVolumes_ && svCurrent.magVol != 0 && ! useInTeslaFromMagField_){
933 bfGV = svCurrent.magVol->inTesla(
GlobalPoint(drVec.x(), drVec.y(), drVec.z()));
934 bf.set(bfGV.x(), bfGV.y(), bfGV.z());
936 bfGV = field_->inTesla(
GlobalPoint(drVec.x(), drVec.y(), drVec.z()));
937 bf.set(bfGV.x(), bfGV.y(), bfGV.z());
943 bf.set(0., 0., 1
e-16);
946 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Improved b "<<b0
947 <<
" at r3 "<<drVec<<std::endl;
950 if (fabs((b0-b0Init)*dS) > 1){
953 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Large bf*dS change "<<fabs((b0-svCurrent.bf.mag())*dS)
954 <<
" --> recalc dedx"<<std::endl;
958 svNext.p3 = svCurrent.p3;
959 svNext.isYokeVol = svCurrent.isYokeVol;
961 dEdx = getDeDx(svNext, dEdXPrime, radX0, rzTmp);
964 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"New dEdX= "<<dEdx
966 <<
" for p0 "<<p0<<std::endl;
970 p0 += dP/2.;
if (p0 < 1
e-2) p0 = 1
e-2;
973 phi = (2.99792458e-3*svCurrent.q*b0*p0Inv)*dS;
974 phiSmall = fabs(phi) < 1
e-4;
977 double phi2 = phi*
phi;
978 double phi3 = phi2*
phi;
979 double phi4 = phi3*
phi;
980 sinPhi = phi - phi3/6. + phi4*phi/120.;
981 cosPhi = 1. -phi2/2. + phi4/24.;
982 oneLessCosPhi = phi2/2. - phi4/24. + phi2*phi4/720.;
983 oneLessCosPhiOPhi = 0.5*phi - phi3/24. + phi2*phi3/720.;
984 sinPhiOPhi = 1. - phi*phi/6. + phi4/120.;
985 phiLessSinPhiOPhi = phi*phi/6. - phi4/120. + phi4*phi2/5040.;
989 oneLessCosPhi = 1.-cosPhi;
990 oneLessCosPhiOPhi = oneLessCosPhi/
phi;
991 sinPhiOPhi = sinPhi/
phi;
992 phiLessSinPhiOPhi = 1. - sinPhiOPhi;
995 bHat = bf; bHat *= 1./b0;
997 btVec = bHat.cross(tau);
998 tauB = tau.dot(bHat);
999 bbtVec = bHat*tauB -
tau;
1001 tauNext = bbtVec*oneLessCosPhi; tauNext -= btVec*sinPhi; tauNext +=
tau;
1002 double tauNextPerpInv = 1./tauNext.perp();
1003 drVec = bbtVec*phiLessSinPhiOPhi; drVec -= btVec*oneLessCosPhiOPhi; drVec +=
tau;
1007 if (svCurrent.hasErrorPropagated_){
1009 double dX0 = fabs(dS)/radX0;
1011 if (applyRadX0Correction_){
1016 double x0 = fabs(svCurrent.radPath());
1017 double alphaX0 = 13.6e-3*p0Inv; alphaX0 *= alphaX0;
1018 double betaX0 = 0.038;
1019 double logx0p1 =
log(x0+1);
1020 theta02 = dX0*alphaX0*(1+betaX0*logx0p1)*(1 + betaX0*logx0p1 + 2.*betaX0*x0/(x0+1) );
1022 theta02 = 196
e-6* p0Inv * p0Inv * dX0;
1025 double epsilonP0 = 1.+ dP/(p0-0.5*dP);
1029 Vector tbtVec(bHat - tauB*tau);
1038 Point xStart = svCurrent.r3;
1044 double qbp = svCurrent.q*p0Inv;
1049 double t11 = tau.x();
double t12 = tau.y();
double t13 = tau.z();
1050 double t21 = tauNext.x();
double t22 = tauNext.y();
double t23 = tauNext.z();
1051 double cosl0 = tau.perp();
1053 double cosecl1 = tauNextPerpInv;
1063 double sint = -sinPhi;
double cost = cosPhi;
1064 double hn1 = hn.x();
double hn2 = hn.y();
double hn3 = hn.z();
1065 double dx1 = dx.x();
double dx2 = dx.y();
double dx3 = dx.z();
1068 double gamma = hn1*t21 + hn2*t22 + hn3*t23;
1069 double an1 = hn2*t23 - hn3*t22;
1070 double an2 = hn3*t21 - hn1*t23;
1071 double an3 = hn1*t22 - hn2*t21;
1073 double auInv = cosl0;
double au = auInv>0 ? 1./auInv : 1e24;
1075 double u11 = -au*t12;
double u12 = au*t11;
1076 double v11 = -t13*u12;
double v12 = t13*u11;
double v13 = auInv;
1077 auInv =
sqrt(1. - t23*t23); au = auInv>0 ? 1./auInv : 1e24;
1079 double u21 = -au*t22;
double u22 = au*t21;
1080 double v21 = -t23*u22;
double v22 = t23*u21;
double v23 = auInv;
1087 double anv = -(hn1*u21 + hn2*u22 );
1088 double anu = (hn1*v21 + hn2*v22 + hn3*v23);
1089 double omcost = oneLessCosPhi;
double tmsint = -phi*phiLessSinPhiOPhi;
1091 double hu1 = - hn3*u12;
1092 double hu2 = hn3*u11;
1093 double hu3 = hn1*u12 - hn2*u11;
1095 double hv1 = hn2*v13 - hn3*v12;
1096 double hv2 = hn3*v11 - hn1*v13;
1097 double hv3 = hn1*v12 - hn2*v11;
1100 dCCurvTransform(0,0) = 1./(epsilonP0*epsilonP0)*(1. + dS*dEdXPrime);
1104 dCCurvTransform(1,0) = phi*p0/svCurrent.q*cosecl1*
1105 (sinPhi*bbtVec.z() - cosPhi*btVec.z());
1109 dCCurvTransform(1,1) = cost*(v11*v21 + v12*v22 + v13*v23) +
1110 sint*(hv1*v21 + hv2*v22 + hv3*v23) +
1111 omcost*(hn1*v11 + hn2*v12 + hn3*v13) * (hn1*v21 + hn2*v22 + hn3*v23) +
1112 anv*(-sint*(v11*t21 + v12*t22 + v13*t23) +
1113 omcost*(v11*an1 + v12*an2 + v13*an3) -
1114 tmsint*gamma*(hn1*v11 + hn2*v12 + hn3*v13) );
1116 dCCurvTransform(1,2) = cost*(u11*v21 + u12*v22 ) +
1117 sint*(hu1*v21 + hu2*v22 + hu3*v23) +
1118 omcost*(hn1*u11 + hn2*u12 ) * (hn1*v21 + hn2*v22 + hn3*v23) +
1119 anv*(-sint*(u11*t21 + u12*t22 ) +
1120 omcost*(u11*an1 + u12*an2 ) -
1121 tmsint*gamma*(hn1*u11 + hn2*u12 ) );
1122 dCCurvTransform(1,2) *= cosl0;
1132 dCCurvTransform(2,0) = - phi*p0/svCurrent.q*cosecl1*cosecl1*
1133 (oneLessCosPhi*bHat.z()*btVec.mag2() + sinPhi*btVec.z() + cosPhi*tbtVec.z()) ;
1136 dCCurvTransform(2,1) = cost*(v11*u21 + v12*u22 ) +
1137 sint*(hv1*u21 + hv2*u22 ) +
1138 omcost*(hn1*v11 + hn2*v12 + hn3*v13) *
1139 (hn1*u21 + hn2*u22 ) +
1140 anu*(-sint*(v11*t21 + v12*t22 + v13*t23) +
1141 omcost*(v11*an1 + v12*an2 + v13*an3) -
1142 tmsint*gamma*(hn1*v11 + hn2*v12 + hn3*v13) );
1143 dCCurvTransform(2,1) *= cosecl1;
1145 dCCurvTransform(2,2) = cost*(u11*u21 + u12*u22 ) +
1146 sint*(hu1*u21 + hu2*u22 ) +
1147 omcost*(hn1*u11 + hn2*u12 ) *
1148 (hn1*u21 + hn2*u22 ) +
1149 anu*(-sint*(u11*t21 + u12*t22 ) +
1150 omcost*(u11*an1 + u12*an2 ) -
1151 tmsint*gamma*(hn1*u11 + hn2*u12 ) );
1152 dCCurvTransform(2,2) *= cosecl1*cosl0;
1164 dCCurvTransform(3,0) = - pp*(u21*dx1 + u22*dx2 );
1165 dCCurvTransform(4,0) = - pp*(v21*dx1 + v22*dx2 + v23*dx3);
1168 dCCurvTransform(3,1) = (sint*(v11*u21 + v12*u22 ) +
1169 omcost*(hv1*u21 + hv2*u22 ) +
1170 tmsint*(hn1*u21 + hn2*u22 ) *
1171 (hn1*v11 + hn2*v12 + hn3*v13))/q;
1173 dCCurvTransform(3,2) = (sint*(u11*u21 + u12*u22 ) +
1174 omcost*(hu1*u21 + hu2*u22 ) +
1175 tmsint*(hn1*u21 + hn2*u22 ) *
1176 (hn1*u11 + hn2*u12 ))*cosl0/q;
1178 dCCurvTransform(3,3) = (u11*u21 + u12*u22 );
1180 dCCurvTransform(3,4) = (v11*u21 + v12*u22 );
1184 dCCurvTransform(4,1) = (sint*(v11*v21 + v12*v22 + v13*v23) +
1185 omcost*(hv1*v21 + hv2*v22 + hv3*v23) +
1186 tmsint*(hn1*v21 + hn2*v22 + hn3*v23) *
1187 (hn1*v11 + hn2*v12 + hn3*v13))/q;
1189 dCCurvTransform(4,2) = (sint*(u11*v21 + u12*v22 ) +
1190 omcost*(hu1*v21 + hu2*v22 + hu3*v23) +
1191 tmsint*(hn1*v21 + hn2*v22 + hn3*v23) *
1192 (hn1*u11 + hn2*u12 ))*cosl0/q;
1194 dCCurvTransform(4,3) = (u11*v21 + u12*v22 );
1196 dCCurvTransform(4,4) = (v11*v21 + v12*v22 + v13*v23);
1201 Basis
rep; setRep(rep, tauNext);
1202 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"rep X: "<<rep.lX<<
" "<<rep.lX.mag()
1203 <<
"\t Y: "<<rep.lY<<
" "<<rep.lY.mag()
1204 <<
"\t Z: "<<rep.lZ<<
" "<<rep.lZ.mag();
1210 double mulRR = theta02*dS*dS/3.;
1211 double mulRP = theta02*fabs(dS)*p0/2.;
1212 double mulPP = theta02*p0*p0;
1213 double losPP = dP*dP*1.6/fabs(dS)*(1.0 + p0*1
e-3);
1220 double sinThetaInv = tauNextPerpInv;
1221 double p0Mat = p0+ 0.5*dP;
1222 double p0Mat2 = p0Mat*p0Mat;
1224 svCurrent.matDCovCurv*=0;
1226 svCurrent.matDCovCurv(0,0) = losPP/(p0Mat2*p0Mat2);
1233 svCurrent.matDCovCurv(1,1) = mulPP/p0Mat2;
1236 svCurrent.matDCovCurv(1,4) = mulRP/p0Mat;
1240 svCurrent.matDCovCurv(2,2) = mulPP/p0Mat2*(sinThetaInv*sinThetaInv);
1241 svCurrent.matDCovCurv(2,3) = mulRP/p0Mat*sinThetaInv;
1246 svCurrent.matDCovCurv(3,2) = mulRP/p0Mat*sinThetaInv;
1248 svCurrent.matDCovCurv(3,3) = mulRR;
1252 svCurrent.matDCovCurv(4,1) = mulRP/p0Mat;
1255 svCurrent.matDCovCurv(4,4) = mulRR;
1267 dP = -dP > pMag ? -pMag+1
e-5 : dP;
1270 getNextState(svCurrent, svNext, dP, tauNext, drVec, dS, dS/radX0,
1275 double SteppingHelixPropagator::getDeDx(
const SteppingHelixPropagator::StateInfo& sv,
1276 double& dEdXPrime,
double& radX0,
1277 MatBounds& rzLims)
const{
1280 rzLims = MatBounds();
1281 if (noMaterialMode_)
return 0;
1285 double lR = sv.r3.perp();
1286 double lZ = fabs(sv.r3.z());
1291 double dEdX_HCal = 0.95;
1292 double dEdX_ECal = 0.45;
1293 double dEdX_coil = 0.35;
1295 double dEdX_MCh = 0.053;
1296 double dEdX_Trk = 0.0114;
1297 double dEdX_Air = 2E-4;
1298 double dEdX_Vac = 0.0;
1300 double radX0_HCal = 1.44/0.8;
1301 double radX0_ECal = 0.89/0.7;
1302 double radX0_coil = 4.;
1303 double radX0_Fe = 1.76;
1304 double radX0_MCh = 1e3;
1305 double radX0_Trk = 320.;
1306 double radX0_Air = 3.e4;
1307 double radX0_Vac = 3.e9;
1311 if (! (lR < 380 && lZ < 785)){
1312 if (lZ > 785 ) rzLims = MatBounds(0, 1e4, 785, 1e4);
1313 if (lZ < 785 ) rzLims = MatBounds(380, 1e4, 0, 785);
1318 double ecShift = sv.r3.z() > 0 ? fabs(ecShiftPos_) : fabs(ecShiftNeg_);
1323 dEdx = dEdX_Vac; radX0 = radX0_Vac;
1324 rzLims = MatBounds(0, 2.9, 0, 1E4);
1328 rzLims = MatBounds(2.9, 129, 0, 294);
1329 dEdx = dEdX_Trk; radX0 = radX0_Trk;
1333 double lEtaDet = fabs(sv.r3.eta());
1334 double scaleRadX = lEtaDet > 1.5 ? 0.7724 : 1./cosh(0.5*lEtaDet);
1335 scaleRadX *= scaleRadX;
1336 if (lEtaDet > 2 && lZ > 20) scaleRadX *= (lEtaDet-1.);
1337 if (lEtaDet > 2.5 && lZ > 20) scaleRadX *= (lEtaDet-1.);
1341 else if ( lZ < 294 + ecShift ){
1343 rzLims = MatBounds(2.9, 129, 294, 294 + ecShift);
1344 dEdx = dEdX_Air; radX0 = radX0_Air;
1346 else if (lZ < 372 + ecShift){
1347 rzLims = MatBounds(2.9, 129, 294 + ecShift, 372 + ecShift);
1348 dEdx = dEdX_ECal; radX0 = radX0_ECal;
1350 else if (lZ < 398 + ecShift){
1351 rzLims = MatBounds(2.9, 129, 372 + ecShift, 398 + ecShift);
1352 dEdx = dEdX_HCal*0.05; radX0 = radX0_Air;
1354 else if (lZ < 555 + ecShift){
1355 rzLims = MatBounds(2.9, 129, 398 + ecShift, 555 + ecShift);
1356 dEdx = dEdX_HCal*0.96; radX0 = radX0_HCal/0.96;
1362 if (lZ < 568 + ecShift) rzLims = MatBounds(2.9, 129, 555 + ecShift, 568 + ecShift);
1363 else if (lZ < 625 + ecShift){
1364 if (lR < 85 + ecShift) rzLims = MatBounds(2.9, 85, 568 + ecShift, 625 + ecShift);
1365 else rzLims = MatBounds(85, 129, 568 + ecShift, 625 + ecShift);
1366 }
else if (lZ < 785 + ecShift) rzLims = MatBounds(2.9, 129, 625 + ecShift, 785 + ecShift);
1367 else if (lZ < 1500 + ecShift) rzLims = MatBounds(2.9, 129, 785 + ecShift, 1500 + ecShift);
1368 else rzLims = MatBounds(2.9, 129, 1500 + ecShift, 1E4);
1371 if (! (lZ > 568 + ecShift && lZ < 625 + ecShift && lR > 85 )
1372 && ! (lZ > 785 + ecShift && lZ < 850 + ecShift && lR > 118)) {dEdx = dEdX_Fe; radX0 = radX0_Fe; }
1373 else { dEdx = dEdX_MCh; radX0 = radX0_MCh; }
1377 if (lZ < 372 + ecShift && lR < 177){
1378 if (lZ < 304) rzLims = MatBounds(129, 177, 0, 304);
1380 if (lR < 135 ) rzLims = MatBounds(129, 135, 304, 343);
1381 else if (lR < 172 ){
1382 if (lZ < 311 ) rzLims = MatBounds(135, 172, 304, 311);
1383 else rzLims = MatBounds(135, 172, 311, 343);
1385 if (lZ < 328) rzLims = MatBounds(172, 177, 304, 328);
1386 else rzLims = MatBounds(172, 177, 328, 343);
1389 else if ( lZ < 343 + ecShift){
1390 rzLims = MatBounds(129, 177, 343, 343 + ecShift);
1393 if (lR < 156 ) rzLims = MatBounds(129, 156, 343 + ecShift, 372 + ecShift);
1394 else if ( (lZ - 343 - ecShift) > (lR - 156)*1.38 )
1395 rzLims = MatBounds(156, 177, 127.72 + ecShift, 372 + ecShift, atan(1.38), 0);
1396 else rzLims = MatBounds(156, 177, 343 + ecShift, 127.72 + ecShift, 0, atan(1.38));
1399 if (!(lR > 135 && lZ <343 + ecShift && lZ > 304 )
1400 && ! (lR > 156 && lZ < 372 + ecShift && lZ > 343 + ecShift && ((lZ-343. - ecShift )< (lR-156.)*1.38)))
1403 double cosThetaEquiv = 0.8/
sqrt(1.+lZ*lZ/lR/lR) + 0.2;
1404 if (lZ > 343) cosThetaEquiv = 1.;
1405 dEdx = dEdX_ECal*cosThetaEquiv; radX0 = radX0_ECal/cosThetaEquiv;
1408 if ( (lZ > 304 && lZ < 328 && lR < 177 && lR > 135)
1409 && ! (lZ > 311 && lR < 172) ) {dEdx = dEdX_Fe; radX0 = radX0_Fe; }
1410 else if ( lZ > 343 && lZ < 343 + ecShift) { dEdx = dEdX_Air; radX0 = radX0_Air; }
1411 else {dEdx = dEdX_ECal*0.2; radX0 = radX0_Air;}
1414 else if (lZ < 554 + ecShift){
1416 if ( lZ > 372 + ecShift && lZ < 398 + ecShift )rzLims = MatBounds(129, 177, 372 + ecShift, 398 + ecShift);
1417 else if (lZ < 548 + ecShift) rzLims = MatBounds(129, 177, 398 + ecShift, 548 + ecShift);
1418 else rzLims = MatBounds(129, 177, 548 + ecShift, 554 + ecShift);
1421 if ((lZ - 307) < (lR - 177.)*1.739) rzLims = MatBounds(177, 193, 0, -0.803, 0, atan(1.739));
1422 else if ( lZ < 389) rzLims = MatBounds(177, 193, -0.803, 389, atan(1.739), 0.);
1423 else if ( lZ < 389 + ecShift) rzLims = MatBounds(177, 193, 389, 389 + ecShift);
1424 else if ( lZ < 548 + ecShift ) rzLims = MatBounds(177, 193, 389 + ecShift, 548 + ecShift);
1425 else rzLims = MatBounds(177, 193, 548 + ecShift, 554 + ecShift);
1428 double anApex = 375.7278 - 193./1.327;
1429 if ( (lZ - 375.7278) < (lR - 193.)/1.327) rzLims = MatBounds(193, 264, 0, anApex, 0, atan(1./1.327));
1430 else if ( (lZ - 392.7278 ) < (lR - 193.)/1.327)
1431 rzLims = MatBounds(193, 264, anApex, anApex+17., atan(1./1.327), atan(1./1.327));
1432 else if ( (lZ - 392.7278 - ecShift ) < (lR - 193.)/1.327)
1433 rzLims = MatBounds(193, 264, anApex+17., anApex+17. + ecShift, atan(1./1.327), atan(1./1.327));
1435 else if ( lZ < 517 + ecShift ) rzLims = MatBounds(193, 264, anApex+17. + ecShift, 517 + ecShift, atan(1./1.327), 0);
1436 else if (lZ < 548 + ecShift){
1437 if (lR < 246 ) rzLims = MatBounds(193, 246, 517 + ecShift, 548 + ecShift);
1438 else rzLims = MatBounds(246, 264, 517 + ecShift, 548 + ecShift);
1440 else rzLims = MatBounds(193, 264, 548 + ecShift, 554 + ecShift);
1442 else if ( lR < 275){
1443 if (lZ < 433) rzLims = MatBounds(264, 275, 0, 433);
1444 else if (lZ < 554 ) rzLims = MatBounds(264, 275, 433, 554);
1445 else rzLims = MatBounds(264, 275, 554, 554 + ecShift);
1448 if (lZ < 402) rzLims = MatBounds(275, 287, 0, 402);
1449 else if (lZ < 554) rzLims = MatBounds(275, 287, 402, 554);
1450 else rzLims = MatBounds(275, 287, 554, 554 + ecShift);
1453 if ((lZ < 433 || lR < 264) && (lZ < 402 || lR < 275) && (lZ < 517 + ecShift || lR < 246)
1455 && lZ < 548 + ecShift
1456 && ! (lZ < 389 + ecShift && lZ > 335 && lR < 193 )
1457 && ! (lZ > 307 && lZ < 335 && lR < 193 && ((lZ - 307) > (lR - 177.)*1.739))
1458 && ! (lR < 177 && lZ < 398 + ecShift)
1459 && ! (lR < 264 && lR > 193 && fabs(441.5+0.5*ecShift - lZ + (lR - 269.)/1.327) < (8.5 + ecShift*0.5)) )
1460 { dEdx = dEdX_HCal; radX0 = radX0_HCal;
1462 else if( (lR < 193 && lZ > 389 && lZ < 389 + ecShift ) || (lR > 264 && lR < 287 && lZ > 554 && lZ < 554 + ecShift)
1463 ||(lR < 264 && lR > 193 && fabs(441.5+8.5+0.5*ecShift - lZ + (lR - 269.)/1.327) < ecShift*0.5) ) {
1464 dEdx = dEdX_Air; radX0 = radX0_Air;
1466 else {dEdx = dEdX_HCal*0.05; radX0 = radX0_Air; }
1469 else if (lZ < 564 + ecShift){
1471 rzLims = MatBounds(129, 251, 554 + ecShift, 564 + ecShift);
1472 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1475 rzLims = MatBounds(251, 287, 554 + ecShift, 564 + ecShift);
1476 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1479 else if (lZ < 625 + ecShift){
1480 rzLims = MatBounds(129, 287, 564 + ecShift, 625 + ecShift);
1481 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1483 else if (lZ < 785 + ecShift){
1484 if (lR < 275) rzLims = MatBounds(129, 275, 625 + ecShift, 785 + ecShift);
1486 if (lZ < 720 + ecShift) rzLims = MatBounds(275, 287, 625 + ecShift, 720 + ecShift);
1487 else rzLims = MatBounds(275, 287, 720 + ecShift, 785 + ecShift);
1489 if (! (lR > 275 && lZ < 720 + ecShift)) { dEdx = dEdX_Fe; radX0 = radX0_Fe; }
1490 else { dEdx = dEdX_MCh; radX0 = radX0_MCh; }
1492 else if (lZ < 850 + ecShift){
1493 rzLims = MatBounds(129, 287, 785 + ecShift, 850 + ecShift);
1494 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1496 else if (lZ < 910 + ecShift){
1497 rzLims = MatBounds(129, 287, 850 + ecShift, 910 + ecShift);
1498 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1500 else if (lZ < 975 + ecShift){
1501 rzLims = MatBounds(129, 287, 910 + ecShift, 975 + ecShift);
1502 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1504 else if (lZ < 1000 + ecShift){
1505 rzLims = MatBounds(129, 287, 975 + ecShift, 1000 + ecShift);
1506 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1508 else if (lZ < 1063 + ecShift){
1509 rzLims = MatBounds(129, 287, 1000 + ecShift, 1063 + ecShift);
1510 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1512 else if ( lZ < 1073 + ecShift){
1513 rzLims = MatBounds(129, 287, 1063 + ecShift, 1073 + ecShift);
1514 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1516 else if (lZ < 1E4 ) {
1517 rzLims = MatBounds(129, 287, 1073 + ecShift, 1E4);
1518 dEdx = dEdX_Air; radX0 = radX0_Air;
1522 dEdx = dEdX_Air; radX0 = radX0_Air;
1525 else if (lR <380 && lZ < 667){
1527 if (lR < 315) rzLims = MatBounds(287, 315, 0, 630);
1528 else if (lR < 341 ) rzLims = MatBounds(315, 341, 0, 630);
1529 else rzLims = MatBounds(341, 380, 0, 630);
1530 }
else rzLims = MatBounds(287, 380, 630, 667);
1532 if (lZ < 630) { dEdx = dEdX_coil; radX0 = radX0_coil; }
1533 else {dEdx = dEdX_Air; radX0 = radX0_Air; }
1538 bool isIron =
false;
1540 if (useIsYokeFlag_ && useMagVolumes_ && sv.magVol != 0){
1541 isIron = sv.isYokeVol;
1543 double bMag = sv.bf.mag();
1544 isIron = (bMag > 0.75 && ! (lZ > 500 && lR <500 && bMag < 1.15)
1545 && ! (lZ < 450 && lR > 420 && bMag < 1.15 ) );
1548 rzLims = MatBounds(380, 850, 0, 667);
1549 if (isIron) { dEdx = dEdX_Fe; radX0 = radX0_Fe; }
1550 else { dEdx = dEdX_MCh; radX0 = radX0_MCh; }
1552 rzLims = MatBounds(850, 1E4, 0, 667);
1553 dEdx = dEdX_Air; radX0 = radX0_Air;
1556 else if (lR > 750 ){
1557 rzLims = MatBounds(750, 1E4, 667, 1E4);
1558 dEdx = dEdX_Air; radX0 = radX0_Air;
1560 else if (lZ < 667 + ecShift){
1561 rzLims = MatBounds(287, 750, 667, 667 + ecShift);
1562 dEdx = dEdX_Air; radX0 = radX0_Air;
1565 else if (lZ < 724 + ecShift){
1566 if (lR < 380 ) rzLims = MatBounds(287, 380, 667 + ecShift, 724 + ecShift);
1567 else rzLims = MatBounds(380, 750, 667 + ecShift, 724 + ecShift);
1568 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1570 else if (lZ < 785 + ecShift){
1571 if (lR < 380 ) rzLims = MatBounds(287, 380, 724 + ecShift, 785 + ecShift);
1572 else rzLims = MatBounds(380, 750, 724 + ecShift, 785 + ecShift);
1573 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1575 else if (lZ < 850 + ecShift){
1576 rzLims = MatBounds(287, 750, 785 + ecShift, 850 + ecShift);
1577 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1579 else if (lZ < 910 + ecShift){
1580 rzLims = MatBounds(287, 750, 850 + ecShift, 910 + ecShift);
1581 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1583 else if (lZ < 975 + ecShift){
1584 rzLims = MatBounds(287, 750, 910 + ecShift, 975 + ecShift);
1585 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1587 else if (lZ < 1000 + ecShift){
1588 rzLims = MatBounds(287, 750, 975 + ecShift, 1000 + ecShift);
1589 dEdx = dEdX_Fe; radX0 = radX0_Fe;
1591 else if (lZ < 1063 + ecShift){
1593 rzLims = MatBounds(287, 360, 1000 + ecShift, 1063 + ecShift);
1594 dEdx = dEdX_MCh; radX0 = radX0_MCh;
1598 rzLims = MatBounds(360, 750, 1000 + ecShift, 1063 + ecShift);
1599 dEdx = dEdX_Air; radX0 = radX0_Air;
1602 else if ( lZ < 1073 + ecShift){
1603 rzLims = MatBounds(287, 750, 1063 + ecShift, 1073 + ecShift);
1605 dEdx = dEdX_Air; radX0 = radX0_Air;
1607 else if (lZ < 1E4 ) {
1608 rzLims = MatBounds(287, 750, 1073 + ecShift, 1E4);
1609 dEdx = dEdX_Air; radX0 = radX0_Air;
1611 else {dEdx = dEdX_Air; radX0 = radX0_Air; }
1617 double p0 = sv.p3.mag();
1618 double logp0 =
log(p0);
1619 double p0powN33 = 0;
1625 double dEdX_mat = -(11.4 + 0.96*fabs(logp0+
log(2.8)) + 0.033*p0*(1.0 - p0powN33) )*1
e-3;
1628 dEdXPrime = dEdx == 0 ? 0 : -dEdx*(0.96/p0 + 0.033 - 0.022*p0powN33)*1
e-3;
1635 int SteppingHelixPropagator::cIndex_(
int ind)
const{
1636 int result = ind%MAX_POINTS;
1637 if (ind != 0 && result == 0){
1638 result = MAX_POINTS;
1643 SteppingHelixPropagator::Result
1644 SteppingHelixPropagator::refToDest(SteppingHelixPropagator::DestType
dest,
1645 const SteppingHelixPropagator::StateInfo& sv,
1646 const double pars[6],
1647 double& dist,
double& tanDist,
1649 double fastSkipDist)
const{
1650 static const std::string metname =
"SteppingHelixPropagator";
1656 double curR = sv.r3.perp();
1657 dist = pars[RADIUS_P] - curR;
1658 if (fabs(dist) > fastSkipDist){
1662 double curP2 = sv.p3.mag2();
1663 double curPtPos2 = sv.p3.perp2();
if(curPtPos2< 1
e-16) curPtPos2=1
e-16;
1665 double cosDPhiPR = (sv.r3.x()*sv.p3.x()+sv.r3.y()*sv.p3.y());
1666 refDirection = dist*cosDPhiPR > 0 ?
1668 tanDist = dist*
sqrt(curP2/curPtPos2);
1674 double curZ = sv.r3.z();
1675 dist = pars[Z_P] - curZ;
1676 if (fabs(dist) > fastSkipDist){
1680 double curP = sv.p3.mag();
1681 refDirection = sv.p3.z()*dist > 0. ?
1683 tanDist = dist/sv.p3.z()*curP;
1689 Point rPlane(pars[0], pars[1], pars[2]);
1690 Vector nPlane(pars[3], pars[4], pars[5]);
1696 double dRDotN = (sv.r3.x()-rPlane.x())*nPlane.x() + (sv.r3.y()-rPlane.y())*nPlane.y() + (sv.r3.z()-rPlane.z())*nPlane.z();
1698 dist = fabs(dRDotN);
1699 if (dist > fastSkipDist){
1703 double curP = sv.p3.mag();
1705 double p0Inv = 1./p0;
1707 double tN = tau.dot(nPlane);
1708 refDirection = tN*dRDotN < 0. ?
1710 double b0 = sv.bf.mag();
1711 if (fabs(tN)>1
e-24){
1712 tanDist = -dRDotN/tN;
1715 if (fabs(dRDotN)>1
e-24) tanDist = 1e6;
1718 if (fabs(tanDist) > 1e4) tanDist = 1e4;
1720 double b0Inv = 1./b0;
1721 double tNInv = 1./tN;
1722 Vector bHat(sv.bf); bHat *=b0Inv;
1723 double bHatN = bHat.dot(nPlane);
1724 double cosPB = bHat.dot(tau);
1725 double kVal = 2.99792458e-3*sv.q*p0Inv*b0;
1726 double aVal = tanDist*kVal;
1727 Vector lVec = bHat.cross(tau);
1728 double bVal = lVec.dot(nPlane)*tNInv;
1729 if (fabs(aVal*bVal)< 0.3){
1730 double cVal = 1. - bHatN*cosPB*tNInv;
1731 double aacVal = cVal*aVal*aVal;
1732 if (fabs(aacVal)<1){
1733 double tanDCorr = bVal/2. + (bVal*bVal/2. + cVal/6)*aVal;
1736 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<tanDist<<
" vs "
1737 <<tanDist*(1.+tanDCorr)<<
" corr "<<tanDist*tanDCorr<<std::endl;
1738 tanDist *= (1.+tanDCorr);
1740 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"AACVal "<< fabs(aacVal)
1741 <<
" = "<<aVal<<
"**2 * "<<cVal<<
" too large:: will not converge"<<std::endl;
1744 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"ABVal "<< fabs(aVal*bVal)
1745 <<
" = "<<aVal<<
" * "<<bVal<<
" too large:: will not converge"<<std::endl;
1753 Point cVertex(pars[0], pars[1], pars[2]);
1754 if (cVertex.perp2() < 1
e-10){
1756 Vector relV3 = sv.r3 - cVertex;
1757 double relV3mag = relV3.mag();
1759 double theta(pars[3]);
1763 double cosV3Theta = relV3.z()/relV3mag;
1764 if (cosV3Theta>1) cosV3Theta=1;
1765 if (cosV3Theta<-1) cosV3Theta=-1;
1766 double sinV3Theta =
sqrt(1.-cosV3Theta*cosV3Theta);
1768 double sinDTheta = sinTheta*cosV3Theta - cosTheta*sinV3Theta;
1769 double cosDTheta = cosTheta*cosV3Theta + sinTheta*sinV3Theta;
1770 bool isInside = sinTheta > sinV3Theta && cosTheta*cosV3Theta > 0;
1771 dist = isInside || cosDTheta > 0 ? relV3mag*sinDTheta : relV3mag;
1772 if (fabs(dist) > fastSkipDist){
1777 double relV3phi=relV3.phi();
1778 double normPhi = isInside ?
1784 Vector norm; norm.setRThetaPhi(fabs(dist), normTheta, normPhi);
1785 double curP = sv.p3.mag();
double cosp3theta = sv.p3.z()/curP;
1786 if (cosp3theta>1) cosp3theta=1;
1787 if (cosp3theta<-1) cosp3theta=-1;
1788 double sineConeP = sinTheta*cosp3theta - cosTheta*
sqrt(1.-cosp3theta*cosp3theta);
1790 double sinSolid = norm.dot(sv.p3)/(fabs(dist)*curP);
1791 tanDist = fabs(sinSolid) > fabs(sineConeP) ? dist/fabs(sinSolid) : dist/fabs(sineConeP);
1794 refDirection = sinSolid > 0 ?
1797 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Cone pars: theta "<<
theta
1798 <<
" normTheta "<<norm.theta()
1799 <<
" p3Theta "<<sv.p3.theta()
1800 <<
" sinD: "<< sineConeP
1801 <<
" sinSolid "<<sinSolid;
1804 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"refToDest:toCone the point is "
1805 <<(isInside?
"in" :
"out")<<
"side the cone"
1816 double curS = fabs(sv.path());
1817 dist = pars[PATHL_P] - curS;
1818 if (fabs(dist) > fastSkipDist){
1822 refDirection = pars[PATHL_P] > 0 ?
1830 Point pDest(pars[0], pars[1], pars[2]);
1831 double curP = sv.p3.mag();
1832 dist = (sv.r3 - pDest).
mag()+ 1
e-24;
1833 tanDist = (sv.r3.dot(sv.p3) - pDest.dot(sv.p3))/curP;
1835 double b0 = sv.bf.mag();
1838 double kVal = 2.99792458e-3*sv.q/p0*b0;
1839 double aVal = fabs(dist*kVal);
1840 tanDist *= 1./(1.+ aVal);
1841 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"corrected by aVal "<<aVal<<
" to "<<tanDist;
1843 refDirection = tanDist < 0 ?
1850 Point rLine(pars[0], pars[1], pars[2]);
1851 Vector dLine(pars[3], pars[4], pars[5]);
1852 dLine = (dLine - rLine);
1853 dLine *= 1./dLine.mag();
if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"dLine "<<dLine;
1856 double curP = sv.p3.mag();
1857 Vector dRPerp = dR - dLine*(dR.dot(dLine));
1858 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"dRperp "<<dRPerp;
1860 dist = dRPerp.mag() + 1
e-24;
1861 tanDist = dRPerp.dot(sv.p3)/curP;
1863 double cosAlpha2 = dLine.dot(sv.p3)/curP; cosAlpha2 *= cosAlpha2;
1864 tanDist *= 1./
sqrt(fabs(1.-cosAlpha2)+1
e-96);
1867 double b0 = sv.bf.mag();
1870 double kVal = 2.99792458e-3*sv.q/p0*b0;
1871 double aVal = fabs(dist*kVal);
1872 tanDist *= 1./(1.+ aVal);
1873 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"corrected by aVal "<<aVal<<
" to "<<tanDist;
1875 refDirection = tanDist < 0 ?
1891 double tanDistConstrained = tanDist;
1892 if (fabs(tanDist) > 4.*fabs(dist) ) tanDistConstrained *= tanDist == 0 ? 0 : fabs(dist/tanDist*4.);
1895 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"refToDest input: dest"<<dest<<
" pars[]: ";
1896 for (
int i = 0;
i < 6;
i++){
1897 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
", "<<
i<<
" "<<pars[
i];
1899 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<std::endl;
1900 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"refToDest output: "
1902 <<
"\t tanDist "<< tanDist
1903 <<
"\t tanDistConstr "<< tanDistConstrained
1904 <<
"\t refDirection "<< refDirection
1907 tanDist = tanDistConstrained;
1912 SteppingHelixPropagator::Result
1913 SteppingHelixPropagator::refToMagVolume(
const SteppingHelixPropagator::StateInfo& sv,
1915 double& dist,
double& tanDist,
1916 double fastSkipDist,
bool expectNewMagVolume,
double maxStep)
const{
1918 static const std::string metname =
"SteppingHelixPropagator";
1922 if (cVol == 0)
return result;
1923 const std::vector<VolumeSide>& cVolFaces(cVol->
faces());
1925 double distToFace[6] = {0,0,0,0,0,0};
1926 double tanDistToFace[6] = {0,0,0,0,0,0};
1932 unsigned int iFDestSorted[6] = {0,0,0,0,0,0};
1933 unsigned int nDestSorted =0;
1934 unsigned int nearParallels = 0;
1936 double curP = sv.p3.mag();
1940 <<
" with "<<cVolFaces.size()<<
" faces"<<std::endl;
1943 unsigned int nFaces = cVolFaces.size();
1944 for (
unsigned int iFace = 0; iFace < nFaces; ++iFace){
1946 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Too many faces"<<std::endl;
1949 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Start with face "<<iFace<<std::endl;
1956 const Cone* cCone = 0;
1957 if (
typeid(cVolFaces[iFace].surface()) ==
typeid(
const Plane&)){
1958 cPlane = &cVolFaces[iFace].surface();
1959 }
else if (
typeid(cVolFaces[iFace].surface()) ==
typeid(
const Cylinder&)){
1960 cCyl =
dynamic_cast<const Cylinder*
>(&cVolFaces[iFace].surface());
1961 }
else if (
typeid(cVolFaces[iFace].surface()) ==
typeid(
const Cone&)){
1962 cCone =
dynamic_cast<const Cone*
>(&cVolFaces[iFace].surface());
1964 edm::LogWarning(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Could not cast a volume side surface to a known type"<<std::endl;
1968 if (cPlane!=0)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"The face is a plane at "<<cPlane<<std::endl;
1969 if (cCyl!=0)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"The face is a cylinder at "<<cCyl<<std::endl;
1972 double pars[6] = {0,0,0,0,0,0};
1973 DestType dType = UNDEFINED_DT;
1979 pars[0] = rPlane.x(); pars[1] = rPlane.y(); pars[2] = rPlane.z();
1980 pars[3] = nPlane.x(); pars[4] = nPlane.y(); pars[5] = nPlane.z();
1982 }
else if (cCyl != 0){
1984 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Cylinder at "<<cCyl->position()
1985 <<
" rorated by "<<cCyl->rotation()
1988 pars[RADIUS_P] = cCyl->radius();
1990 }
else if (cCone != 0){
1992 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Cone at "<<cCone->position()
1993 <<
" rorated by "<<cCone->rotation()
1994 <<
" vertex at "<<cCone->vertex()
1995 <<
" angle of "<<cCone->openingAngle()
1998 pars[0] = cCone->vertex().x(); pars[1] = cCone->vertex().y();
1999 pars[2] = cCone->vertex().z();
2000 pars[3] = cCone->openingAngle();
2003 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Unknown surface"<<std::endl;
2007 resultToFace[iFace] =
2008 refToDest(dType, sv, pars,
2009 distToFace[iFace], tanDistToFace[iFace], refDirectionToFace[iFace], fastSkipDist);
2020 double invDTFPosiF = 1./(1
e-32+fabs(tanDistToFace[iFace]));
2021 double dSlope = fabs(distToFace[iFace])*invDTFPosiF;
2022 double maxStepL = maxStep> 100 ? 100 : maxStep;
if (maxStepL < 10) maxStepL = 10.;
2023 bool isNearParallel = fabs(tanDistToFace[iFace]) + 100.*curP*dSlope < maxStepL
2026 if (refDirectionToFace[iFace] == dir || isNearParallel){
2027 if (isNearParallel) nearParallels++;
2028 iFDestSorted[nDestSorted] = iFace;
2034 if (refDirectionToFace[iFace] == dir){
2035 if (iDistMin == -1) iDistMin = iFace;
2036 else if (fabs(distToFace[iFace]) < fabs(distToFace[iDistMin])) iDistMin = iFace;
2039 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<cVol<<
" "<<iFace<<
" "
2040 <<tanDistToFace[iFace]<<
" "<<distToFace[iFace]<<
" "<<refDirectionToFace[iFace]<<
" "<<dir<<std::endl;
2044 for (
unsigned int i = 0;
i<nDestSorted; ++
i){
2045 unsigned int iMax = nDestSorted-
i-1;
2046 for (
unsigned int j=0;
j<nDestSorted-
i; ++
j){
2047 if (fabs(tanDistToFace[iFDestSorted[
j]]) > fabs(tanDistToFace[iFDestSorted[iMax]]) ){
2051 unsigned int iTmp = iFDestSorted[nDestSorted-i-1];
2052 iFDestSorted[nDestSorted-i-1] = iFDestSorted[iMax];
2053 iFDestSorted[iMax] = iTmp;
2057 for (
unsigned int i=0;i<nDestSorted;++
i){
2058 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<cVol<<
" "<<i<<
" "<<iFDestSorted[
i]<<
" "<<tanDistToFace[iFDestSorted[
i]]<<std::endl;
2065 for (
unsigned int i=0; i<nDestSorted;++
i){
2066 iFDest = iFDestSorted[
i];
2069 Point gPointEst(sv.r3);
2070 Vector lDelta(sv.p3); lDelta *= sign/curP*fabs(distToFace[iFDest]);
2071 gPointEst += lDelta;
2073 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Linear est point "<<gPointEst
2074 <<
" for iFace "<<iFDest<<std::endl;
2076 GlobalPoint gPointEstNorZ(gPointEst.x(), gPointEst.y(), gPointEst.z() );
2077 if ( cVol->
inside(gPointEstNorZ) ){
2079 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"The point is inside the volume"<<std::endl;
2083 dist = distToFace[iFDest];
2084 tanDist = tanDistToFace[iFDest];
2086 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Got a point near closest boundary -- face "<<iFDest<<std::endl;
2099 Point gPointEst(sv.r3);
2100 double lDist = iDistMin == -1 ? fastSkipDist : fabs(distToFace[iDistMin]);
2101 if (lDist > fastSkipDist) lDist = fastSkipDist;
2102 Vector lDelta(sv.p3); lDelta *= sign/curP*lDist;
2103 gPointEst += lDelta;
2105 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Linear est point to shortest dist "<<gPointEst
2106 <<
" for iFace "<<iDistMin<<
" at distance "<<lDist*sign<<std::endl;
2108 GlobalPoint gPointEstNorZ(gPointEst.x(), gPointEst.y(), gPointEst.z() );
2109 if ( cVol->
inside(gPointEstNorZ) ){
2111 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"The point is inside the volume"<<std::endl;
2121 tanDist = dist*1.01;
2123 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Wrong volume located: return small dist, tandist"<<std::endl;
2129 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"All faces are too far"<<std::endl;
2131 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Appear to be in a wrong volume"<<std::endl;
2133 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Something else went wrong"<<std::endl;
2141 SteppingHelixPropagator::Result
2142 SteppingHelixPropagator::refToMatVolume(
const SteppingHelixPropagator::StateInfo& sv,
2144 double& dist,
double& tanDist,
2145 double fastSkipDist)
const{
2147 static const std::string metname =
"SteppingHelixPropagator";
2150 double parLim[6] = {sv.rzLims.rMin, sv.rzLims.rMax,
2151 sv.rzLims.zMin, sv.rzLims.zMax,
2152 sv.rzLims.th1, sv.rzLims.th2 };
2154 double distToFace[4] = {0,0,0,0};
2155 double tanDistToFace[4] = {0,0,0,0};
2160 double curP = sv.p3.mag();
2162 for (
unsigned int iFace = 0; iFace < 4; iFace++){
2164 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Start with mat face "<<iFace<<std::endl;
2167 double pars[6] = {0,0,0,0,0,0};
2168 DestType dType = UNDEFINED_DT;
2170 if (fabs(parLim[iFace+2])< 1
e-6){
2172 pars[0] = 0; pars[1] = 0; pars[2] = -parLim[iFace];
2173 pars[3] = 0; pars[4] = 0; pars[5] = 1;
2175 pars[0] = 0; pars[1] = 0; pars[2] = parLim[iFace];
2176 pars[3] = 0; pars[4] = 0; pars[5] = 1;
2181 pars[0] = 0; pars[1] = 0;
2182 pars[2] = parLim[iFace];
2183 pars[3] =
Geom::pi()/2. - parLim[iFace+2];
2185 pars[0] = 0; pars[1] = 0;
2186 pars[2] = - parLim[iFace];
2187 pars[3] =
Geom::pi()/2. + parLim[iFace+2];
2192 pars[RADIUS_P] = parLim[iFace];
2196 resultToFace[iFace] =
2197 refToDest(dType, sv, pars,
2198 distToFace[iFace], tanDistToFace[iFace], refDirectionToFace[iFace], fastSkipDist);
2204 if (refDirectionToFace[iFace] == dir || fabs(distToFace[iFace]) < 2
e-2*fabs(tanDistToFace[iFace]) ){
2206 Point gPointEst(sv.r3);
2207 Vector lDelta(sv.p3); lDelta *= sign*fabs(distToFace[iFace])/curP;
2208 gPointEst += lDelta;
2210 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Linear est point "<<gPointEst
2213 double lZ = fabs(gPointEst.z());
2214 double lR = gPointEst.perp();
2215 double tan4 = parLim[4] == 0 ? 0 :
tan(parLim[4]);
2216 double tan5 = parLim[5] == 0 ? 0 :
tan(parLim[5]);
2217 if ( (lZ - parLim[2]) > lR*tan4
2218 && (lZ - parLim[3]) < lR*tan5
2219 && lR > parLim[0] && lR < parLim[1]){
2221 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"The point is inside the volume"<<std::endl;
2227 if (fabs(tanDistToFace[iFDest]) > fabs(tanDistToFace[iFace])){
2233 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"The point is NOT inside the volume"<<std::endl;
2241 dist = distToFace[iFDest];
2242 tanDist = tanDistToFace[iFDest];
2244 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Got a point near closest boundary -- face "<<iFDest<<std::endl;
2248 LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Failed to find a dest point inside the volume"<<std::endl;
2256 bool SteppingHelixPropagator::isYokeVolume(
const MagVolume* vol)
const {
2257 static const std::string metname =
"SteppingHelixPropagator";
2258 if (vol == 0)
return false;
2280 bool result = vol->
isIron();
2282 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Volume is magnetic, located at "<<vol->
position()<<std::endl;
2284 if (debug_)
LogTrace(metname)<<std::setprecision(17)<<std::setw(20)<<std::scientific<<
"Volume is not magnetic, located at "<<vol->
position()<<std::endl;
double z0() const
z coordinate
DDSolidShape shapeType() const
const std::string metname
ROOT::Math::Plane3D::Vector Vector
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
ROOT::Math::SMatrixIdentity AlgebraicMatrixID
Sin< T >::type sin(const T &t)
Global3DPoint GlobalPoint
Geom::Theta< T > theta() const
AlgebraicSymMatrix55 covCurv
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
double dydz() const
dydz slope
static const char *const name(DDSolidShape s)
virtual bool inside(const GlobalPoint &gp, double tolerance=0.) const =0
tuple SteppingHelixPropagator
Cos< T >::type cos(const T &t)
Tan< T >::type tan(const T &t)
double dxdz() const
dxdz slope
bool isIron() const
Temporary hack to pass information on material. Will eventually be replaced!
virtual const std::vector< VolumeSide > & faces() const =0
Access to volume faces.
std::vector< std::vector< double > > tmp
double y0() const
y coordinate
const RotationType & rotation() const
const PositionType & position() const
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepStd< double, 5, 5 > > AlgebraicMatrix55
static const std::string ResultName[MAX_RESULT]
double x0() const
x coordinate