File indexing completed on 2024-04-06 11:58:34
0001
0002
0003
0004
0005
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0008
0009 #include "CalibPPS/AlignmentRelative/interface/JanAlignmentAlgorithm.h"
0010 #include "CalibPPS/AlignmentRelative/interface/AlignmentTask.h"
0011 #include "CalibPPS/AlignmentRelative/interface/Utilities.h"
0012
0013 #include "TMatrixDSymEigen.h"
0014 #include "TDecompSVD.h"
0015 #include "TFile.h"
0016 #include "TCanvas.h"
0017 #include "TH2D.h"
0018
0019 #include <cmath>
0020
0021
0022
0023 using namespace std;
0024 using namespace edm;
0025
0026
0027
0028 JanAlignmentAlgorithm::JanAlignmentAlgorithm(const ParameterSet &ps, AlignmentTask *_t)
0029 : AlignmentAlgorithm(ps, _t), Sc(nullptr), Mc(nullptr) {
0030 const ParameterSet &lps = ps.getParameterSet("JanAlignmentAlgorithm");
0031 weakLimit = lps.getParameter<double>("weakLimit");
0032 stopOnSingularModes = lps.getParameter<bool>("stopOnSingularModes");
0033 buildDiagnosticPlots = lps.getParameter<bool>("buildDiagnosticPlots");
0034 }
0035
0036
0037
0038 JanAlignmentAlgorithm::~JanAlignmentAlgorithm() {}
0039
0040
0041
0042 void JanAlignmentAlgorithm::begin(const CTPPSGeometry *geometryReal, const CTPPSGeometry *geometryMisaligned) {
0043
0044 Mc = new TVectorD[task->quantityClasses.size()];
0045 Sc = new TMatrixD *[task->quantityClasses.size()];
0046 for (unsigned int i = 0; i < task->quantityClasses.size(); i++) {
0047 unsigned int rows = task->quantitiesOfClass(task->quantityClasses[i]);
0048
0049 Mc[i].ResizeTo(rows);
0050 Mc[i].Zero();
0051
0052 Sc[i] = new TMatrixD[task->quantityClasses.size()];
0053 for (unsigned int j = 0; j < task->quantityClasses.size(); j++) {
0054 unsigned int cols = task->quantitiesOfClass(task->quantityClasses[j]);
0055 Sc[i][j].ResizeTo(rows, cols);
0056 Sc[i][j].Zero();
0057 }
0058 }
0059
0060
0061 if (buildDiagnosticPlots) {
0062 for (const auto &it : task->geometry.getSensorMap()) {
0063 unsigned int id = it.first;
0064 char buf[50];
0065 DetStat s;
0066
0067 sprintf(buf, "%u: m distribution", id);
0068 s.m_dist = new TH1D(buf, ";u or v (mm)", 100, -25., 25.);
0069
0070 sprintf(buf, "%u: R distribution", id);
0071 s.R_dist = new TH1D(buf, ";R (mm)", 500, -0.5, 0.5);
0072
0073 for (unsigned int c = 0; c < task->quantityClasses.size(); c++) {
0074 sprintf(buf, "%u: coef, %s", id, task->quantityClassTag(task->quantityClasses[c]).c_str());
0075 s.coefHist.push_back(new TH1D(buf, ";coefficient", 100, -2., +2.));
0076
0077 sprintf(buf, "%u: R vs. coef, %s", id, task->quantityClassTag(task->quantityClasses[c]).c_str());
0078 TGraph *g = new TGraph();
0079 g->SetName(buf);
0080 g->SetTitle(";coefficient;residual (mm)");
0081 s.resVsCoef.push_back(g);
0082 }
0083
0084 statistics[id] = s;
0085 }
0086 }
0087
0088 events = 0;
0089 }
0090
0091
0092
0093 void JanAlignmentAlgorithm::feed(const HitCollection &selection, const LocalTrackFit &trackFit) {
0094 if (verbosity > 9)
0095 printf("\n>> JanAlignmentAlgorithm::Feed\n");
0096
0097 events++;
0098
0099
0100 double hax = trackFit.ax;
0101 double hay = trackFit.ay;
0102 double hbx = trackFit.bx + trackFit.ax * (task->geometry.z0 - trackFit.z0);
0103 double hby = trackFit.by + trackFit.ay * (task->geometry.z0 - trackFit.z0);
0104
0105
0106 TMatrixD *Ga = new TMatrixD[task->quantityClasses.size()];
0107 for (unsigned int i = 0; i < task->quantityClasses.size(); i++) {
0108 Ga[i].ResizeTo(selection.size(), Mc[i].GetNrows());
0109 Ga[i].Zero();
0110 }
0111
0112 TMatrixD A(selection.size(), 4);
0113 TMatrixD Vi(selection.size(), selection.size());
0114 TVectorD m(selection.size());
0115
0116 set<unsigned int> rpSet;
0117 if (buildDiagnosticPlots) {
0118 for (const auto &hit : selection) {
0119 CTPPSDetId detId(hit.id);
0120 const unsigned int rpDecId = 100 * detId.arm() + 10 * detId.station() + detId.rp();
0121 rpSet.insert(rpDecId);
0122 }
0123 }
0124
0125
0126 unsigned int j = 0;
0127
0128 for (HitCollection::const_iterator hit = selection.begin(); hit != selection.end(); ++hit, ++j) {
0129 unsigned int id = hit->id;
0130
0131 const DetGeometry &d = task->geometry.get(id);
0132 const auto &dirData = d.getDirectionData(hit->dirIdx);
0133
0134 A(j, 0) = hit->z * dirData.dx;
0135 A(j, 1) = dirData.dx;
0136 A(j, 2) = hit->z * dirData.dy;
0137 A(j, 3) = dirData.dy;
0138
0139 m(j) = hit->position + dirData.s - (hit->z - d.z) * dirData.dz;
0140
0141 Vi(j, j) = 1. / hit->sigma / hit->sigma;
0142
0143 double C = dirData.dx, S = dirData.dy;
0144
0145 double hx = hax * hit->z + hbx;
0146 double hy = hay * hit->z + hby;
0147 double R = m(j) - (hx * C + hy * S);
0148
0149 if (buildDiagnosticPlots) {
0150 statistics[id].m_dist->Fill(m(j));
0151 statistics[id].R_dist->Fill(R);
0152 }
0153
0154 for (unsigned int i = 0; i < task->quantityClasses.size(); i++) {
0155
0156 signed int matrixIndex = task->getMeasurementIndex(task->quantityClasses[i], hit->id, hit->dirIdx);
0157 if (matrixIndex < 0)
0158 continue;
0159
0160 matrixIndex = task->getQuantityIndex(task->quantityClasses[i], hit->id);
0161
0162 switch (task->quantityClasses[i]) {
0163 case AlignmentTask::qcShR1:
0164 Ga[i][j][matrixIndex] = -1.;
0165 break;
0166
0167 case AlignmentTask::qcShR2:
0168 Ga[i][j][matrixIndex] = -1.;
0169 break;
0170
0171 case AlignmentTask::qcShZ:
0172 Ga[i][j][matrixIndex] = hax * C + hay * S;
0173 break;
0174
0175 case AlignmentTask::qcRotZ:
0176 Ga[i][j][matrixIndex] = (hax * hit->z + hbx - d.sx) * (-S) + (hay * hit->z + hby - d.sy) * C;
0177 break;
0178 }
0179
0180 if (buildDiagnosticPlots) {
0181 double c = Ga[i][j][matrixIndex];
0182 DetStat &s = statistics[id];
0183 s.coefHist[i]->Fill(c);
0184 s.resVsCoef[i]->SetPoint(s.resVsCoef[i]->GetN(), c, R);
0185
0186 if (task->quantityClasses[i] == AlignmentTask::qcRotZ) {
0187 map<set<unsigned int>, ScatterPlot>::iterator hit = s.resVsCoefRot_perRPSet.find(rpSet);
0188 if (hit == s.resVsCoefRot_perRPSet.end()) {
0189 ScatterPlot sp;
0190 sp.g = new TGraph();
0191 sp.h = new TH2D("", "", 40, -20., +20., 60, -0.15, +0.15);
0192 hit = s.resVsCoefRot_perRPSet.insert(pair<set<unsigned int>, ScatterPlot>(rpSet, sp)).first;
0193 }
0194 hit->second.g->SetPoint(hit->second.g->GetN(), c, R);
0195 hit->second.h->Fill(c, R);
0196 }
0197 }
0198 }
0199 }
0200
0201
0202 TMatrixD AT(TMatrixD::kTransposed, A);
0203 TMatrixD ATViA(4, 4);
0204 ATViA = AT * Vi * A;
0205 TMatrixD ATViAI(ATViA);
0206 ATViAI = ATViA.Invert();
0207 TMatrixD sigma(Vi);
0208 sigma -= Vi * A * ATViAI * AT * Vi;
0209
0210
0211 TMatrixD *GaT = new TMatrixD[task->quantityClasses.size()];
0212 for (unsigned int i = 0; i < task->quantityClasses.size(); i++) {
0213 GaT[i].ResizeTo(Mc[i].GetNrows(), selection.size());
0214 GaT[i].Transpose(Ga[i]);
0215 }
0216
0217
0218 TVectorD r(selection.size());
0219 r = sigma * m;
0220
0221
0222 for (unsigned int i = 0; i < task->quantityClasses.size(); i++) {
0223 if (Mc[i].GetNrows() < 1)
0224 continue;
0225
0226 Mc[i] += GaT[i] * r;
0227 }
0228
0229
0230 for (unsigned int i = 0; i < task->quantityClasses.size(); i++) {
0231 for (unsigned int j = 0; j < task->quantityClasses.size(); j++) {
0232 if (Sc[i][j].GetNrows() < 1 || Sc[i][j].GetNcols() < 1)
0233 continue;
0234
0235 Sc[i][j] += GaT[i] * sigma * Ga[j];
0236 }
0237 }
0238
0239 #ifdef DEBUG
0240 printf("* checking normalized residuals, selection.size = %u\n", selection.size());
0241 r.Print();
0242
0243 for (unsigned int i = 0; i < task->quantityClasses.size(); i++) {
0244 printf("- class %u\n", i);
0245 TVectorD t(Mc[i].GetNrows());
0246 for (int j = 0; j < t.GetNrows(); j++)
0247 t[j] = 1.;
0248 t.Print();
0249
0250 Ga[i].Print();
0251
0252 TVectorD tt(selection.size());
0253 tt = sigma * Ga[i] * t;
0254
0255 double ttn = sqrt(tt.Norm2Sqr());
0256 printf("|tt| = %E\n", ttn);
0257 if (ttn > 1E-8)
0258 tt.Print();
0259 }
0260 #endif
0261
0262 delete[] Ga;
0263 delete[] GaT;
0264 }
0265
0266
0267
0268 void JanAlignmentAlgorithm::analyze() {
0269 if (verbosity > 2)
0270 printf("\n>> JanAlignmentAlgorithm::Analyze\n");
0271
0272
0273 unsigned int dim = 0;
0274 for (unsigned int i = 0; i < task->quantityClasses.size(); i++)
0275 dim += Mc[i].GetNrows();
0276
0277 if (verbosity > 2) {
0278 printf("\tsensors: %u\n", task->geometry.getNumberOfDetectors());
0279 printf("\tfull dimension: %u\n", dim);
0280 printf("\tquantity classes: %lu\n", task->quantityClasses.size());
0281 }
0282
0283
0284 M.ResizeTo(dim);
0285 unsigned int offset = 0;
0286 for (unsigned int i = 0; i < task->quantityClasses.size(); i++) {
0287 M.SetSub(offset, Mc[i]);
0288 offset += Mc[i].GetNrows();
0289 }
0290
0291
0292 S.ResizeTo(dim, dim);
0293 unsigned int r_offset = 0, c_offset = 0;
0294 for (unsigned int i = 0; i < task->quantityClasses.size(); i++) {
0295 c_offset = 0;
0296 unsigned int r_size = 0, c_size = 0;
0297 for (unsigned int j = 0; j < task->quantityClasses.size(); j++) {
0298 r_size = Sc[i][j].GetNrows();
0299 c_size = Sc[i][j].GetNcols();
0300
0301 if (r_size < 1 || c_size < 1)
0302 continue;
0303
0304 TMatrixDSub(S, r_offset, r_offset + r_size - 1, c_offset, c_offset + c_size - 1) = Sc[i][j];
0305 c_offset += c_size;
0306 }
0307 r_offset += r_size;
0308 }
0309
0310
0311 if (verbosity >= 3) {
0312 double maxDiff = 0., maxElem = 0.;
0313 for (unsigned int i = 0; i < dim; i++) {
0314 for (unsigned int j = 0; j < dim; j++) {
0315 double diff = S[i][j] - S[j][i];
0316 if (fabs(diff) > maxDiff)
0317 maxDiff = diff;
0318 if (S[i][j] > maxElem)
0319 maxElem = S[i][j];
0320 }
0321 }
0322
0323 printf("\n* S matrix:\n\tdimension = %i\n\tmaximum asymmetry: %E\t(ratio to maximum element %E)\n",
0324 dim,
0325 maxDiff,
0326 maxDiff / maxElem);
0327 }
0328
0329
0330 TMatrixDSym S_sym(dim);
0331 for (unsigned int j = 0; j < dim; j++) {
0332 for (unsigned int i = 0; i < dim; i++) {
0333 S_sym[i][j] = S[i][j];
0334 }
0335 }
0336
0337
0338 TMatrixDSymEigen S_eig(S_sym);
0339 const TVectorD &S_eigVal_temp = S_eig.GetEigenValues();
0340 S_eigVal.ResizeTo(S_eigVal_temp.GetNrows());
0341 S_eigVal = S_eigVal_temp;
0342 const TMatrixD &S_eigVec_temp = S_eig.GetEigenVectors();
0343 S_eigVec.ResizeTo(S_eigVec_temp);
0344 S_eigVec = S_eigVec_temp;
0345
0346
0347 for (int i = 0; i < S_eigVal.GetNrows(); i++) {
0348 double nev = S_eigVal[i] / events;
0349 if (fabs(nev) < singularLimit) {
0350 SingularMode sM{S_eigVal[i], TMatrixDColumn(S_eigVec, i), i};
0351 singularModes.push_back(sM);
0352 }
0353 }
0354
0355 #if DEBUG
0356
0357 if (singularModes.size() > 0) {
0358 printf("\n* S singular modes\n | ");
0359 for (unsigned int i = 0; i < singularModes.size(); i++)
0360 printf("%+10.3E ", singularModes[i].val);
0361 printf("\n-- | ");
0362
0363 for (unsigned int i = 0; i < singularModes.size(); i++)
0364 printf("---------- ");
0365 printf("\n");
0366
0367 for (unsigned int j = 0; j < dim; j++) {
0368 printf("%2u | ", j);
0369 for (unsigned int i = 0; i < singularModes.size(); i++) {
0370 printf("%+10.3E ", singularModes[i].vec[j]);
0371 }
0372 printf("\n");
0373 }
0374 } else
0375 printf("\n* S has no singular modes\n");
0376 #endif
0377 }
0378
0379
0380
0381 unsigned int JanAlignmentAlgorithm::solve(const std::vector<AlignmentConstraint> &constraints,
0382 map<unsigned int, AlignmentResult> &results,
0383 TDirectory *dir) {
0384 if (verbosity)
0385 printf(">> JanAlignmentAlgorithm::Solve\n");
0386
0387 results.clear();
0388
0389
0390 unsigned int dim = S.GetNrows();
0391 TMatrixD C(dim, constraints.size());
0392 TMatrixD C2(dim, constraints.size());
0393 for (unsigned int i = 0; i < constraints.size(); i++) {
0394 unsigned int offset = 0;
0395 for (auto &quantityClass : task->quantityClasses) {
0396 const TVectorD &cv = constraints[i].coef.find(quantityClass)->second;
0397 for (int k = 0; k < cv.GetNrows(); k++) {
0398 C[offset][i] = events * cv[k];
0399 C2[offset][i] = events * cv[k] * 1E3;
0400 offset++;
0401 }
0402 }
0403 }
0404
0405 #ifdef DEBUG
0406 printf("\n* constraint matrix\n");
0407 Print(C);
0408 #endif
0409
0410
0411 TMatrixD E(S.GetNrows(), singularModes.size());
0412 for (unsigned int i = 0; i < singularModes.size(); i++)
0413 for (int j = 0; j < S.GetNrows(); j++)
0414 E(j, i) = singularModes[i].vec[j];
0415
0416
0417 TMatrixDSym CS(dim + constraints.size());
0418 TMatrixDSym CS2(dim + constraints.size());
0419 CS.Zero();
0420 CS2.Zero();
0421 for (unsigned int j = 0; j < dim; j++) {
0422 for (unsigned int i = 0; i < dim; i++) {
0423 CS[i][j] = S[i][j];
0424 CS2[i][j] = S[i][j];
0425 }
0426 }
0427
0428 for (unsigned int i = 0; i < constraints.size(); i++) {
0429 for (unsigned int j = 0; j < dim; j++) {
0430 CS[j][dim + i] = CS[dim + i][j] = C(j, i);
0431 CS2[j][dim + i] = CS2[dim + i][j] = C2(j, i);
0432 }
0433 }
0434
0435
0436 TMatrixDSymEigen CS_eig(CS);
0437 TVectorD CS_eigVal = CS_eig.GetEigenValues();
0438 TMatrixD CS_eigVec = CS_eig.GetEigenVectors();
0439
0440
0441 if (verbosity >= 2) {
0442 printf("\n* eigen values of CS and S matrices (events = %u)\n", events);
0443 printf(" # CS norm. CS S norm. S\n");
0444 }
0445
0446 unsigned int singularModeCount = 0;
0447 vector<unsigned int> weakModeIdx;
0448 for (int i = 0; i < CS_eigVal.GetNrows(); i++) {
0449 const double CS_nev = CS_eigVal[i] / events;
0450
0451 if (fabs(CS_nev) < singularLimit)
0452 singularModeCount++;
0453
0454 if (verbosity >= 2) {
0455 printf("%4i%+12.2E%+12.2E", i, CS_eigVal[i], CS_nev);
0456 if (fabs(CS_nev) < singularLimit) {
0457 singularModeCount++;
0458 printf(" (S)");
0459 } else {
0460 if (fabs(CS_nev) < weakLimit) {
0461 weakModeIdx.push_back(i);
0462 printf(" (W)");
0463 } else {
0464 printf(" ");
0465 }
0466 }
0467
0468 if (i < S_eigVal.GetNrows()) {
0469 double S_nev = S_eigVal[i] / events;
0470 printf("%+12.2E%+12.2E", S_eigVal[i], S_nev);
0471 if (fabs(S_nev) < singularLimit)
0472 printf(" (S)");
0473 else if (fabs(S_nev) < weakLimit)
0474 printf(" (W)");
0475 }
0476
0477 printf("\n");
0478 }
0479 }
0480
0481 if (verbosity >= 2) {
0482
0483 if (!weakModeIdx.empty()) {
0484 unsigned int columns = 10;
0485 unsigned int first = 0;
0486
0487 while (first < weakModeIdx.size()) {
0488 unsigned int last = first + columns;
0489 if (last >= weakModeIdx.size())
0490 last = weakModeIdx.size();
0491
0492 printf("\n* CS weak modes\n | ");
0493 for (unsigned int i = first; i < last; i++)
0494 printf("%+10.3E ", CS_eigVal[weakModeIdx[i]]);
0495 printf("\n--- | ");
0496
0497 for (unsigned int i = first; i < last; i++)
0498 printf("---------- ");
0499 printf("\n");
0500
0501
0502 vector<double> maxs;
0503 for (unsigned int i = first; i < last; i++) {
0504 double max = 0;
0505 for (unsigned int j = 0; j < dim + constraints.size(); j++) {
0506 double v = fabs(CS_eigVec(weakModeIdx[i], j));
0507 if (v > max)
0508 max = v;
0509 }
0510 maxs.push_back(max);
0511 }
0512
0513 for (unsigned int j = 0; j < dim + constraints.size(); j++) {
0514 printf("%3u | ", j);
0515 for (unsigned int i = first; i < last; i++) {
0516 double v = CS_eigVec(weakModeIdx[i], j);
0517 if (fabs(v) / maxs[i - first] > 1E-3)
0518 printf("%+10.3E ", v);
0519 else
0520 printf(" . ");
0521 }
0522 printf("\n");
0523 }
0524
0525 first = last;
0526 }
0527 } else
0528 printf("\n* CS has no weak modes\n");
0529 }
0530
0531
0532 if (verbosity >= 2) {
0533 if (E.GetNcols() == C.GetNcols()) {
0534 TMatrixD CTE(C, TMatrixD::kTransposeMult, E);
0535 print(CTE, "* CTE matrix:");
0536 const double &det = CTE.Determinant();
0537 printf(
0538 "\n* det(CTE) = %E, max(CTE) = %E, det(CTE)/max(CTE) = %E\n\tmax(C) = %E, max(E) = %E, "
0539 "det(CTE)/max(C)/max(E) = %E\n",
0540 det,
0541 CTE.Max(),
0542 det / CTE.Max(),
0543 C.Max(),
0544 E.Max(),
0545 det / C.Max() / E.Max());
0546 } else {
0547 printf(">> JanAlignmentAlgorithm::Solve > WARNING: C matrix has %u, while E matrix %u columns.\n",
0548 C.GetNcols(),
0549 E.GetNcols());
0550 }
0551 }
0552
0553
0554 if (singularModeCount > 0 && stopOnSingularModes) {
0555 LogError("PPS") << "\n>> JanAlignmentAlgorithm::Solve > ERROR: There are " << singularModeCount
0556 << " singular modes in CS matrix. Stopping.";
0557 return 1;
0558 }
0559
0560
0561 TVectorD MV(dim + constraints.size());
0562 for (unsigned int i = 0; i < dim; i++)
0563 MV[i] = M[i];
0564 for (unsigned int i = 0; i < constraints.size(); i++)
0565 MV[dim + i] = events * constraints[i].val;
0566
0567
0568 TMatrixD CSI(TMatrixD::kInverted, CS);
0569 TMatrixD CS2I(TMatrixD::kInverted, CS2);
0570 TVectorD AL(MV);
0571 AL = CSI * MV;
0572
0573
0574 TMatrixD S0(S);
0575 S0.ResizeTo(dim + constraints.size(), dim + constraints.size());
0576 TMatrixD EM(CS);
0577 EM = CSI * S0 * CSI;
0578
0579 TMatrixD EM2(CS2);
0580 EM2 = CS2I * S0 * CS2I;
0581
0582 TMatrixD EMdiff(EM2 - EM);
0583
0584 if (verbosity >= 3) {
0585 double max1 = -1., max2 = -1., maxDiff = -1.;
0586 for (int i = 0; i < EMdiff.GetNrows(); i++) {
0587 for (int j = 0; j < EMdiff.GetNcols(); j++) {
0588 if (maxDiff < fabs(EMdiff(i, j)))
0589 maxDiff = fabs(EMdiff(i, j));
0590
0591 if (max1 < fabs(EM(i, j)))
0592 max1 = fabs(EM(i, j));
0593
0594 if (max2 < fabs(EM2(i, j)))
0595 max2 = fabs(EM2(i, j));
0596 }
0597 }
0598
0599 printf("EM max = %E, EM2 max = %E, EM2 - EM max = %E\n", max1, max2, maxDiff);
0600 }
0601
0602
0603 TMatrixD &U = CS_eigVec;
0604 TMatrixD UT(TMatrixD::kTransposed, U);
0605
0606
0607
0608
0609 TMatrixD EMEi(EM);
0610 EMEi = UT * EM * U;
0611
0612
0613 if (verbosity >= 3) {
0614 double max = -1.;
0615 for (int i = 0; i < EMEi.GetNrows(); i++) {
0616 for (int j = 0; j < EMEi.GetNcols(); j++) {
0617 if (max < EMEi(i, j))
0618 max = EMEi(i, j);
0619 }
0620 }
0621
0622 printf("max = %E\n", max);
0623 }
0624
0625
0626 if (verbosity >= 3) {
0627 printf("\n* Lambda (from the contribution of singular modes to MV)\n");
0628 for (unsigned int i = 0; i < constraints.size(); i++) {
0629 printf("\t%u (%25s)\t%+10.1E +- %10.1E\n",
0630 i,
0631 constraints[i].name.c_str(),
0632 AL[dim + i] * 1E3,
0633 sqrt(EM[i + dim][i + dim]) * 1E3);
0634 }
0635 }
0636
0637
0638 unsigned int offset = 0;
0639 vector<unsigned int> offsets;
0640 for (unsigned int i = 0; i < task->quantityClasses.size(); i++) {
0641 offsets.push_back(offset);
0642 offset += Mc[i].GetNrows();
0643 }
0644
0645 for (const auto &dit : task->geometry.getSensorMap()) {
0646 AlignmentResult r;
0647
0648 for (unsigned int i = 0; i < task->quantityClasses.size(); i++) {
0649 signed idx = task->getQuantityIndex(task->quantityClasses[i], dit.first);
0650 if (idx < 0)
0651 continue;
0652
0653 unsigned int fi = offsets[i] + idx;
0654 double v = AL[fi];
0655 double e = sqrt(EM[fi][fi]);
0656 switch (task->quantityClasses[i]) {
0657 case AlignmentTask::qcShR1:
0658 r.setShR1(v);
0659 r.setShR1Unc(e);
0660 break;
0661 case AlignmentTask::qcShR2:
0662 r.setShR2(v);
0663 r.setShR2Unc(e);
0664 break;
0665 case AlignmentTask::qcShZ:
0666 r.setShZ(v);
0667 r.setShZUnc(e);
0668 break;
0669 case AlignmentTask::qcRotZ:
0670 r.setRotZ(v);
0671 r.setRotZUnc(e);
0672 break;
0673 }
0674 }
0675
0676 results[dit.first] = r;
0677 }
0678
0679
0680 if (dir) {
0681 dir->cd();
0682
0683 S.Write("S");
0684 S_eigVal.Write("S_eigen_values");
0685 S_eigVec.Write("S_eigen_vectors");
0686
0687 E.Write("E");
0688 C.Write("C");
0689
0690 CS.Write("CS");
0691 CS_eigVal.Write("CS_eigen_values");
0692 CS_eigVec.Write("CS_eigen_vectors");
0693
0694 MV.Write("MV");
0695 AL.Write("AL");
0696
0697 S0.Write("S0");
0698 EM.Write("EM");
0699 }
0700
0701
0702 return 0;
0703 }
0704
0705
0706
0707 void JanAlignmentAlgorithm::end() {
0708 delete[] Mc;
0709
0710 for (unsigned int i = 0; i < task->quantityClasses.size(); i++) {
0711 delete[] Sc[i];
0712 }
0713 delete[] Sc;
0714 }
0715
0716
0717
0718 void JanAlignmentAlgorithm::saveDiagnostics(TDirectory *dir) {
0719 if (!buildDiagnosticPlots)
0720 return;
0721
0722 for (map<unsigned int, DetStat>::iterator it = statistics.begin(); it != statistics.end(); ++it) {
0723 char buf[50];
0724 sprintf(buf, "%u", it->first);
0725 gDirectory = dir->mkdir(buf);
0726
0727 it->second.m_dist->Write();
0728 it->second.R_dist->Write();
0729
0730 for (unsigned int c = 0; c < task->quantityClasses.size(); c++) {
0731 it->second.coefHist[c]->Write();
0732 it->second.resVsCoef[c]->Write();
0733 }
0734
0735 gDirectory = gDirectory->mkdir("R vs. rot. coef, per RP set");
0736 TCanvas *c = new TCanvas;
0737 c->SetName("R vs. rot. coef, overlapped");
0738 TH2D *frame = new TH2D("frame", "frame", 100, -20., +20., 100, -0.15, +0.15);
0739 frame->Draw();
0740 unsigned int idx = 0;
0741 for (map<set<unsigned int>, ScatterPlot>::iterator iit = it->second.resVsCoefRot_perRPSet.begin();
0742 iit != it->second.resVsCoefRot_perRPSet.end();
0743 ++iit, ++idx) {
0744 string label;
0745 bool first = true;
0746 for (set<unsigned int>::iterator sit = iit->first.begin(); sit != iit->first.end(); ++sit) {
0747 char buf[50];
0748 sprintf(buf, "%u", *sit);
0749
0750 if (first) {
0751 label = buf;
0752 first = false;
0753 } else {
0754 label = label + ", " + buf;
0755 }
0756 }
0757
0758 iit->second.g->SetTitle(";rotation coefficient (mm);residual (mm)");
0759 iit->second.g->SetMarkerColor(idx + 1);
0760 iit->second.g->SetName(label.c_str());
0761 iit->second.g->Draw((idx == 0) ? "p" : "p");
0762 iit->second.g->Write();
0763
0764 iit->second.h->SetName((label + " (hist)").c_str());
0765 iit->second.h->SetTitle(";rotation coefficient (mm);residual (mm)");
0766 iit->second.h->Write();
0767 }
0768
0769 gDirectory->cd("..");
0770 c->Write();
0771 }
0772 }