File indexing completed on 2025-08-05 08:18:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include "RKTrackRep.h"
0021 #include "IO.h"
0022
0023 #include <Exception.h>
0024 #include <FieldManager.h>
0025 #include <MaterialEffects.h>
0026 #include <MeasuredStateOnPlane.h>
0027 #include <MeasurementOnPlane.h>
0028
0029 #include <TBuffer.h>
0030 #include <TDecompLU.h>
0031 #include <TMath.h>
0032
0033 #include <algorithm>
0034
0035 #define MINSTEP 0.001
0036
0037 namespace {
0038
0039 const bool useInvertFast = false;
0040 }
0041
0042 namespace genfit {
0043
0044
0045 RKTrackRep::RKTrackRep() :
0046 AbsTrackRep(),
0047 lastStartState_(this),
0048 lastEndState_(this),
0049 RKStepsFXStart_(0),
0050 RKStepsFXStop_(0),
0051 fJacobian_(5,5),
0052 fNoise_(5),
0053 useCache_(false),
0054 cachePos_(0)
0055 {
0056 initArrays();
0057 }
0058
0059
0060 RKTrackRep::RKTrackRep(int pdgCode, char propDir) :
0061 AbsTrackRep(pdgCode, propDir),
0062 lastStartState_(this),
0063 lastEndState_(this),
0064 RKStepsFXStart_(0),
0065 RKStepsFXStop_(0),
0066 fJacobian_(5,5),
0067 fNoise_(5),
0068 useCache_(false),
0069 cachePos_(0)
0070 {
0071 initArrays();
0072 }
0073
0074
0075 RKTrackRep::~RKTrackRep() {
0076 ;
0077 }
0078
0079
0080 double RKTrackRep::extrapolateToPlane(StateOnPlane& state,
0081 const SharedPlanePtr& plane,
0082 bool stopAtBoundary,
0083 bool calcJacobianNoise) const {
0084
0085 if (debugLvl_ > 0) {
0086 debugOut << "RKTrackRep::extrapolateToPlane()\n";
0087 }
0088
0089
0090 if (state.getPlane() == plane) {
0091 if (debugLvl_ > 0) {
0092 debugOut << "state is already defined at plane. Do nothing! \n";
0093 }
0094 return 0;
0095 }
0096
0097 checkCache(state, &plane);
0098
0099
0100 M1x7 state7 = {{0, 0, 0, 0, 0, 0, 0}};
0101 getState7(state, state7);
0102
0103 TMatrixDSym* covPtr(nullptr);
0104 bool fillExtrapSteps(false);
0105 if (dynamic_cast<MeasuredStateOnPlane*>(&state) != nullptr) {
0106 covPtr = &(static_cast<MeasuredStateOnPlane*>(&state)->getCov());
0107 fillExtrapSteps = true;
0108 }
0109 else if (calcJacobianNoise)
0110 fillExtrapSteps = true;
0111
0112
0113 bool isAtBoundary(false);
0114 double flightTime( 0. );
0115 double coveredDistance( Extrap(*(state.getPlane()), *plane, getCharge(state), getMass(state), isAtBoundary, state7, flightTime, fillExtrapSteps, covPtr, false, stopAtBoundary) );
0116
0117 if (stopAtBoundary && isAtBoundary) {
0118 state.setPlane(SharedPlanePtr(new DetPlane(TVector3(state7[0], state7[1], state7[2]),
0119 TVector3(state7[3], state7[4], state7[5]))));
0120 }
0121 else {
0122 state.setPlane(plane);
0123 }
0124
0125
0126 getState5(state, state7);
0127 setTime(state, getTime(state) + flightTime);
0128
0129 lastEndState_ = state;
0130
0131 return coveredDistance;
0132 }
0133
0134
0135 double RKTrackRep::extrapolateToLine(StateOnPlane& state,
0136 const TVector3& linePoint,
0137 const TVector3& lineDirection,
0138 bool stopAtBoundary,
0139 bool calcJacobianNoise) const {
0140
0141 if (debugLvl_ > 0) {
0142 debugOut << "RKTrackRep::extrapolateToLine()\n";
0143 }
0144
0145 checkCache(state, nullptr);
0146
0147 static const unsigned int maxIt(1000);
0148
0149
0150 M1x7 state7;
0151 getState7(state, state7);
0152
0153 bool fillExtrapSteps(false);
0154 if (dynamic_cast<MeasuredStateOnPlane*>(&state) != nullptr) {
0155 fillExtrapSteps = true;
0156 }
0157 else if (calcJacobianNoise)
0158 fillExtrapSteps = true;
0159
0160
0161 double step(0.), lastStep(0.), maxStep(1.E99), angle(0), distToPoca(0), tracklength(0);
0162 double charge = getCharge(state);
0163 double mass = getMass(state);
0164 double flightTime = 0;
0165 TVector3 dir(state7[3], state7[4], state7[5]);
0166 TVector3 lastDir(0,0,0);
0167 TVector3 poca, poca_onwire;
0168 bool isAtBoundary(false);
0169
0170 DetPlane startPlane(*(state.getPlane()));
0171 SharedPlanePtr plane(new DetPlane(linePoint, dir.Cross(lineDirection), lineDirection));
0172 unsigned int iterations(0);
0173
0174 while(true){
0175 if(++iterations == maxIt) {
0176 Exception exc("RKTrackRep::extrapolateToLine ==> extrapolation to line failed, maximum number of iterations reached",__LINE__,__FILE__);
0177 exc.setFatal();
0178 throw exc;
0179 }
0180
0181 lastStep = step;
0182 lastDir = dir;
0183
0184 step = this->Extrap(startPlane, *plane, charge, mass, isAtBoundary, state7, flightTime, false, nullptr, true, stopAtBoundary, maxStep);
0185 tracklength += step;
0186
0187 dir.SetXYZ(state7[3], state7[4], state7[5]);
0188 poca.SetXYZ(state7[0], state7[1], state7[2]);
0189 poca_onwire = pocaOnLine(linePoint, lineDirection, poca);
0190
0191
0192 if (stopAtBoundary && isAtBoundary) {
0193 plane->setON(dir, poca);
0194 break;
0195 }
0196
0197 angle = fabs(dir.Angle((poca_onwire-poca))-TMath::PiOver2());
0198 distToPoca = (poca_onwire-poca).Mag();
0199 if (angle*distToPoca < 0.1*MINSTEP) break;
0200
0201
0202
0203 if (lastStep*step < 0){
0204 dir += lastDir;
0205 maxStep = 0.5*fabs(lastStep);
0206 }
0207
0208 startPlane = *plane;
0209 plane->setU(dir.Cross(lineDirection));
0210 }
0211
0212 if (fillExtrapSteps) {
0213
0214 lastEndState_.setPlane(plane);
0215 getState5(lastEndState_, state7);
0216
0217 tracklength = extrapolateToPlane(state, plane, false, true);
0218 lastEndState_.getAuxInfo()(1) = state.getAuxInfo()(1);
0219 }
0220 else {
0221 state.setPlane(plane);
0222 getState5(state, state7);
0223 state.getAuxInfo()(1) += flightTime;
0224 }
0225
0226 if (debugLvl_ > 0) {
0227 debugOut << "RKTrackRep::extrapolateToLine(): Reached POCA after " << iterations+1 << " iterations. Distance: " << (poca_onwire-poca).Mag() << " cm. Angle deviation: " << dir.Angle((poca_onwire-poca))-TMath::PiOver2() << " rad \n";
0228 }
0229
0230 lastEndState_ = state;
0231
0232 return tracklength;
0233 }
0234
0235
0236 double RKTrackRep::extrapToPoint(StateOnPlane& state,
0237 const TVector3& point,
0238 const TMatrixDSym* G,
0239 bool stopAtBoundary,
0240 bool calcJacobianNoise) const {
0241
0242 if (debugLvl_ > 0) {
0243 debugOut << "RKTrackRep::extrapolateToPoint()\n";
0244 }
0245
0246 checkCache(state, nullptr);
0247
0248 static const unsigned int maxIt(1000);
0249
0250
0251 M1x7 state7;
0252 getState7(state, state7);
0253
0254 bool fillExtrapSteps(false);
0255 if (dynamic_cast<MeasuredStateOnPlane*>(&state) != nullptr) {
0256 fillExtrapSteps = true;
0257 }
0258 else if (calcJacobianNoise)
0259 fillExtrapSteps = true;
0260
0261
0262 double step(0.), lastStep(0.), maxStep(1.E99), angle(0), distToPoca(0), tracklength(0);
0263 TVector3 dir(state7[3], state7[4], state7[5]);
0264 if (G != nullptr) {
0265 if(G->GetNrows() != 3) {
0266 Exception exc("RKTrackRep::extrapolateToLine ==> G is not 3x3",__LINE__,__FILE__);
0267 exc.setFatal();
0268 throw exc;
0269 }
0270 dir = TMatrix(*G) * dir;
0271 }
0272 TVector3 lastDir(0,0,0);
0273
0274 TVector3 poca;
0275 bool isAtBoundary(false);
0276
0277 DetPlane startPlane(*(state.getPlane()));
0278 SharedPlanePtr plane(new DetPlane(point, dir));
0279 unsigned int iterations(0);
0280 double charge = getCharge(state);
0281 double mass = getMass(state);
0282 double flightTime = 0;
0283
0284 while(true){
0285 if(++iterations == maxIt) {
0286 Exception exc("RKTrackRep::extrapolateToPoint ==> extrapolation to point failed, maximum number of iterations reached",__LINE__,__FILE__);
0287 exc.setFatal();
0288 throw exc;
0289 }
0290
0291 lastStep = step;
0292 lastDir = dir;
0293
0294 step = this->Extrap(startPlane, *plane, charge, mass, isAtBoundary, state7, flightTime, false, nullptr, true, stopAtBoundary, maxStep);
0295 tracklength += step;
0296
0297 dir.SetXYZ(state7[3], state7[4], state7[5]);
0298 if (G != nullptr) {
0299 dir = TMatrix(*G) * dir;
0300 }
0301 poca.SetXYZ(state7[0], state7[1], state7[2]);
0302
0303
0304 if (stopAtBoundary && isAtBoundary) {
0305 plane->setON(dir, poca);
0306 break;
0307 }
0308
0309 angle = fabs(dir.Angle((point-poca))-TMath::PiOver2());
0310 distToPoca = (point-poca).Mag();
0311 if (angle*distToPoca < 0.1*MINSTEP) break;
0312
0313
0314
0315 if (lastStep*step < 0){
0316 if (G != nullptr) {
0317 dir.SetMag(1.);
0318 lastDir.SetMag(1.);
0319 }
0320 dir += lastDir;
0321 maxStep = 0.5*fabs(lastStep);
0322 }
0323
0324 startPlane = *plane;
0325 plane->setNormal(dir);
0326 }
0327
0328 if (fillExtrapSteps) {
0329
0330 lastEndState_.setPlane(plane);
0331 getState5(lastEndState_, state7);
0332
0333 tracklength = extrapolateToPlane(state, plane, false, true);
0334 lastEndState_.getAuxInfo()(1) = state.getAuxInfo()(1);
0335 }
0336 else {
0337 state.setPlane(plane);
0338 getState5(state, state7);
0339 state.getAuxInfo()(1) += flightTime;
0340 }
0341
0342
0343 if (debugLvl_ > 0) {
0344 debugOut << "RKTrackRep::extrapolateToPoint(): Reached POCA after " << iterations+1 << " iterations. Distance: " << (point-poca).Mag() << " cm. Angle deviation: " << dir.Angle((point-poca))-TMath::PiOver2() << " rad \n";
0345 }
0346
0347 lastEndState_ = state;
0348
0349 return tracklength;
0350 }
0351
0352
0353 double RKTrackRep::extrapolateToCylinder(StateOnPlane& state,
0354 double radius,
0355 const TVector3& linePoint,
0356 const TVector3& lineDirection,
0357 bool stopAtBoundary,
0358 bool calcJacobianNoise) const {
0359
0360 if (debugLvl_ > 0) {
0361 debugOut << "RKTrackRep::extrapolateToCylinder()\n";
0362 }
0363
0364 checkCache(state, nullptr);
0365
0366 static const unsigned int maxIt(1000);
0367
0368
0369 M1x7 state7;
0370 getState7(state, state7);
0371
0372 bool fillExtrapSteps(false);
0373 if (dynamic_cast<MeasuredStateOnPlane*>(&state) != nullptr) {
0374 fillExtrapSteps = true;
0375 }
0376 else if (calcJacobianNoise)
0377 fillExtrapSteps = true;
0378
0379 double tracklength(0.), maxStep(1.E99);
0380
0381 TVector3 dest, pos, dir;
0382
0383 bool isAtBoundary(false);
0384
0385 DetPlane startPlane(*(state.getPlane()));
0386 SharedPlanePtr plane(new DetPlane());
0387 unsigned int iterations(0);
0388 double charge = getCharge(state);
0389 double mass = getMass(state);
0390 double flightTime = 0;
0391
0392 while(true){
0393 if(++iterations == maxIt) {
0394 Exception exc("RKTrackRep::extrapolateToCylinder ==> maximum number of iterations reached",__LINE__,__FILE__);
0395 exc.setFatal();
0396 throw exc;
0397 }
0398
0399 pos.SetXYZ(state7[0], state7[1], state7[2]);
0400 dir.SetXYZ(state7[3], state7[4], state7[5]);
0401
0402
0403 TVector3 AO = (pos - linePoint);
0404 TVector3 AOxAB = (AO.Cross(lineDirection));
0405 TVector3 VxAB = (dir.Cross(lineDirection));
0406 float ab2 = (lineDirection * lineDirection);
0407 float a = (VxAB * VxAB);
0408 float b = 2 * (VxAB * AOxAB);
0409 float c = (AOxAB * AOxAB) - (radius*radius * ab2);
0410 double arg = b*b - 4.*a*c;
0411 if(arg < 0) {
0412 Exception exc("RKTrackRep::extrapolateToCylinder ==> cannot solve",__LINE__,__FILE__);
0413 exc.setFatal();
0414 throw exc;
0415 }
0416 double term = sqrt(arg);
0417 double k1, k2;
0418 if (b<0) {
0419 k1 = (-b + term)/(2.*a);
0420 k2 = 2.*c/(-b + term);
0421 }
0422 else {
0423 k1 = 2.*c/(-b - term);
0424 k2 = (-b - term)/(2.*a);
0425 }
0426
0427
0428 double k = k1;
0429 if (fabs(k2)<fabs(k))
0430 k = k2;
0431
0432 if (debugLvl_ > 0) {
0433 debugOut << "RKTrackRep::extrapolateToCylinder(); k = " << k << "\n";
0434 }
0435
0436 dest = pos + k * dir;
0437
0438 plane->setO(dest);
0439 plane->setUV((dest-linePoint).Cross(lineDirection), lineDirection);
0440
0441 tracklength += this->Extrap(startPlane, *plane, charge, mass, isAtBoundary, state7, flightTime, false, nullptr, true, stopAtBoundary, maxStep);
0442
0443
0444 if (stopAtBoundary && isAtBoundary) {
0445 pos.SetXYZ(state7[0], state7[1], state7[2]);
0446 dir.SetXYZ(state7[3], state7[4], state7[5]);
0447 plane->setO(pos);
0448 plane->setUV((pos-linePoint).Cross(lineDirection), lineDirection);
0449 break;
0450 }
0451
0452 if(fabs(k)<MINSTEP) break;
0453
0454 startPlane = *plane;
0455
0456 }
0457
0458 if (fillExtrapSteps) {
0459
0460 lastEndState_.setPlane(plane);
0461 getState5(lastEndState_, state7);
0462
0463 tracklength = extrapolateToPlane(state, plane, false, true);
0464 lastEndState_.getAuxInfo()(1) = state.getAuxInfo()(1);
0465 }
0466 else {
0467 state.setPlane(plane);
0468 getState5(state, state7);
0469 state.getAuxInfo()(1) += flightTime;
0470 }
0471
0472 lastEndState_ = state;
0473
0474 return tracklength;
0475 }
0476
0477
0478 double RKTrackRep::extrapolateToCone(StateOnPlane& state,
0479 double openingAngle,
0480 const TVector3& conePoint,
0481 const TVector3& coneDirection,
0482 bool stopAtBoundary,
0483 bool calcJacobianNoise) const {
0484
0485 if (debugLvl_ > 0) {
0486 debugOut << "RKTrackRep::extrapolateToCone()\n";
0487 }
0488
0489 checkCache(state, nullptr);
0490
0491 static const unsigned int maxIt(1000);
0492
0493
0494 M1x7 state7;
0495 getState7(state, state7);
0496
0497 bool fillExtrapSteps(false);
0498 if (dynamic_cast<MeasuredStateOnPlane*>(&state) != nullptr) {
0499 fillExtrapSteps = true;
0500 }
0501 else if (calcJacobianNoise)
0502 fillExtrapSteps = true;
0503
0504 double tracklength(0.), maxStep(1.E99);
0505
0506 TVector3 dest, pos, dir;
0507
0508 bool isAtBoundary(false);
0509
0510 DetPlane startPlane(*(state.getPlane()));
0511 SharedPlanePtr plane(new DetPlane());
0512 unsigned int iterations(0);
0513 double charge = getCharge(state);
0514 double mass = getMass(state);
0515 double flightTime = 0;
0516
0517 while(true){
0518 if(++iterations == maxIt) {
0519 Exception exc("RKTrackRep::extrapolateToCone ==> maximum number of iterations reached",__LINE__,__FILE__);
0520 exc.setFatal();
0521 throw exc;
0522 }
0523
0524 pos.SetXYZ(state7[0], state7[1], state7[2]);
0525 dir.SetXYZ(state7[3], state7[4], state7[5]);
0526
0527
0528
0529
0530
0531
0532 TVector3 cDirection = coneDirection.Unit();
0533 TVector3 Delta = (pos - conePoint);
0534 double DirDelta = cDirection * Delta;
0535 double Delta2 = Delta*Delta;
0536 double UDir = dir * cDirection;
0537 double UDelta = dir * Delta;
0538 double U2 = dir * dir;
0539 double cosAngle2 = cos(openingAngle)*cos(openingAngle);
0540 double a = UDir*UDir - cosAngle2*U2;
0541 double b = UDir*DirDelta - cosAngle2*UDelta;
0542 double c = DirDelta*DirDelta - cosAngle2*Delta2;
0543
0544 double arg = b*b - a*c;
0545 if(arg < -1e-9) {
0546 Exception exc("RKTrackRep::extrapolateToCone ==> cannot solve",__LINE__,__FILE__);
0547 exc.setFatal();
0548 throw exc;
0549 } else if(arg < 0) {
0550 arg = 0;
0551 }
0552
0553 double term = sqrt(arg);
0554 double k1, k2;
0555 k1 = (-b + term) / a;
0556 k2 = (-b - term) / a;
0557
0558
0559 double k = k1;
0560 if(fabs(k2) < fabs(k)) {
0561 k = k2;
0562 }
0563
0564 if (debugLvl_ > 0) {
0565 debugOut << "RKTrackRep::extrapolateToCone(); k = " << k << "\n";
0566 }
0567
0568 dest = pos + k * dir;
0569
0570
0571
0572 plane->setO(dest);
0573 plane->setUV((dest-conePoint).Cross(coneDirection), dest-conePoint);
0574
0575 tracklength += this->Extrap(startPlane, *plane, charge, mass, isAtBoundary, state7, flightTime, false, nullptr, true, stopAtBoundary, maxStep);
0576
0577
0578 if (stopAtBoundary && isAtBoundary) {
0579 pos.SetXYZ(state7[0], state7[1], state7[2]);
0580 dir.SetXYZ(state7[3], state7[4], state7[5]);
0581 plane->setO(pos);
0582 plane->setUV((pos-conePoint).Cross(coneDirection), pos-conePoint);
0583 break;
0584 }
0585
0586 if(fabs(k)<MINSTEP) break;
0587
0588 startPlane = *plane;
0589
0590 }
0591
0592 if (fillExtrapSteps) {
0593
0594 lastEndState_.setPlane(plane);
0595 getState5(lastEndState_, state7);
0596
0597 tracklength = extrapolateToPlane(state, plane, false, true);
0598 lastEndState_.getAuxInfo()(1) = state.getAuxInfo()(1);
0599 }
0600 else {
0601 state.setPlane(plane);
0602 getState5(state, state7);
0603 state.getAuxInfo()(1) += flightTime;
0604 }
0605
0606 lastEndState_ = state;
0607
0608 return tracklength;
0609 }
0610
0611
0612 double RKTrackRep::extrapolateToSphere(StateOnPlane& state,
0613 double radius,
0614 const TVector3& point,
0615 bool stopAtBoundary,
0616 bool calcJacobianNoise) const {
0617
0618 if (debugLvl_ > 0) {
0619 debugOut << "RKTrackRep::extrapolateToSphere()\n";
0620 }
0621
0622 checkCache(state, nullptr);
0623
0624 static const unsigned int maxIt(1000);
0625
0626
0627 M1x7 state7;
0628 getState7(state, state7);
0629
0630 bool fillExtrapSteps(false);
0631 if (dynamic_cast<MeasuredStateOnPlane*>(&state) != nullptr) {
0632 fillExtrapSteps = true;
0633 }
0634 else if (calcJacobianNoise)
0635 fillExtrapSteps = true;
0636
0637 double tracklength(0.), maxStep(1.E99);
0638
0639 TVector3 dest, pos, dir;
0640
0641 bool isAtBoundary(false);
0642
0643 DetPlane startPlane(*(state.getPlane()));
0644 SharedPlanePtr plane(new DetPlane());
0645 unsigned int iterations(0);
0646 double charge = getCharge(state);
0647 double mass = getMass(state);
0648 double flightTime = 0;
0649
0650 while(true){
0651 if(++iterations == maxIt) {
0652 Exception exc("RKTrackRep::extrapolateToSphere ==> maximum number of iterations reached",__LINE__,__FILE__);
0653 exc.setFatal();
0654 throw exc;
0655 }
0656
0657 pos.SetXYZ(state7[0], state7[1], state7[2]);
0658 dir.SetXYZ(state7[3], state7[4], state7[5]);
0659
0660
0661 TVector3 AO = (pos - point);
0662 double dirAO = dir * AO;
0663 double arg = dirAO*dirAO - AO*AO + radius*radius;
0664 if(arg < 0) {
0665 Exception exc("RKTrackRep::extrapolateToSphere ==> cannot solve",__LINE__,__FILE__);
0666 exc.setFatal();
0667 throw exc;
0668 }
0669 double term = sqrt(arg);
0670 double k1, k2;
0671 k1 = -dirAO + term;
0672 k2 = -dirAO - term;
0673
0674
0675 double k = k1;
0676 if (fabs(k2)<fabs(k))
0677 k = k2;
0678
0679 if (debugLvl_ > 0) {
0680 debugOut << "RKTrackRep::extrapolateToSphere(); k = " << k << "\n";
0681 }
0682
0683 dest = pos + k * dir;
0684
0685 plane->setON(dest, dest-point);
0686
0687 tracklength += this->Extrap(startPlane, *plane, charge, mass, isAtBoundary, state7, flightTime, false, nullptr, true, stopAtBoundary, maxStep);
0688
0689
0690 if (stopAtBoundary && isAtBoundary) {
0691 pos.SetXYZ(state7[0], state7[1], state7[2]);
0692 dir.SetXYZ(state7[3], state7[4], state7[5]);
0693 plane->setON(pos, pos-point);
0694 break;
0695 }
0696
0697 if(fabs(k)<MINSTEP) break;
0698
0699 startPlane = *plane;
0700
0701 }
0702
0703 if (fillExtrapSteps) {
0704
0705 lastEndState_.setPlane(plane);
0706 getState5(lastEndState_, state7);
0707
0708 tracklength = extrapolateToPlane(state, plane, false, true);
0709 lastEndState_.getAuxInfo()(1) = state.getAuxInfo()(1);
0710 }
0711 else {
0712 state.setPlane(plane);
0713 getState5(state, state7);
0714 state.getAuxInfo()(1) += flightTime;
0715 }
0716
0717 lastEndState_ = state;
0718
0719 return tracklength;
0720 }
0721
0722
0723 double RKTrackRep::extrapolateBy(StateOnPlane& state,
0724 double step,
0725 bool stopAtBoundary,
0726 bool calcJacobianNoise) const {
0727
0728 if (debugLvl_ > 0) {
0729 debugOut << "RKTrackRep::extrapolateBy()\n";
0730 }
0731
0732 checkCache(state, nullptr);
0733
0734 static const unsigned int maxIt(1000);
0735
0736
0737 M1x7 state7;
0738 getState7(state, state7);
0739
0740 bool fillExtrapSteps(false);
0741 if (dynamic_cast<MeasuredStateOnPlane*>(&state) != nullptr) {
0742 fillExtrapSteps = true;
0743 }
0744 else if (calcJacobianNoise)
0745 fillExtrapSteps = true;
0746
0747 double tracklength(0.);
0748
0749 TVector3 dest, pos, dir;
0750
0751 bool isAtBoundary(false);
0752
0753 DetPlane startPlane(*(state.getPlane()));
0754 SharedPlanePtr plane(new DetPlane());
0755 unsigned int iterations(0);
0756 double charge = getCharge(state);
0757 double mass = getMass(state);
0758 double flightTime = 0;
0759
0760 while(true){
0761 if(++iterations == maxIt) {
0762 Exception exc("RKTrackRep::extrapolateBy ==> maximum number of iterations reached",__LINE__,__FILE__);
0763 exc.setFatal();
0764 throw exc;
0765 }
0766
0767 pos.SetXYZ(state7[0], state7[1], state7[2]);
0768 dir.SetXYZ(state7[3], state7[4], state7[5]);
0769
0770 dest = pos + 1.5*(step-tracklength) * dir;
0771
0772 plane->setON(dest, dir);
0773
0774 tracklength += this->Extrap(startPlane, *plane, charge, mass, isAtBoundary, state7, flightTime, false, nullptr, true, stopAtBoundary, (step-tracklength));
0775
0776
0777 if (stopAtBoundary && isAtBoundary) {
0778 pos.SetXYZ(state7[0], state7[1], state7[2]);
0779 dir.SetXYZ(state7[3], state7[4], state7[5]);
0780 plane->setON(pos, dir);
0781 break;
0782 }
0783
0784 if (fabs(tracklength-step) < MINSTEP) {
0785 if (debugLvl_ > 0) {
0786 debugOut << "RKTrackRep::extrapolateBy(): reached after " << iterations << " iterations. \n";
0787 }
0788 pos.SetXYZ(state7[0], state7[1], state7[2]);
0789 dir.SetXYZ(state7[3], state7[4], state7[5]);
0790 plane->setON(pos, dir);
0791 break;
0792 }
0793
0794 startPlane = *plane;
0795
0796 }
0797
0798 if (fillExtrapSteps) {
0799
0800 lastEndState_.setPlane(plane);
0801 getState5(lastEndState_, state7);
0802
0803 tracklength = extrapolateToPlane(state, plane, false, true);
0804 lastEndState_.getAuxInfo()(1) = state.getAuxInfo()(1);
0805 }
0806 else {
0807 state.setPlane(plane);
0808 getState5(state, state7);
0809 state.getAuxInfo()(1) += flightTime;
0810 }
0811
0812 lastEndState_ = state;
0813
0814 return tracklength;
0815 }
0816
0817
0818 TVector3 RKTrackRep::getPos(const StateOnPlane& state) const {
0819 M1x7 state7;
0820 getState7(state, state7);
0821
0822 return TVector3(state7[0], state7[1], state7[2]);
0823 }
0824
0825
0826 TVector3 RKTrackRep::getMom(const StateOnPlane& state) const {
0827 M1x7 state7 = {{0, 0, 0, 0, 0, 0, 0}};
0828 getState7(state, state7);
0829
0830 TVector3 mom(state7[3], state7[4], state7[5]);
0831 mom.SetMag(getCharge(state)/state7[6]);
0832 return mom;
0833 }
0834
0835
0836 void RKTrackRep::getPosMom(const StateOnPlane& state, TVector3& pos, TVector3& mom) const {
0837 M1x7 state7 = {{0, 0, 0, 0, 0, 0, 0}};
0838 getState7(state, state7);
0839
0840 pos.SetXYZ(state7[0], state7[1], state7[2]);
0841 mom.SetXYZ(state7[3], state7[4], state7[5]);
0842 mom.SetMag(getCharge(state)/state7[6]);
0843 }
0844
0845
0846 void RKTrackRep::getPosMomCov(const MeasuredStateOnPlane& state, TVector3& pos, TVector3& mom, TMatrixDSym& cov) const {
0847 getPosMom(state, pos, mom);
0848 cov.ResizeTo(6,6);
0849 transformPM6(state, *((M6x6*) cov.GetMatrixArray()));
0850 }
0851
0852
0853 TMatrixDSym RKTrackRep::get6DCov(const MeasuredStateOnPlane& state) const {
0854 TMatrixDSym cov(6);
0855 transformPM6(state, *((M6x6*) cov.GetMatrixArray()));
0856
0857 return cov;
0858 }
0859
0860
0861 double RKTrackRep::getCharge(const StateOnPlane& state) const {
0862
0863 if (dynamic_cast<const MeasurementOnPlane*>(&state) != nullptr) {
0864 Exception exc("RKTrackRep::getCharge - cannot get charge from MeasurementOnPlane",__LINE__,__FILE__);
0865 exc.setFatal();
0866 throw exc;
0867 }
0868
0869 double pdgCharge( this->getPDGCharge() );
0870
0871
0872 if (state.getState()(0) * pdgCharge < 0)
0873 return -pdgCharge;
0874 else
0875 return pdgCharge;
0876 }
0877
0878
0879 double RKTrackRep::getMomMag(const StateOnPlane& state) const {
0880
0881 double p = getCharge(state)/state.getState()(0);
0882 assert (p>=0);
0883 return p;
0884 }
0885
0886
0887 double RKTrackRep::getMomVar(const MeasuredStateOnPlane& state) const {
0888
0889 if (dynamic_cast<const MeasurementOnPlane*>(&state) != nullptr) {
0890 Exception exc("RKTrackRep::getMomVar - cannot get momVar from MeasurementOnPlane",__LINE__,__FILE__);
0891 exc.setFatal();
0892 throw exc;
0893 }
0894
0895
0896
0897
0898
0899
0900
0901
0902
0903 return state.getCov()(0,0) * pow(getCharge(state), 2) / pow(state.getState()(0), 4);
0904 }
0905
0906
0907 double RKTrackRep::getSpu(const StateOnPlane& state) const {
0908
0909 if (dynamic_cast<const MeasurementOnPlane*>(&state) != nullptr) {
0910 Exception exc("RKTrackRep::getSpu - cannot get spu from MeasurementOnPlane",__LINE__,__FILE__);
0911 exc.setFatal();
0912 throw exc;
0913 }
0914
0915 const TVectorD& auxInfo = state.getAuxInfo();
0916 if (auxInfo.GetNrows() == 2
0917 || auxInfo.GetNrows() == 1)
0918 return state.getAuxInfo()(0);
0919 else
0920 return 1.;
0921 }
0922
0923 double RKTrackRep::getTime(const StateOnPlane& state) const {
0924
0925 const TVectorD& auxInfo = state.getAuxInfo();
0926 if (auxInfo.GetNrows() == 2)
0927 return state.getAuxInfo()(1);
0928 else
0929 return 0.;
0930 }
0931
0932
0933 void RKTrackRep::calcForwardJacobianAndNoise(const M1x7& startState7, const DetPlane& startPlane,
0934 const M1x7& destState7, const DetPlane& destPlane) const {
0935
0936 if (debugLvl_ > 0) {
0937 debugOut << "RKTrackRep::calcForwardJacobianAndNoise " << std::endl;
0938 }
0939
0940 if (ExtrapSteps_.size() == 0) {
0941 Exception exc("RKTrackRep::calcForwardJacobianAndNoise ==> cache is empty. Extrapolation must run with a MeasuredStateOnPlane.",__LINE__,__FILE__);
0942 throw exc;
0943 }
0944
0945
0946 TMatrixD jac(TMatrixD::kTransposed, TMatrixD(7, 7, ExtrapSteps_.back().jac7_.begin()));
0947 TMatrixDSym noise(7, ExtrapSteps_.back().noise7_.begin());
0948 for (int i = ExtrapSteps_.size() - 2; i >= 0; --i) {
0949 noise += TMatrixDSym(7, ExtrapSteps_[i].noise7_.begin()).Similarity(jac);
0950 jac *= TMatrixD(TMatrixD::kTransposed, TMatrixD(7, 7, ExtrapSteps_[i].jac7_.begin()));
0951 }
0952
0953
0954 M1x3 pTilde = {{startState7[3], startState7[4], startState7[5]}};
0955 const TVector3& normal = startPlane.getNormal();
0956 double pTildeW = pTilde[0] * normal.X() + pTilde[1] * normal.Y() + pTilde[2] * normal.Z();
0957 double spu = pTildeW > 0 ? 1 : -1;
0958 for (unsigned int i=0; i<3; ++i) {
0959 pTilde[i] *= spu/pTildeW;
0960 }
0961 M5x7 J_pM;
0962 calcJ_pM_5x7(J_pM, startPlane.getU(), startPlane.getV(), pTilde, spu);
0963 M7x5 J_Mp;
0964 calcJ_Mp_7x5(J_Mp, destPlane.getU(), destPlane.getV(), destPlane.getNormal(), *((M1x3*) &destState7[3]));
0965 jac.Transpose(jac);
0966 RKTools::J_pMTTxJ_MMTTxJ_MpTT(J_Mp, *(M7x7 *)jac.GetMatrixArray(),
0967 J_pM, *(M5x5 *)fJacobian_.GetMatrixArray());
0968 RKTools::J_MpTxcov7xJ_Mp(J_Mp, *(M7x7 *)noise.GetMatrixArray(),
0969 *(M5x5 *)fNoise_.GetMatrixArray());
0970
0971 if (debugLvl_ > 0) {
0972 debugOut << "total jacobian : "; fJacobian_.Print();
0973 debugOut << "total noise : "; fNoise_.Print();
0974 }
0975
0976 }
0977
0978
0979 void RKTrackRep::getForwardJacobianAndNoise(TMatrixD& jacobian, TMatrixDSym& noise, TVectorD& deltaState) const {
0980
0981 jacobian.ResizeTo(5,5);
0982 jacobian = fJacobian_;
0983
0984 noise.ResizeTo(5,5);
0985 noise = fNoise_;
0986
0987
0988 deltaState.ResizeTo(5);
0989
0990
0991 deltaState = lastStartState_.getState();
0992 deltaState *= jacobian;
0993 deltaState -= lastEndState_.getState();
0994 deltaState *= -1;
0995
0996
0997 if (debugLvl_ > 0) {
0998 debugOut << "delta state : "; deltaState.Print();
0999 }
1000 }
1001
1002
1003 void RKTrackRep::getBackwardJacobianAndNoise(TMatrixD& jacobian, TMatrixDSym& noise, TVectorD& deltaState) const {
1004
1005 if (debugLvl_ > 0) {
1006 debugOut << "RKTrackRep::getBackwardJacobianAndNoise " << std::endl;
1007 }
1008
1009 if (ExtrapSteps_.size() == 0) {
1010 Exception exc("RKTrackRep::getBackwardJacobianAndNoise ==> cache is empty. Extrapolation must run with a MeasuredStateOnPlane.",__LINE__,__FILE__);
1011 throw exc;
1012 }
1013
1014 jacobian.ResizeTo(5,5);
1015 jacobian = fJacobian_;
1016 if (!useInvertFast) {
1017 bool status = TDecompLU::InvertLU(jacobian, 0.0);
1018 if(status == 0){
1019 Exception e("cannot invert matrix, status = 0", __LINE__,__FILE__);
1020 e.setFatal();
1021 throw e;
1022 }
1023 } else {
1024 double det;
1025 jacobian.InvertFast(&det);
1026 if(det < 1e-80){
1027 Exception e("cannot invert matrix, status = 0", __LINE__,__FILE__);
1028 e.setFatal();
1029 throw e;
1030 }
1031 }
1032
1033 noise.ResizeTo(5,5);
1034 noise = fNoise_;
1035 noise.Similarity(jacobian);
1036
1037
1038 deltaState.ResizeTo(5);
1039 deltaState = lastStartState_.getState() - jacobian * lastEndState_.getState();
1040 }
1041
1042
1043 std::vector<genfit::MatStep> RKTrackRep::getSteps() const {
1044
1045
1046
1047 if (RKSteps_.size() == 0) {
1048 Exception exc("RKTrackRep::getSteps ==> cache is empty.",__LINE__,__FILE__);
1049 throw exc;
1050 }
1051
1052 std::vector<MatStep> retVal;
1053 retVal.reserve(RKSteps_.size());
1054
1055 for (unsigned int i = 0; i<RKSteps_.size(); ++i) {
1056 retVal.push_back(RKSteps_[i].matStep_);
1057 }
1058
1059 return retVal;
1060 }
1061
1062
1063 double RKTrackRep::getRadiationLenght() const {
1064
1065
1066
1067 if (RKSteps_.size() == 0) {
1068 Exception exc("RKTrackRep::getRadiationLenght ==> cache is empty.",__LINE__,__FILE__);
1069 throw exc;
1070 }
1071
1072 double radLen(0);
1073
1074 for (unsigned int i = 0; i<RKSteps_.size(); ++i) {
1075 radLen += RKSteps_.at(i).matStep_.stepSize_ / RKSteps_.at(i).matStep_.material_.radiationLength;
1076 }
1077
1078 return radLen;
1079 }
1080
1081
1082
1083 void RKTrackRep::setPosMom(StateOnPlane& state, const TVector3& pos, const TVector3& mom) const {
1084
1085 if (state.getRep() != this){
1086 Exception exc("RKTrackRep::setPosMom ==> state is defined wrt. another TrackRep",__LINE__,__FILE__);
1087 throw exc;
1088 }
1089
1090 if (dynamic_cast<MeasurementOnPlane*>(&state) != nullptr) {
1091 Exception exc("RKTrackRep::setPosMom - cannot set pos/mom of a MeasurementOnPlane",__LINE__,__FILE__);
1092 exc.setFatal();
1093 throw exc;
1094 }
1095
1096 if (mom.Mag2() == 0) {
1097 Exception exc("RKTrackRep::setPosMom - momentum is 0",__LINE__,__FILE__);
1098 exc.setFatal();
1099 throw exc;
1100 }
1101
1102
1103 TVectorD& auxInfo = state.getAuxInfo();
1104 if (auxInfo.GetNrows() != 2) {
1105 bool alreadySet = auxInfo.GetNrows() == 1;
1106 auxInfo.ResizeTo(2);
1107 if (!alreadySet)
1108 setSpu(state, 1.);
1109 }
1110
1111 if (state.getPlane() != nullptr && state.getPlane()->distance(pos) < MINSTEP) {
1112
1113 M1x7 state7;
1114
1115 state7[0] = pos.X();
1116 state7[1] = pos.Y();
1117 state7[2] = pos.Z();
1118
1119 state7[3] = mom.X();
1120 state7[4] = mom.Y();
1121 state7[5] = mom.Z();
1122
1123
1124 double norm = 1. / sqrt(state7[3]*state7[3] + state7[4]*state7[4] + state7[5]*state7[5]);
1125 for (unsigned int i=3; i<6; ++i)
1126 state7[i] *= norm;
1127
1128 state7[6] = getCharge(state) * norm;
1129
1130 getState5(state, state7);
1131
1132 }
1133 else {
1134
1135
1136 SharedPlanePtr plane(new DetPlane(pos, mom));
1137 state.setPlane(plane);
1138
1139 TVectorD& state5(state.getState());
1140
1141 state5(0) = getCharge(state)/mom.Mag();
1142 state5(1) = 0.;
1143 state5(2) = 0.;
1144 state5(3) = 0.;
1145 state5(4) = 0.;
1146
1147 setSpu(state, 1.);
1148 }
1149
1150 }
1151
1152
1153 void RKTrackRep::setPosMom(StateOnPlane& state, const TVectorD& state6) const {
1154 if (state6.GetNrows()!=6){
1155 Exception exc("RKTrackRep::setPosMom ==> state has to be 6d (x, y, z, px, py, pz)",__LINE__,__FILE__);
1156 throw exc;
1157 }
1158 setPosMom(state, TVector3(state6(0), state6(1), state6(2)), TVector3(state6(3), state6(4), state6(5)));
1159 }
1160
1161
1162 void RKTrackRep::setPosMomErr(MeasuredStateOnPlane& state, const TVector3& pos, const TVector3& mom, const TVector3& posErr, const TVector3& momErr) const {
1163
1164
1165
1166 setPosMom(state, pos, mom);
1167
1168 const TVector3& U(state.getPlane()->getU());
1169 const TVector3& V(state.getPlane()->getV());
1170 TVector3 W(state.getPlane()->getNormal());
1171
1172 double pw = mom * W;
1173 double pu = mom * U;
1174 double pv = mom * V;
1175
1176 TMatrixDSym& cov(state.getCov());
1177
1178 cov(0,0) = pow(getCharge(state), 2) / pow(mom.Mag(), 6) *
1179 (mom.X()*mom.X() * momErr.X()*momErr.X()+
1180 mom.Y()*mom.Y() * momErr.Y()*momErr.Y()+
1181 mom.Z()*mom.Z() * momErr.Z()*momErr.Z());
1182
1183 cov(1,1) = pow((U.X()/pw - W.X()*pu/(pw*pw)),2.) * momErr.X()*momErr.X() +
1184 pow((U.Y()/pw - W.Y()*pu/(pw*pw)),2.) * momErr.Y()*momErr.Y() +
1185 pow((U.Z()/pw - W.Z()*pu/(pw*pw)),2.) * momErr.Z()*momErr.Z();
1186
1187 cov(2,2) = pow((V.X()/pw - W.X()*pv/(pw*pw)),2.) * momErr.X()*momErr.X() +
1188 pow((V.Y()/pw - W.Y()*pv/(pw*pw)),2.) * momErr.Y()*momErr.Y() +
1189 pow((V.Z()/pw - W.Z()*pv/(pw*pw)),2.) * momErr.Z()*momErr.Z();
1190
1191 cov(3,3) = posErr.X()*posErr.X() * U.X()*U.X() +
1192 posErr.Y()*posErr.Y() * U.Y()*U.Y() +
1193 posErr.Z()*posErr.Z() * U.Z()*U.Z();
1194
1195 cov(4,4) = posErr.X()*posErr.X() * V.X()*V.X() +
1196 posErr.Y()*posErr.Y() * V.Y()*V.Y() +
1197 posErr.Z()*posErr.Z() * V.Z()*V.Z();
1198
1199 }
1200
1201
1202
1203
1204 void RKTrackRep::setPosMomCov(MeasuredStateOnPlane& state, const TVector3& pos, const TVector3& mom, const TMatrixDSym& cov6x6) const {
1205
1206 if (cov6x6.GetNcols()!=6 || cov6x6.GetNrows()!=6){
1207 Exception exc("RKTrackRep::setPosMomCov ==> cov has to be 6x6 (x, y, z, px, py, pz)",__LINE__,__FILE__);
1208 throw exc;
1209 }
1210
1211 setPosMom(state, pos, mom);
1212
1213 M1x7 state7;
1214 getState7(state, state7);
1215
1216 const M6x6& cov6x6_( *((M6x6*) cov6x6.GetMatrixArray()) );
1217
1218 transformM6P(cov6x6_, state7, state);
1219
1220 }
1221
1222 void RKTrackRep::setPosMomCov(MeasuredStateOnPlane& state, const TVectorD& state6, const TMatrixDSym& cov6x6) const {
1223
1224 if (state6.GetNrows()!=6){
1225 Exception exc("RKTrackRep::setPosMomCov ==> state has to be 6d (x, y, z, px, py, pz)",__LINE__,__FILE__);
1226 throw exc;
1227 }
1228
1229 if (cov6x6.GetNcols()!=6 || cov6x6.GetNrows()!=6){
1230 Exception exc("RKTrackRep::setPosMomCov ==> cov has to be 6x6 (x, y, z, px, py, pz)",__LINE__,__FILE__);
1231 throw exc;
1232 }
1233
1234 TVector3 pos(state6(0), state6(1), state6(2));
1235 TVector3 mom(state6(3), state6(4), state6(5));
1236 setPosMom(state, pos, mom);
1237
1238 M1x7 state7;
1239 getState7(state, state7);
1240
1241 const M6x6& cov6x6_( *((M6x6*) cov6x6.GetMatrixArray()) );
1242
1243 transformM6P(cov6x6_, state7, state);
1244
1245 }
1246
1247
1248 void RKTrackRep::setChargeSign(StateOnPlane& state, double charge) const {
1249
1250 if (dynamic_cast<MeasurementOnPlane*>(&state) != nullptr) {
1251 Exception exc("RKTrackRep::setChargeSign - cannot set charge of a MeasurementOnPlane",__LINE__,__FILE__);
1252 exc.setFatal();
1253 throw exc;
1254 }
1255
1256 if (state.getState()(0) * charge < 0) {
1257 state.getState()(0) *= -1.;
1258 }
1259 }
1260
1261
1262 void RKTrackRep::setSpu(StateOnPlane& state, double spu) const {
1263 state.getAuxInfo().ResizeTo(2);
1264 (state.getAuxInfo())(0) = spu;
1265 }
1266
1267 void RKTrackRep::setTime(StateOnPlane& state, double time) const {
1268 state.getAuxInfo().ResizeTo(2);
1269 (state.getAuxInfo())(1) = time;
1270 }
1271
1272
1273
1274 double RKTrackRep::RKPropagate(M1x7& state7,
1275 M7x7* jacobianT,
1276 M1x3& SA,
1277 double S,
1278 bool varField,
1279 bool calcOnlyLastRowOfJ) const {
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294 static const double EC ( 0.000149896229 );
1295 static const double P3 ( 1./3. );
1296 static const double DLT ( .0002 );
1297
1298 M1x3& R = *((M1x3*) &state7[0]);
1299 M1x3& A = *((M1x3*) &state7[3]);
1300 double S3(0), S4(0), PS2(0);
1301 M1x3 H0 = {{0.,0.,0.}}, H1 = {{0.,0.,0.}}, H2 = {{0.,0.,0.}};
1302 M1x3 r = {{0.,0.,0.}};
1303
1304 double A0(0), A1(0), A2(0), A3(0), A4(0), A5(0), A6(0);
1305 double B0(0), B1(0), B2(0), B3(0), B4(0), B5(0), B6(0);
1306 double C0(0), C1(0), C2(0), C3(0), C4(0), C5(0), C6(0);
1307
1308
1309
1310
1311 S3 = P3*S;
1312 S4 = 0.25*S;
1313 PS2 = state7[6]*EC * S;
1314
1315
1316 r[0] = R[0]; r[1] = R[1]; r[2]=R[2];
1317 FieldManager::getInstance()->getFieldVal(r[0], r[1], r[2], H0[0], H0[1], H0[2]);
1318 H0[0] *= PS2; H0[1] *= PS2; H0[2] *= PS2;
1319 A0 = A[1]*H0[2]-A[2]*H0[1]; B0 = A[2]*H0[0]-A[0]*H0[2]; C0 = A[0]*H0[1]-A[1]*H0[0];
1320 A2 = A[0]+A0 ; B2 = A[1]+B0 ; C2 = A[2]+C0 ;
1321 A1 = A2+A[0] ; B1 = B2+A[1] ; C1 = C2+A[2] ;
1322
1323
1324 if (varField) {
1325 r[0] += A1*S4; r[1] += B1*S4; r[2] += C1*S4;
1326 FieldManager::getInstance()->getFieldVal(r[0], r[1], r[2], H1[0], H1[1], H1[2]);
1327 H1[0] *= PS2; H1[1] *= PS2; H1[2] *= PS2;
1328 }
1329 else { H1 = H0; };
1330 A3 = B2*H1[2]-C2*H1[1]+A[0]; B3 = C2*H1[0]-A2*H1[2]+A[1]; C3 = A2*H1[1]-B2*H1[0]+A[2];
1331 A4 = B3*H1[2]-C3*H1[1]+A[0]; B4 = C3*H1[0]-A3*H1[2]+A[1]; C4 = A3*H1[1]-B3*H1[0]+A[2];
1332 A5 = A4-A[0]+A4 ; B5 = B4-A[1]+B4 ; C5 = C4-A[2]+C4 ;
1333
1334
1335 if (varField) {
1336 r[0]=R[0]+S*A4; r[1]=R[1]+S*B4; r[2]=R[2]+S*C4;
1337 FieldManager::getInstance()->getFieldVal(r[0], r[1], r[2], H2[0], H2[1], H2[2]);
1338 H2[0] *= PS2; H2[1] *= PS2; H2[2] *= PS2;
1339 }
1340 else { H2 = H0; };
1341 A6 = B5*H2[2]-C5*H2[1]; B6 = C5*H2[0]-A5*H2[2]; C6 = A5*H2[1]-B5*H2[0];
1342
1343
1344
1345
1346
1347 if(jacobianT != nullptr){
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357 M7x7& J = *jacobianT;
1358
1359 double dA0(0), dA2(0), dA3(0), dA4(0), dA5(0), dA6(0);
1360 double dB0(0), dB2(0), dB3(0), dB4(0), dB5(0), dB6(0);
1361 double dC0(0), dC2(0), dC3(0), dC4(0), dC5(0), dC6(0);
1362
1363 int start(0);
1364
1365 if (!calcOnlyLastRowOfJ) {
1366
1367 if (!varField) {
1368
1369 J(0, 0) = 1; J(1, 1) = 1; J(2, 2) = 1;
1370
1371
1372 start = 3;
1373 }
1374
1375 for(int i=start; i<6; ++i) {
1376
1377
1378 dA0 = H0[2]*J(i, 4)-H0[1]*J(i, 5);
1379 dB0 = H0[0]*J(i, 5)-H0[2]*J(i, 3);
1380 dC0 = H0[1]*J(i, 3)-H0[0]*J(i, 4);
1381
1382 dA2 = dA0+J(i, 3);
1383 dB2 = dB0+J(i, 4);
1384 dC2 = dC0+J(i, 5);
1385
1386
1387 dA3 = J(i, 3)+dB2*H1[2]-dC2*H1[1];
1388 dB3 = J(i, 4)+dC2*H1[0]-dA2*H1[2];
1389 dC3 = J(i, 5)+dA2*H1[1]-dB2*H1[0];
1390
1391 dA4 = J(i, 3)+dB3*H1[2]-dC3*H1[1];
1392 dB4 = J(i, 4)+dC3*H1[0]-dA3*H1[2];
1393 dC4 = J(i, 5)+dA3*H1[1]-dB3*H1[0];
1394
1395
1396 dA5 = dA4+dA4-J(i, 3);
1397 dB5 = dB4+dB4-J(i, 4);
1398 dC5 = dC4+dC4-J(i, 5);
1399
1400 dA6 = dB5*H2[2]-dC5*H2[1];
1401 dB6 = dC5*H2[0]-dA5*H2[2];
1402 dC6 = dA5*H2[1]-dB5*H2[0];
1403
1404
1405 J(i, 0) += (dA2+dA3+dA4)*S3; J(i, 3) = ((dA0+2.*dA3)+(dA5+dA6))*P3;
1406 J(i, 1) += (dB2+dB3+dB4)*S3; J(i, 4) = ((dB0+2.*dB3)+(dB5+dB6))*P3;
1407 J(i, 2) += (dC2+dC3+dC4)*S3; J(i, 5) = ((dC0+2.*dC3)+(dC5+dC6))*P3;
1408 }
1409
1410 }
1411
1412 J(6, 3) *= state7[6]; J(6, 4) *= state7[6]; J(6, 5) *= state7[6];
1413
1414
1415 dA0 = H0[2]*J(6, 4)-H0[1]*J(6, 5) + A0;
1416 dB0 = H0[0]*J(6, 5)-H0[2]*J(6, 3) + B0;
1417 dC0 = H0[1]*J(6, 3)-H0[0]*J(6, 4) + C0;
1418
1419 dA2 = dA0+J(6, 3);
1420 dB2 = dB0+J(6, 4);
1421 dC2 = dC0+J(6, 5);
1422
1423
1424 dA3 = J(6, 3)+dB2*H1[2]-dC2*H1[1] + (A3-A[0]);
1425 dB3 = J(6, 4)+dC2*H1[0]-dA2*H1[2] + (B3-A[1]);
1426 dC3 = J(6, 5)+dA2*H1[1]-dB2*H1[0] + (C3-A[2]);
1427
1428 dA4 = J(6, 3)+dB3*H1[2]-dC3*H1[1] + (A4-A[0]);
1429 dB4 = J(6, 4)+dC3*H1[0]-dA3*H1[2] + (B4-A[1]);
1430 dC4 = J(6, 5)+dA3*H1[1]-dB3*H1[0] + (C4-A[2]);
1431
1432
1433 dA5 = dA4+dA4-J(6, 3);
1434 dB5 = dB4+dB4-J(6, 4);
1435 dC5 = dC4+dC4-J(6, 5);
1436
1437 dA6 = dB5*H2[2]-dC5*H2[1] + A6;
1438 dB6 = dC5*H2[0]-dA5*H2[2] + B6;
1439 dC6 = dA5*H2[1]-dB5*H2[0] + C6;
1440
1441
1442 J(6, 0) += (dA2+dA3+dA4)*S3/state7[6]; J(6, 3) = ((dA0+2.*dA3)+(dA5+dA6))*P3/state7[6];
1443 J(6, 1) += (dB2+dB3+dB4)*S3/state7[6]; J(6, 4) = ((dB0+2.*dB3)+(dB5+dB6))*P3/state7[6];
1444 J(6, 2) += (dC2+dC3+dC4)*S3/state7[6]; J(6, 5) = ((dC0+2.*dC3)+(dC5+dC6))*P3/state7[6];
1445
1446 }
1447
1448
1449
1450
1451 R[0] += (A2+A3+A4)*S3; A[0] += (SA[0]=((A0+2.*A3)+(A5+A6))*P3-A[0]);
1452 R[1] += (B2+B3+B4)*S3; A[1] += (SA[1]=((B0+2.*B3)+(B5+B6))*P3-A[1]);
1453 R[2] += (C2+C3+C4)*S3; A[2] += (SA[2]=((C0+2.*C3)+(C5+C6))*P3-A[2]);
1454
1455
1456 double CBA ( 1./sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]) );
1457 A[0] *= CBA; A[1] *= CBA; A[2] *= CBA;
1458
1459
1460
1461 double EST ( fabs((A1+A6)-(A3+A4)) +
1462 fabs((B1+B6)-(B3+B4)) +
1463 fabs((C1+C6)-(C3+C4)) );
1464 if (debugLvl_ > 0) {
1465 debugOut << " RKTrackRep::RKPropagate. Step = "<< S << "; quality EST = " << EST << " \n";
1466 }
1467
1468
1469
1470 if (EST < DLT*1e-5)
1471 return 10;
1472
1473
1474
1475 return pow(DLT/EST, 1./5.);
1476 }
1477
1478
1479
1480 void RKTrackRep::initArrays() const {
1481 std::fill(noiseArray_.begin(), noiseArray_.end(), 0);
1482 std::fill(noiseProjection_.begin(), noiseProjection_.end(), 0);
1483 for (unsigned int i=0; i<7; ++i)
1484 noiseProjection_[i*8] = 1;
1485 std::fill(J_MMT_.begin(), J_MMT_.end(), 0);
1486
1487 fJacobian_.UnitMatrix();
1488 fNoise_.Zero();
1489 limits_.reset();
1490
1491 RKSteps_.reserve(100);
1492 ExtrapSteps_.reserve(100);
1493
1494 lastStartState_.getAuxInfo().ResizeTo(2);
1495 lastEndState_.getAuxInfo().ResizeTo(2);
1496 }
1497
1498
1499 void RKTrackRep::getState7(const StateOnPlane& state, M1x7& state7) const {
1500
1501 if (dynamic_cast<const MeasurementOnPlane*>(&state) != nullptr) {
1502 Exception exc("RKTrackRep::getState7 - cannot get pos or mom from a MeasurementOnPlane",__LINE__,__FILE__);
1503 exc.setFatal();
1504 throw exc;
1505 }
1506
1507 const TVector3& U(state.getPlane()->getU());
1508 const TVector3& V(state.getPlane()->getV());
1509 const TVector3& O(state.getPlane()->getO());
1510 const TVector3& W(state.getPlane()->getNormal());
1511
1512 assert(state.getState().GetNrows() == 5);
1513 const double* state5 = state.getState().GetMatrixArray();
1514
1515 double spu = getSpu(state);
1516
1517 state7[0] = O.X() + state5[3]*U.X() + state5[4]*V.X();
1518 state7[1] = O.Y() + state5[3]*U.Y() + state5[4]*V.Y();
1519 state7[2] = O.Z() + state5[3]*U.Z() + state5[4]*V.Z();
1520
1521 state7[3] = spu * (W.X() + state5[1]*U.X() + state5[2]*V.X());
1522 state7[4] = spu * (W.Y() + state5[1]*U.Y() + state5[2]*V.Y());
1523 state7[5] = spu * (W.Z() + state5[1]*U.Z() + state5[2]*V.Z());
1524
1525
1526 double norm = 1. / sqrt(state7[3]*state7[3] + state7[4]*state7[4] + state7[5]*state7[5]);
1527 for (unsigned int i=3; i<6; ++i) state7[i] *= norm;
1528
1529 state7[6] = state5[0];
1530 }
1531
1532
1533 void RKTrackRep::getState5(StateOnPlane& state, const M1x7& state7) const {
1534
1535
1536
1537 double spu(1.);
1538
1539 const TVector3& O(state.getPlane()->getO());
1540 const TVector3& U(state.getPlane()->getU());
1541 const TVector3& V(state.getPlane()->getV());
1542 const TVector3& W(state.getPlane()->getNormal());
1543
1544
1545 double AtW( state7[3]*W.X() + state7[4]*W.Y() + state7[5]*W.Z() );
1546 if (AtW < 0.) {
1547
1548
1549 spu = -1.;
1550 }
1551
1552 double* state5 = state.getState().GetMatrixArray();
1553
1554 state5[0] = state7[6];
1555 state5[1] = (state7[3]*U.X() + state7[4]*U.Y() + state7[5]*U.Z()) / AtW;
1556 state5[2] = (state7[3]*V.X() + state7[4]*V.Y() + state7[5]*V.Z()) / AtW;
1557 state5[3] = ((state7[0]-O.X())*U.X() +
1558 (state7[1]-O.Y())*U.Y() +
1559 (state7[2]-O.Z())*U.Z());
1560 state5[4] = ((state7[0]-O.X())*V.X() +
1561 (state7[1]-O.Y())*V.Y() +
1562 (state7[2]-O.Z())*V.Z());
1563
1564 setSpu(state, spu);
1565
1566 }
1567
1568 void RKTrackRep::calcJ_pM_5x7(M5x7& J_pM, const TVector3& U, const TVector3& V, const M1x3& pTilde, double spu) const {
1569
1570
1571
1572
1573
1574
1575
1576
1577 std::fill(J_pM.begin(), J_pM.end(), 0);
1578
1579 const double pTildeMag = sqrt(pTilde[0]*pTilde[0] + pTilde[1]*pTilde[1] + pTilde[2]*pTilde[2]);
1580 const double pTildeMag2 = pTildeMag*pTildeMag;
1581
1582 const double utpTildeOverpTildeMag2 = (U.X()*pTilde[0] + U.Y()*pTilde[1] + U.Z()*pTilde[2]) / pTildeMag2;
1583 const double vtpTildeOverpTildeMag2 = (V.X()*pTilde[0] + V.Y()*pTilde[1] + V.Z()*pTilde[2]) / pTildeMag2;
1584
1585
1586
1587
1588 J_pM[21] = U.X();
1589 J_pM[22] = U.Y();
1590 J_pM[23] = U.Z();
1591
1592 J_pM[28] = V.X();
1593 J_pM[29] = V.Y();
1594 J_pM[30] = V.Z();
1595
1596 J_pM[6] = 1.;
1597
1598 double fact = spu / pTildeMag;
1599 J_pM[10] = fact * ( U.X() - pTilde[0]*utpTildeOverpTildeMag2 );
1600 J_pM[11] = fact * ( U.Y() - pTilde[1]*utpTildeOverpTildeMag2 );
1601 J_pM[12] = fact * ( U.Z() - pTilde[2]*utpTildeOverpTildeMag2 );
1602
1603 J_pM[17] = fact * ( V.X() - pTilde[0]*vtpTildeOverpTildeMag2 );
1604 J_pM[18] = fact * ( V.Y() - pTilde[1]*vtpTildeOverpTildeMag2 );
1605 J_pM[19] = fact * ( V.Z() - pTilde[2]*vtpTildeOverpTildeMag2 );
1606
1607
1608
1609
1610 }
1611
1612
1613 void RKTrackRep::transformPM6(const MeasuredStateOnPlane& state,
1614 M6x6& out6x6) const {
1615
1616
1617 const TVector3& U(state.getPlane()->getU());
1618 const TVector3& V(state.getPlane()->getV());
1619 const TVector3& W(state.getPlane()->getNormal());
1620
1621 const TVectorD& state5(state.getState());
1622 double spu(getSpu(state));
1623
1624 M1x3 pTilde;
1625 pTilde[0] = spu * (W.X() + state5(1)*U.X() + state5(2)*V.X());
1626 pTilde[1] = spu * (W.Y() + state5(1)*U.Y() + state5(2)*V.Y());
1627 pTilde[2] = spu * (W.Z() + state5(1)*U.Z() + state5(2)*V.Z());
1628
1629 const double pTildeMag = sqrt(pTilde[0]*pTilde[0] + pTilde[1]*pTilde[1] + pTilde[2]*pTilde[2]);
1630 const double pTildeMag2 = pTildeMag*pTildeMag;
1631
1632 const double utpTildeOverpTildeMag2 = (U.X()*pTilde[0] + U.Y()*pTilde[1] + U.Z()*pTilde[2]) / pTildeMag2;
1633 const double vtpTildeOverpTildeMag2 = (V.X()*pTilde[0] + V.Y()*pTilde[1] + V.Z()*pTilde[2]) / pTildeMag2;
1634
1635
1636
1637 const double qop = state5(0);
1638 const double p = getCharge(state)/qop;
1639
1640 M5x6 J_pM_5x6;
1641 std::fill(J_pM_5x6.begin(), J_pM_5x6.end(), 0);
1642
1643
1644 double fact = -1. * p / (pTildeMag * qop);
1645 J_pM_5x6[3] = fact * pTilde[0];
1646 J_pM_5x6[4] = fact * pTilde[1];
1647 J_pM_5x6[5] = fact * pTilde[2];
1648
1649 fact = p * spu / pTildeMag;
1650 J_pM_5x6[9] = fact * ( U.X() - pTilde[0]*utpTildeOverpTildeMag2 );
1651 J_pM_5x6[10] = fact * ( U.Y() - pTilde[1]*utpTildeOverpTildeMag2 );
1652 J_pM_5x6[11] = fact * ( U.Z() - pTilde[2]*utpTildeOverpTildeMag2 );
1653
1654 J_pM_5x6[15] = fact * ( V.X() - pTilde[0]*vtpTildeOverpTildeMag2 );
1655 J_pM_5x6[16] = fact * ( V.Y() - pTilde[1]*vtpTildeOverpTildeMag2 );
1656 J_pM_5x6[17] = fact * ( V.Z() - pTilde[2]*vtpTildeOverpTildeMag2 );
1657
1658 J_pM_5x6[18] = U.X();
1659 J_pM_5x6[19] = U.Y();
1660 J_pM_5x6[20] = U.Z();
1661
1662 J_pM_5x6[24] = V.X();
1663 J_pM_5x6[25] = V.Y();
1664 J_pM_5x6[26] = V.Z();
1665
1666
1667
1668
1669 const M5x5& in5x5_ = *((M5x5*) state.getCov().GetMatrixArray());
1670 RKTools::J_pMTxcov5xJ_pM(J_pM_5x6, in5x5_, out6x6);
1671
1672 }
1673
1674 void RKTrackRep::calcJ_Mp_7x5(M7x5& J_Mp, const TVector3& U, const TVector3& V, const TVector3& W, const M1x3& A) const {
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684 std::fill(J_Mp.begin(), J_Mp.end(), 0);
1685
1686 const double AtU = A[0]*U.X() + A[1]*U.Y() + A[2]*U.Z();
1687 const double AtV = A[0]*V.X() + A[1]*V.Y() + A[2]*V.Z();
1688 const double AtW = A[0]*W.X() + A[1]*W.Y() + A[2]*W.Z();
1689
1690
1691
1692
1693 double fact = 1./(AtW*AtW);
1694 J_Mp[16] = fact * (U.X()*AtW - W.X()*AtU);
1695 J_Mp[21] = fact * (U.Y()*AtW - W.Y()*AtU);
1696 J_Mp[26] = fact * (U.Z()*AtW - W.Z()*AtU);
1697
1698 J_Mp[17] = fact * (V.X()*AtW - W.X()*AtV);
1699 J_Mp[22] = fact * (V.Y()*AtW - W.Y()*AtV);
1700 J_Mp[27] = fact * (V.Z()*AtW - W.Z()*AtV);
1701
1702 J_Mp[30] = 1.;
1703
1704 J_Mp[3] = U.X();
1705 J_Mp[8] = U.Y();
1706 J_Mp[13] = U.Z();
1707
1708 J_Mp[4] = V.X();
1709 J_Mp[9] = V.Y();
1710 J_Mp[14] = V.Z();
1711
1712
1713
1714
1715
1716 }
1717
1718
1719 void RKTrackRep::transformM6P(const M6x6& in6x6,
1720 const M1x7& state7,
1721 MeasuredStateOnPlane& state) const {
1722
1723
1724 const TVector3& U(state.getPlane()->getU());
1725 const TVector3& V(state.getPlane()->getV());
1726 const TVector3& W(state.getPlane()->getNormal());
1727
1728 const double AtU = state7[3]*U.X() + state7[4]*U.Y() + state7[5]*U.Z();
1729 const double AtV = state7[3]*V.X() + state7[4]*V.Y() + state7[5]*V.Z();
1730 const double AtW = state7[3]*W.X() + state7[4]*W.Y() + state7[5]*W.Z();
1731
1732
1733
1734 const double qop = state7[6];
1735 const double p = getCharge(state)/qop;
1736
1737 M6x5 J_Mp_6x5;
1738 std::fill(J_Mp_6x5.begin(), J_Mp_6x5.end(), 0);
1739
1740
1741 J_Mp_6x5[3] = U.X();
1742 J_Mp_6x5[8] = U.Y();
1743 J_Mp_6x5[13] = U.Z();
1744
1745 J_Mp_6x5[4] = V.X();
1746 J_Mp_6x5[9] = V.Y();
1747 J_Mp_6x5[14] = V.Z();
1748
1749 double fact = (-1.) * qop / p;
1750 J_Mp_6x5[15] = fact * state7[3];
1751 J_Mp_6x5[20] = fact * state7[4];
1752 J_Mp_6x5[25] = fact * state7[5];
1753
1754 fact = 1./(p*AtW*AtW);
1755 J_Mp_6x5[16] = fact * (U.X()*AtW - W.X()*AtU);
1756 J_Mp_6x5[21] = fact * (U.Y()*AtW - W.Y()*AtU);
1757 J_Mp_6x5[26] = fact * (U.Z()*AtW - W.Z()*AtU);
1758
1759 J_Mp_6x5[17] = fact * (V.X()*AtW - W.X()*AtV);
1760 J_Mp_6x5[22] = fact * (V.Y()*AtW - W.Y()*AtV);
1761 J_Mp_6x5[27] = fact * (V.Z()*AtW - W.Z()*AtV);
1762
1763
1764
1765 M5x5& out5x5_ = *((M5x5*) state.getCov().GetMatrixArray());
1766 RKTools::J_MpTxcov6xJ_Mp(J_Mp_6x5, in6x6, out5x5_);
1767
1768 }
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801 bool RKTrackRep::RKutta(const M1x4& SU,
1802 const DetPlane& plane,
1803 double charge,
1804 double mass,
1805 M1x7& state7,
1806 M7x7* jacobianT,
1807 M1x7* J_MMT_unprojected_lastRow,
1808 double& coveredDistance,
1809 double& flightTime,
1810 bool& checkJacProj,
1811 M7x7& noiseProjection,
1812 StepLimits& limits,
1813 bool onlyOneStep,
1814 bool calcOnlyLastRowOfJ) const {
1815
1816
1817 static const double Wmax ( 3000. );
1818 static const double AngleMax ( 6.3 );
1819 static const double Pmin ( 4.E-3 );
1820 static const unsigned int maxNumIt ( 1000 );
1821
1822 M1x3& R ( *((M1x3*) &state7[0]) );
1823 M1x3& A ( *((M1x3*) &state7[3]) );
1824 M1x3 SA = {{0.,0.,0.}};
1825 double Way ( 0. );
1826 double momentum ( fabs(charge/state7[6]) );
1827 double relMomLoss ( 0 );
1828 double deltaAngle ( 0. );
1829
1830 double An(0), S(0), Sl(0), CBA(0);
1831
1832
1833 if (debugLvl_ > 0) {
1834 debugOut << "RKTrackRep::RKutta \n";
1835 debugOut << "position: "; TVector3(R[0], R[1], R[2]).Print();
1836 debugOut << "direction: "; TVector3(A[0], A[1], A[2]).Print();
1837 debugOut << "momentum: " << momentum << " GeV\n";
1838 debugOut << "destination: "; plane.Print();
1839 }
1840
1841 checkJacProj = false;
1842
1843
1844 if(momentum < Pmin){
1845 std::ostringstream sstream;
1846 sstream << "RKTrackRep::RKutta ==> momentum too low: " << momentum*1000. << " MeV";
1847 Exception exc(sstream.str(),__LINE__,__FILE__);
1848 exc.setFatal();
1849 throw exc;
1850 }
1851
1852 unsigned int counter(0);
1853
1854
1855 S = estimateStep(state7, SU, plane, charge, relMomLoss, limits);
1856
1857
1858
1859
1860 while (fabs(S) >= MINSTEP || counter == 0) {
1861
1862 if(++counter > maxNumIt){
1863 Exception exc("RKTrackRep::RKutta ==> maximum number of iterations exceeded",__LINE__,__FILE__);
1864 exc.setFatal();
1865 throw exc;
1866 }
1867
1868 if (debugLvl_ > 0) {
1869 debugOut << "------ RKutta main loop nr. " << counter-1 << " ------\n";
1870 }
1871
1872 M1x3 ABefore = {{ A[0], A[1], A[2] }};
1873 RKPropagate(state7, jacobianT, SA, S, true, calcOnlyLastRowOfJ);
1874
1875
1876 coveredDistance += S;
1877 Way += fabs(S);
1878
1879 double beta = 1/hypot(1, mass*state7[6]/charge);
1880 flightTime += S / beta / 29.9792458;
1881
1882
1883 if(Way > Wmax){
1884 std::ostringstream sstream;
1885 sstream << "RKTrackRep::RKutta ==> Total extrapolation length is longer than length limit : " << Way << " cm !";
1886 Exception exc(sstream.str(),__LINE__,__FILE__);
1887 exc.setFatal();
1888 throw exc;
1889 }
1890
1891 if (onlyOneStep) return(true);
1892
1893
1894 if (limits.getLowestLimit().first == stp_momLoss) {
1895 if (debugLvl_ > 0) {
1896 debugOut<<" momLossExceeded -> return(true); \n";
1897 }
1898 return(true);
1899 }
1900
1901
1902 if (limits.getLowestLimit().first == stp_boundary) {
1903 if (debugLvl_ > 0) {
1904 debugOut<<" at boundary -> return(true); \n";
1905 }
1906 return(true);
1907 }
1908
1909
1910
1911 Sl = S;
1912 limits.removeLimit(stp_fieldCurv);
1913 limits.removeLimit(stp_momLoss);
1914 limits.removeLimit(stp_boundary);
1915 limits.removeLimit(stp_plane);
1916 S = estimateStep(state7, SU, plane, charge, relMomLoss, limits);
1917
1918 if (limits.getLowestLimit().first == stp_plane &&
1919 fabs(S) < MINSTEP) {
1920 if (debugLvl_ > 0) {
1921 debugOut<<" (at Plane && fabs(S) < MINSTEP) -> break and do linear extrapolation \n";
1922 }
1923 break;
1924 }
1925 if (limits.getLowestLimit().first == stp_momLoss &&
1926 fabs(S) < MINSTEP) {
1927 if (debugLvl_ > 0) {
1928 debugOut<<" (momLossExceeded && fabs(S) < MINSTEP) -> return(true), no linear extrapolation; \n";
1929 }
1930 RKSteps_.erase(RKSteps_.end()-1);
1931 --RKStepsFXStop_;
1932 return(true);
1933 }
1934
1935
1936 double arg = ABefore[0]*A[0] + ABefore[1]*A[1] + ABefore[2]*A[2];
1937 arg = arg > 1 ? 1 : arg;
1938 arg = arg < -1 ? -1 : arg;
1939 deltaAngle += acos(arg);
1940 if (fabs(deltaAngle) > AngleMax){
1941 std::ostringstream sstream;
1942 sstream << "RKTrackRep::RKutta ==> Do not get to an active plane! Already extrapolated " << deltaAngle * 180 / TMath::Pi() << "°.";
1943 Exception exc(sstream.str(),__LINE__,__FILE__);
1944 exc.setFatal();
1945 throw exc;
1946 }
1947
1948
1949 if (counter > 3){
1950 if (S *RKSteps_.at(counter-1).matStep_.stepSize_ < 0 &&
1951 RKSteps_.at(counter-1).matStep_.stepSize_*RKSteps_.at(counter-2).matStep_.stepSize_ < 0 &&
1952 RKSteps_.at(counter-2).matStep_.stepSize_*RKSteps_.at(counter-3).matStep_.stepSize_ < 0){
1953 Exception exc("RKTrackRep::RKutta ==> Do not get closer to plane!",__LINE__,__FILE__);
1954 exc.setFatal();
1955 throw exc;
1956 }
1957 }
1958
1959 }
1960
1961
1962
1963
1964
1965 if (limits.getLowestLimit().first == stp_plane) {
1966
1967 if (fabs(Sl) > 0.001*MINSTEP){
1968 if (debugLvl_ > 0) {
1969 debugOut << " RKutta - linear extrapolation to surface\n";
1970 }
1971 Sl = 1./Sl;
1972
1973
1974 SA[0]*=Sl; SA[1]*=Sl; SA[2]*=Sl;
1975
1976
1977 A[0] += SA[0]*S;
1978 A[1] += SA[1]*S;
1979 A[2] += SA[2]*S;
1980
1981
1982 CBA = 1./sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]);
1983 A[0] *= CBA; A[1] *= CBA; A[2] *= CBA;
1984
1985 R[0] += S*(A[0]-0.5*S*SA[0]);
1986 R[1] += S*(A[1]-0.5*S*SA[1]);
1987 R[2] += S*(A[2]-0.5*S*SA[2]);
1988
1989
1990 coveredDistance += S;
1991
1992 Way += fabs(S);
1993
1994 double beta = 1/hypot(1, mass*state7[6]/charge);
1995 flightTime += S / beta / 29.9792458;
1996 }
1997 else if (debugLvl_ > 0) {
1998 debugOut << " RKutta - last stepsize too small -> can't do linear extrapolation! \n";
1999 }
2000
2001
2002
2003
2004 if (jacobianT != nullptr) {
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015 if (checkJacProj && RKSteps_.size()>0){
2016 Exception exc("RKTrackRep::Extrap ==> covariance is projected onto destination plane again",__LINE__,__FILE__);
2017 throw exc;
2018 }
2019
2020 if (debugLvl_ > 0) {
2021
2022
2023 debugOut << " Project Jacobian of extrapolation onto destination plane\n";
2024 }
2025 An = A[0]*SU[0] + A[1]*SU[1] + A[2]*SU[2];
2026 An = (fabs(An) > 1.E-7 ? 1./An : 0);
2027 double norm;
2028 int i=0;
2029 if (calcOnlyLastRowOfJ)
2030 i = 42;
2031
2032 double* jacPtr = jacobianT->begin();
2033
2034 for(unsigned int j=42; j<49; j+=7) {
2035 (*J_MMT_unprojected_lastRow)[j-42] = jacPtr[j];
2036 }
2037
2038 for(; i<49; i+=7) {
2039 norm = (jacPtr[i]*SU[0] + jacPtr[i+1]*SU[1] + jacPtr[i+2]*SU[2]) * An;
2040 jacPtr[i] -= norm*A [0]; jacPtr[i+1] -= norm*A [1]; jacPtr[i+2] -= norm*A [2];
2041 jacPtr[i+3] -= norm*SA[0]; jacPtr[i+4] -= norm*SA[1]; jacPtr[i+5] -= norm*SA[2];
2042 }
2043 checkJacProj = true;
2044
2045
2046 if (debugLvl_ > 0) {
2047
2048
2049 }
2050
2051 if (!calcOnlyLastRowOfJ) {
2052 for (int iRow = 0; iRow < 3; ++iRow) {
2053 for (int iCol = 0; iCol < 3; ++iCol) {
2054 noiseProjection[iRow*7 + iCol] = (iRow == iCol) - An * SU[iCol] * A[iRow];
2055 noiseProjection[(iRow + 3)*7 + iCol] = - An * SU[iCol] * SA[iRow];
2056 }
2057 }
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067 }
2068
2069 }
2070 }
2071
2072 return(true);
2073
2074 }
2075
2076
2077 double RKTrackRep::estimateStep(const M1x7& state7,
2078 const M1x4& SU,
2079 const DetPlane& plane,
2080 const double& charge,
2081 double& relMomLoss,
2082 StepLimits& limits) const {
2083
2084 if (useCache_) {
2085 if (cachePos_ >= RKSteps_.size()) {
2086 useCache_ = false;
2087 }
2088 else {
2089 if (RKSteps_.at(cachePos_).limits_.getLowestLimit().first == stp_plane) {
2090
2091 useCache_ = false;
2092 RKSteps_.erase(RKSteps_.begin() + cachePos_, RKSteps_.end());
2093 }
2094 else {
2095 if (debugLvl_ > 0) {
2096 debugOut << " RKTrackRep::estimateStep: use stepSize " << cachePos_ << " from cache: " << RKSteps_.at(cachePos_).matStep_.stepSize_ << "\n";
2097 }
2098
2099 ++RKStepsFXStop_;
2100 limits = RKSteps_.at(cachePos_).limits_;
2101 return RKSteps_.at(cachePos_++).matStep_.stepSize_;
2102 }
2103 }
2104 }
2105
2106 limits.setLimit(stp_sMax, 25.);
2107
2108 if (debugLvl_ > 0) {
2109 debugOut << " RKTrackRep::estimateStep \n";
2110 debugOut << " position: "; TVector3(state7[0], state7[1], state7[2]).Print();
2111 debugOut << " direction: "; TVector3(state7[3], state7[4], state7[5]).Print();
2112 }
2113
2114
2115 double Dist ( SU[3] - (state7[0]*SU[0] +
2116 state7[1]*SU[1] +
2117 state7[2]*SU[2]) );
2118 double An ( state7[3]*SU[0] +
2119 state7[4]*SU[1] +
2120 state7[5]*SU[2] );
2121
2122 double SLDist;
2123 if (fabs(An) > 1.E-10)
2124 SLDist = Dist/An;
2125 else {
2126 SLDist = Dist*1.E10;
2127 if (An<0) SLDist *= -1.;
2128 }
2129
2130 limits.setLimit(stp_plane, SLDist);
2131 limits.setStepSign(SLDist);
2132
2133 if (debugLvl_ > 0) {
2134 debugOut << " Distance to plane: " << Dist << "\n";
2135 debugOut << " SL distance to plane: " << SLDist << "\n";
2136 if (limits.getStepSign()>0)
2137 debugOut << " Direction is pointing towards surface.\n";
2138 else
2139 debugOut << " Direction is pointing away from surface.\n";
2140 }
2141
2142
2143
2144
2145
2146
2147 double fieldCurvLimit( limits.getLowestLimitSignedVal() );
2148 std::pair<double, double> distVsStep (9.E99, 9.E99);
2149
2150 static const unsigned int maxNumIt = 10;
2151 unsigned int counter(0);
2152
2153 while (fabs(fieldCurvLimit) > MINSTEP) {
2154
2155 if(++counter > maxNumIt){
2156
2157
2158
2159 fieldCurvLimit *= 0.5;
2160 break;
2161 }
2162
2163 M1x7 state7_temp = state7;
2164 M1x3 SA = {{0, 0, 0}};
2165
2166 double q ( RKPropagate(state7_temp, nullptr, SA, fieldCurvLimit, true) );
2167 if (debugLvl_ > 0) {
2168 debugOut << " maxStepArg = " << fieldCurvLimit << "; q = " << q << " \n";
2169 }
2170
2171
2172
2173 Dist = SU[3] - (state7_temp[0] * SU[0] +
2174 state7_temp[1] * SU[1] +
2175 state7_temp[2] * SU[2]);
2176
2177 An = state7_temp[3] * SU[0] +
2178 state7_temp[4] * SU[1] +
2179 state7_temp[5] * SU[2];
2180
2181 if (fabs(Dist/An) < fabs(distVsStep.first)) {
2182 distVsStep.first = Dist/An;
2183 distVsStep.second = fieldCurvLimit;
2184 }
2185
2186
2187
2188
2189 if (q>2) {
2190 fieldCurvLimit *= 2;
2191 break;
2192 }
2193
2194 fieldCurvLimit *= q * 0.95;
2195
2196 if (fabs(q-1) < 0.25 ||
2197 fabs(fieldCurvLimit) > limits.getLowestLimitVal())
2198 break;
2199 }
2200 if (fabs(fieldCurvLimit) < MINSTEP)
2201 limits.setLimit(stp_fieldCurv, MINSTEP);
2202 else
2203 limits.setLimit(stp_fieldCurv, fieldCurvLimit);
2204
2205 double stepToPlane(limits.getLimitSigned(stp_plane));
2206 if (fabs(distVsStep.first) < 8.E99) {
2207 stepToPlane = distVsStep.first + distVsStep.second;
2208 }
2209 limits.setLimit(stp_plane, stepToPlane);
2210
2211
2212
2213
2214
2215
2216 if (propDir_ == 0 || !plane.isFinite()){
2217 if (debugLvl_ > 0) {
2218 debugOut << " auto select direction";
2219 if (!plane.isFinite()) debugOut << ", plane is not finite";
2220 debugOut << ".\n";
2221 }
2222 }
2223
2224 else if ( limits.getLimit(stp_plane) < 0.2*limits.getLimit(stp_fieldCurv) ){
2225 if (debugLvl_ > 0) {
2226 debugOut << " straight line approximation is fine.\n";
2227 }
2228
2229
2230 if( plane.isInActive(state7[0], state7[1], state7[2], state7[3], state7[4], state7[5]) ) {
2231 if (debugLvl_ > 0) {
2232 debugOut << " direction is pointing to active part of surface. \n";
2233 }
2234 }
2235
2236 else {
2237 limits.removeLimit(stp_plane);
2238 limits.setStepSign(propDir_);
2239 if (debugLvl_ > 0) {
2240 debugOut << " we are near the plane, but not pointing to the active area. make a big step! \n";
2241 }
2242 }
2243 }
2244
2245 else {
2246 if (limits.getStepSign() * propDir_ < 0){
2247 limits.removeLimit(stp_plane);
2248 limits.setStepSign(propDir_);
2249 if (debugLvl_ > 0) {
2250 debugOut << " invert Step according to propDir_ and make a big step. \n";
2251 }
2252 }
2253 }
2254
2255
2256
2257 static const RKStep defaultRKStep;
2258 RKSteps_.push_back( defaultRKStep );
2259 std::vector<RKStep>::iterator lastStep = RKSteps_.end() - 1;
2260 lastStep->state7_ = state7;
2261 ++RKStepsFXStop_;
2262
2263 if(limits.getLowestLimitVal() > MINSTEP){
2264 M1x7 state7_temp = {{ state7[0], state7[1], state7[2], state7[3], state7[4], state7[5], state7[6] }};
2265
2266 MaterialEffects::getInstance()->stepper(this,
2267 state7_temp,
2268 charge/state7[6],
2269 relMomLoss,
2270 pdgCode_,
2271 lastStep->matStep_.material_,
2272 limits,
2273 true);
2274 } else {
2275 if (RKSteps_.size()>1) {
2276 lastStep->matStep_.material_ = (lastStep - 1)->matStep_.material_;
2277 }
2278 }
2279
2280 if (debugLvl_ > 0) {
2281 debugOut << " final limits:\n";
2282 limits.Print();
2283 }
2284
2285 double finalStep = limits.getLowestLimitSignedVal();
2286
2287 lastStep->matStep_.stepSize_ = finalStep;
2288 lastStep->limits_ = limits;
2289
2290 if (debugLvl_ > 0) {
2291 debugOut << " --> Step to be used: " << finalStep << "\n";
2292 }
2293
2294 return finalStep;
2295
2296 }
2297
2298
2299 TVector3 RKTrackRep::pocaOnLine(const TVector3& linePoint, const TVector3& lineDirection, const TVector3& point) const {
2300
2301 TVector3 retVal(lineDirection);
2302
2303 double t = 1./(retVal.Mag2()) * ((point*retVal) - (linePoint*retVal));
2304 retVal *= t;
2305 retVal += linePoint;
2306 return retVal;
2307
2308 }
2309
2310
2311 double RKTrackRep::Extrap(const DetPlane& startPlane,
2312 const DetPlane& destPlane,
2313 double charge,
2314 double mass,
2315 bool& isAtBoundary,
2316 M1x7& state7,
2317 double& flightTime,
2318 bool fillExtrapSteps,
2319 TMatrixDSym* cov,
2320 bool onlyOneStep,
2321 bool stopAtBoundary,
2322 double maxStep) const
2323 {
2324
2325 static const unsigned int maxNumIt(500);
2326 unsigned int numIt(0);
2327
2328 double coveredDistance(0.);
2329
2330 double dqop(0.);
2331
2332 const TVector3 W(destPlane.getNormal());
2333 M1x4 SU = {{W.X(), W.Y(), W.Z(), destPlane.distance(0., 0., 0.)}};
2334
2335
2336 if (W*destPlane.getO() < 0) {
2337 SU[0] *= -1;
2338 SU[1] *= -1;
2339 SU[2] *= -1;
2340 }
2341
2342
2343 M1x7 startState7 = state7;
2344
2345 while(true){
2346
2347 if (debugLvl_ > 0) {
2348 debugOut << "\n============ RKTrackRep::Extrap loop nr. " << numIt << " ============\n";
2349 debugOut << "Start plane: "; startPlane.Print();
2350 debugOut << "fillExtrapSteps " << fillExtrapSteps << "\n";
2351 }
2352
2353 if(++numIt > maxNumIt){
2354 Exception exc("RKTrackRep::Extrap ==> maximum number of iterations exceeded",__LINE__,__FILE__);
2355 exc.setFatal();
2356 throw exc;
2357 }
2358
2359
2360 for(int i = 0; i < 7*7; ++i) J_MMT_[i] = 0;
2361 for(int i=0; i<7; ++i) J_MMT_[8*i] = 1.;
2362
2363 M7x7* noise = nullptr;
2364 isAtBoundary = false;
2365
2366
2367 bool checkJacProj = false;
2368 limits_.reset();
2369 limits_.setLimit(stp_sMaxArg, maxStep-fabs(coveredDistance));
2370
2371 M1x7 J_MMT_unprojected_lastRow = {{0, 0, 0, 0, 0, 0, 1}};
2372
2373 if( ! RKutta(SU, destPlane, charge, mass, state7, &J_MMT_, &J_MMT_unprojected_lastRow,
2374 coveredDistance, flightTime, checkJacProj, noiseProjection_,
2375 limits_, onlyOneStep, !fillExtrapSteps) ) {
2376 Exception exc("RKTrackRep::Extrap ==> Runge Kutta propagation failed",__LINE__,__FILE__);
2377 exc.setFatal();
2378 throw exc;
2379 }
2380
2381 bool atPlane(limits_.getLowestLimit().first == stp_plane);
2382 if (limits_.getLowestLimit().first == stp_boundary)
2383 isAtBoundary = true;
2384
2385
2386 if (debugLvl_ > 0) {
2387 debugOut<<"RKSteps \n";
2388 for (std::vector<RKStep>::iterator it = RKSteps_.begin(); it != RKSteps_.end(); ++it){
2389 debugOut << "stepSize = " << it->matStep_.stepSize_ << "\t";
2390 it->matStep_.material_.Print();
2391 }
2392 debugOut<<"\n";
2393 }
2394
2395
2396
2397
2398 if(fillExtrapSteps) {
2399 noise = &noiseArray_;
2400 for(int i = 0; i < 7*7; ++i) noiseArray_[i] = 0;
2401 }
2402
2403 unsigned int nPoints(RKStepsFXStop_ - RKStepsFXStart_);
2404 if ( nPoints>0){
2405
2406 double momLoss = MaterialEffects::getInstance()->effects(RKSteps_,
2407 RKStepsFXStart_,
2408 RKStepsFXStop_,
2409 fabs(charge/state7[6]),
2410 pdgCode_,
2411 noise);
2412
2413 RKStepsFXStart_ = RKStepsFXStop_;
2414
2415 if (debugLvl_ > 0) {
2416 debugOut << "momLoss: " << momLoss << " GeV; relative: " << momLoss/fabs(charge/state7[6])
2417 << "; coveredDistance = " << coveredDistance << "\n";
2418 if (debugLvl_ > 1 && noise != nullptr) {
2419 debugOut << "7D noise: \n";
2420 RKTools::printDim(noise->begin(), 7, 7);
2421 }
2422 }
2423
2424
2425 if(fabs(state7[6])>1.E-10) {
2426
2427 if (debugLvl_ > 0) {
2428 debugOut << "correct state7 with dx/dqop, dy/dqop ...\n";
2429 }
2430
2431 dqop = charge/(fabs(charge/state7[6])-momLoss) - state7[6];
2432
2433
2434
2435
2436
2437
2438 if (checkJacProj && fabs(coveredDistance) > MINSTEP) {
2439 M1x3 state7_correction_unprojected = {{0, 0, 0}};
2440 for (unsigned int i=0; i<3; ++i) {
2441 state7_correction_unprojected[i] = 0.5 * dqop * J_MMT_unprojected_lastRow[i];
2442
2443
2444 }
2445
2446 M1x3 state7_correction_projected = {{0, 0, 0}};
2447 for (unsigned int i=0; i<3; ++i) {
2448 state7_correction_projected[i] = 0.5 * dqop * J_MMT_[6*7 + i];
2449
2450
2451 }
2452
2453
2454 M1x3 delta_state = {{0, 0, 0}};
2455 for (unsigned int i=0; i<3; ++i) {
2456 delta_state[i] = state7_correction_unprojected[i] - state7_correction_projected[i];
2457 }
2458
2459 double Dist( sqrt(delta_state[0]*delta_state[0]
2460 + delta_state[1]*delta_state[1]
2461 + delta_state[2]*delta_state[2] ) );
2462
2463
2464 if (delta_state[0]*state7[3] + delta_state[1]*state7[4] + delta_state[2]*state7[5] > 0)
2465 Dist *= -1.;
2466
2467 double correctionFactor( 1. + Dist / coveredDistance );
2468 flightTime *= correctionFactor;
2469 momLoss *= correctionFactor;
2470 coveredDistance = coveredDistance + Dist;
2471
2472 if (debugLvl_ > 0) {
2473 debugOut << "correctionFactor-1 = " << correctionFactor-1. << "; Dist = " << Dist << "\n";
2474 debugOut << "corrected momLoss: " << momLoss << " GeV; relative: " << momLoss/fabs(charge/state7[6])
2475 << "; corrected coveredDistance = " << coveredDistance << "\n";
2476 }
2477 }
2478
2479
2480 double qop( charge/(fabs(charge/state7[6])-momLoss) );
2481 dqop = qop - state7[6];
2482 state7[6] = qop;
2483
2484 for (unsigned int i=0; i<6; ++i) {
2485 state7[i] += 0.5 * dqop * J_MMT_[6*7 + i];
2486 }
2487
2488 double norm( 1. / sqrt(state7[3]*state7[3] + state7[4]*state7[4] + state7[5]*state7[5]) );
2489 for (unsigned int i=3; i<6; ++i)
2490 state7[i] *= norm;
2491
2492 }
2493 }
2494
2495
2496
2497 if (fillExtrapSteps) {
2498 static const ExtrapStep defaultExtrapStep;
2499 ExtrapSteps_.push_back(defaultExtrapStep);
2500 std::vector<ExtrapStep>::iterator lastStep = ExtrapSteps_.end() - 1;
2501
2502
2503 lastStep->jac7_ = J_MMT_;
2504
2505 if( checkJacProj == true ){
2506
2507 RKTools::Np_N_NpT(noiseProjection_, noiseArray_);
2508
2509 if (debugLvl_ > 1) {
2510 debugOut << "7D noise projected onto plane: \n";
2511 RKTools::printDim(noiseArray_.begin(), 7, 7);
2512 }
2513 }
2514
2515
2516 lastStep->noise7_ = noiseArray_;
2517
2518 if (debugLvl_ > 2) {
2519 debugOut<<"ExtrapSteps \n";
2520 for (std::vector<ExtrapStep>::iterator it = ExtrapSteps_.begin(); it != ExtrapSteps_.end(); ++it){
2521 debugOut << "7D Jacobian: "; RKTools::printDim((it->jac7_.begin()), 5,5);
2522 debugOut << "7D noise: "; RKTools::printDim((it->noise7_.begin()), 5,5);
2523 }
2524 debugOut<<"\n";
2525 }
2526 }
2527
2528
2529
2530
2531 if (stopAtBoundary and isAtBoundary) {
2532 if (debugLvl_ > 0) {
2533 debugOut << "stopAtBoundary -> break; \n ";
2534 }
2535 break;
2536 }
2537
2538 if (onlyOneStep) {
2539 if (debugLvl_ > 0) {
2540 debugOut << "onlyOneStep -> break; \n ";
2541 }
2542 break;
2543 }
2544
2545
2546 if(atPlane) {
2547 if (debugLvl_ > 0) {
2548 debugOut << "arrived at destPlane with a distance of " << destPlane.distance(state7[0], state7[1], state7[2]) << " cm left. ";
2549 if (destPlane.isInActive(state7[0], state7[1], state7[2], state7[3], state7[4], state7[5]))
2550 debugOut << "In active area of destPlane. \n";
2551 else
2552 debugOut << "NOT in active area of plane. \n";
2553
2554 debugOut << " position: "; TVector3(state7[0], state7[1], state7[2]).Print();
2555 debugOut << " direction: "; TVector3(state7[3], state7[4], state7[5]).Print();
2556 }
2557 break;
2558 }
2559
2560 }
2561
2562 if (fillExtrapSteps) {
2563
2564 calcForwardJacobianAndNoise(startState7, startPlane, state7, destPlane);
2565
2566 if (cov != nullptr) {
2567 cov->Similarity(fJacobian_);
2568 *cov += fNoise_;
2569 }
2570
2571 if (debugLvl_ > 0) {
2572 if (cov != nullptr) {
2573 debugOut << "final covariance matrix after Extrap: "; cov->Print();
2574 }
2575 }
2576 }
2577
2578 return coveredDistance;
2579 }
2580
2581
2582 void RKTrackRep::checkCache(const StateOnPlane& state, const SharedPlanePtr* plane) const {
2583
2584 if (state.getRep() != this){
2585 Exception exc("RKTrackRep::checkCache ==> state is defined wrt. another TrackRep",__LINE__,__FILE__);
2586 exc.setFatal();
2587 throw exc;
2588 }
2589
2590 if (dynamic_cast<const MeasurementOnPlane*>(&state) != nullptr) {
2591 Exception exc("RKTrackRep::checkCache - cannot extrapolate MeasurementOnPlane",__LINE__,__FILE__);
2592 exc.setFatal();
2593 throw exc;
2594 }
2595
2596 cachePos_ = 0;
2597 RKStepsFXStart_ = 0;
2598 RKStepsFXStop_ = 0;
2599 ExtrapSteps_.clear();
2600 initArrays();
2601
2602
2603 if (plane &&
2604 lastStartState_.getPlane() &&
2605 lastEndState_.getPlane() &&
2606 state.getPlane() == lastStartState_.getPlane() &&
2607 state.getState() == lastStartState_.getState() &&
2608 (*plane)->distance(getPos(lastEndState_)) <= MINSTEP) {
2609 useCache_ = true;
2610
2611
2612 double firstStep(0);
2613 for (unsigned int i=0; i<RKSteps_.size(); ++i) {
2614 if (i == 0) {
2615 firstStep = RKSteps_.at(0).matStep_.stepSize_;
2616 continue;
2617 }
2618 if (RKSteps_.at(i).matStep_.stepSize_ * firstStep < 0) {
2619 if (RKSteps_.at(i-1).matStep_.material_ == RKSteps_.at(i).matStep_.material_) {
2620 RKSteps_.at(i-1).matStep_.stepSize_ += RKSteps_.at(i).matStep_.stepSize_;
2621 }
2622 RKSteps_.erase(RKSteps_.begin()+i, RKSteps_.end());
2623 }
2624 }
2625
2626 if (debugLvl_ > 0) {
2627 debugOut << "RKTrackRep::checkCache: use cached material and step values.\n";
2628 }
2629 }
2630 else {
2631
2632 if (debugLvl_ > 0) {
2633 debugOut << "RKTrackRep::checkCache: can NOT use cached material and step values.\n";
2634
2635 if (plane != nullptr) {
2636 if (state.getPlane() != lastStartState_.getPlane()) {
2637 debugOut << "state.getPlane() != lastStartState_.getPlane()\n";
2638 }
2639 else {
2640 if (! (state.getState() == lastStartState_.getState())) {
2641 debugOut << "state.getState() != lastStartState_.getState()\n";
2642 }
2643 else if (lastEndState_.getPlane().get() != nullptr) {
2644 debugOut << "distance " << (*plane)->distance(getPos(lastEndState_)) << "\n";
2645 }
2646 }
2647 }
2648 }
2649
2650 useCache_ = false;
2651 RKSteps_.clear();
2652
2653 lastStartState_.setStatePlane(state.getState(), state.getPlane());
2654 }
2655 }
2656
2657
2658 double RKTrackRep::momMag(const M1x7& state7) const {
2659
2660 return fabs(1/state7[6]);
2661 }
2662
2663
2664 bool RKTrackRep::isSameType(const AbsTrackRep* other) {
2665 if (dynamic_cast<const RKTrackRep*>(other) == nullptr)
2666 return false;
2667
2668 return true;
2669 }
2670
2671
2672 bool RKTrackRep::isSame(const AbsTrackRep* other) {
2673 if (getPDG() != other->getPDG())
2674 return false;
2675
2676 return isSameType(other);
2677 }
2678
2679
2680 void RKTrackRep::Streamer(TBuffer &R__b)
2681 {
2682
2683
2684
2685 typedef ::genfit::RKTrackRep thisClass;
2686 UInt_t R__s, R__c;
2687 if (R__b.IsReading()) {
2688 ::genfit::AbsTrackRep::Streamer(R__b);
2689 Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
2690 R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
2691 lastStartState_.setRep(this);
2692 lastEndState_.setRep(this);
2693 } else {
2694 ::genfit::AbsTrackRep::Streamer(R__b);
2695 R__c = R__b.WriteVersion(thisClass::IsA(), kTRUE);
2696 R__b.SetByteCount(R__c, kTRUE);
2697 }
2698 }
2699
2700 }