ATLAS Offline Software
Loading...
Searching...
No Matches
PatternVisualizationTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
5
10
13
18
19#include "Acts/Utilities/Helpers.hpp"
20
21#include <format>
22#include <sstream>
23#include <filesystem>
24
25
26#include "TH1F.h"
27#include "TH2F.h"
28#include "TMarker.h"
29#include "TColor.h"
30namespace {
31 constexpr int truthColor = kOrange +2;
32 constexpr int parLineColor = kRed;
33 using SpacePointSet = std::unordered_set<const MuonR4::SpacePoint*>;
34}
35
36
37namespace MuonValR4 {
38 using namespace MuonR4;
39 using namespace SegmentFit;
41
43 if (m_canvasLimit > 0) {
44 m_clientToken.canvasLimit = m_canvasLimit;
45 m_clientToken.preFixName = m_canvasPrefix;
46 m_clientToken.saveSinglePlots = m_saveSinglePDFs;
47 m_clientToken.saveSummaryPlot = m_saveSummaryPDF;
48 m_clientToken.subDirectory = m_subDir;
49 ATH_CHECK(m_visualSvc.retrieve());
50 ATH_CHECK(m_visualSvc->registerClient(m_clientToken));
51 } else {
52 m_plotsDone = true;
53 }
54 ATH_CHECK(m_prepContainerKeys.initialize(!m_truthSegLinks.empty()));
56 ATH_MSG_INFO("Hits linked to the following segment decorations are considered as truth");
57 for (const std::string& decorName : m_truthSegLinks) {
58 ATH_MSG_INFO(" **** "<<decorName);
59 if (decorName.empty()) {
60 ATH_MSG_FATAL("Decoration must not be empty");
61 return StatusCode::FAILURE;
62 }
64 m_truthLinkDecorKeys.emplace_back(key, decorName);
65 m_truthLinkDecors.push_back(SegLinkDecor_t{decorName});
66 }
67 }
68 ATH_CHECK(m_truthLinkDecorKeys.initialize());
69 m_displayOnlyTruth.value() &= !m_truthLinkDecorKeys.empty();
70
71 ATH_CHECK(m_idHelperSvc.retrieve());
72 ATH_CHECK(m_geoCtxKey.initialize());
73 ATH_CHECK(detStore()->retrieve(m_detMgr));
74 return StatusCode::SUCCESS;
75 }
81 return std::find_if(m_truthLinkDecors.begin(), m_truthLinkDecors.end(),
82 [&hit](const SegLinkDecor_t& decor){
83 return !decor(hit).empty();
84 }) != m_truthLinkDecors.end();
85 }
86
87 LabeledSegmentSet PatternVisualizationTool::getLabeledSegments(const std::vector<const MuonR4::SpacePoint*>& hits) const {
88 std::vector<const xAOD::UncalibratedMeasurement*> measurements{};
89 measurements.reserve(2* hits.size());
90 for (const SpacePoint* hit: hits) {
91 measurements.push_back(hit->primaryMeasurement());
92 if(hit->secondaryMeasurement()) {
93 measurements.push_back(hit->secondaryMeasurement());
94 }
95 }
96 return getLabeledSegments(measurements);
97 }
98 LabeledSegmentSet PatternVisualizationTool::getLabeledSegments(const std::vector<const xAOD::UncalibratedMeasurement*>& hits) const {
99 LabeledSegmentSet truthSegs{};
100 for (const xAOD::UncalibratedMeasurement* hit : hits) {
101 for (const SegLinkDecor_t& decor: m_truthLinkDecors) {
102 for (const SegLink_t& link : decor(*hit)) {
103 truthSegs.insert(*link);
104 }
105 }
106 }
107 return truthSegs;
108 }
109 // void PatternVisualizationTool::drawPrimitives(const TCanvas& can, PrimitiveVec& primitives) const {
110 // const double yLow = can.GetPad(0)->GetUymin();
111 // const double yHigh = can.GetPad(0)->GetUymax();
112 // for (auto& prim : primitives) {
113 // const TObject &primRef = *prim;
114 // if (typeid(primRef) == typeid(TLine)){
115 // TLine* line = static_cast<TLine*>(prim.get());
116 // const Amg::Vector3D linePoint{line->GetX1(), line->GetY1(), 0.};
117 // const Amg::Vector3D lineDir = Amg::Vector3D{(line->GetX2() - line->GetX1()) / (line->GetY2() - line->GetY1()), 1.,0.}.unit();
118
119 // const Amg::Vector3D newHigh = linePoint + Amg::intersect<3>(linePoint, lineDir, Amg::Vector3D::UnitY(), yHigh).value_or(0.) * lineDir;
120 // const Amg::Vector3D newLow = linePoint + Amg::intersect<3>(linePoint, lineDir, Amg::Vector3D::UnitY(), yLow).value_or(0.) * lineDir;
121 // line->SetX1(newLow.x());
122 // line->SetY1(newLow.y());
123 // line->SetX2(newHigh.x());
124 // line->SetY2(newHigh.y());
125 // }
126 // prim->Draw();
127 // }
128 // }
130 const MuonR4::HoughPlane& accumulator,
131 const Acts::HoughTransformUtils::HoughAxisRanges& axisRanges,
132 const MaximumVec& maxima,
133 const std::string& extraLabel) const {
134 PrimitiveVec primitives{};
135 visualizeAccumulator(ctx, accumulator, axisRanges, maxima, extraLabel, std::move(primitives));
136 }
138 const MuonR4::HoughPlane& accumulator,
139 const Acts::HoughTransformUtils::HoughAxisRanges& axisRanges,
140 const MaximumVec& maxima,
141 const std::string& extraLabel,
142 PrimitiveVec&& primitives) const {
143
145 if (m_plotsDone) {
146 return;
147 }
148 if (accumulator.getNonEmptyBins().empty()) {
149 ATH_MSG_WARNING("Hough accumulator is empty");
150 return;
151 }
152
153 auto accHisto = std::make_unique<TH2F>("AccumulatorHisto", "histo",
154 accumulator.nBinsX(), axisRanges.xMin, axisRanges.xMax,
155 accumulator.nBinsY(), axisRanges.yMin, axisRanges.yMax);
156 accHisto->SetDirectory(nullptr);
157
158 std::vector<const SpacePoint*> spacePointsInAcc{};
159 for (const std::size_t bin : accumulator.getNonEmptyBins()) {
160 const auto [xBin, yBin] = accumulator.axisBins(bin);
161 auto hitIds = accumulator.hitIds(xBin, yBin);
162 spacePointsInAcc.insert(spacePointsInAcc.end(),hitIds.begin(), hitIds.end());
163 accHisto->SetBinContent(xBin+1, yBin+1, accumulator.nHits(bin));
164 }
165
166 const LabeledSegmentSet truthSegs{getLabeledSegments(spacePointsInAcc)};
167 if (truthSegs.empty() && m_displayOnlyTruth) {
168 return;
169 }
170 auto canvas = m_visualSvc->prepareCanvas(ctx, m_clientToken, extraLabel);
171 if (!canvas){
172 m_plotsDone = true;
173 return;
174 }
175 canvas->expandPad(axisRanges.xMin, axisRanges.yMin);
176 canvas->expandPad(axisRanges.xMax, axisRanges.yMax);
177 canvas->setAxisTitles(std::format("tan#{}", m_accumlIsEta ? "beta" : "#alpha"),
178 std::format("{:}_{{0}} [mm]", m_accumlIsEta ? "y" : "x"));
179 canvas->add(std::move(accHisto), "HIST SAME");
180
181 for (const xAOD::MuonSegment* segment : truthSegs) {
182 const auto [pos, dir] = makeLine(localSegmentPars(*segment));
183 const double tan = m_accumlIsEta ? houghTanBeta(dir) : houghTanAlpha(dir);
184 const double icept = pos[m_accumlIsEta ? objViewEta : objViewPhi];
185 auto truthMarker = std::make_unique<TMarker>(tan, icept, kFullCrossX);
186 truthMarker->SetMarkerColor(truthColor);
187 truthMarker->SetMarkerSize(8);
188 canvas->add(std::move(truthMarker));
189 canvas->add(drawLabel(std::format("true parameters: {:}",
190 makeLabel(localSegmentPars(*segment))),0.2, 0.9));
191 }
192 for (const auto& maximum : maxima) {
193 auto maxMarker = std::make_unique<TMarker>(maximum.x, maximum.y, kFullTriangleUp);
194 maxMarker->SetMarkerColor(parLineColor);
195 maxMarker->SetMarkerSize(8);
196 canvas->add(std::move(maxMarker));
197 }
198 canvas->add(std::move(primitives));
199 }
200 void PatternVisualizationTool::paintSimHits(const EventContext& ctx,
201 const xAOD::MuonSegment& truthSeg,
202 Canvas_t& canvas,
203 const int view) const {
204 if (!m_paintTruthHits) {
205 return;
206 }
207 auto truthHits = getMatchingSimHits(truthSeg);
208 const ActsTrk::GeometryContext* geoCtx{nullptr};
209 if (!SG::get(geoCtx, m_geoCtxKey, ctx).isSuccess()) {
210 return;
211 }
212 for (const xAOD::MuonSimHit* simHit : truthHits) {
213 const MuonGMR4::MuonReadoutElement* re = m_detMgr->getReadoutElement(simHit->identify());
214 const IdentifierHash hash = re->detectorType() == ActsTrk::DetectorType::Mdt ?
215 re->measurementHash(simHit->identify()) :
216 re->layerHash(simHit->identify());
217 const Amg::Transform3D trf = re->msSector()->globalToLocalTrans(*geoCtx) *
218 re->localToGlobalTrans(*geoCtx, hash);
219 const Amg::Vector3D locPos = trf * xAOD::toEigen(simHit->localPosition());
220 const Amg::Vector3D locDir = trf.linear() * xAOD::toEigen(simHit->localDirection());
221 canvas.add(drawArrow(locPos, locDir, truthColor, kDashed, view));
222 }
223 }
224 void PatternVisualizationTool::visualizeSeed(const EventContext& ctx,
225 const MuonR4::SegmentSeed& seed,
226 const std::string& extraLabel) const {
227 PrimitiveVec primitives{};
228 visualizeSeed(ctx, seed, extraLabel, std::move(primitives));
229 }
230 void PatternVisualizationTool::visualizeSeed(const EventContext& ctx,
231 const MuonR4::SegmentSeed& seed,
232 const std::string& extraLabel,
233 PrimitiveVec&& primitives) const {
234
236 if (m_plotsDone) {
237 return;
238 }
239 const LabeledSegmentSet truthSegs{getLabeledSegments(seed.getHitsInMax())};
240 if (truthSegs.empty() && m_displayOnlyTruth) {
241 return;
242 }
243
244 auto canvas = m_visualSvc->prepareCanvas(ctx, m_clientToken, extraLabel);
245 if (!canvas) {
246 m_plotsDone = true;
247 return;
248 }
249 canvas->add(std::move(primitives));
250
251
252 for (const int view : {objViewEta, objViewPhi}) {
253 if ((view == objViewEta && !m_doEtaBucketViews) ||
254 (view == objViewPhi && !m_doPhiBucketViews)){
255 continue;
256 }
257 canvas->setAxisTitles(std::format("{:} [mm]", view == objViewEta ? 'y' : 'x'), "z [mm]");
258
259 if (!drawHits(*seed.parentBucket(), seed.getHitsInMax(), *canvas, view)) {
260 continue;
261 }
262 for (const xAOD::MuonSegment* segment : truthSegs) {
263 canvas->add(drawLine(localSegmentPars(*segment),
264 canvas->corner(Edges::yLow), canvas->corner(Edges::yHigh),
265 truthColor, kDotted, view));
266 paintSimHits(ctx,*segment, *canvas, view);
267 }
268 canvas->add(drawLine(seed.parameters(), canvas->corner(Edges::yLow),
269 canvas->corner(Edges::yHigh), parLineColor, kDashed, view));
270
271 writeChi2(seed.parameters(), seed.getHitsInMax(), *canvas);
272
273 std::string legendLabel = std::format("Event: {:}, chamber : {:}, #{:}-view ({:})",
274 ctx.eventID().event_number(),
275 m_idHelperSvc->toStringChamber(seed.getHitsInMax().front()->identify()),
276 view ==objViewEta ? "eta" : "phi",
277 extraLabel);
278 canvas->add(drawLabel(legendLabel, 0.1, 0.96));
279 canvas->add(drawLabel(makeLabel(seed.parameters()),0.25, 0.89));
280 }
281 }
282
283 void PatternVisualizationTool::visualizeBucket(const EventContext& ctx,
284 const MuonR4::SpacePointBucket& bucket,
285 const std::string& extraLabel) const {
286 PrimitiveVec primitives{};
287 visualizeBucket(ctx, bucket, extraLabel, std::move(primitives));
288 }
289 void PatternVisualizationTool::visualizeBucket(const EventContext& ctx,
290 const MuonR4::SpacePointBucket& bucket,
291 const std::string& extraLabel,
292 PrimitiveVec&& primitives) const {
294 if (m_plotsDone) {
295 return;
296 }
297
298 LabeledSegmentSet truthSegs{getLabeledSegments(Acts::unpackConstSmartPointers(bucket))};
299 if (truthSegs.empty() && m_displayOnlyTruth) {
300 return;
301 }
302 auto canvas = m_visualSvc->prepareCanvas(ctx, m_clientToken, extraLabel);
303 if (!canvas){
304 m_plotsDone = true;
305 return;
306 }
307 canvas->add(std::move(primitives));
308
309 for (const int view : {objViewEta, objViewPhi}) {
310 if ((view == objViewEta && !m_doEtaBucketViews) ||
311 (view == objViewPhi && !m_doPhiBucketViews)){
312 continue;
313 }
314 canvas->setAxisTitles(std::format("{:} [mm]", view == objViewEta ? 'y' : 'x'), "z [mm]");
316 if (!drawHits(bucket, bucket, *canvas, view)) {
317 continue;
318 }
319 bool drawnTrueLabel{false};
320 for (const xAOD::MuonSegment* segment : truthSegs) {
321 canvas->add(drawLine(localSegmentPars(*segment),
322 canvas->corner(Edges::yLow), canvas->corner(Edges::yHigh),
323 truthColor, kDotted, view));
324 if (!drawnTrueLabel) {
325 canvas->add(drawLabel(std::format("true parameters: {:}",makeLabel(localSegmentPars(*segment))),0.2, 0.89));
326 drawnTrueLabel = true;
327 }
328 paintSimHits(ctx,*segment, *canvas, view);
329 }
330
331 std::string legendLabel = std::format("Event: {:}, chamber : {:}, #{:}-view ({:})",
332 ctx.eventID().event_number(),
333 bucket.msSector()->identString(),
334 view ==objViewEta ? "eta" : "phi",
335 extraLabel);
336 canvas->add(drawLabel(legendLabel, 0.15, 0.96));
337 }
338 }
339
340 void PatternVisualizationTool::visualizeSegment(const EventContext& ctx,
341 const MuonR4::Segment& segment,
342 const std::string& extraLabel) const {
343 PrimitiveVec primitives{};
344 visualizeSegment(ctx, segment,extraLabel, std::move(primitives));
345 }
346
347 void PatternVisualizationTool::visualizeSegment(const EventContext& ctx,
348 const MuonR4::Segment& segment,
349 const std::string& extraLabel,
350 PrimitiveVec&& primitives) const {
352 if (m_plotsDone) {
353 return;
354 }
355
356 const LabeledSegmentSet truthSegs{getLabeledSegments(segment.parent()->getHitsInMax())};
357 if (truthSegs.empty() && m_displayOnlyTruth) {
358 return;
359 }
360 const ActsTrk::GeometryContext* geoCtx{nullptr};
361 if (!SG::get(geoCtx, m_geoCtxKey, ctx).isSuccess()) {
362 return;
363 }
364 auto canvas = m_visualSvc->prepareCanvas(ctx, m_clientToken, extraLabel);
365 if (!canvas) {
366 m_plotsDone = true;
367 return;
368 }
369 canvas->add(std::move(primitives));
370
371
372 const Parameters segPars = SegmentFit::localSegmentPars(*geoCtx, segment);
373
374 for (const int view : {objViewEta, objViewPhi}) {
375 if ((view == objViewEta && !m_doEtaBucketViews) ||
376 (view == objViewPhi && !m_doPhiBucketViews)){
377 continue;
378 }
379 canvas->setAxisTitles(std::format("{:} [mm]", view == objViewEta ? 'y' : 'x'), "z [mm]");
380 if (!drawHits(*segment.parent()->parentBucket(), segment.measurements(),
381 *canvas, view)) {
382 continue;
383 }
384 for (const xAOD::MuonSegment* segment : truthSegs) {
385 canvas->add(drawLine(localSegmentPars(*segment), canvas->corner(Edges::yLow), canvas->corner(Edges::yHigh),
386 truthColor, kDotted, view));
387 paintSimHits(ctx,*segment, *canvas, view);
388 }
389 writeChi2(segPars, segment.measurements(), *canvas);
390
391 canvas->add(drawLine(segPars, canvas->corner(Edges::yLow), canvas->corner(Edges::yHigh),
392 parLineColor, kDashed, view));
393
394 const Identifier canvasId{segment.parent()->getHitsInMax().front()->identify()};
395 std::string legendLabel=std::format("Event: {:}, chamber: {:}, #chi^{{2}} / nDoF: {:.2f} ({:d}), #{:}-view (:)",
396 ctx.eventID().event_number(), m_idHelperSvc->toStringChamber(canvasId),
397 segment.chi2() /std::max(1u, segment.nDoF()), segment.nDoF(),
398 view ==objViewEta ? "eta" : "phi", extraLabel);
399
400 canvas->add(drawLabel(legendLabel, 0.2, 0.96));
401 canvas->add(drawLabel(makeLabel(segPars),0.25, 0.91));
402 }
403 }
404
405 template<class SpacePointType>
406 const SpacePoint*
407 PatternVisualizationTool::drawHit(const SpacePointType& hit, Canvas_t& canvas,
408 const unsigned int view,
409 unsigned int fillStyle) const {
410
412 if ((view == objViewEta && !hit.measuresEta()) || (view == objViewPhi && !hit.measuresPhi())) {
413 return nullptr;
414 }
415
416 if (hit.type() != xAOD::UncalibMeasType::Other) {
417 canvas.expandPad(hit.localPosition()[view] - hit.driftRadius(),
418 hit.localPosition().z() - hit.driftRadius());
419 canvas.expandPad(hit.localPosition()[view] + hit.driftRadius(),
420 hit.localPosition().z() + hit.driftRadius());
421 }
422
423 const SpacePoint* underlyingSp{nullptr};
425 constexpr int invalidCalibFill = 3305;
426 if constexpr (std::is_same_v<SpacePointType, SpacePoint>) {
427 underlyingSp = &hit;
429 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(hit.primaryMeasurement());
430 if (dc->status() != Muon::MdtDriftCircleStatus::MdtStatusDriftTime) {
431 fillStyle = invalidCalibFill;
432 }
433 }
434 } else if constexpr(std::is_same_v<SpacePointType, CalibratedSpacePoint>) {
435 underlyingSp = hit.spacePoint();
436 if (hit.fitState() == CalibratedSpacePoint::State::Valid) {
437 fillStyle = fullFilling;
438 } else if (hit.fitState() == CalibratedSpacePoint::State::FailedCalib) {
439 fillStyle = invalidCalibFill;
440 } else {
441 fillStyle = hatchedFilling;
442 }
443 }
444 switch(hit.type()) {
446 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(underlyingSp->primaryMeasurement());
447 canvas.add(drawDriftCircle(hit.localPosition(), dc->readoutElement()->innerTubeRadius(),
448 kBlack, hollowFilling));
449
450 const int circColor = isLabeled(*dc) ? truthColor : kBlue;
451 canvas.add(drawDriftCircle(hit.localPosition(), hit.driftRadius(), circColor, fillStyle));
452 break;
454 const auto* meas{static_cast<const xAOD::RpcMeasurement*>(underlyingSp->primaryMeasurement())};
455 const int boxColor = isLabeled(*meas) ? truthColor : kGreen +2;
456 const double boxWidth = 0.5*std::sqrt(12)*std::sqrt(underlyingSp->covariance()[view]);
457 canvas.add(drawBox(hit.localPosition(), boxWidth, 0.5*meas->readoutElement()->gasGapPitch(),
458 boxColor, fillStyle));
459 break;
461 const auto* meas{static_cast<const xAOD::TgcStrip*>(underlyingSp->primaryMeasurement())};
462 const int boxColor = isLabeled(*meas) ? truthColor : kCyan + 2;
463 const double boxWidth = 0.5*std::sqrt(12)*std::sqrt(underlyingSp->covariance()[view]);
464 canvas.add(drawBox(hit.localPosition(), boxWidth, 0.5*meas->readoutElement()->gasGapPitch(),
465 boxColor, fillStyle));
466 break;
468 const int boxColor = isLabeled(*underlyingSp->primaryMeasurement()) ? truthColor : kAquamarine;
469 const double boxWidth = 5*Gaudi::Units::mm;
470 canvas.add(drawBox(hit.localPosition(), boxWidth, 10.*Gaudi::Units::mm, boxColor, fillStyle));
471 break;
473 break;
475 const int boxColor = isLabeled(*underlyingSp->primaryMeasurement()) ? truthColor : kTeal;
476 const double boxWidth = 5*Gaudi::Units::mm;
477 canvas.add(drawBox(hit.localPosition(), boxWidth, 10.*Gaudi::Units::mm, boxColor, fillStyle));
478 break;
479 } default: {
480 ATH_MSG_WARNING("Please implement proper drawings of the new small wheel.. "<<__FILE__<<":"<<__LINE__);
481 break;
482 }
483 }
484 return underlyingSp;
485 }
486
487 template<class SpacePointType>
489 const std::vector<SpacePointType>& hitsToDraw,
490 Canvas_t& canvas,
491 unsigned int view) const {
492
493 SpacePointSet drawnPoints{};
494 for (const SpacePointType& hit : hitsToDraw) {
495 drawnPoints.insert(drawHit(*hit, canvas, view, fullFilling));
496 }
497 if (m_displayBucket) {
498 for (const SpacePointBucket::value_type& hit : bucket) {
499 // Don't redraw the other points
500 if (drawnPoints.count(hit.get())) {
501 continue;
502 }
503 drawHit(*hit, canvas, view, hollowFilling);
504 }
505 }
506 return drawnPoints.size() - drawnPoints.count(nullptr) > 1;
507 }
508 template<class SpacePointType>
510 const std::vector<SpacePointType>& hits,
511 Canvas_t& canvas,
512 const double legX, double startLegY,
513 const double endLegY) const {
514 const auto [pos, dir] = makeLine(pars);
515
516 for (const SpacePointType& hit : hits) {
517 const SpacePoint* underlyingSp{nullptr};
518 bool displayChi2{true};
519 if constexpr(std::is_same_v<SpacePointType, Segment::MeasType>) {
520 underlyingSp = hit->spacePoint();
521 displayChi2 = (hit->fitState() == CalibratedSpacePoint::State::Valid);
522 } else {
523 underlyingSp = hit;
524 }
525 const Identifier hitId = underlyingSp ? underlyingSp->identify(): Identifier{};
526 std::string legendstream{};
527 switch(hit->type()) {
529 const int driftSign{SeedingAux::strawSign(pos, dir, *hit)};
530 const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
531 legendstream = std::format("ML: {:1d}, TL: {:1d}, T: {:3d}, {:}",
532 idHelper.multilayer(hitId), idHelper.tubeLayer(hitId),
533 idHelper.tube(hitId), driftSign == -1 ? "L" : "R");
534 break;
536 const RpcIdHelper& idHelper{m_idHelperSvc->rpcIdHelper()};
537 legendstream= std::format("DR: {:1d}, DZ: {:1d}, GAP: {:1d}, #eta/#phi: {:}/{:}",
538 idHelper.doubletR(hitId), idHelper.doubletZ(hitId), idHelper.gasGap(hitId),
539 hit->measuresEta() ? "si" : "nay", hit->measuresPhi() ? "si" : "nay");
540 break;
542 const TgcIdHelper& idHelper{m_idHelperSvc->tgcIdHelper()};
543 legendstream = std::format("ST: {:}, GAP: {:1d}, #eta/#phi: {:}/{:}",
544 m_idHelperSvc->stationNameString(hitId), idHelper.gasGap(hitId),
545 hit->measuresEta() ? "si" : "nay", hit->measuresPhi() ? "si" : "nay");
546 break;
548 const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
549 const auto* clus = static_cast<const xAOD::MMCluster*>(underlyingSp->primaryMeasurement());
550 const MuonGMR4::StripDesign& design = clus->readoutElement()->stripLayer(clus->layerHash()).design();
551 legendstream = std::format("ML: {:1d}, GAP: {:1d}, {:}", idHelper.multilayer(hitId), idHelper.gasGap(hitId),
552 !design.hasStereoAngle() ? "X" : design.stereoAngle() > 0 ? "U" :"V");
553 break;
555 const sTgcIdHelper& idHelper{m_idHelperSvc->stgcIdHelper()};
556 legendstream = std::format("ML: {:1d}, GAP: {:1d}, #eta/#phi: {:}/{:}",
557 idHelper.multilayer(hitId), idHelper.gasGap(hitId),
558 hit->measuresEta() ? "si" : "nay", hit->measuresPhi() ? "si" : "nay");
559 break;
561 legendstream = "Ext. constaint";
562 }
563 default:
564 break;
565 }
566 if (displayChi2) {
567 const double chi2 = SeedingAux::chi2Term(pos, dir,*hit);
568 legendstream+=std::format(", #chi^{{2}}: {:.2f}", chi2);
569 } else {
570 legendstream+=", #chi^{2}: ---";
571 }
572 canvas.add(drawLabel(legendstream, legX, startLegY, 14));
573 startLegY -= 0.05;
574 if (startLegY<= endLegY) {
575 break;
576 }
577 }
578 }
579}
const boost::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
This is a "hash" representation of an Identifier.
int multilayer(const Identifier &id) const
Access to components of the ID.
int tube(const Identifier &id) const
int tubeLayer(const Identifier &id) const
int gasGap(const Identifier &id) const override
get the hashes
int multilayer(const Identifier &id) const
The MuonReadoutElement is an abstract class representing the geometry representing the muon detector.
std::string identString() const
Returns a string encoding the chamber index & the sector of the MS sector.
double stereoAngle() const
Returns the value of the stereo angle.
bool hasStereoAngle() const
Returns whether a stereo angle is defined.
Representation of a segment seed (a fully processed hough maximum) produced by the hough transform.
Definition SegmentSeed.h:14
const std::vector< HitType > & getHitsInMax() const
Returns the list of assigned hits.
const SpacePointBucket * parentBucket() const
Returns the bucket out of which the seed was formed.
Placeholder for what will later be the muon segment EDM representation.
unsigned int nDoF() const
Returns the number of degrees of freedom.
const SegmentSeed * parent() const
Returns the seed out of which the segment was built.
const MeasVec & measurements() const
Returns the associated measurements.
: The muon space point bucket represents a collection of points that will bre processed together in t...
const MuonGMR4::SpectrometerSector * msSector() const
returns th associated muonChamber
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
const xAOD::UncalibratedMeasurement * secondaryMeasurement() const
const Identifier & identify() const
: Identifier of the primary measurement
const Cov_t & covariance() const
Returns the covariance array.
const xAOD::UncalibratedMeasurement * primaryMeasurement() const
Gaudi::Property< std::string > m_subDir
Define the subdirectory in which the plots shall be saved.
Gaudi::Property< bool > m_doEtaBucketViews
Switch to visualize the eta view of the bucket event.
virtual StatusCode initialize() override final
Gaudi::Property< bool > m_accumlIsEta
Swtich toggling whether the accumulator view are in the eta or phi plane.
virtual void visualizeAccumulator(const EventContext &ctx, const MuonR4::HoughPlane &accumulator, const Acts::HoughTransformUtils::HoughAxisRanges &axisRanges, const MaximumVec &maxima, const std::string &extraLabel) const override final
virtual void visualizeSegment(const EventContext &ctx, const MuonR4::Segment &segment, const std::string &extraLabel) const override final
Gaudi::Property< unsigned int > m_canvasLimit
Maximum canvases to draw.
Gaudi::Property< bool > m_displayBucket
Display the surrounding hits from the bucket not part of the seed.
Gaudi::Property< std::string > m_canvasPrefix
Prefix of the individual canvas file names <MANDATORY>
virtual void visualizeBucket(const EventContext &ctx, const MuonR4::SpacePointBucket &bucket, const std::string &extraLabel) const override final
Gaudi::Property< bool > m_saveSinglePDFs
If set to true each canvas is saved into a dedicated pdf file.
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
Geometry context key to retrieve the alignment.
std::unordered_set< const xAOD::MuonSegment * > LabeledSegmentSet
virtual void visualizeSeed(const EventContext &ctx, const MuonR4::SegmentSeed &seed, const std::string &extraLabel) const override final
IRootVisualizationService::ClientToken m_clientToken
Token to present to the visualization service such that the display froms this tool are grouped toget...
std::vector< SegLinkDecor_t > m_truthLinkDecors
Gaudi::Property< bool > m_doPhiBucketViews
Switch to visualize the phi view of the bucket event.
SG::ReadDecorHandleKeyArray< xAOD::UncalibratedMeasurementContainer > m_truthLinkDecorKeys
Declaration of the dependency on the decorations.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Service Handle to the IMuonIdHelperSvc.
SG::ReadHandleKeyArray< xAOD::UncalibratedMeasurementContainer > m_prepContainerKeys
Declare dependency on the prep data containers.
bool drawHits(const MuonR4::SpacePointBucket &bucket, const std::vector< SpacePointType > &hitsToDraw, Canvas_t &canvasDim, unsigned int view) const
Translates the Spacepoint information into TObjects that are dawn on the canvas & evaluates the size ...
virtual LabeledSegmentSet getLabeledSegments(const std::vector< const MuonR4::SpacePoint * > &hits) const override final
Returns whether the hit has been used on the labeled segments we refer to (e.g.
IRootVisualizationService::ICanvasObject Canvas_t
Gaudi::Property< std::set< std::string > > m_truthSegLinks
List of truth segment links to fetch.
void paintSimHits(const EventContext &ctx, const xAOD::MuonSegment &truthSeg, Canvas_t &canvas, const int view) const
Paints the truth sim hits associated with the segment.
ElementLink< xAOD::MuonSegmentContainer > SegLink_t
ServiceHandle< IRootVisualizationService > m_visualSvc
Service handle of the visualization service.
virtual bool isLabeled(const MuonR4::SpacePoint &hit) const override final
Fetches all labeled (e.g.
Gaudi::Property< bool > m_saveSummaryPDF
If set to true a summary Canvas is created.
const MuonR4::SpacePoint * drawHit(const SpacePointType &hit, Canvas_t &canvas, const unsigned int view, unsigned int fillStyle) const
Converts a Hit into a particular TBox/ TEllipse for drawing.
void writeChi2(const MuonR4::SegmentFit::Parameters &pars, const std::vector< SpacePointType > &hits, Canvas_t &canvas, const double legX=0.2, double startLegY=0.8, const double endLegY=0.3) const
Writes the chi2 of the hits onto the Canvas.
const MuonGMR4::MuonDetectorManager * m_detMgr
pointer to the Detector manager
Gaudi::Property< bool > m_paintTruthHits
Switch to visualize the truth hits.
std::atomic< bool > m_plotsDone
Flag toggling whether all Canvases have been exhausted.
SG::AuxElement::ConstAccessor< SegLinkVec_t > SegLinkDecor_t
int gasGap(const Identifier &id) const override
get the hashes
int doubletR(const Identifier &id) const
int doubletZ(const Identifier &id) const
Property holding a SG store/key/clid from which a ReadHandle is made.
int gasGap(const Identifier &id) const override
get the hashes
int multilayer(const Identifier &id) const
int gasGap(const Identifier &id) const override
get the hashes
double chi2(TH1 *h0, TH1 *h1)
@ Mdt
MuonSpectrometer.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
std::pair< Amg::Vector3D, Amg::Vector3D > makeLine(const Parameters &pars)
Returns the parsed parameters into an Eigen line parametrization.
Acts::Experimental::CompositeSpacePointLineFitter::ParamVec_t Parameters
std::string makeLabel(const Parameters &pars)
Dumps the parameters into a string in the form of TLatex.
double houghTanBeta(const Amg::Vector3D &v)
Returns the hough tanBeta [y] / [z].
std::unordered_set< const xAOD::MuonSimHit * > getMatchingSimHits(const xAOD::MuonSegment &segment)
: Returns all sim hits matched to a xAOD::MuonSegment
MuonValR4::IPatternVisualizationTool::PrimitiveVec PrimitiveVec
Acts::HoughTransformUtils::HoughPlane< HoughHitType > HoughPlane
double houghTanAlpha(const Amg::Vector3D &v)
: Returns the hough tanAlpha [x] / [z]
Lightweight algorithm to read xAOD MDT sim hits and (fast-digitised) drift circles from SG and fill a...
constexpr int objViewEta
ObjectView.
PatternVisualizationTool::LabeledSegmentSet LabeledSegmentSet
constexpr int hollowFilling
Filling codes for hollow / fullFilling / hatched filling.
std::unique_ptr< TLine > drawLine(const MuonR4::SegmentFit::Parameters &pars, const double lowEnd, const double highEnd, const int color=kRed+1, const int lineStyle=kDashed, const int view=objViewEta)
Draws a line from the segment fit parameters.
constexpr int hatchedFilling
std::unique_ptr< TEllipse > drawDriftCircle(const Amg::Vector3D &center, const double radius, const int color=kViolet, const int fillStyle=hollowFilling)
Create a TEllipse for drawing a drift circle.
constexpr int fullFilling
constexpr int objViewPhi
std::unique_ptr< TArrow > drawArrow(const Amg::Vector3D &start, const Amg::Vector3D &dir, const int color=kRed+1, const int lineStyle=kDashed, const int view=objViewEta)
Draw an arror between two endpoints in the y-z or the x-z plane.
std::unique_ptr< TLatex > drawLabel(const std::string &text, const double xPos, const double yPos, const unsigned int fontSize=18)
Create a TLatex label,.
std::unique_ptr< TBox > drawBox(const Amg::Vector3D &boxCenter, const double boxWidth, const double boxHeight, const int color=kGreen+2, const int fillStyle=hollowFilling, const int view=objViewEta)
Creates a box for drawing, e.g strip measurements.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
std::vector< const SpacePoint * > SpacePointSet
vector of space points
Definition FitterTypes.h:38
MdtDriftCircle_v1 MdtDriftCircle
MuonSimHit_v1 MuonSimHit
Defined the version of the MuonSimHit.
Definition MuonSimHit.h:12
TgcStrip_v1 TgcStrip
Definition TgcStripFwd.h:9
RpcMeasurement_v1 RpcMeasurement
MMCluster_v1 MMCluster
MuonSegment_v1 MuonSegment
Reference the current persistent version:
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.