File indexing completed on 2025-08-05 08:18:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 #include "GblTrajectory.h"
0134
0135
0136 namespace gbl {
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 GblTrajectory::GblTrajectory(const std::vector<GblPoint> &aPointList,
0148 bool flagCurv, bool flagU1dir, bool flagU2dir) :
0149 numAllPoints(aPointList.size()), numPoints(), numOffsets(0), numInnerTrans(
0150 0), numCurvature(flagCurv ? 1 : 0), numParameters(0), numLocals(
0151 0), numMeasurements(0), externalPoint(0), theDimension(0), thePoints(), theData(), measDataIndex(), scatDataIndex(), externalSeed(), innerTransformations(), externalDerivatives(), externalMeasurements(), externalPrecisions() {
0152
0153 if (flagU1dir)
0154 theDimension.push_back(0);
0155 if (flagU2dir)
0156 theDimension.push_back(1);
0157
0158 thePoints.push_back(aPointList);
0159 numPoints.push_back(numAllPoints);
0160 construct();
0161 }
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 GblTrajectory::GblTrajectory(const std::vector<GblPoint> &aPointList,
0176 unsigned int aLabel, const TMatrixDSym &aSeed, bool flagCurv,
0177 bool flagU1dir, bool flagU2dir) :
0178 numAllPoints(aPointList.size()), numPoints(), numOffsets(0), numInnerTrans(
0179 0), numCurvature(flagCurv ? 1 : 0), numParameters(0), numLocals(
0180 0), numMeasurements(0), externalPoint(aLabel), theDimension(0), thePoints(), theData(), measDataIndex(), scatDataIndex(), externalSeed(
0181 aSeed), innerTransformations(), externalDerivatives(), externalMeasurements(), externalPrecisions() {
0182
0183 if (flagU1dir)
0184 theDimension.push_back(0);
0185 if (flagU2dir)
0186 theDimension.push_back(1);
0187
0188 thePoints.push_back(aPointList);
0189 numPoints.push_back(numAllPoints);
0190 construct();
0191 }
0192
0193
0194
0195
0196
0197
0198 GblTrajectory::GblTrajectory(
0199 const std::vector<std::pair<std::vector<GblPoint>, TMatrixD> > &aPointsAndTransList) :
0200 numAllPoints(), numPoints(), numOffsets(0), numInnerTrans(
0201 aPointsAndTransList.size()), numParameters(0), numLocals(0), numMeasurements(
0202 0), externalPoint(0), theDimension(0), thePoints(), theData(), measDataIndex(), scatDataIndex(), externalSeed(), innerTransformations(), externalDerivatives(), externalMeasurements(), externalPrecisions() {
0203
0204 for (unsigned int iTraj = 0; iTraj < aPointsAndTransList.size(); ++iTraj) {
0205 thePoints.push_back(aPointsAndTransList[iTraj].first);
0206 numPoints.push_back(thePoints.back().size());
0207 numAllPoints += numPoints.back();
0208 innerTransformations.push_back(aPointsAndTransList[iTraj].second);
0209 }
0210 theDimension.push_back(0);
0211 theDimension.push_back(1);
0212 numCurvature = innerTransformations[0].GetNcols();
0213 construct();
0214 }
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224 GblTrajectory::GblTrajectory(
0225 const std::vector<std::pair<std::vector<GblPoint>, TMatrixD> > &aPointsAndTransList,
0226 const TMatrixD &extDerivatives, const TVectorD &extMeasurements,
0227 const TVectorD &extPrecisions) :
0228 numAllPoints(), numPoints(), numOffsets(0), numInnerTrans(
0229 aPointsAndTransList.size()), numParameters(0), numLocals(0), numMeasurements(
0230 0), externalPoint(0), theDimension(0), thePoints(), theData(), measDataIndex(), scatDataIndex(), externalSeed(), innerTransformations(), externalDerivatives(
0231 extDerivatives), externalMeasurements(extMeasurements), externalPrecisions(
0232 extPrecisions) {
0233
0234 for (unsigned int iTraj = 0; iTraj < aPointsAndTransList.size(); ++iTraj) {
0235 thePoints.push_back(aPointsAndTransList[iTraj].first);
0236 numPoints.push_back(thePoints.back().size());
0237 numAllPoints += numPoints.back();
0238 innerTransformations.push_back(aPointsAndTransList[iTraj].second);
0239 }
0240 theDimension.push_back(0);
0241 theDimension.push_back(1);
0242 numCurvature = innerTransformations[0].GetNcols();
0243 construct();
0244 }
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 GblTrajectory::GblTrajectory(
0255 const std::vector<std::pair<std::vector<GblPoint>, TMatrixD> > &aPointsAndTransList,
0256 const TMatrixD &extDerivatives, const TVectorD &extMeasurements,
0257 const TMatrixDSym &extPrecisions) :
0258 numAllPoints(), numPoints(), numOffsets(0), numInnerTrans(
0259 aPointsAndTransList.size()), numParameters(0), numLocals(0), numMeasurements(
0260 0), externalPoint(0), theDimension(0), thePoints(), theData(), measDataIndex(), scatDataIndex(), externalSeed(), innerTransformations() {
0261
0262
0263 TMatrixDSymEigen extEigen(extPrecisions);
0264 TMatrixD extTransformation = extEigen.GetEigenVectors();
0265 extTransformation.T();
0266 externalDerivatives.ResizeTo(extDerivatives);
0267 externalDerivatives = extTransformation * extDerivatives;
0268 externalMeasurements.ResizeTo(extMeasurements);
0269 externalMeasurements = extTransformation * extMeasurements;
0270 externalPrecisions.ResizeTo(extMeasurements);
0271 externalPrecisions = extEigen.GetEigenValues();
0272
0273 for (unsigned int iTraj = 0; iTraj < aPointsAndTransList.size(); ++iTraj) {
0274 thePoints.push_back(aPointsAndTransList[iTraj].first);
0275 numPoints.push_back(thePoints.back().size());
0276 numAllPoints += numPoints.back();
0277 innerTransformations.push_back(aPointsAndTransList[iTraj].second);
0278 }
0279 theDimension.push_back(0);
0280 theDimension.push_back(1);
0281 numCurvature = innerTransformations[0].GetNcols();
0282 construct();
0283 }
0284
0285 GblTrajectory::~GblTrajectory() {
0286 }
0287
0288
0289 bool GblTrajectory::isValid() const {
0290 return constructOK;
0291 }
0292
0293
0294 unsigned int GblTrajectory::getNumPoints() const {
0295 return numAllPoints;
0296 }
0297
0298
0299
0300
0301
0302 void GblTrajectory::construct() {
0303
0304 constructOK = false;
0305 fitOK = false;
0306 unsigned int aLabel = 0;
0307 if (numAllPoints < 2) {
0308 std::cout << " GblTrajectory construction failed: too few GblPoints "
0309 << std::endl;
0310 return;
0311 }
0312
0313 numTrajectories = thePoints.size();
0314
0315 for (unsigned int iTraj = 0; iTraj < numTrajectories; ++iTraj) {
0316 std::vector<GblPoint>::iterator itPoint;
0317 for (itPoint = thePoints[iTraj].begin();
0318 itPoint < thePoints[iTraj].end(); ++itPoint) {
0319 numLocals = std::max(numLocals, itPoint->getNumLocals());
0320 numMeasurements += itPoint->hasMeasurement();
0321 itPoint->setLabel(++aLabel);
0322 }
0323 }
0324 defineOffsets();
0325 calcJacobians();
0326 try {
0327 prepare();
0328 } catch (std::overflow_error &e) {
0329 std::cout << " GblTrajectory construction failed: " << e.what()
0330 << std::endl;
0331 return;
0332 }
0333 constructOK = true;
0334
0335 numParameters = (numOffsets - 2 * numInnerTrans) * theDimension.size()
0336 + numCurvature + numLocals;
0337 }
0338
0339
0340
0341
0342
0343
0344 void GblTrajectory::defineOffsets() {
0345
0346
0347 for (unsigned int iTraj = 0; iTraj < numTrajectories; ++iTraj) {
0348
0349 thePoints[iTraj].front().setOffset(numOffsets++);
0350
0351 std::vector<GblPoint>::iterator itPoint;
0352 for (itPoint = thePoints[iTraj].begin() + 1;
0353 itPoint < thePoints[iTraj].end() - 1; ++itPoint) {
0354 if (itPoint->hasScatterer()) {
0355 itPoint->setOffset(numOffsets++);
0356 } else {
0357 itPoint->setOffset(-numOffsets);
0358 }
0359 }
0360
0361 thePoints[iTraj].back().setOffset(numOffsets++);
0362 }
0363 }
0364
0365
0366 void GblTrajectory::calcJacobians() {
0367
0368 SMatrix55 scatJacobian;
0369
0370 for (unsigned int iTraj = 0; iTraj < numTrajectories; ++iTraj) {
0371
0372 GblPoint* previousPoint = &thePoints[iTraj].front();
0373 unsigned int numStep = 0;
0374 std::vector<GblPoint>::iterator itPoint;
0375 for (itPoint = thePoints[iTraj].begin() + 1;
0376 itPoint < thePoints[iTraj].end(); ++itPoint) {
0377 if (numStep == 0) {
0378 scatJacobian = itPoint->getP2pJacobian();
0379 } else {
0380 scatJacobian = itPoint->getP2pJacobian() * scatJacobian;
0381 }
0382 numStep++;
0383 itPoint->addPrevJacobian(scatJacobian);
0384 if (itPoint->getOffset() >= 0) {
0385 previousPoint->addNextJacobian(scatJacobian);
0386 numStep = 0;
0387 previousPoint = &(*itPoint);
0388 }
0389 }
0390
0391 for (itPoint = thePoints[iTraj].end() - 1;
0392 itPoint > thePoints[iTraj].begin(); --itPoint) {
0393 if (itPoint->getOffset() >= 0) {
0394 scatJacobian = itPoint->getP2pJacobian();
0395 continue;
0396 }
0397 itPoint->addNextJacobian(scatJacobian);
0398 scatJacobian = scatJacobian * itPoint->getP2pJacobian();
0399 }
0400 }
0401 }
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 std::pair<std::vector<unsigned int>, TMatrixD> GblTrajectory::getJacobian(
0413 int aSignedLabel) const {
0414
0415 unsigned int nDim = theDimension.size();
0416 unsigned int nCurv = numCurvature;
0417 unsigned int nLocals = numLocals;
0418 unsigned int nBorder = nCurv + nLocals;
0419 unsigned int nParBRL = nBorder + 2 * nDim;
0420 unsigned int nParLoc = nLocals + 5;
0421 std::vector<unsigned int> anIndex;
0422 anIndex.reserve(nParBRL);
0423 TMatrixD aJacobian(nParLoc, nParBRL);
0424 aJacobian.Zero();
0425
0426 unsigned int aLabel = abs(aSignedLabel);
0427 unsigned int firstLabel = 1;
0428 unsigned int lastLabel = 0;
0429 unsigned int aTrajectory = 0;
0430
0431 for (unsigned int iTraj = 0; iTraj < numTrajectories; ++iTraj) {
0432 aTrajectory = iTraj;
0433 lastLabel += numPoints[iTraj];
0434 if (aLabel <= lastLabel)
0435 break;
0436 if (iTraj < numTrajectories - 1)
0437 firstLabel += numPoints[iTraj];
0438 }
0439 int nJacobian;
0440
0441 if (aSignedLabel > 0) {
0442 nJacobian = 1;
0443 if (aLabel >= lastLabel) {
0444 aLabel = lastLabel;
0445 nJacobian = 0;
0446 }
0447 } else {
0448 nJacobian = 0;
0449 if (aLabel <= firstLabel) {
0450 aLabel = firstLabel;
0451 nJacobian = 1;
0452 }
0453 }
0454 const GblPoint aPoint = thePoints[aTrajectory][aLabel - firstLabel];
0455 std::vector<unsigned int> labDer(5);
0456 SMatrix55 matDer;
0457 getFitToLocalJacobian(labDer, matDer, aPoint, 5, nJacobian);
0458
0459
0460 for (unsigned int i = 0; i < nLocals; ++i) {
0461 aJacobian(i + 5, i) = 1.0;
0462 anIndex.push_back(i + 1);
0463 }
0464
0465 unsigned int iCol = nLocals;
0466 for (unsigned int i = 0; i < 5; ++i) {
0467 if (labDer[i] > 0) {
0468 anIndex.push_back(labDer[i]);
0469 for (unsigned int j = 0; j < 5; ++j) {
0470 aJacobian(j, iCol) = matDer(j, i);
0471 }
0472 ++iCol;
0473 }
0474 }
0475 return std::make_pair(anIndex, aJacobian);
0476 }
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488 void GblTrajectory::getFitToLocalJacobian(std::vector<unsigned int> &anIndex,
0489 SMatrix55 &aJacobian, const GblPoint &aPoint, unsigned int measDim,
0490 unsigned int nJacobian) const {
0491
0492 unsigned int nDim = theDimension.size();
0493 unsigned int nCurv = numCurvature;
0494 unsigned int nLocals = numLocals;
0495
0496 int nOffset = aPoint.getOffset();
0497
0498 if (nOffset < 0)
0499 {
0500 SMatrix22 prevW, prevWJ, nextW, nextWJ, matN;
0501 SVector2 prevWd, nextWd;
0502 int ierr;
0503 aPoint.getDerivatives(0, prevW, prevWJ, prevWd);
0504 aPoint.getDerivatives(1, nextW, nextWJ, nextWd);
0505 const SMatrix22 sumWJ(prevWJ + nextWJ);
0506 matN = sumWJ.Inverse(ierr);
0507
0508 const SMatrix22 prevNW(matN * prevW);
0509 const SMatrix22 nextNW(matN * nextW);
0510 const SVector2 prevNd(matN * prevWd);
0511 const SVector2 nextNd(matN * nextWd);
0512
0513 unsigned int iOff = nDim * (-nOffset - 1) + nLocals + nCurv + 1;
0514
0515
0516 if (nCurv > 0) {
0517 aJacobian.Place_in_col(-prevNd - nextNd, 3, 0);
0518 anIndex[0] = nLocals + 1;
0519 }
0520 aJacobian.Place_at(prevNW, 3, 1);
0521 aJacobian.Place_at(nextNW, 3, 3);
0522 for (unsigned int i = 0; i < nDim; ++i) {
0523 anIndex[1 + theDimension[i]] = iOff + i;
0524 anIndex[3 + theDimension[i]] = iOff + nDim + i;
0525 }
0526
0527
0528 if (measDim > 2) {
0529
0530 const SMatrix22 prevWPN(nextWJ * prevNW);
0531 const SMatrix22 nextWPN(prevWJ * nextNW);
0532 const SVector2 prevWNd(nextWJ * prevNd);
0533 const SVector2 nextWNd(prevWJ * nextNd);
0534 if (nCurv > 0) {
0535 aJacobian(0, 0) = 1.0;
0536 aJacobian.Place_in_col(prevWNd - nextWNd, 1, 0);
0537 }
0538 aJacobian.Place_at(-prevWPN, 1, 1);
0539 aJacobian.Place_at(nextWPN, 1, 3);
0540 }
0541 } else {
0542
0543
0544
0545 unsigned int iOff1 = nDim * nOffset + nCurv + nLocals + 1;
0546 unsigned int index1 = 3 - 2 * nJacobian;
0547 unsigned int iOff2 = iOff1 + nDim * (nJacobian * 2 - 1);
0548 unsigned int index2 = 1 + 2 * nJacobian;
0549
0550 aJacobian(3, index1) = 1.0;
0551 aJacobian(4, index1 + 1) = 1.0;
0552 for (unsigned int i = 0; i < nDim; ++i) {
0553 anIndex[index1 + theDimension[i]] = iOff1 + i;
0554 }
0555
0556
0557 if (measDim > 2) {
0558 SMatrix22 matW, matWJ;
0559 SVector2 vecWd;
0560 aPoint.getDerivatives(nJacobian, matW, matWJ, vecWd);
0561 double sign = (nJacobian > 0) ? 1. : -1.;
0562 if (nCurv > 0) {
0563 aJacobian(0, 0) = 1.0;
0564 aJacobian.Place_in_col(-sign * vecWd, 1, 0);
0565 anIndex[0] = nLocals + 1;
0566 }
0567 aJacobian.Place_at(-sign * matWJ, 1, index1);
0568 aJacobian.Place_at(sign * matW, 1, index2);
0569 for (unsigned int i = 0; i < nDim; ++i) {
0570 anIndex[index2 + theDimension[i]] = iOff2 + i;
0571 }
0572 }
0573 }
0574 }
0575
0576
0577
0578
0579
0580
0581
0582
0583 void GblTrajectory::getFitToKinkJacobian(std::vector<unsigned int> &anIndex,
0584 SMatrix27 &aJacobian, const GblPoint &aPoint) const {
0585
0586 unsigned int nDim = theDimension.size();
0587 unsigned int nCurv = numCurvature;
0588 unsigned int nLocals = numLocals;
0589
0590 int nOffset = aPoint.getOffset();
0591
0592 SMatrix22 prevW, prevWJ, nextW, nextWJ;
0593 SVector2 prevWd, nextWd;
0594 aPoint.getDerivatives(0, prevW, prevWJ, prevWd);
0595 aPoint.getDerivatives(1, nextW, nextWJ, nextWd);
0596 const SMatrix22 sumWJ(prevWJ + nextWJ);
0597 const SVector2 sumWd(prevWd + nextWd);
0598
0599 unsigned int iOff = (nOffset - 1) * nDim + nCurv + nLocals + 1;
0600
0601
0602 if (nCurv > 0) {
0603 aJacobian.Place_in_col(-sumWd, 0, 0);
0604 anIndex[0] = nLocals + 1;
0605 }
0606 aJacobian.Place_at(prevW, 0, 1);
0607 aJacobian.Place_at(-sumWJ, 0, 3);
0608 aJacobian.Place_at(nextW, 0, 5);
0609 for (unsigned int i = 0; i < nDim; ++i) {
0610 anIndex[1 + theDimension[i]] = iOff + i;
0611 anIndex[3 + theDimension[i]] = iOff + nDim + i;
0612 anIndex[5 + theDimension[i]] = iOff + nDim * 2 + i;
0613 }
0614 }
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631 unsigned int GblTrajectory::getResults(int aSignedLabel, TVectorD &localPar,
0632 TMatrixDSym &localCov) const {
0633 if (not fitOK)
0634 return 1;
0635 std::pair<std::vector<unsigned int>, TMatrixD> indexAndJacobian =
0636 getJacobian(aSignedLabel);
0637 unsigned int nParBrl = indexAndJacobian.first.size();
0638 TVectorD aVec(nParBrl);
0639 for (unsigned int i = 0; i < nParBrl; ++i) {
0640 aVec[i] = theVector(indexAndJacobian.first[i] - 1);
0641 }
0642 TMatrixDSym aMat = theMatrix.getBlockMatrix(indexAndJacobian.first);
0643 localPar = indexAndJacobian.second * aVec;
0644 localCov = aMat.Similarity(indexAndJacobian.second);
0645 return 0;
0646 }
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661 unsigned int GblTrajectory::getMeasResults(unsigned int aLabel,
0662 unsigned int &numData, TVectorD &aResiduals, TVectorD &aMeasErrors,
0663 TVectorD &aResErrors, TVectorD &aDownWeights) {
0664 numData = 0;
0665 if (not fitOK)
0666 return 1;
0667
0668 unsigned int firstData = measDataIndex[aLabel - 1];
0669 numData = measDataIndex[aLabel] - firstData;
0670 for (unsigned int i = 0; i < numData; ++i) {
0671 getResAndErr(firstData + i, aResiduals[i], aMeasErrors[i],
0672 aResErrors[i], aDownWeights[i]);
0673 }
0674 return 0;
0675 }
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690 unsigned int GblTrajectory::getScatResults(unsigned int aLabel,
0691 unsigned int &numData, TVectorD &aResiduals, TVectorD &aMeasErrors,
0692 TVectorD &aResErrors, TVectorD &aDownWeights) {
0693 numData = 0;
0694 if (not fitOK)
0695 return 1;
0696
0697 unsigned int firstData = scatDataIndex[aLabel - 1];
0698 numData = scatDataIndex[aLabel] - firstData;
0699 for (unsigned int i = 0; i < numData; ++i) {
0700 getResAndErr(firstData + i, aResiduals[i], aMeasErrors[i],
0701 aResErrors[i], aDownWeights[i]);
0702 }
0703 return 0;
0704 }
0705
0706
0707
0708
0709
0710
0711 unsigned int GblTrajectory::getLabels(std::vector<unsigned int> &aLabelList) {
0712 if (not constructOK)
0713 return 1;
0714
0715 unsigned int aLabel = 0;
0716 unsigned int nPoint = thePoints[0].size();
0717 aLabelList.resize(nPoint);
0718 for (unsigned i = 0; i < nPoint; ++i) {
0719 aLabelList[i] = ++aLabel;
0720 }
0721 return 0;
0722 }
0723
0724
0725
0726
0727
0728
0729 unsigned int GblTrajectory::getLabels(
0730 std::vector<std::vector<unsigned int> > &aLabelList) {
0731 if (not constructOK)
0732 return 1;
0733
0734 unsigned int aLabel = 0;
0735 aLabelList.resize(numTrajectories);
0736 for (unsigned int iTraj = 0; iTraj < numTrajectories; ++iTraj) {
0737 unsigned int nPoint = thePoints[iTraj].size();
0738 aLabelList[iTraj].resize(nPoint);
0739 for (unsigned i = 0; i < nPoint; ++i) {
0740 aLabelList[iTraj][i] = ++aLabel;
0741 }
0742 }
0743 return 0;
0744 }
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756 void GblTrajectory::getResAndErr(unsigned int aData, double &aResidual,
0757 double &aMeasError, double &aResError, double &aDownWeight) {
0758
0759 double aMeasVar;
0760 std::vector<unsigned int>* indLocal;
0761 std::vector<double>* derLocal;
0762 theData[aData].getResidual(aResidual, aMeasVar, aDownWeight, indLocal,
0763 derLocal);
0764 unsigned int nParBrl = (*indLocal).size();
0765 TVectorD aVec(nParBrl);
0766 for (unsigned int j = 0; j < nParBrl; ++j) {
0767 aVec[j] = (*derLocal)[j];
0768 }
0769 TMatrixDSym aMat = theMatrix.getBlockMatrix(*indLocal);
0770 double aFitVar = aMat.Similarity(aVec);
0771 aMeasError = sqrt(aMeasVar);
0772 aResError = (aFitVar < aMeasVar ? sqrt(aMeasVar - aFitVar) : 0.);
0773 }
0774
0775
0776 void GblTrajectory::buildLinearEquationSystem() {
0777 unsigned int nBorder = numCurvature + numLocals;
0778 theVector.resize(numParameters);
0779 theMatrix.resize(numParameters, nBorder);
0780 double aValue, aWeight;
0781 std::vector<unsigned int>* indLocal;
0782 std::vector<double>* derLocal;
0783 std::vector<GblData>::iterator itData;
0784 for (itData = theData.begin(); itData < theData.end(); ++itData) {
0785 itData->getLocalData(aValue, aWeight, indLocal, derLocal);
0786 for (unsigned int j = 0; j < indLocal->size(); ++j) {
0787 theVector((*indLocal)[j] - 1) += (*derLocal)[j] * aWeight * aValue;
0788 }
0789 theMatrix.addBlockMatrix(aWeight, indLocal, derLocal);
0790 }
0791 }
0792
0793
0794
0795
0796
0797 void GblTrajectory::prepare() {
0798 unsigned int nDim = theDimension.size();
0799
0800 unsigned int maxData = numMeasurements + nDim * (numOffsets - 2)
0801 + externalSeed.GetNrows();
0802 theData.reserve(maxData);
0803 measDataIndex.resize(numAllPoints + 3);
0804 scatDataIndex.resize(numAllPoints + 1);
0805 unsigned int nData = 0;
0806 std::vector<TMatrixD> innerTransDer;
0807 std::vector<std::vector<unsigned int> > innerTransLab;
0808
0809 if (numInnerTrans > 0) {
0810
0811 for (unsigned int iTraj = 0; iTraj < numTrajectories; ++iTraj) {
0812
0813 GblPoint* innerPoint = &thePoints[iTraj].front();
0814
0815 std::vector<unsigned int> firstLabels(5);
0816 SMatrix55 matFitToLocal, matLocalToFit;
0817 getFitToLocalJacobian(firstLabels, matFitToLocal, *innerPoint, 5);
0818
0819 int ierr;
0820 matLocalToFit = matFitToLocal.Inverse(ierr);
0821 TMatrixD localToFit(5, 5);
0822 for (unsigned int i = 0; i < 5; ++i) {
0823 for (unsigned int j = 0; j < 5; ++j) {
0824 localToFit(i, j) = matLocalToFit(i, j);
0825 }
0826 }
0827
0828 innerTransDer.push_back(localToFit * innerTransformations[iTraj]);
0829 innerTransLab.push_back(firstLabels);
0830 }
0831 }
0832
0833 SMatrix55 matP;
0834
0835 std::vector<GblPoint>::iterator itPoint;
0836 for (unsigned int iTraj = 0; iTraj < numTrajectories; ++iTraj) {
0837 for (itPoint = thePoints[iTraj].begin();
0838 itPoint < thePoints[iTraj].end(); ++itPoint) {
0839 SVector5 aMeas, aPrec;
0840 unsigned int nLabel = itPoint->getLabel();
0841 unsigned int measDim = itPoint->hasMeasurement();
0842 if (measDim) {
0843 const TMatrixD localDer = itPoint->getLocalDerivatives();
0844 const std::vector<int> globalLab = itPoint->getGlobalLabels();
0845 const TMatrixD globalDer = itPoint->getGlobalDerivatives();
0846 TMatrixD transDer;
0847 itPoint->getMeasurement(matP, aMeas, aPrec);
0848 unsigned int iOff = 5 - measDim;
0849 std::vector<unsigned int> labDer(5);
0850 SMatrix55 matDer, matPDer;
0851 unsigned int nJacobian =
0852 (itPoint < thePoints[iTraj].end() - 1) ? 1 : 0;
0853 getFitToLocalJacobian(labDer, matDer, *itPoint, measDim,
0854 nJacobian);
0855 if (measDim > 2) {
0856 matPDer = matP * matDer;
0857 } else {
0858 matPDer.Place_at(
0859 matP.Sub<SMatrix22>(3, 3)
0860 * matDer.Sub<SMatrix25>(3, 0), 3, 0);
0861 }
0862
0863 if (numInnerTrans > 0) {
0864
0865 TMatrixD proDer(measDim, 5);
0866
0867 unsigned int ifirst = 0;
0868 unsigned int ilabel = 0;
0869 while (ilabel < 5) {
0870 if (labDer[ilabel] > 0) {
0871 while (innerTransLab[iTraj][ifirst]
0872 != labDer[ilabel] and ifirst < 5) {
0873 ++ifirst;
0874 }
0875 if (ifirst >= 5) {
0876 labDer[ilabel] -= 2 * nDim * (iTraj + 1);
0877 } else {
0878
0879 labDer[ilabel] = 0;
0880 for (unsigned int k = iOff; k < 5; ++k) {
0881 proDer(k - iOff, ifirst) = matPDer(k,
0882 ilabel);
0883 }
0884 }
0885 }
0886 ++ilabel;
0887 }
0888 transDer.ResizeTo(measDim, numCurvature);
0889 transDer = proDer * innerTransDer[iTraj];
0890 }
0891 for (unsigned int i = iOff; i < 5; ++i) {
0892 if (aPrec(i) > 0.) {
0893 GblData aData(nLabel, aMeas(i), aPrec(i));
0894 aData.addDerivatives(i, labDer, matPDer, iOff, localDer,
0895 globalLab, globalDer, numLocals, transDer);
0896 theData.push_back(aData);
0897 nData++;
0898 }
0899 }
0900
0901 }
0902 measDataIndex[nLabel] = nData;
0903 }
0904 }
0905
0906
0907 SMatrix22 matT;
0908 scatDataIndex[0] = nData;
0909 scatDataIndex[1] = nData;
0910
0911 for (unsigned int iTraj = 0; iTraj < numTrajectories; ++iTraj) {
0912 for (itPoint = thePoints[iTraj].begin() + 1;
0913 itPoint < thePoints[iTraj].end() - 1; ++itPoint) {
0914 SVector2 aMeas, aPrec;
0915 unsigned int nLabel = itPoint->getLabel();
0916 if (itPoint->hasScatterer()) {
0917 itPoint->getScatterer(matT, aMeas, aPrec);
0918 TMatrixD transDer;
0919 std::vector<unsigned int> labDer(7);
0920 SMatrix27 matDer, matTDer;
0921 getFitToKinkJacobian(labDer, matDer, *itPoint);
0922 matTDer = matT * matDer;
0923 if (numInnerTrans > 0) {
0924
0925 TMatrixD proDer(nDim, 5);
0926
0927 unsigned int ifirst = 0;
0928 unsigned int ilabel = 0;
0929 while (ilabel < 7) {
0930 if (labDer[ilabel] > 0) {
0931 while (innerTransLab[iTraj][ifirst]
0932 != labDer[ilabel] and ifirst < 5) {
0933 ++ifirst;
0934 }
0935 if (ifirst >= 5) {
0936 labDer[ilabel] -= 2 * nDim * (iTraj + 1);
0937 } else {
0938
0939 labDer[ilabel] = 0;
0940 for (unsigned int k = 0; k < nDim; ++k) {
0941 proDer(k, ifirst) = matTDer(k, ilabel);
0942 }
0943 }
0944 }
0945 ++ilabel;
0946 }
0947 transDer.ResizeTo(nDim, numCurvature);
0948 transDer = proDer * innerTransDer[iTraj];
0949 }
0950 for (unsigned int i = 0; i < nDim; ++i) {
0951 unsigned int iDim = theDimension[i];
0952 if (aPrec(iDim) > 0.) {
0953 GblData aData(nLabel, aMeas(iDim), aPrec(iDim));
0954 aData.addDerivatives(iDim, labDer, matTDer, numLocals,
0955 transDer);
0956 theData.push_back(aData);
0957 nData++;
0958 }
0959 }
0960 }
0961 scatDataIndex[nLabel] = nData;
0962 }
0963 scatDataIndex[thePoints[iTraj].back().getLabel()] = nData;
0964 }
0965
0966
0967 if (externalPoint > 0) {
0968 std::pair<std::vector<unsigned int>, TMatrixD> indexAndJacobian =
0969 getJacobian(externalPoint);
0970 std::vector<unsigned int> externalSeedIndex = indexAndJacobian.first;
0971 std::vector<double> externalSeedDerivatives(externalSeedIndex.size());
0972 const TMatrixDSymEigen externalSeedEigen(externalSeed);
0973 const TVectorD valEigen = externalSeedEigen.GetEigenValues();
0974 TMatrixD vecEigen = externalSeedEigen.GetEigenVectors();
0975 vecEigen = vecEigen.T() * indexAndJacobian.second;
0976 for (int i = 0; i < externalSeed.GetNrows(); ++i) {
0977 if (valEigen(i) > 0.) {
0978 for (int j = 0; j < externalSeed.GetNcols(); ++j) {
0979 externalSeedDerivatives[j] = vecEigen(i, j);
0980 }
0981 GblData aData(externalPoint, 0., valEigen(i));
0982 aData.addDerivatives(externalSeedIndex,
0983 externalSeedDerivatives);
0984 theData.push_back(aData);
0985 nData++;
0986 }
0987 }
0988 }
0989 measDataIndex[numAllPoints + 1] = nData;
0990
0991 unsigned int nExt = externalMeasurements.GetNrows();
0992 if (nExt > 0) {
0993 std::vector<unsigned int> index(numCurvature);
0994 std::vector<double> derivatives(numCurvature);
0995 for (unsigned int iExt = 0; iExt < nExt; ++iExt) {
0996 for (unsigned int iCol = 0; iCol < numCurvature; ++iCol) {
0997 index[iCol] = numLocals + iCol + 1;
0998 derivatives[iCol] = externalDerivatives(iExt, iCol);
0999 }
1000 GblData aData(1U, externalMeasurements(iExt),
1001 externalPrecisions(iExt));
1002 aData.addDerivatives(index, derivatives);
1003 theData.push_back(aData);
1004 nData++;
1005 }
1006 }
1007 measDataIndex[numAllPoints + 2] = nData;
1008 }
1009
1010
1011 void GblTrajectory::predict() {
1012 std::vector<GblData>::iterator itData;
1013 for (itData = theData.begin(); itData < theData.end(); ++itData) {
1014 itData->setPrediction(theVector);
1015 }
1016 }
1017
1018
1019
1020
1021
1022 double GblTrajectory::downWeight(unsigned int aMethod) {
1023 double aLoss = 0.;
1024 std::vector<GblData>::iterator itData;
1025 for (itData = theData.begin(); itData < theData.end(); ++itData) {
1026 aLoss += (1. - itData->setDownWeighting(aMethod));
1027 }
1028 return aLoss;
1029 }
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043 unsigned int GblTrajectory::fit(double &Chi2, int &Ndf, double &lostWeight,
1044 std::string optionList) {
1045 const double normChi2[4] = { 1.0, 0.8737, 0.9326, 0.8228 };
1046 const std::string methodList = "TtHhCc";
1047
1048 Chi2 = 0.;
1049 Ndf = -1;
1050 lostWeight = 0.;
1051 if (not constructOK)
1052 return 10;
1053
1054 unsigned int aMethod = 0;
1055
1056 buildLinearEquationSystem();
1057 lostWeight = 0.;
1058 unsigned int ierr = 0;
1059 try {
1060
1061 theMatrix.solveAndInvertBorderedBand(theVector, theVector);
1062 predict();
1063
1064 for (unsigned int i = 0; i < optionList.size(); ++i)
1065 {
1066 size_t aPosition = methodList.find(optionList[i]);
1067 if (aPosition != std::string::npos) {
1068 aMethod = aPosition / 2 + 1;
1069 lostWeight = downWeight(aMethod);
1070 buildLinearEquationSystem();
1071 theMatrix.solveAndInvertBorderedBand(theVector, theVector);
1072 predict();
1073 }
1074 }
1075 Ndf = theData.size() - numParameters;
1076 Chi2 = 0.;
1077 for (unsigned int i = 0; i < theData.size(); ++i) {
1078 Chi2 += theData[i].getChi2();
1079 }
1080 Chi2 /= normChi2[aMethod];
1081 fitOK = true;
1082
1083 } catch (int e) {
1084 std::cout << " GblTrajectory::fit exception " << e << std::endl;
1085 ierr = e;
1086 }
1087 return ierr;
1088 }
1089
1090
1091 void GblTrajectory::milleOut(MilleBinary &aMille) {
1092 double aValue;
1093 double aErr;
1094 std::vector<unsigned int>* indLocal;
1095 std::vector<double>* derLocal;
1096 std::vector<int>* labGlobal;
1097 std::vector<double>* derGlobal;
1098
1099 if (not constructOK)
1100 return;
1101
1102
1103 std::vector<GblData>::iterator itData;
1104 for (itData = theData.begin(); itData != theData.end(); ++itData) {
1105 itData->getAllData(aValue, aErr, indLocal, derLocal, labGlobal,
1106 derGlobal);
1107 aMille.addData(aValue, aErr, *indLocal, *derLocal, *labGlobal,
1108 *derGlobal);
1109 }
1110 aMille.writeRecord();
1111 }
1112
1113
1114
1115
1116
1117 void GblTrajectory::printTrajectory(unsigned int level) {
1118 if (numInnerTrans) {
1119 std::cout << "Composed GblTrajectory, " << numInnerTrans
1120 << " subtrajectories" << std::endl;
1121 } else {
1122 std::cout << "Simple GblTrajectory" << std::endl;
1123 }
1124 if (theDimension.size() < 2) {
1125 std::cout << " 2D-trajectory" << std::endl;
1126 }
1127 std::cout << " Number of GblPoints : " << numAllPoints
1128 << std::endl;
1129 std::cout << " Number of points with offsets: " << numOffsets << std::endl;
1130 std::cout << " Number of fit parameters : " << numParameters
1131 << std::endl;
1132 std::cout << " Number of measurements : " << numMeasurements
1133 << std::endl;
1134 if (externalMeasurements.GetNrows()) {
1135 std::cout << " Number of ext. measurements : "
1136 << externalMeasurements.GetNrows() << std::endl;
1137 }
1138 if (externalPoint) {
1139 std::cout << " Label of point with ext. seed: " << externalPoint
1140 << std::endl;
1141 }
1142 if (constructOK) {
1143 std::cout << " Constructed OK " << std::endl;
1144 }
1145 if (fitOK) {
1146 std::cout << " Fitted OK " << std::endl;
1147 }
1148 if (level > 0) {
1149 if (numInnerTrans) {
1150 std::cout << " Inner transformations" << std::endl;
1151 for (unsigned int i = 0; i < numInnerTrans; ++i) {
1152 innerTransformations[i].Print();
1153 }
1154 }
1155 if (externalMeasurements.GetNrows()) {
1156 std::cout << " External measurements" << std::endl;
1157 std::cout << " Measurements:" << std::endl;
1158 externalMeasurements.Print();
1159 std::cout << " Precisions:" << std::endl;
1160 externalPrecisions.Print();
1161 std::cout << " Derivatives:" << std::endl;
1162 externalDerivatives.Print();
1163 }
1164 if (externalPoint) {
1165 std::cout << " External seed:" << std::endl;
1166 externalSeed.Print();
1167 }
1168 if (fitOK) {
1169 std::cout << " Fit results" << std::endl;
1170 std::cout << " Parameters:" << std::endl;
1171 theVector.print();
1172 std::cout << " Covariance matrix (bordered band part):"
1173 << std::endl;
1174 theMatrix.printMatrix();
1175 }
1176 }
1177 }
1178
1179
1180
1181
1182
1183 void GblTrajectory::printPoints(unsigned int level) {
1184 std::cout << "GblPoints " << std::endl;
1185 for (unsigned int iTraj = 0; iTraj < numTrajectories; ++iTraj) {
1186 std::vector<GblPoint>::iterator itPoint;
1187 for (itPoint = thePoints[iTraj].begin();
1188 itPoint < thePoints[iTraj].end(); ++itPoint) {
1189 itPoint->printPoint(level);
1190 }
1191 }
1192 }
1193
1194
1195 void GblTrajectory::printData() {
1196 std::cout << "GblData blocks " << std::endl;
1197 std::vector<GblData>::iterator itData;
1198 for (itData = theData.begin(); itData < theData.end(); ++itData) {
1199 itData->printData();
1200 }
1201 }
1202
1203 }