File indexing completed on 2024-04-06 11:58:34
0001
0002
0003
0004
0005
0006 #include "FWCore/Framework/interface/Event.h"
0007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0008 #include "FWCore/Framework/interface/EventSetup.h"
0009 #include "FWCore/Framework/interface/ESHandle.h"
0010
0011 #include "CondFormats/PPSObjects/interface/CTPPSRPAlignmentCorrectionsMethods.h"
0012 #include "CondFormats/AlignmentRecord/interface/RPRealAlignmentRecord.h"
0013 #include "Geometry/VeryForwardGeometryBuilder/interface/CTPPSGeometry.h"
0014 #include "Geometry/Records/interface/VeryForwardRealGeometryRecord.h"
0015
0016 #include "CalibPPS/AlignmentRelative/interface/StraightTrackAlignment.h"
0017 #include "CalibPPS/AlignmentRelative/interface/Utilities.h"
0018
0019 #include "CalibPPS/AlignmentRelative/interface/IdealResult.h"
0020 #include "CalibPPS/AlignmentRelative/interface/JanAlignmentAlgorithm.h"
0021
0022 #include <set>
0023 #include <unordered_set>
0024 #include <vector>
0025 #include <string>
0026
0027 #include "TDecompLU.h"
0028 #include "TH1D.h"
0029 #include "TFile.h"
0030 #include "TGraph.h"
0031 #include "TCanvas.h"
0032
0033
0034
0035 using namespace edm;
0036 using namespace std;
0037
0038
0039
0040 TH1D *StraightTrackAlignment::newResiduaHist(const char *name) {
0041 return new TH1D(name, ";residual (mm)", 2000, -3., +3.);
0042 }
0043
0044
0045
0046 TGraph *newGraph(const string &name, const string &title) {
0047 TGraph *g = new TGraph();
0048 g->SetName(name.c_str());
0049 g->SetTitle(title.c_str());
0050 return g;
0051 }
0052
0053
0054
0055 StraightTrackAlignment::RPSetPlots::RPSetPlots(const string &_name) : name(_name) {
0056 chisqn_lin_fitted = new TH1D("chi^2 norm, lin, fitted", ";#chi^{2}/ndf;", 5000, 0., 500.);
0057 chisqn_lin_selected = new TH1D("chi^2 norm, lin, selected", ";#chi^{2}/ndf;", 5000, 0., 500.);
0058 chisqn_log_fitted = new TH1D("chi^2 norm, log, fitted", ";log_{10}(#chi^{2}/ndf);", 700, -1., 6.);
0059 chisqn_log_selected = new TH1D("chi^2 norm, log, selected", ";log_{10}(#chi^{2}/ndf);", 700, -1., 6.);
0060
0061 fitAxVsAyGraph_fitted = newGraph("ax vs. ay, fitted", ";a_{x} (rad);a_{y} (rad)");
0062 fitAxVsAyGraph_selected = newGraph("ax vs. ay, selected", ";a_{x} (rad);a_{y} (rad)");
0063 fitBxVsByGraph_fitted = newGraph("bx vs. by, fitted", ";b_{x} (mm);b_{y} (mm)");
0064 fitBxVsByGraph_selected = newGraph("bx vs. by, selected", ";b_{x} (mm);b_{y} (mm)");
0065 }
0066
0067
0068 void StraightTrackAlignment::RPSetPlots::free() {
0069 delete chisqn_lin_fitted;
0070 delete chisqn_lin_selected;
0071 delete chisqn_log_fitted;
0072 delete chisqn_log_selected;
0073
0074 delete fitAxVsAyGraph_fitted;
0075 delete fitAxVsAyGraph_selected;
0076 delete fitBxVsByGraph_fitted;
0077 delete fitBxVsByGraph_selected;
0078 }
0079
0080
0081
0082 void StraightTrackAlignment::RPSetPlots::write() const {
0083 chisqn_lin_fitted->Write();
0084 chisqn_lin_selected->Write();
0085 chisqn_log_fitted->Write();
0086 chisqn_log_selected->Write();
0087
0088 fitAxVsAyGraph_fitted->Write();
0089 fitAxVsAyGraph_selected->Write();
0090 fitBxVsByGraph_fitted->Write();
0091 fitBxVsByGraph_selected->Write();
0092 }
0093
0094
0095
0096
0097 StraightTrackAlignment::StraightTrackAlignment(const ParameterSet &ps)
0098 : verbosity(ps.getUntrackedParameter<unsigned int>("verbosity", 0)),
0099
0100 rpIds(ps.getParameter<vector<unsigned int> >("rpIds")),
0101 excludePlanes(ps.getParameter<vector<unsigned int> >("excludePlanes")),
0102 z0(ps.getParameter<double>("z0")),
0103
0104 maxEvents(ps.getParameter<signed int>("maxEvents")),
0105
0106 removeImpossible(ps.getParameter<bool>("removeImpossible")),
0107 requireNumberOfUnits(ps.getParameter<unsigned int>("requireNumberOfUnits")),
0108 requireAtLeast3PotsInOverlap(ps.getParameter<bool>("requireAtLeast3PotsInOverlap")),
0109 requireOverlap(ps.getParameter<bool>("requireOverlap")),
0110 cutOnChiSqPerNdf(ps.getParameter<bool>("cutOnChiSqPerNdf")),
0111 chiSqPerNdfCut(ps.getParameter<double>("chiSqPerNdfCut")),
0112 maxTrackAx(ps.getParameter<double>("maxTrackAx")),
0113 maxTrackAy(ps.getParameter<double>("maxTrackAy")),
0114
0115 fileNamePrefix(ps.getParameter<string>("fileNamePrefix")),
0116 expandedFileNamePrefix(ps.getParameter<string>("expandedFileNamePrefix")),
0117 factoredFileNamePrefix(ps.getParameter<string>("factoredFileNamePrefix")),
0118 preciseXMLFormat(ps.getParameter<bool>("preciseXMLFormat")),
0119 saveXMLUncertainties(ps.getParameter<bool>("saveXMLUncertainties")),
0120
0121 saveIntermediateResults(ps.getParameter<bool>("saveIntermediateResults")),
0122 taskDataFileName(ps.getParameter<string>("taskDataFileName")),
0123 taskDataFile(nullptr),
0124
0125 task(ps),
0126 fitter(ps),
0127
0128 buildDiagnosticPlots(ps.getParameter<bool>("buildDiagnosticPlots")),
0129 diagnosticsFile(ps.getParameter<string>("diagnosticsFile")),
0130 fitNdfHist_fitted(new TH1D("ndf_fitted", ";ndf;", 41, -4.5, 36.5)),
0131 fitNdfHist_selected(new TH1D("ndf_selected", ";ndf;", 41, -4.5, 36.5)),
0132 fitPHist_fitted(new TH1D("p_fitted", ";p value;", 100, 0., 1.)),
0133 fitPHist_selected(new TH1D("p_selected", ";p value;", 100, 0., 1.)),
0134 fitAxHist_fitted(new TH1D("ax_fitted", ";a_{x} (rad);", 10000, -0.1, 0.1)),
0135 fitAxHist_selected(new TH1D("ax_selected", ";a_{x} (rad);", 10000, -0.1, 0.1)),
0136 fitAyHist_fitted(new TH1D("ay_fitted", ";a_{y} (rad);", 10000, -0.1, 0.1)),
0137 fitAyHist_selected(new TH1D("ay_selected", ";a_{y} (rad);", 10000, -0.1, 0.1)),
0138 fitBxHist_fitted(new TH1D("bx_fitted", ";b_{x} (mm);", 500, -30., 30.)),
0139 fitBxHist_selected(new TH1D("bx_selected", ";b_{x} (mm);", 500, -30., 30.)),
0140 fitByHist_fitted(new TH1D("by_fitted", ";b_{y} (mm);", 500, -30., 30.)),
0141 fitByHist_selected(new TH1D("by_selected", ";b_{y} (mm);", 500, -30., 30.)),
0142
0143 globalPlots("global") {
0144
0145 if (!taskDataFileName.empty())
0146 taskDataFile = new TFile(taskDataFileName.c_str(), "recreate");
0147
0148
0149
0150 vector<string> alNames(ps.getParameter<vector<string> >("algorithms"));
0151 for (unsigned int i = 0; i < alNames.size(); i++) {
0152 AlignmentAlgorithm *a = nullptr;
0153
0154 if (alNames[i] == "Ideal") {
0155 IdealResult *ir = new IdealResult(ps, &task);
0156 a = ir;
0157 } else if (alNames[i] == "Jan") {
0158 JanAlignmentAlgorithm *jaa = new JanAlignmentAlgorithm(ps, &task);
0159 a = jaa;
0160 }
0161
0162 if (a)
0163 algorithms.push_back(a);
0164 else
0165 throw cms::Exception("PPS") << "Unknown alignment algorithm `" << alNames[i] << "'.";
0166 }
0167
0168
0169 string ct = ps.getParameter<string>("constraintsType");
0170 if (ct.compare("fixedDetectors") == 0)
0171 constraintsType = ctFixedDetectors;
0172 else if (ct.compare("standard") == 0)
0173 constraintsType = ctStandard;
0174 else
0175 throw cms::Exception("PPS") << "Unknown constraints type `" << ct << "'.";
0176
0177
0178 string aars_str = ps.getParameter<string>("additionalAcceptedRPSets");
0179
0180 size_t idx_b = 0, idx_e = string::npos;
0181 while (idx_b != string::npos) {
0182
0183 idx_e = aars_str.find(';', idx_b);
0184 size_t len = (idx_e == string::npos) ? string::npos : idx_e - idx_b;
0185 string block = aars_str.substr(idx_b, len);
0186
0187
0188 if (!block.empty()) {
0189 set<unsigned int> rpSet;
0190
0191
0192 size_t bi_b = 0, bi_e = string::npos;
0193 while (bi_b != string::npos) {
0194 bi_e = block.find(',', bi_b);
0195 size_t bit_len = (bi_e == string::npos) ? string::npos : bi_e - bi_b;
0196 const string &bit = block.substr(bi_b, bit_len);
0197
0198 unsigned int rp = atoi(bit.c_str());
0199 rpSet.insert(rp);
0200
0201 bi_b = (bi_e == string::npos) ? string::npos : bi_e + 1;
0202 }
0203
0204 additionalAcceptedRPSets.push_back(rpSet);
0205 }
0206
0207
0208 idx_b = (idx_e == string::npos) ? string::npos : idx_e + 1;
0209 }
0210 }
0211
0212
0213
0214 StraightTrackAlignment::~StraightTrackAlignment() {
0215 if (taskDataFile)
0216 delete taskDataFile;
0217
0218 for (vector<AlignmentAlgorithm *>::iterator it = algorithms.begin(); it != algorithms.end(); ++it)
0219 delete (*it);
0220
0221 delete fitNdfHist_fitted;
0222 delete fitNdfHist_selected;
0223 delete fitPHist_fitted;
0224 delete fitPHist_selected;
0225 delete fitAxHist_fitted;
0226 delete fitAyHist_fitted;
0227 delete fitAxHist_selected;
0228 delete fitAyHist_selected;
0229 delete fitBxHist_fitted;
0230 delete fitByHist_fitted;
0231 delete fitBxHist_selected;
0232 delete fitByHist_selected;
0233
0234 globalPlots.free();
0235
0236 for (auto &p : rpSetPlots)
0237 p.second.free();
0238
0239 for (auto it = residuaHistograms.begin(); it != residuaHistograms.end(); ++it) {
0240 delete it->second.total_fitted;
0241 delete it->second.total_selected;
0242 delete it->second.selected_vs_chiSq;
0243 for (auto sit = it->second.perRPSet_fitted.begin(); sit != it->second.perRPSet_fitted.end(); ++sit)
0244 delete sit->second;
0245 for (auto sit = it->second.perRPSet_selected.begin(); sit != it->second.perRPSet_selected.end(); ++sit)
0246 delete sit->second;
0247 }
0248 }
0249
0250
0251
0252 void StraightTrackAlignment::begin(edm::ESHandle<CTPPSRPAlignmentCorrectionsData> hRealAlignment,
0253 edm::ESHandle<CTPPSGeometry> hRealGeometry,
0254 edm::ESHandle<CTPPSGeometry> hMisalignedGeometry) {
0255
0256 eventsTotal = 0;
0257 eventsFitted = 0;
0258 eventsSelected = 0;
0259 fittedTracksPerRPSet.clear();
0260 selectedTracksPerRPSet.clear();
0261 selectedHitsPerPlane.clear();
0262
0263
0264 task.buildGeometry(rpIds, excludePlanes, hRealGeometry.product(), z0, task.geometry);
0265
0266
0267 task.buildIndexMaps();
0268
0269
0270 if (verbosity > 1)
0271 task.geometry.print();
0272
0273
0274 if (taskDataFile) {
0275 taskDataFile->WriteObject(&task, "task");
0276 taskDataFile->WriteObject(&fitter, "fitter");
0277 }
0278
0279
0280 for (const auto &a : algorithms)
0281 a->begin(hRealGeometry.product(), hMisalignedGeometry.product());
0282
0283
0284 initialAlignments = *hRealAlignment;
0285 }
0286
0287
0288
0289 void StraightTrackAlignment::processEvent(const edm::EventID &eventId,
0290 const DetSetVector<TotemRPUVPattern> &uvPatternsStrip,
0291 const DetSetVector<CTPPSDiamondRecHit> &hitsDiamond,
0292 const edm::DetSetVector<CTPPSPixelRecHit> &hitsPixel,
0293 const DetSetVector<CTPPSPixelLocalTrack> &tracksPixel) {
0294 eventsTotal++;
0295
0296 if (verbosity > 9)
0297 printf("\n---------- StraightTrackAlignment::ProcessEvent (%u:%llu)\n", eventId.run(), eventId.event());
0298
0299
0300
0301 HitCollection hitSelection;
0302
0303
0304 for (const auto &pv : uvPatternsStrip) {
0305 const CTPPSDetId detId(pv.detId());
0306 const unsigned int rpDecId = detId.arm() * 100 + detId.station() * 10 + detId.rp();
0307
0308
0309 if (find(rpIds.begin(), rpIds.end(), rpDecId) == rpIds.end())
0310 continue;
0311
0312
0313 unsigned int n_U = 0, n_V = 0;
0314 unsigned int idx_U = 0, idx_V = 0;
0315 for (unsigned int pi = 0; pi < pv.size(); pi++) {
0316 const TotemRPUVPattern &pattern = pv[pi];
0317
0318 switch (pattern.projection()) {
0319 case TotemRPUVPattern::projU:
0320 n_U++;
0321 idx_U = pi;
0322 break;
0323
0324 case TotemRPUVPattern::projV:
0325 n_V++;
0326 idx_V = pi;
0327 break;
0328
0329 default:
0330 break;
0331 }
0332 }
0333
0334 if (n_U != 1 || n_V != 1)
0335 continue;
0336
0337
0338 if (!pv[idx_U].fittable() || !pv[idx_V].fittable())
0339 continue;
0340
0341
0342 for (const auto &pattern : {pv[idx_U], pv[idx_V]}) {
0343 for (const auto &hitsDetSet : pattern.hits()) {
0344
0345 if (!task.geometry.isValidSensorId(hitsDetSet.detId()))
0346 continue;
0347
0348 const double &z = task.geometry.get(hitsDetSet.detId()).z;
0349 for (auto &hit : hitsDetSet)
0350 hitSelection.emplace_back(Hit(hitsDetSet.detId(), 2, hit.position(), hit.sigma(), z));
0351 }
0352 }
0353 }
0354
0355
0356 for (const auto &pv : hitsDiamond) {
0357
0358 const CTPPSDetId detId(pv.detId());
0359 const unsigned int rpDecId = detId.arm() * 100 + detId.station() * 10 + detId.rp();
0360
0361
0362 if (find(rpIds.begin(), rpIds.end(), rpDecId) == rpIds.end())
0363 continue;
0364
0365
0366 if (!task.geometry.isValidSensorId(detId))
0367 continue;
0368
0369 const double &z = task.geometry.get(pv.detId()).z;
0370
0371 for (const auto &h : pv)
0372 hitSelection.emplace_back(Hit(pv.detId(), 1, h.x(), h.xWidth() / sqrt(12.), z));
0373 }
0374
0375
0376 map<unsigned int, unsigned int> pixelPlaneMultiplicity;
0377 for (const auto &pv : hitsPixel)
0378 pixelPlaneMultiplicity[pv.detId()] += pv.size();
0379
0380 for (const auto &pv : hitsPixel) {
0381
0382 const CTPPSDetId detId(pv.detId());
0383 const unsigned int rpDecId = detId.arm() * 100 + detId.station() * 10 + detId.rp();
0384
0385
0386 if (find(rpIds.begin(), rpIds.end(), rpDecId) == rpIds.end())
0387 continue;
0388
0389
0390 if (!task.geometry.isValidSensorId(detId))
0391 continue;
0392
0393
0394 if (pixelPlaneMultiplicity[pv.detId()] > 1)
0395 continue;
0396
0397 for (const auto &h : pv) {
0398 const auto &dg = task.geometry.get(pv.detId());
0399 const double dz1 = dg.getDirectionData(1).dz;
0400 const double dz2 = dg.getDirectionData(2).dz;
0401 const double z = dg.z + h.point().x() * dz1 + h.point().y() * dz2;
0402
0403 double x_unc = sqrt(h.error().xx());
0404 double y_unc = sqrt(h.error().yy());
0405
0406
0407
0408 if (x_unc <= 0.)
0409 x_unc = 10E-3;
0410 if (y_unc <= 0.)
0411 y_unc = 10E-3;
0412
0413 hitSelection.emplace_back(Hit(pv.detId(), 1, h.point().x(), x_unc, z));
0414 hitSelection.emplace_back(Hit(pv.detId(), 2, h.point().y(), y_unc, z));
0415 }
0416 }
0417
0418
0419 for (const auto &pv : tracksPixel) {
0420 const CTPPSDetId rpId(pv.detId());
0421 const unsigned int rpDecId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
0422
0423
0424 if (find(rpIds.begin(), rpIds.end(), rpDecId) == rpIds.end())
0425 continue;
0426
0427
0428 unsigned int n_valid_tracks = 0;
0429 for (const auto &tr : pv) {
0430 if (tr.isValid())
0431 n_valid_tracks++;
0432 }
0433
0434 if (n_valid_tracks > 1)
0435 continue;
0436
0437
0438 for (const auto &tr : pv) {
0439 if (!tr.isValid())
0440 continue;
0441
0442
0443 for (const auto &hv : tr.hits()) {
0444 const CTPPSPixelDetId senId(hv.detId());
0445
0446
0447 if (!task.geometry.isValidSensorId(senId))
0448 continue;
0449
0450 for (const auto &h : hv) {
0451
0452 if (!h.isUsedForFit())
0453 continue;
0454
0455 const auto &dg = task.geometry.get(senId);
0456 const double dz1 = dg.getDirectionData(1).dz;
0457 const double dz2 = dg.getDirectionData(2).dz;
0458 const double z = dg.z + h.point().x() * dz1 + h.point().y() * dz2;
0459
0460 double x_unc = sqrt(h.error().xx());
0461 double y_unc = sqrt(h.error().yy());
0462
0463 if (x_unc <= 0.)
0464 x_unc = 10E-3;
0465 if (y_unc <= 0.)
0466 y_unc = 10E-3;
0467
0468 hitSelection.emplace_back(Hit(senId, 1, h.point().x(), x_unc, z));
0469 hitSelection.emplace_back(Hit(senId, 2, h.point().y(), y_unc, z));
0470 }
0471 }
0472 }
0473 }
0474
0475 if (hitSelection.empty())
0476 return;
0477
0478
0479
0480 LocalTrackFit trackFit;
0481 if (!fitter.fit(hitSelection, task.geometry, trackFit))
0482 return;
0483
0484 set<unsigned int> selectedRPs;
0485 for (const auto &hit : hitSelection) {
0486 CTPPSDetId detId(hit.id);
0487 const unsigned int decRPId = detId.arm() * 100 + detId.station() * 10 + detId.rp();
0488 selectedRPs.insert(decRPId);
0489 }
0490
0491 eventsFitted++;
0492 fittedTracksPerRPSet[selectedRPs]++;
0493
0494
0495
0496 bool top = false, bottom = false, horizontal = false;
0497 unordered_set<unsigned int> units;
0498 for (const auto &rp : selectedRPs) {
0499 unsigned int rpIdx = rp % 10;
0500 unsigned int stId = rp / 10;
0501 unsigned int unitId = stId * 10;
0502 if (rpIdx > 2)
0503 unitId++;
0504
0505 if (rpIdx == 0 || rpIdx == 4)
0506 top = true;
0507 if (rpIdx == 1 || rpIdx == 5)
0508 bottom = true;
0509 if (rpIdx == 2 || rpIdx == 3)
0510 horizontal = true;
0511
0512 units.insert(unitId);
0513 }
0514
0515 bool overlap = (top && horizontal) || (bottom && horizontal);
0516
0517 bool rp_set_accepted = true;
0518
0519
0520 if (removeImpossible && top && bottom)
0521 rp_set_accepted = false;
0522
0523
0524 if (units.size() < requireNumberOfUnits)
0525 rp_set_accepted = false;
0526
0527 if (requireOverlap && !overlap)
0528 rp_set_accepted = false;
0529
0530 if (requireAtLeast3PotsInOverlap && overlap && selectedRPs.size() < 3)
0531 rp_set_accepted = false;
0532
0533
0534 if (find(additionalAcceptedRPSets.begin(), additionalAcceptedRPSets.end(), selectedRPs) !=
0535 additionalAcceptedRPSets.end())
0536 rp_set_accepted = true;
0537
0538 if (verbosity > 5)
0539 printf("* rp set accepted: %u\n", rp_set_accepted);
0540
0541 bool selected = rp_set_accepted;
0542
0543
0544 if (cutOnChiSqPerNdf && trackFit.chiSqPerNdf() > chiSqPerNdfCut)
0545 selected = false;
0546
0547
0548 if (fabs(trackFit.ax) > maxTrackAx || fabs(trackFit.ay) > maxTrackAy)
0549 selected = false;
0550
0551 updateDiagnosticHistograms(hitSelection, selectedRPs, trackFit, selected);
0552
0553 if (verbosity > 5)
0554 printf("* event selected: %u\n", selected);
0555
0556 if (!selected)
0557 return;
0558
0559
0560 eventsSelected++;
0561 selectedTracksPerRPSet[selectedRPs]++;
0562
0563 for (const auto &h : hitSelection)
0564 selectedHitsPerPlane[h.id]++;
0565
0566
0567
0568 for (auto &a : algorithms)
0569 a->feed(hitSelection, trackFit);
0570
0571
0572
0573 if (eventsSelected == maxEvents)
0574 throw "StraightTrackAlignment: Number of tracks processed reached maximum";
0575 }
0576
0577
0578
0579 void StraightTrackAlignment::updateDiagnosticHistograms(const HitCollection &selection,
0580 const set<unsigned int> &selectedRPs,
0581 const LocalTrackFit &trackFit,
0582 bool trackSelected) {
0583 if (!buildDiagnosticPlots)
0584 return;
0585
0586 fitNdfHist_fitted->Fill(trackFit.ndf);
0587 fitPHist_fitted->Fill(trackFit.pValue());
0588 fitAxHist_fitted->Fill(trackFit.ax);
0589 fitAyHist_fitted->Fill(trackFit.ay);
0590 fitBxHist_fitted->Fill(trackFit.bx);
0591 fitByHist_fitted->Fill(trackFit.by);
0592
0593 globalPlots.chisqn_lin_fitted->Fill(trackFit.chiSqPerNdf());
0594 globalPlots.chisqn_log_fitted->Fill(log10(trackFit.chiSqPerNdf()));
0595 globalPlots.fitAxVsAyGraph_fitted->SetPoint(globalPlots.fitAxVsAyGraph_fitted->GetN(), trackFit.ax, trackFit.ay);
0596 globalPlots.fitBxVsByGraph_fitted->SetPoint(globalPlots.fitBxVsByGraph_fitted->GetN(), trackFit.bx, trackFit.by);
0597
0598 if (trackSelected) {
0599 fitNdfHist_selected->Fill(trackFit.ndf);
0600 fitPHist_selected->Fill(trackFit.pValue());
0601 fitAxHist_selected->Fill(trackFit.ax);
0602 fitAyHist_selected->Fill(trackFit.ay);
0603 fitBxHist_selected->Fill(trackFit.bx);
0604 fitByHist_selected->Fill(trackFit.by);
0605
0606 globalPlots.chisqn_lin_selected->Fill(trackFit.chiSqPerNdf());
0607 globalPlots.chisqn_log_selected->Fill(log10(trackFit.chiSqPerNdf()));
0608 globalPlots.fitAxVsAyGraph_selected->SetPoint(
0609 globalPlots.fitAxVsAyGraph_selected->GetN(), trackFit.ax, trackFit.ay);
0610 globalPlots.fitBxVsByGraph_selected->SetPoint(
0611 globalPlots.fitBxVsByGraph_selected->GetN(), trackFit.bx, trackFit.by);
0612 }
0613
0614 auto it = rpSetPlots.find(selectedRPs);
0615 if (it == rpSetPlots.end())
0616 it = rpSetPlots.insert({selectedRPs, RPSetPlots(setToString(selectedRPs))}).first;
0617
0618 it->second.chisqn_lin_fitted->Fill(trackFit.chiSqPerNdf());
0619 it->second.chisqn_log_fitted->Fill(log10(trackFit.chiSqPerNdf()));
0620 it->second.fitAxVsAyGraph_fitted->SetPoint(it->second.fitAxVsAyGraph_fitted->GetN(), trackFit.ax, trackFit.ay);
0621 it->second.fitBxVsByGraph_fitted->SetPoint(it->second.fitBxVsByGraph_fitted->GetN(), trackFit.bx, trackFit.by);
0622
0623 if (trackSelected) {
0624 it->second.chisqn_lin_selected->Fill(trackFit.chiSqPerNdf());
0625 it->second.chisqn_log_selected->Fill(log10(trackFit.chiSqPerNdf()));
0626 it->second.fitAxVsAyGraph_selected->SetPoint(it->second.fitAxVsAyGraph_selected->GetN(), trackFit.ax, trackFit.ay);
0627 it->second.fitBxVsByGraph_selected->SetPoint(it->second.fitBxVsByGraph_selected->GetN(), trackFit.bx, trackFit.by);
0628 }
0629
0630 for (const auto &hit : selection) {
0631 unsigned int id = hit.id;
0632
0633 const DetGeometry &geom = task.geometry.get(id);
0634 const auto dirData = geom.getDirectionData(hit.dirIdx);
0635
0636 double m = hit.position + dirData.s - (hit.z - geom.z) * dirData.dz;
0637 double x = trackFit.ax * hit.z + trackFit.bx;
0638 double y = trackFit.ay * hit.z + trackFit.by;
0639 double f = x * dirData.dx + y * dirData.dy;
0640 double R = m - f;
0641
0642 auto it = residuaHistograms.find(id);
0643 if (it == residuaHistograms.end()) {
0644 it = residuaHistograms.insert(pair<unsigned int, ResiduaHistogramSet>(id, ResiduaHistogramSet())).first;
0645 char buf[30];
0646 sprintf(buf, "%u: total_fitted", id);
0647 it->second.total_fitted = newResiduaHist(buf);
0648 sprintf(buf, "%u: total_selected", id);
0649 it->second.total_selected = newResiduaHist(buf);
0650 it->second.selected_vs_chiSq = new TGraph();
0651 sprintf(buf, "%u: selected_vs_chiSq", id);
0652 it->second.selected_vs_chiSq->SetName(buf);
0653 }
0654
0655 it->second.total_fitted->Fill(R);
0656
0657 if (trackSelected) {
0658 it->second.total_selected->Fill(R);
0659 it->second.selected_vs_chiSq->SetPoint(it->second.selected_vs_chiSq->GetN(), trackFit.chiSqPerNdf(), R);
0660 }
0661
0662 auto sit = it->second.perRPSet_fitted.find(selectedRPs);
0663 if (sit == it->second.perRPSet_fitted.end()) {
0664 char buf[10];
0665 sprintf(buf, "%u: ", id);
0666 string label = buf;
0667 label += setToString(selectedRPs);
0668 sit =
0669 it->second.perRPSet_fitted.insert(pair<set<unsigned int>, TH1D *>(selectedRPs, newResiduaHist(label.c_str())))
0670 .first;
0671 }
0672
0673 sit->second->Fill(R);
0674
0675 if (trackSelected) {
0676 sit = it->second.perRPSet_selected.find(selectedRPs);
0677 if (sit == it->second.perRPSet_selected.end()) {
0678 char buf[10];
0679 sprintf(buf, "%u: ", id);
0680 string label = buf;
0681 label += setToString(selectedRPs);
0682 sit = it->second.perRPSet_selected
0683 .insert(pair<set<unsigned int>, TH1D *>(selectedRPs, newResiduaHist(label.c_str())))
0684 .first;
0685 }
0686
0687 sit->second->Fill(R);
0688 }
0689 }
0690 }
0691
0692
0693
0694 void StraightTrackAlignment::buildConstraints(vector<AlignmentConstraint> &constraints) {
0695 constraints.clear();
0696
0697 switch (constraintsType) {
0698 case ctFixedDetectors:
0699 task.buildFixedDetectorsConstraints(constraints);
0700 return;
0701
0702 case ctStandard:
0703 task.buildStandardConstraints(constraints);
0704 return;
0705 }
0706 }
0707
0708
0709
0710 void StraightTrackAlignment::finish() {
0711
0712 if (verbosity) {
0713 printf("----------------------------------------------------------------------------------------------------\n");
0714 printf("\n>> StraightTrackAlignment::Finish\n");
0715 printf("\tevents total = %i\n", eventsTotal);
0716 printf("\tevents fitted = %i\n", eventsFitted);
0717 printf("\tevents selected = %i\n", eventsSelected);
0718
0719 printf("\n* events per RP set:\n");
0720 printf("%30s %10s%10s\n", "set of RPs", "fitted", "selected");
0721
0722 for (auto it = fittedTracksPerRPSet.begin(); it != fittedTracksPerRPSet.end(); ++it) {
0723 const string &label = setToString(it->first);
0724
0725 auto sit = selectedTracksPerRPSet.find(it->first);
0726 unsigned long sv = (sit == selectedTracksPerRPSet.end()) ? 0 : sit->second;
0727
0728 printf("%30s :%10lu%10lu\n", label.c_str(), it->second, sv);
0729 }
0730
0731 if (verbosity >= 2) {
0732 printf("\n* hits per plane:\n");
0733 for (const auto it : selectedHitsPerPlane) {
0734 printf(" ");
0735 printId(it.first);
0736 printf(" : %u\n", it.second);
0737 }
0738 }
0739 }
0740
0741
0742 saveDiagnostics();
0743
0744
0745 for (auto a : algorithms)
0746 a->analyze();
0747
0748
0749 vector<AlignmentConstraint> constraints;
0750 buildConstraints(constraints);
0751
0752
0753 if (taskDataFile)
0754 taskDataFile->WriteObject(&constraints, "constraints");
0755
0756 if (verbosity) {
0757 printf("\n>> StraightTrackAlignment::Finish > %lu constraints built\n", constraints.size());
0758 for (unsigned int i = 0; i < constraints.size(); i++)
0759 printf("\t%s\n", constraints[i].name.c_str());
0760 }
0761
0762
0763 vector<map<unsigned int, AlignmentResult> > results;
0764 for (auto algorithm : algorithms) {
0765 TDirectory *dir = nullptr;
0766 if (taskDataFile && saveIntermediateResults)
0767 dir = taskDataFile->mkdir((algorithm->getName() + "_data").c_str());
0768
0769 results.resize(results.size() + 1);
0770 unsigned int rf = algorithm->solve(constraints, results.back(), dir);
0771
0772 if (rf)
0773 throw cms::Exception("PPS") << "The Solve method of `" << algorithm->getName()
0774 << "' algorithm has failed (return value " << rf << ").";
0775 }
0776
0777
0778 if (verbosity) {
0779 printf("\n>> StraightTrackAlignment::Finish > Print\n");
0780
0781 printLineSeparator(results);
0782 printQuantitiesLine(results);
0783 printAlgorithmsLine(results);
0784
0785 signed int prevRPId = -1;
0786
0787 for (const auto &dit : task.geometry.getSensorMap()) {
0788 signed int rpId = CTPPSDetId(dit.first).rpId();
0789 if (rpId != prevRPId)
0790 printLineSeparator(results);
0791 prevRPId = rpId;
0792
0793 printId(dit.first);
0794 printf(" ║");
0795
0796 for (unsigned int q = 0; q < task.quantityClasses.size(); q++) {
0797 for (unsigned int a = 0; a < results.size(); a++) {
0798 const auto it = results[a].find(dit.first);
0799 if (it == results[a].end()) {
0800 if (algorithms[a]->hasErrorEstimate())
0801 printf("%19s", "----");
0802 else
0803 printf("%8s", "----");
0804
0805 if (a + 1 == results.size())
0806 printf("║");
0807 else
0808 printf("│");
0809
0810 continue;
0811 }
0812
0813 const auto &ac = it->second;
0814 double v = 0., e = 0.;
0815 switch (task.quantityClasses[q]) {
0816 case AlignmentTask::qcShR1:
0817 v = ac.getShR1();
0818 e = ac.getShR1Unc();
0819 break;
0820 case AlignmentTask::qcShR2:
0821 v = ac.getShR2();
0822 e = ac.getShR2Unc();
0823 break;
0824 case AlignmentTask::qcShZ:
0825 v = ac.getShZ();
0826 e = ac.getShZUnc();
0827 break;
0828 case AlignmentTask::qcRotZ:
0829 v = ac.getRotZ();
0830 e = ac.getRotZUnc();
0831 break;
0832 }
0833
0834 if (algorithms[a]->hasErrorEstimate())
0835 printf("%+8.1f ± %7.1f", v * 1E3, e * 1E3);
0836 else
0837 printf("%+8.1f", v * 1E3);
0838
0839 if (a + 1 == results.size())
0840 printf("║");
0841 else
0842 printf("│");
0843 }
0844 }
0845
0846 printf("\n");
0847 }
0848
0849 printLineSeparator(results);
0850 printAlgorithmsLine(results);
0851 printQuantitiesLine(results);
0852 printLineSeparator(results);
0853 }
0854
0855
0856 for (unsigned int a = 0; a < results.size(); a++) {
0857
0858 CTPPSRPAlignmentCorrectionsData convertedAlignments;
0859 for (const auto &p : results[a]) {
0860 const DetGeometry &d = task.geometry.get(p.first);
0861 const auto dir1 = d.getDirectionData(1);
0862 const auto dir2 = d.getDirectionData(2);
0863
0864 const double det = dir1.dx * dir2.dy - dir1.dy * dir2.dx;
0865 const double sh_x = (dir2.dy * p.second.getShR1() - dir1.dy * p.second.getShR2()) / det;
0866 const double sh_y = (-dir2.dx * p.second.getShR1() + dir1.dx * p.second.getShR2()) / det;
0867
0868 const double sh_x_e =
0869 sqrt(pow(dir2.dy / det * p.second.getShR1Unc(), 2) + pow(dir1.dy / det * p.second.getShR2Unc(), 2));
0870 const double sh_y_e =
0871 sqrt(pow(dir2.dx / det * p.second.getShR1Unc(), 2) + pow(dir1.dx / det * p.second.getShR2Unc(), 2));
0872
0873 const CTPPSRPAlignmentCorrectionData corr(sh_x,
0874 sh_x_e,
0875 sh_y,
0876 sh_y_e,
0877 p.second.getShZ(),
0878 p.second.getShZUnc(),
0879 0.,
0880 0.,
0881 0.,
0882 0.,
0883 p.second.getRotZ(),
0884 p.second.getRotZUnc());
0885 convertedAlignments.setSensorCorrection(p.first, corr);
0886 }
0887
0888
0889 if (!fileNamePrefix.empty()) {
0890 CTPPSRPAlignmentCorrectionsMethods::writeToXML(convertedAlignments,
0891 fileNamePrefix + algorithms[a]->getName() + ".xml",
0892 preciseXMLFormat,
0893 saveXMLUncertainties,
0894 true,
0895 true,
0896 true,
0897 true);
0898 }
0899
0900
0901 CTPPSRPAlignmentCorrectionsData cumulativeAlignments;
0902
0903 cumulativeAlignments.addCorrections(initialAlignments, false, true, true);
0904 cumulativeAlignments.addCorrections(convertedAlignments, false, true, true);
0905
0906
0907 if (!expandedFileNamePrefix.empty() || !factoredFileNamePrefix.empty()) {
0908 CTPPSRPAlignmentCorrectionsData expandedAlignments;
0909 CTPPSRPAlignmentCorrectionsData factoredAlignments;
0910
0911 if (verbosity)
0912 printf(">> Factorizing results of %s algorithm\n", algorithms[a]->getName().c_str());
0913
0914 const bool equalWeights = false;
0915 factorRPFromSensorCorrections(
0916 cumulativeAlignments, expandedAlignments, factoredAlignments, task.geometry, equalWeights, verbosity);
0917
0918 if (!expandedFileNamePrefix.empty()) {
0919 CTPPSRPAlignmentCorrectionsMethods::writeToXML(expandedAlignments,
0920 expandedFileNamePrefix + algorithms[a]->getName() + ".xml",
0921 preciseXMLFormat,
0922 saveXMLUncertainties,
0923 true,
0924 true,
0925 true,
0926 true);
0927 }
0928
0929 if (!factoredFileNamePrefix.empty()) {
0930 CTPPSRPAlignmentCorrectionsMethods::writeToXML(factoredAlignments,
0931 factoredFileNamePrefix + algorithms[a]->getName() + ".xml",
0932 preciseXMLFormat,
0933 saveXMLUncertainties,
0934 true,
0935 true,
0936 true,
0937 true);
0938 }
0939 }
0940 }
0941
0942
0943 for (const auto &algorithm : algorithms)
0944 algorithm->end();
0945 }
0946
0947
0948
0949 string StraightTrackAlignment::setToString(const set<unsigned int> &s) {
0950 unsigned int N = s.size();
0951 if (N == 0)
0952 return "empty";
0953
0954 string str;
0955 char buf[10];
0956 unsigned int i = 0;
0957 for (set<unsigned int>::iterator it = s.begin(); it != s.end(); ++it, ++i) {
0958 sprintf(buf, "%u", *it);
0959 str += buf;
0960 if (i < N - 1)
0961 str += ", ";
0962 }
0963
0964 return str;
0965 }
0966
0967
0968
0969 void StraightTrackAlignment::printN(const char *str, unsigned int N) {
0970 for (unsigned int i = 0; i < N; i++)
0971 printf("%s", str);
0972 }
0973
0974
0975
0976 void StraightTrackAlignment::printLineSeparator(const std::vector<std::map<unsigned int, AlignmentResult> > &results) {
0977 printf("═════════════════════════╬");
0978 for (unsigned int q = 0; q < task.quantityClasses.size(); q++) {
0979 for (unsigned int a = 0; a < results.size(); a++) {
0980 printN("═", algorithms[a]->hasErrorEstimate() ? 18 : 8);
0981 if (a + 1 != results.size())
0982 printf("═");
0983 }
0984 printf("╬");
0985 }
0986 printf("\n");
0987 }
0988
0989
0990
0991 void StraightTrackAlignment::printQuantitiesLine(const std::vector<std::map<unsigned int, AlignmentResult> > &results) {
0992 printf(" ║");
0993
0994 for (unsigned int q = 0; q < task.quantityClasses.size(); q++) {
0995 unsigned int size = 0;
0996 for (unsigned int a = 0; a < results.size(); a++)
0997 size += (algorithms[a]->hasErrorEstimate()) ? 18 : 8;
0998 size += algorithms.size() - 1;
0999
1000 const string &tag = task.quantityClassTag(task.quantityClasses[q]);
1001 unsigned int space = (size - tag.size()) / 2;
1002 printN(" ", space);
1003 printf("%s", tag.c_str());
1004 printN(" ", size - space - tag.size());
1005 printf("║");
1006 }
1007 printf("\n");
1008 }
1009
1010
1011
1012 void StraightTrackAlignment::printAlgorithmsLine(const std::vector<std::map<unsigned int, AlignmentResult> > &results) {
1013 printf(" ║");
1014
1015 for (unsigned int q = 0; q < task.quantityClasses.size(); q++) {
1016 for (unsigned int a = 0; a < results.size(); a++) {
1017 printf((algorithms[a]->hasErrorEstimate()) ? "%18s" : "%8s", algorithms[a]->getName().substr(0, 8).c_str());
1018
1019 if (a + 1 == results.size())
1020 printf("║");
1021 else
1022 printf("│");
1023 }
1024 }
1025 printf("\n");
1026 }
1027
1028
1029
1030 void StraightTrackAlignment::saveDiagnostics() const {
1031 if (diagnosticsFile.empty())
1032 return;
1033
1034 TFile *df = new TFile(diagnosticsFile.c_str(), "recreate");
1035 if (df->IsZombie())
1036 throw cms::Exception("PPS") << "Cannot open file `" << diagnosticsFile << "' for writing.";
1037
1038 if (buildDiagnosticPlots) {
1039 TDirectory *commonDir = df->mkdir("common");
1040 gDirectory = commonDir;
1041
1042 fitNdfHist_fitted->Write();
1043 fitNdfHist_selected->Write();
1044 fitAxHist_fitted->Write();
1045 fitAyHist_fitted->Write();
1046 fitAxHist_selected->Write();
1047 fitAyHist_selected->Write();
1048 fitBxHist_fitted->Write();
1049 fitByHist_fitted->Write();
1050 fitBxHist_selected->Write();
1051 fitByHist_selected->Write();
1052 fitPHist_fitted->Write();
1053 fitPHist_selected->Write();
1054
1055 gDirectory = commonDir->mkdir("plots global");
1056 globalPlots.write();
1057
1058 TDirectory *ppsDir = commonDir->mkdir("plots per RP set");
1059 for (map<set<unsigned int>, RPSetPlots>::const_iterator it = rpSetPlots.begin(); it != rpSetPlots.end(); ++it) {
1060 gDirectory = ppsDir->mkdir(setToString(it->first).c_str());
1061
1062 it->second.write();
1063 }
1064
1065 TDirectory *resDir = commonDir->mkdir("residuals");
1066 for (map<unsigned int, ResiduaHistogramSet>::const_iterator it = residuaHistograms.begin();
1067 it != residuaHistograms.end();
1068 ++it) {
1069 char buf[10];
1070 sprintf(buf, "%u", it->first);
1071 gDirectory = resDir->mkdir(buf);
1072 it->second.total_fitted->Write();
1073 it->second.total_selected->Write();
1074 it->second.selected_vs_chiSq->Write();
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084 gDirectory = gDirectory->mkdir("selected per RP set");
1085 TCanvas *c = new TCanvas;
1086 c->SetName("alltogether");
1087 unsigned int idx = 0;
1088 for (map<set<unsigned int>, TH1D *>::const_iterator sit = it->second.perRPSet_selected.begin();
1089 sit != it->second.perRPSet_selected.end();
1090 ++sit, ++idx) {
1091 sit->second->SetLineColor(idx + 1);
1092 sit->second->Draw((idx == 0) ? "" : "same");
1093 sit->second->Write();
1094 }
1095 c->Write();
1096 }
1097 }
1098
1099
1100 for (vector<AlignmentAlgorithm *>::const_iterator it = algorithms.begin(); it != algorithms.end(); ++it) {
1101 TDirectory *algDir = df->mkdir((*it)->getName().c_str());
1102 (*it)->saveDiagnostics(algDir);
1103 }
1104
1105 delete df;
1106 }