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 #include "GFGbl.h"
0046 #include "GblTrajectory.h"
0047 #include "GblPoint.h"
0048 #include "MyDebugTools.h"
0049
0050 #include "AbsMeasurement.h"
0051 #include "PlanarMeasurement.h"
0052 #include "KalmanFitterInfo.h"
0053
0054 #include "Track.h"
0055 #include <TFile.h>
0056 #include <TH1F.h>
0057 #include <TTree.h>
0058 #include <string>
0059 #include <list>
0060 #include <FieldManager.h>
0061 #include <HMatrixU.h>
0062 #include <HMatrixV.h>
0063 #include <Math/SMatrix.h>
0064 #include <TMatrixD.h>
0065 #include <TVectorDfwd.h>
0066 #include <TMatrixT.h>
0067
0068 #include <TVector3.h>
0069
0070
0071
0072
0073
0074 #ifdef DEBUG
0075
0076 #endif
0077
0078 #ifdef OUTPUT
0079
0080 std::string rootFileName = "gbl.root";
0081
0082
0083 TFile* diag;
0084 TH1F* resHistosU[12];
0085 TH1F* resHistosV[12];
0086 TH1F* mhistosU[12];
0087 TH1F* mhistosV[12];
0088 TH1F* ghistosU[12];
0089 TH1F* ghistosV[12];
0090 TH1F* downWeightsHistosU[12];
0091 TH1F* downWeightsHistosV[12];
0092 TH1F* localPar1[12];
0093 TH1F* localPar2[12];
0094 TH1F* localPar3[12];
0095 TH1F* localPar4[12];
0096 TH1F* localPar5[12];
0097 TH1F* localCov1[12];
0098 TH1F* localCov2[12];
0099 TH1F* localCov3[12];
0100 TH1F* localCov4[12];
0101 TH1F* localCov5[12];
0102 TH1F* localCov12[12];
0103 TH1F* localCov13[12];
0104 TH1F* localCov14[12];
0105 TH1F* localCov15[12];
0106 TH1F* localCov23[12];
0107 TH1F* localCov24[12];
0108 TH1F* localCov25[12];
0109 TH1F* localCov34[12];
0110 TH1F* localCov35[12];
0111 TH1F* localCov45[12];
0112 TH1I* fitResHisto;
0113 TH1I* ndfHisto;
0114 TH1F* chi2OndfHisto;
0115 TH1F* pValueHisto;
0116 TH1I* stats;
0117
0118
0119
0120 bool writeHistoDataForLabel(double label, TVectorD res, TVectorD measErr, TVectorD resErr, TVectorD downWeights, TVectorD localPar, TMatrixDSym localCov)
0121 {
0122 if (label < 1.) return false;
0123
0124 unsigned int id = floor(label);
0125
0126 id = id >> 5;
0127 unsigned int sensor = id & 7;
0128 id = id >> 3;
0129 unsigned int ladder = id & 31;
0130 id = id >> 5;
0131 unsigned int layer = id & 7;
0132 if (layer == 7 && ladder == 2) {
0133 label = sensor;
0134 } else if (layer == 7 && ladder == 3) {
0135 label = sensor + 9 - 3;
0136 } else {
0137 label = layer + 3;
0138 }
0139
0140 if (label > 12.) return false;
0141
0142 int i = int(label);
0143
0144 #ifdef OUTPUT
0145 resHistosU[i - 1]->Fill(res[0]);
0146 resHistosV[i - 1]->Fill(res[1]);
0147 mhistosU[i - 1]->Fill(res[0] / measErr[0]);
0148 mhistosV[i - 1]->Fill(res[1] / measErr[1]);
0149 ghistosU[i - 1]->Fill(res[0] / resErr[0]);
0150 ghistosV[i - 1]->Fill(res[1] / resErr[1]);
0151 downWeightsHistosU[i - 1]->Fill(downWeights[0]);
0152 downWeightsHistosV[i - 1]->Fill(downWeights[1]);
0153 localPar1[i - 1]->Fill(localPar(0));
0154 localPar2[i - 1]->Fill(localPar(1));
0155 localPar3[i - 1]->Fill(localPar(2));
0156 localPar4[i - 1]->Fill(localPar(3));
0157 localPar5[i - 1]->Fill(localPar(4));
0158 #endif
0159
0160
0161 return true;
0162 }
0163 #endif
0164
0165
0166 gbl::MilleBinary* milleFile;
0167
0168 const double scatEpsilon = 1.e-8;
0169
0170
0171 using namespace gbl;
0172 using namespace std;
0173 using namespace genfit;
0174
0175 GFGbl::GFGbl() :
0176 AbsFitter(), m_milleFileName("millefile.dat"), m_gblInternalIterations("THC"), m_pValueCut(0.), m_minNdf(1),
0177 m_chi2Cut(0.),
0178 m_enableScatterers(true),
0179 m_enableIntermediateScatterer(true)
0180 {
0181
0182 }
0183
0184 void GFGbl::beginRun()
0185 {
0186 milleFile = new MilleBinary(m_milleFileName);
0187
0188 #ifdef OUTPUT
0189 diag = new TFile(rootFileName.c_str(), "RECREATE");
0190 char name[20];
0191
0192 for (int i = 0; i < 12; i++) {
0193 sprintf(name, "res_u_%i", i + 1);
0194 resHistosU[i] = new TH1F(name, "Residual (U)", 1000, -0.1, 0.1);
0195 sprintf(name, "res_v_%i", i + 1);
0196 resHistosV[i] = new TH1F(name, "Residual (V)", 1000, -0.1, 0.1);
0197 sprintf(name, "meas_pull_u_%i", i + 1);
0198 mhistosU[i] = new TH1F(name, "Res/Meas.Err. (U)", 1000, -20., 20.);
0199 sprintf(name, "meas_pull_v_%i", i + 1);
0200 mhistosV[i] = new TH1F(name, "Res/Meas.Err. (V)", 1000, -20., 20.);
0201 sprintf(name, "pull_u_%i", i + 1);
0202 ghistosU[i] = new TH1F(name, "Res/Res.Err. (U)", 1000, -20., 20.);
0203 sprintf(name, "pull_v_%i", i + 1);
0204 ghistosV[i] = new TH1F(name, "Res/Res.Err. (V)", 1000, -20., 20.);
0205 sprintf(name, "downWeights_u_%i", i + 1);
0206 downWeightsHistosU[i] = new TH1F(name, "Down-weights (U)", 1000, 0., 1.);
0207 sprintf(name, "downWeights_v_%i", i + 1);
0208 downWeightsHistosV[i] = new TH1F(name, "Down-weights (V)", 1000, 0., 1.);
0209 sprintf(name, "localPar1_%i", i + 1);
0210
0211 localPar1[i] = new TH1F(name, "Residual (U)", 1000, -0.1, 0.1);
0212 sprintf(name, "localPar2_%i", i + 1);
0213 localPar2[i] = new TH1F(name, "Residual (U)", 1000, -0.1, 0.1);
0214 sprintf(name, "localPar3_%i", i + 1);
0215 localPar3[i] = new TH1F(name, "Residual (U)", 1000, -0.1, 0.1);
0216 sprintf(name, "localPar4_%i", i + 1);
0217 localPar4[i] = new TH1F(name, "Residual (U)", 1000, -0.1, 0.1);
0218 sprintf(name, "localPar5_%i", i + 1);
0219 localPar5[i] = new TH1F(name, "Residual (U)", 1000, -0.1, 0.1);
0220 }
0221 fitResHisto = new TH1I("fit_result", "GBL Fit Result", 21, -1, 20);
0222 ndfHisto = new TH1I("ndf", "GBL Track NDF", 41, -1, 40);
0223 chi2OndfHisto = new TH1F("chi2_ndf", "Track Chi2/NDF", 100, 0., 10.);
0224 pValueHisto = new TH1F("p_value", "Track P-value", 100, 0., 1.);
0225
0226 stats = new TH1I("stats", "0: NDF>0 | 1: fTel&VXD | 2: all | 3: VXD | 4: SVD | 5: all - PXD | 6: fTel&SVD | 7: bTel", 10, 0, 10);
0227
0228 #endif
0229 }
0230
0231 void GFGbl::endRun()
0232 {
0233 #ifdef OUTPUT
0234 diag->cd();
0235 diag->Write();
0236 diag->Close();
0237 #endif
0238
0239 if (milleFile)
0240 delete milleFile;
0241 }
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263 void getScattererFromMatList(double& length, double& theta, double& s, double& ds, const double p, const double mass, const double charge, const std::vector<MatStep>& steps)
0264 {
0265 theta = 0.; s = 0.; ds = 0.;
0266 if (steps.empty()) return;
0267
0268
0269 double len = 0.;
0270
0271 double sumxx = 0.;
0272
0273 double sumx2x2 = 0.;
0274
0275 double sumx3x3 = 0.;
0276
0277
0278 double xmin = 0.;
0279 double xmax = 0.;
0280
0281 for (unsigned int i = 0; i < steps.size(); i++) {
0282 const MatStep step = steps.at(i);
0283
0284 double rho = 1. / step.material_.radiationLength;
0285 len += fabs(step.stepSize_);
0286 xmin = xmax;
0287 xmax = xmin + fabs(step.stepSize_);
0288
0289
0290
0291 sumxx += rho * (xmax - xmin);
0292
0293 sumx2x2 += rho * (xmax * xmax - xmin * xmin) / 2.;
0294
0295 sumx3x3 += rho * (xmax * xmax * xmax - xmin * xmin * xmin) / 3.;
0296 }
0297
0298 if (sumxx < 1.0e-10) return;
0299
0300
0301
0302 double beta = p / sqrt(p * p + mass * mass);
0303 theta = (0.0136 / p / beta) * fabs(charge) * sqrt(sumxx) * (1. + 0.038 * log(sumxx));
0304
0305
0306
0307 length = len;
0308
0309 double N = 1. / sumxx;
0310
0311 s = N * sumx2x2;
0312
0313
0314 double ds_2 = N * (sumx3x3 - 2. * sumx2x2 * s + sumxx * s * s);
0315 ds = sqrt(ds_2);
0316
0317 #ifdef DEBUG
0318
0319
0320
0321
0322
0323 #endif
0324 }
0325
0326
0327 void GFGbl::processTrackWithRep(Track* trk, const AbsTrackRep* rep, bool )
0328 {
0329
0330
0331 bool skipMeasurement = false;
0332
0333 double trkChi2 = 0.;
0334
0335
0336 bool fitQoverP = true;
0337
0338 double Bfield = genfit::FieldManager::getInstance()->getFieldVal(TVector3(0., 0., 0.)).Mag();
0339 if (!(Bfield > 0.))
0340 fitQoverP = false;
0341
0342
0343 int dim = rep->getDim();
0344
0345 TrackPoint* point_meas;
0346
0347 AbsMeasurement* raw_meas;
0348
0349
0350 TVectorD scatResidual(2);
0351 scatResidual.Zero();
0352
0353
0354 int npoints_meas = trk->getNumPointsWithMeasurement();
0355
0356 #ifdef DEBUG
0357 int npoints_all = trk->getNumPoints();
0358
0359 if (resortHits)
0360 cout << "WARNING: Hits resorting in GBL interface not supported." << endl;
0361
0362 cout << "-------------------------------------------------------" << endl;
0363 cout << " GBL processing genfit::Track " << endl;
0364 cout << "-------------------------------------------------------" << endl;
0365 cout << " # Ref. Track Points : " << npoints_all << endl;
0366 cout << " # Meas. Points : " << npoints_meas << endl;
0367
0368 #endif
0369
0370 std::vector<GblPoint> listOfPoints;
0371
0372 std::vector<double> listOfLayers;
0373
0374
0375 unsigned int seedLabel = 0;
0376
0377
0378
0379 TMatrixDSym clSeed(dim);
0380
0381
0382 TMatrixD jacPointToPoint(dim, dim);
0383 jacPointToPoint.UnitMatrix();
0384
0385 int n_gbl_points = 0;
0386 int n_gbl_meas_points = 0;
0387 int Ndf = 0;
0388 double Chi2 = 0.;
0389 double lostWeight = 0.;
0390
0391
0392 double trackMomMag = 0.;
0393
0394 double particleCharge = 1.;
0395
0396 for (int ipoint_meas = 0; ipoint_meas < npoints_meas; ipoint_meas++) {
0397 point_meas = trk->getPointWithMeasurement(ipoint_meas);
0398
0399 if (!point_meas->hasFitterInfo(rep)) {
0400 cout << " ERROR: Measurement point does not have a fitter info. Track will be skipped." << endl;
0401 return;
0402 }
0403
0404 KalmanFitterInfo* fi = dynamic_cast<KalmanFitterInfo*>(point_meas->getFitterInfo(rep));
0405 if (!fi) {
0406 cout << " ERROR: KalmanFitterInfo (with reference state) for measurement does not exist. Track will be skipped." << endl;
0407 return;
0408 }
0409
0410 SharedPlanePtr plane = fi->getPlane();
0411 if (!fi->hasReferenceState()) {
0412 cout << " ERROR: Fitter info does not contain reference state. Track will be skipped." << endl;
0413 return;
0414 }
0415
0416 ReferenceStateOnPlane* reference = new ReferenceStateOnPlane(*fi->getReferenceState());
0417
0418 TVectorD state = reference->getState();
0419
0420 TVector3 trackDir = rep->getDir(*reference);
0421
0422 trackMomMag = rep->getMomMag(*reference);
0423
0424 particleCharge = rep->getCharge(*reference);
0425
0426 double particleMass = rep->getMass(*reference);
0427
0428
0429 double trackLen = 0.;
0430 double scatTheta = 0.;
0431 double scatSMean = 0.;
0432 double scatDeltaS = 0.;
0433
0434 double theta1 = 0.;
0435 double theta2 = 0.;
0436 double s1 = 0.;
0437 double s2 = 0.;
0438
0439 TMatrixDSym noise;
0440 TVectorD deltaState;
0441
0442 TMatrixD jacMeas2Scat(dim, dim);
0443 jacMeas2Scat.UnitMatrix();
0444
0445
0446
0447
0448
0449
0450 int sensorId = 0;
0451 PlanarMeasurement* measPlanar = dynamic_cast<PlanarMeasurement*>(point_meas->getRawMeasurement(0));
0452 if (measPlanar) sensorId = measPlanar->getPlaneId();
0453
0454
0455
0456
0457 if (point_meas->getRawMeasurement(0)->getDim() != 2
0458 && trk->getPointWithMeasurement(ipoint_meas)->getNumRawMeasurements() == 2
0459 && point_meas->getRawMeasurement(0)->getDim() == 1
0460 && point_meas->getRawMeasurement(1)->getDim() == 1) {
0461 AbsMeasurement* raw_measU = 0;
0462 AbsMeasurement* raw_measV = 0;
0463
0464
0465
0466 int sensorId2 = -1;
0467 PlanarMeasurement* measPlanar2 = dynamic_cast<PlanarMeasurement*>(point_meas->getRawMeasurement(0));
0468 if (measPlanar2) sensorId2 = measPlanar->getPlaneId();
0469
0470
0471
0472 if (sensorId != sensorId2) {
0473 skipMeasurement = true;
0474 cout << " ERROR: Incompatible sensorIDs at measurement point " << ipoint_meas << ". Measurement will be skipped." << endl;
0475 }
0476
0477
0478 AbsMeasurement* raw_meas1 = point_meas->getRawMeasurement(0);
0479 AbsMeasurement* raw_meas2 = point_meas->getRawMeasurement(1);
0480
0481 if (raw_meas1->constructHMatrix(rep)->isEqual(genfit::HMatrixU())
0482 && raw_meas2->constructHMatrix(rep)->isEqual(genfit::HMatrixV())) {
0483
0484 raw_measU = raw_meas1;
0485 raw_measV = raw_meas2;
0486 } else if (raw_meas2->constructHMatrix(rep)->isEqual(genfit::HMatrixU())
0487 && raw_meas1->constructHMatrix(rep)->isEqual(genfit::HMatrixV())) {
0488
0489 raw_measU = raw_meas2;
0490 raw_measV = raw_meas1;
0491 } else {
0492
0493 cout << " ERROR: Incompatible 1D measurements at meas. point " << ipoint_meas << ". Track will be skipped." << endl;
0494 return;
0495 }
0496
0497 TVectorD _raw_coor(2);
0498 _raw_coor(0) = raw_measU->getRawHitCoords()(0);
0499 _raw_coor(1) = raw_measV->getRawHitCoords()(0);
0500
0501 TMatrixDSym _raw_cov(2);
0502 _raw_cov.Zero();
0503 _raw_cov(0, 0) = raw_measU->getRawHitCov()(0, 0);
0504 _raw_cov(1, 1) = raw_measV->getRawHitCov()(0, 0);
0505
0506 raw_meas = new PlanarMeasurement(_raw_coor, _raw_cov, raw_measU->getDetId(), raw_measU->getHitId(), point_meas);
0507 } else {
0508
0509 raw_meas = point_meas->getRawMeasurement(0);
0510 }
0511
0512 if (raw_meas->getRawHitCoords().GetNoElements() != 2) {
0513 skipMeasurement = true;
0514 #ifdef DEBUG
0515 cout << " WARNING: Measurement " << (ipoint_meas + 1) << " is not 2D. Measurement Will be skipped. " << endl;
0516 #endif
0517 }
0518
0519
0520
0521 if (!skipMeasurement) {
0522
0523 TVectorD raw_coor = raw_meas->getRawHitCoords();
0524
0525 TMatrixDSym raw_cov = raw_meas->getRawHitCov();
0526
0527 std::unique_ptr<const AbsHMatrix> HitHMatrix(raw_meas->constructHMatrix(rep));
0528
0529 TVectorD residual = -1. * (raw_coor - HitHMatrix->Hv(state));
0530
0531 trkChi2 += residual(0) * residual(0) / raw_cov(0, 0) + residual(1) * residual(1) / raw_cov(1, 1);
0532
0533
0534 GblPoint measPoint(jacPointToPoint);
0535
0536
0537
0538 TMatrixD proL2m(2, 2);
0539 proL2m.Zero();
0540 proL2m(0, 0) = HitHMatrix->getMatrix()(0, 3);
0541 proL2m(0, 1) = HitHMatrix->getMatrix()(0, 4);
0542 proL2m(1, 1) = HitHMatrix->getMatrix()(1, 4);
0543 proL2m(1, 0) = HitHMatrix->getMatrix()(1, 3);
0544 proL2m.Invert();
0545
0546
0547 measPoint.addMeasurement(proL2m, residual, raw_cov.Invert());
0548
0549
0550
0551
0552 int label = sensorId * 10;
0553
0554
0555 TMatrixD derGlobal(2, 12);
0556
0557
0558 std::vector<int> labGlobal;
0559
0560
0561 TVector3 tDir = trackDir;
0562
0563 TVector3 uDir = plane->getU();
0564
0565 TVector3 vDir = plane->getV();
0566
0567 TVector3 nDir = plane->getNormal();
0568
0569
0570
0571
0572
0573 TVector3 tLoc = TVector3(uDir.Dot(tDir), vDir.Dot(tDir), nDir.Dot(tDir));
0574
0575
0576 double uSlope = tLoc[0] / tLoc[2];
0577
0578 double vSlope = tLoc[1] / tLoc[2];
0579
0580
0581 double uPos = raw_coor[0];
0582
0583 double vPos = raw_coor[1];
0584
0585
0586 derGlobal(0, 0) = 1.0;
0587 derGlobal(0, 1) = 0.0;
0588 derGlobal(0, 2) = - uSlope;
0589 derGlobal(0, 3) = vPos * uSlope;
0590 derGlobal(0, 4) = -uPos * uSlope;
0591 derGlobal(0, 5) = vPos;
0592
0593 derGlobal(1, 0) = 0.0;
0594 derGlobal(1, 1) = 1.0;
0595 derGlobal(1, 2) = - vSlope;
0596 derGlobal(1, 3) = vPos * vSlope;
0597 derGlobal(1, 4) = -uPos * vSlope;
0598 derGlobal(1, 5) = -uPos;
0599
0600 labGlobal.push_back(label + 1);
0601 labGlobal.push_back(label + 2);
0602 labGlobal.push_back(label + 3);
0603 labGlobal.push_back(label + 4);
0604 labGlobal.push_back(label + 5);
0605 labGlobal.push_back(label + 6);
0606
0607
0608
0609
0610
0611 TVector3 detPos = plane->getO();
0612
0613
0614
0615
0616 TVector3 pred = detPos + uPos * uDir + vPos * vDir;
0617
0618
0619
0620 double xPred = pred[0];
0621 double yPred = pred[1];
0622 double zPred = pred[2];
0623
0624
0625 double tn = tDir.Dot(nDir);
0626
0627
0628
0629
0630 TMatrixD drdm(3, 3);
0631 drdm.UnitMatrix();
0632 for (int row = 0; row < 3; row++)
0633 for (int col = 0; col < 3; col++)
0634 drdm(row, col) -= tDir[row] * nDir[col] / tn;
0635
0636
0637
0638
0639
0640 TMatrixD dmdg(3, 6);
0641 dmdg.Zero();
0642 dmdg(0, 0) = 1.; dmdg(0, 4) = -zPred; dmdg(0, 5) = yPred;
0643 dmdg(1, 1) = 1.; dmdg(1, 3) = zPred; dmdg(1, 5) = -xPred;
0644 dmdg(2, 2) = 1.; dmdg(2, 3) = -yPred; dmdg(2, 4) = xPred;
0645
0646
0647
0648
0649
0650 TMatrixD drldrg(3, 3);
0651 drldrg.Zero();
0652 drldrg(0, 0) = uDir[0]; drldrg(0, 1) = uDir[1]; drldrg(0, 2) = uDir[2];
0653 drldrg(1, 0) = vDir[0]; drldrg(1, 1) = vDir[1]; drldrg(1, 2) = vDir[2];
0654
0655
0656
0657
0658
0659
0660
0661
0662 TMatrixD drldg(3, 6);
0663 drldg = drldrg * (drdm * dmdg);
0664
0665
0666
0667
0668
0669
0670
0671 int offset = 0;
0672
0673
0674 derGlobal(0, 6) = drldg(0, 0); labGlobal.push_back(offset + 1);
0675 derGlobal(0, 7) = drldg(0, 1); labGlobal.push_back(offset + 2);
0676 derGlobal(0, 8) = drldg(0, 2); labGlobal.push_back(offset + 3);
0677 derGlobal(0, 9) = drldg(0, 3); labGlobal.push_back(offset + 4);
0678 derGlobal(0, 10) = drldg(0, 4); labGlobal.push_back(offset + 5);
0679 derGlobal(0, 11) = drldg(0, 5); labGlobal.push_back(offset + 6);
0680
0681 derGlobal(1, 6) = drldg(1, 0);
0682 derGlobal(1, 7) = drldg(1, 1);
0683 derGlobal(1, 8) = drldg(1, 2);
0684 derGlobal(1, 9) = drldg(1, 3);
0685 derGlobal(1, 10) = drldg(1, 4);
0686 derGlobal(1, 11) = drldg(1, 5);
0687
0688
0689
0690 measPoint.addGlobals(labGlobal, derGlobal);
0691 listOfPoints.push_back(measPoint);
0692 listOfLayers.push_back((unsigned int) sensorId);
0693 n_gbl_points++;
0694 n_gbl_meas_points++;
0695 } else {
0696
0697 GblPoint dummyPoint(jacPointToPoint);
0698 listOfPoints.push_back(dummyPoint);
0699 listOfLayers.push_back((unsigned int) sensorId);
0700 n_gbl_points++;
0701 skipMeasurement = false;
0702 #ifdef DEBUG
0703 cout << " Dummy point inserted. " << endl;
0704 #endif
0705 }
0706
0707
0708
0709 try {
0710
0711
0712 if (ipoint_meas < npoints_meas - 1) {
0713
0714 if (!trk->getPoint(ipoint_meas + 1)->hasFitterInfo(rep)) {
0715 cout << " ERROR: Measurement point does not have a fitter info. Track will be skipped." << endl;
0716 return;
0717 }
0718
0719 KalmanFitterInfo* fi_i_plus_1 = dynamic_cast<KalmanFitterInfo*>(trk->getPoint(ipoint_meas + 1)->getFitterInfo(rep));
0720 if (!fi_i_plus_1) {
0721 cout << " ERROR: KalmanFitterInfo (with reference state) for measurement does not exist. Track will be skipped." << endl;
0722 return;
0723 }
0724 StateOnPlane refCopy(*reference);
0725
0726 rep->extrapolateToPlane(refCopy, trk->getPoint(ipoint_meas + 1)->getFitterInfo(rep)->getPlane(), false, false);
0727 getScattererFromMatList(trackLen,
0728 scatTheta,
0729 scatSMean,
0730 scatDeltaS,
0731 trackMomMag,
0732 particleMass,
0733 particleCharge,
0734 rep->getSteps());
0735
0736
0737 s1 = 0.;
0738 s2 = scatSMean + scatDeltaS * scatDeltaS / (scatSMean - s1);
0739 theta1 = sqrt(scatTheta * scatTheta * scatDeltaS * scatDeltaS / (scatDeltaS * scatDeltaS + (scatSMean - s1) * (scatSMean - s1)));
0740 theta2 = sqrt(scatTheta * scatTheta * (scatSMean - s1) * (scatSMean - s1) / (scatDeltaS * scatDeltaS + (scatSMean - s1) * (scatSMean - s1)));
0741
0742 if (m_enableScatterers && !m_enableIntermediateScatterer) {
0743 theta1 = scatTheta;
0744 theta2 = 0;
0745 } else if (!m_enableScatterers) {
0746 theta1 = 0.;
0747 theta2 = 0.;
0748 }
0749
0750 if (s2 < 1.e-4 || s2 >= trackLen - 1.e-4 || s2 <= 1.e-4) {
0751 cout << " WARNING: GBL points will be too close. GBLTrajectory construction might fail. Let's try it..." << endl;
0752 }
0753
0754 }
0755
0756 delete reference;
0757 reference = new ReferenceStateOnPlane(*fi->getReferenceState());
0758
0759
0760 if (ipoint_meas < npoints_meas - 1) {
0761 if (theta2 > scatEpsilon) {
0762
0763
0764
0765
0766 rep->extrapolateBy(*reference, s2, false, true);
0767 rep->getForwardJacobianAndNoise(jacMeas2Scat, noise, deltaState);
0768
0769 double nextStep = rep->extrapolateToPlane(*reference, trk->getPoint(ipoint_meas + 1)->getFitterInfo(rep)->getPlane(), false, true);
0770 if (0. > nextStep) {
0771 cout << " ERROR: The extrapolation to measurement point " << (ipoint_meas + 2) << " stepped back by " << nextStep << "cm !!! Track will be skipped." << endl;
0772 return;
0773 }
0774 rep->getForwardJacobianAndNoise(jacPointToPoint, noise, deltaState);
0775
0776 } else {
0777
0778 rep->extrapolateToPlane(*reference, trk->getPoint(ipoint_meas + 1)->getFitterInfo(rep)->getPlane(), false, true);
0779
0780
0781 rep->getForwardJacobianAndNoise(jacPointToPoint, noise, deltaState);
0782
0783 }
0784 }
0785 } catch (...) {
0786 cout << " ERROR: Extrapolation failed. Track will be skipped." << endl;
0787 return;
0788 }
0789
0790
0791
0792
0793
0794
0795 if (ipoint_meas < npoints_meas - 1) {
0796
0797 if (theta1 > scatEpsilon) {
0798
0799
0800
0801
0802 double c1 = trackDir.Dot(plane->getU());
0803 double c2 = trackDir.Dot(plane->getV());
0804 TMatrixDSym scatCov(2);
0805 scatCov(0, 0) = 1. - c2 * c2;
0806 scatCov(1, 1) = 1. - c1 * c1;
0807 scatCov(0, 1) = c1 * c2;
0808 scatCov(1, 0) = c1 * c2;
0809 scatCov *= theta1 * theta1 / (1. - c1 * c1 - c2 * c2) / (1. - c1 * c1 - c2 * c2) ;
0810
0811
0812 GblPoint& lastPoint = listOfPoints.at(n_gbl_points - 1);
0813 lastPoint.addScatterer(scatResidual, scatCov.Invert());
0814
0815 }
0816
0817 if (theta2 > scatEpsilon) {
0818
0819
0820
0821 TMatrixDSym scatCov(2);
0822 scatCov.Zero();
0823 scatCov(0, 0) = theta2 * theta2;
0824 scatCov(1, 1) = theta2 * theta2;
0825
0826 GblPoint scatPoint(jacMeas2Scat);
0827 scatPoint.addScatterer(scatResidual, scatCov.Invert());
0828 listOfPoints.push_back(scatPoint);
0829 listOfLayers.push_back(((unsigned int) sensorId) + 0.5);
0830 n_gbl_points++;
0831 }
0832
0833
0834 }
0835
0836 delete reference;
0837 }
0838
0839 if (n_gbl_meas_points > 1) {
0840 int fitRes = -1;
0841 double pvalue = 0.;
0842 GblTrajectory* traj = 0;
0843 try {
0844
0845 traj = new GblTrajectory(listOfPoints, seedLabel, clSeed, fitQoverP);
0846
0847 fitRes = traj->fit(Chi2, Ndf, lostWeight, m_gblInternalIterations);
0848 if (fitRes != 0) {
0849
0850
0851
0852
0853
0854 }
0855 } catch (...) {
0856
0857 return;
0858 }
0859
0860 pvalue = TMath::Prob(Chi2, Ndf);
0861
0862
0863
0864
0865
0866 #ifdef OUTPUT
0867
0868 fitResHisto->Fill(fitRes);
0869 ndfHisto->Fill(Ndf);
0870 #endif
0871
0872 #ifdef DEBUG
0873 cout << " Ref. Track Chi2 : " << trkChi2 << endl;
0874 cout << " Ref. end momentum : " << trackMomMag << " GeV/c ";
0875 if (abs(trk->getCardinalRep()->getPDG()) == 11) {
0876 if (particleCharge < 0.)
0877 cout << "(electron)";
0878 else
0879 cout << "(positron)";
0880 }
0881 cout << endl;
0882 cout << "------------------ GBL Fit Results --------------------" << endl;
0883 cout << " Fit q/p parameter : " << ((fitQoverP) ? ("True") : ("False")) << endl;
0884 cout << " Valid trajectory : " << ((traj->isValid()) ? ("True") : ("False")) << endl;
0885 cout << " Fit result : " << fitRes << " (0 for success)" << endl;
0886 cout << " # GBL meas. points : " << n_gbl_meas_points << endl;
0887 cout << " # GBL all points : " << n_gbl_points << endl;
0888 cout << " GBL track NDF : " << Ndf << " (-1 for failure)" << endl;
0889 cout << " GBL track Chi2 : " << Chi2 << endl;
0890 cout << " GBL track P-value : " << pvalue;
0891 if (pvalue < m_pValueCut)
0892 cout << " < p-value cut " << m_pValueCut;
0893 cout << endl;
0894 cout << "-------------------------------------------------------" << endl;
0895 #endif
0896
0897 #ifdef OUTPUT
0898 bool hittedLayers[12];
0899 for (int hl = 0; hl < 12; hl++) {
0900 hittedLayers[hl] = false;
0901 }
0902 #endif
0903
0904
0905
0906
0907 if (traj->isValid() && pvalue >= m_pValueCut && Ndf >= m_minNdf) {
0908
0909
0910 if (!milleFile && m_milleFileName != "")
0911 milleFile = new MilleBinary(m_milleFileName);
0912
0913
0914 for (unsigned int p = 0; p < listOfPoints.size(); p++) {
0915 unsigned int label = p + 1;
0916 unsigned int numRes;
0917 TVectorD residuals(2);
0918 TVectorD measErrors(2);
0919 TVectorD resErrors(2);
0920 TVectorD downWeights(2);
0921
0922 if (!listOfPoints.at(p).hasMeasurement())
0923 continue;
0924
0925 #ifdef OUTPUT
0926
0927 unsigned int l = 0;
0928 unsigned int id = listOfLayers.at(p);
0929
0930 id = id >> 5;
0931 unsigned int sensor = id & 7;
0932 id = id >> 3;
0933 unsigned int ladder = id & 31;
0934 id = id >> 5;
0935 unsigned int layer = id & 7;
0936
0937 if (layer == 7 && ladder == 2) {
0938 l = sensor;
0939 } else if (layer == 7 && ladder == 3) {
0940 l = sensor + 9 - 3;
0941 } else {
0942 l = layer + 3;
0943 }
0944
0945 hittedLayers[l - 1] = true;
0946 #endif
0947 TVectorD localPar(5);
0948 TMatrixDSym localCov(5);
0949 traj->getResults(label, localPar, localCov);
0950
0951 traj->getMeasResults(label, numRes, residuals, measErrors, resErrors, downWeights);
0952 if (m_chi2Cut && (fabs(residuals[0] / resErrors[0]) > m_chi2Cut || fabs(residuals[1] / resErrors[1]) > m_chi2Cut))
0953 return;
0954
0955 #ifdef OUTPUT
0956 if (!writeHistoDataForLabel(listOfLayers.at(p), residuals, measErrors, resErrors, downWeights, localPar, localCov))
0957 return;
0958 #endif
0959
0960 }
0961
0962
0963 if (milleFile && m_milleFileName != "" && pvalue >= m_pValueCut && Ndf >= m_minNdf) {
0964 traj->milleOut(*milleFile);
0965 #ifdef DEBUG
0966 cout << " GBL Track written to Millepede II binary file." << endl;
0967 cout << "-------------------------------------------------------" << endl;
0968 #endif
0969 }
0970
0971 #ifdef OUTPUT
0972
0973 chi2OndfHisto->Fill(Chi2 / Ndf);
0974 pValueHisto->Fill(TMath::Prob(Chi2, Ndf));
0975
0976 stats->Fill(0);
0977
0978 if (
0979 hittedLayers[0] &&
0980 hittedLayers[1] &&
0981 hittedLayers[2] &&
0982 hittedLayers[3] &&
0983 hittedLayers[4] &&
0984 hittedLayers[5] &&
0985 hittedLayers[6] &&
0986 hittedLayers[7] &&
0987 hittedLayers[8]
0988 ) {
0989
0990 stats->Fill(1);
0991 }
0992
0993 if (
0994 hittedLayers[0] &&
0995 hittedLayers[1] &&
0996 hittedLayers[2] &&
0997 hittedLayers[3] &&
0998 hittedLayers[4] &&
0999 hittedLayers[5] &&
1000 hittedLayers[6] &&
1001 hittedLayers[7] &&
1002 hittedLayers[8] &&
1003 hittedLayers[9] &&
1004 hittedLayers[10] &&
1005 hittedLayers[11]
1006 ) {
1007
1008 stats->Fill(2);
1009 }
1010 if (
1011 hittedLayers[3] &&
1012 hittedLayers[4] &&
1013 hittedLayers[5] &&
1014 hittedLayers[6] &&
1015 hittedLayers[7] &&
1016 hittedLayers[8]
1017 ) {
1018
1019 stats->Fill(3);
1020 }
1021 if (
1022 hittedLayers[5] &&
1023 hittedLayers[6] &&
1024 hittedLayers[7] &&
1025 hittedLayers[8]
1026 ) {
1027
1028 stats->Fill(4);
1029 }
1030 if (
1031 hittedLayers[0] &&
1032 hittedLayers[1] &&
1033 hittedLayers[2] &&
1034
1035 hittedLayers[5] &&
1036 hittedLayers[6] &&
1037 hittedLayers[7] &&
1038 hittedLayers[8] &&
1039 hittedLayers[9] &&
1040 hittedLayers[10] &&
1041 hittedLayers[11]
1042 ) {
1043
1044 stats->Fill(5);
1045 }
1046 if (
1047 hittedLayers[0] &&
1048 hittedLayers[1] &&
1049 hittedLayers[2] &&
1050
1051 hittedLayers[5] &&
1052 hittedLayers[6] &&
1053 hittedLayers[7] &&
1054 hittedLayers[8]
1055 ) {
1056
1057 stats->Fill(6);
1058 }
1059 if (
1060 hittedLayers[9] &&
1061 hittedLayers[10] &&
1062 hittedLayers[11]
1063 ) {
1064
1065 stats->Fill(7);
1066 }
1067 #endif
1068 }
1069
1070
1071 delete traj;
1072 }
1073 }
1074