14#include "Acts/Utilities/Helpers.hpp"
19 constexpr int truthColor = kOrange +2;
20 using SpacePointSet = std::unordered_set<const MuonR4::SpacePoint*>;
22 double inDegrees(
double angle) {
23 return angle / Gaudi::Units::deg;
29 using namespace MuonR4;
46 ATH_MSG_INFO(
"Hits linked to the following segment decorations are considered as truth");
49 if (decorName.empty()) {
51 return StatusCode::FAILURE;
65 ATH_MSG_ERROR(
"No bucket view enabled. Please enable at least one of the bucket views to visualize the buckets.");
66 return StatusCode::FAILURE;
69 ATH_MSG_ERROR(
"Multiple bucket views enabled. Please enable only one bucket view.");
70 return StatusCode::FAILURE;
72 return StatusCode::SUCCESS;
81 return !decor(hit).empty();
85 std::vector<const xAOD::UncalibratedMeasurement*> measurements{};
86 measurements.reserve(2* hits.size());
88 measurements.push_back(hit->primaryMeasurement());
89 if(hit->secondaryMeasurement()) {
90 measurements.push_back(hit->secondaryMeasurement());
99 for (
const SegLink_t& link : decor(*hit)) {
100 truthSegs.insert(*link);
107 const std::string& extraLabel,
108 PatternHitVisualInfoVec&& patternVisualVec)
const {
110 plotPatternBuckets(ctx, extraLabel, std::move(patternVisualVec), std::move(primitives));
113 const std::string& extraLabel,
114 PatternHitVisualInfoVec&& patternVisualVec,
116 if (patternVisualVec.empty()) {
117 ATH_MSG_VERBOSE(
"No pattern visual info available. Do not create visualization.");
121 unsigned sPatIdx{0u}, fPatIdx{0u}, oPatIdx{0u};
122 for (PatternHitVisualInfo& patVisual : patternVisualVec) {
124 std::string
label {};
125 switch(patVisual.status) {
126 case PatternHitVisualInfo::PatternStatus::eSuccessful:
127 label = std::format(
"s{}_{}", sPatIdx++, extraLabel);
129 case PatternHitVisualInfo::PatternStatus::eFailed:
130 label = std::format(
"f{}_{}", fPatIdx++, extraLabel);
132 case PatternHitVisualInfo::PatternStatus::eOverlap:
133 label = std::format(
"o{}_{}", oPatIdx++, extraLabel);
140 const std::string& extraLabel,
141 PatternHitVisualInfo&& patternVisual)
const {
147 const std::string& extraLabel,
148 PatternHitVisualInfo&& patternVisual,
151 PatternHitVisualInfo patternVisualCopy {patternVisual};
153 plotPatternBucket(ctx, extraLabel, *bucket, std::move(patternVisualCopy), std::move(extraPaintsCopy));
157 const std::string& extraLabel,
159 PatternHitVisualInfo&& patternVisual,
161 using PatternStatus = FastRecoVisualizationTool::PatternHitVisualInfo::PatternStatus;
162 using HitStatus = FastRecoVisualizationTool::PatternHitVisualInfo::HitStatus;
173 PatternStatus patStatus{patternVisual.status};
180 std::vector<const MuonR4::SpacePoint*> patHitsInBucket{};
184 if (std::ranges::find_if(bucket,
185 [hit](
const std::shared_ptr<MuonR4::SpacePoint>
sp) {
return sp.get() == hit; }) != bucket.end()) {
186 patHitsInBucket.push_back(hit);
200 canvas->add(std::move(extraPaints));
203 throw std::runtime_error(
"Failed to retrieve GeometryContext from EventStore");
215 canvas->setAxisTitles(
"y [mm]",
"z [mm]");
218 canvas->setAxisTitles(
"x [mm]",
"z [mm]");
221 canvas->setAxisTitles(
"z [mm]",
"R [mm]");
224 canvas->setAxisTitles(
"R [mm]",
"z [mm]");
228 if (!
drawHits(bucket, localToGlobalBucket, patHitsInBucket, *canvas, view)) {
235 drawSearchWindow(localToGlobalBucket, lines, patternVisual.thetaSearchMin, patternVisual.thetaSearchMax, *canvas, view);
238 for (
const auto&
sp : bucket) {
241 if (patternVisual.hitLineInfo.find(testHit) == patternVisual.hitLineInfo.end()) {
245 const HitStatus hitStatus {std::ranges::find(patternVisual.discardedHits, testHit) != patternVisual.discardedHits.end() ? HitStatus::eDiscarded :
246 (std::ranges::find(patternVisual.replacedHits, testHit) != patternVisual.replacedHits.end() ? HitStatus::eReplaced : HitStatus::eKept)};
249 const auto& [lineSlope, deltaRWindow] = patternVisual.hitLineInfo.at(testHit);
250 drawLineResidual(*geoCtx, localToGlobalBucket, lines, patternVisual.seed, testHit, lineSlope, deltaRWindow, hitStatus, *canvas, view);
255 auto printOnCanvas = [&lines, &yLegend](
const std::string& text){
256 lines.push_back(
drawLabel(text, 0.2, yLegend, 13));
260 printOnCanvas(std::format(
"Seed hit: {}",
m_idHelperSvc->toString(patternVisual.seed->identify())));
261 printOnCanvas(std::format(
"Chamber: {}",
m_idHelperSvc->toStringChamber(bucket.front()->identify())));
262 printOnCanvas(std::format(
"nPrec: {:d}", pat.nPrecisionHits()));
263 printOnCanvas(std::format(
"nEtaNonPrec: {:d}", pat.nEtaNonPrecisionHits()));
264 printOnCanvas(std::format(
"nPhi: {:d}", pat.nPhiHits()));
265 printOnCanvas(std::format(
"theta: {:.2f}^{{#circ}}", inDegrees(pat.theta())));
266 printOnCanvas(std::format(
"phi: {:.2f}^{{#circ}}", inDegrees(pat.phi())));
267 printOnCanvas(std::format(
"MeanNormResidual: {:.2f}", pat.meanNormResidual2()));
268 printOnCanvas(std::format(
"Status: {}", patStatus == PatternStatus::eSuccessful ?
"Success" : (patStatus == PatternStatus::eFailed ?
"Fail" :
"Overlap")));
269 printOnCanvas(std::format(
"Sector: {:d}", pat.sector()));
270 printOnCanvas(std::format(
"OverlapSector: {:d}", pat.isSectorOverlap() ? pat.secondarySector() : -1));
273 bool drawnTrueLabel{
true};
275 drawSegment(*segment, localToGlobalBucket, lines, drawnTrueLabel, *canvas, view);
276 paintSimHits(*geoCtx, localToGlobalBucket, *segment, lines, view);
278 canvas->add(std::move(lines));
280 std::string legendLabel = std::format(
"Event: {:}, chamber : {:}, #{:}-view ({:})",
281 ctx.eventID().event_number(),
285 canvas->add(
drawLabel(legendLabel, 0.15, 0.96));
289 const double thetaMin,
290 const double thetaMax,
292 const View view)
const {
297 auto addSearchWindowLine = [&outputContainer, &localToGlobalBucket, &view, &canvas,
this](
const double globLineTheta){
298 constexpr double smallAngle {1e-3};
299 if (std::abs(globLineTheta) < smallAngle || std::abs(globLineTheta -
M_PI) < smallAngle) {
301 throw std::runtime_error(
"Unexpected horizontal pattern search line in global frame. Cannot draw search window.");
310 lineDirection = Acts::makeDirectionFromAxisTangents(0., tan(globLineTheta));
311 linePosition = Amg::Vector3D::Zero();
312 lowEnd = view ==
View::objViewZR ? canvas.corner(Edges::yLow) : canvas.corner(Edges::xLow);
313 upEnd = view ==
View::objViewZR ? canvas.corner(Edges::yHigh) : canvas.corner(Edges::xHigh);
316 const double globLinePhi {localToGlobalBucket.translation().phi()};
317 const Amg::Vector3D globLineDir {Acts::makeDirectionFromPhiTheta(globLinePhi,globLineTheta)};
318 lineDirection = localToGlobalBucket.inverse().linear() * globLineDir;
319 linePosition = localToGlobalBucket.inverse() * Amg::Vector3D::Zero();
320 lowEnd = canvas.corner(Edges::yLow);
321 upEnd = canvas.corner(Edges::yHigh);
323 outputContainer.emplace_back(
drawLine(lineDirection, linePosition,
324 lowEnd, upEnd, kOrange, kDashed, view));
326 addSearchWindowLine(thetaMin);
327 addSearchWindowLine(thetaMax);
334 const double lineSlope,
335 const double Rwindow,
336 const PatternHitVisualInfo::HitStatus status,
338 const View view)
const {
339 using HitStatus = PatternHitVisualInfo::HitStatus;
344 if (std::abs(lineSlope) < std::numeric_limits<double>::epsilon()) {
348 auto color {status == HitStatus::eKept ? kGreen : (status == HitStatus::eReplaced ? kPink : kGray)};
351 const Amg::Vector3D lineDir {Acts::makeDirectionFromAxisTangents(0., lineSlope)};
352 const Amg::Vector3D seedGlobalPos {seed->msSector()->localToGlobalTransform(gctx) * seed->localPosition()};
353 const Amg::Vector3D linePos {seedGlobalPos.perp()* Amg::Vector3D::UnitY() + seedGlobalPos.z() * Amg::Vector3D::UnitZ()};
355 const double seedGlobalR {seedGlobalPos.perp()};
356 const double testGlobalR {(localToGlobalBucket * testHit->
localPosition()).perp()};
357 const double testGlobalZ {(localToGlobalBucket * testHit->
localPosition()).z()};
358 const double lineIntercept {linePos.y() - lineSlope * linePos.z()};
359 const double line2WindowInters {lineSlope*testGlobalZ + lineIntercept};
362 if (seedGlobalR < testGlobalR) {
363 lowLimit = (seed->msSector() == testHit->
msSector() ?
364 seedGlobalR : (view ==
View::objViewZR ? canvas.corner(Edges::yLow) : canvas.corner(Edges::xLow)));
365 upLimit = line2WindowInters;
367 upLimit = (seed->msSector() == testHit->
msSector() ?
368 seedGlobalR : (view ==
View::objViewZR ? canvas.corner(Edges::yHigh) : canvas.corner(Edges::xHigh)));
369 lowLimit = line2WindowInters;
371 outputContainer.emplace_back(
drawLine(lineDir, linePos,
372 lowLimit, upLimit,
color, kDashed, view));
376 const Amg::Vector3D barLinePos {testGlobalZ* Amg::Vector3D::UnitZ()};
377 lowLimit = testGlobalR - Rwindow;
378 upLimit = testGlobalR + Rwindow;
379 outputContainer.emplace_back(
drawLine(barLineDir, barLinePos,
380 lowLimit, upLimit,
color, kDotted, view));
383 const double globLineTheta { lineSlope > 0 ? atan(lineSlope) : atan(lineSlope) +
M_PI };
384 const double globLinePhi {localToGlobalBucket.translation().phi()};
385 const Amg::Vector3D globLineDir {Acts::makeDirectionFromPhiTheta(globLinePhi,globLineTheta)};
386 const Amg::Vector3D locLineDir {localToGlobalBucket.inverse().linear() * globLineDir};
388 const Amg::Vector3D seedGlobalPos {seed->msSector()->localToGlobalTransform(gctx) * seed->localPosition()};
389 const Amg::Vector3D seedLocalPos {localToGlobalBucket.inverse() * seedGlobalPos};
393 const double testGlobalR {(localToGlobalBucket * testHit->
localPosition()).perp()};
394 double seedGlobalR {seedGlobalPos.perp()};
395 const bool isBarrel {seed->msSector()->barrel()};
396 const double line2WindowInters {
isBarrel ? Acts::detail::LineHelper::lineIntersect<3>(seedLocalPos, locLineDir, testLocalY* Amg::Vector3D::UnitY(), Amg::Vector3D::UnitZ()).position().z()
397 : Acts::detail::LineHelper::lineIntersect<3>(seedLocalPos, locLineDir, testLocalZ* Amg::Vector3D::UnitZ(), Amg::Vector3D::UnitY()).position().z()};
400 if (seedGlobalR < testGlobalR) {
401 lowLimit = (seed->msSector() == testHit->
msSector() ? seedLocalPos.z() : canvas.corner(Edges::yLow));
402 upLimit = line2WindowInters;
404 upLimit = (seed->msSector() == testHit->
msSector() ? seedLocalPos.z() : canvas.corner(Edges::yHigh));
405 lowLimit = line2WindowInters;
407 outputContainer.emplace_back(
drawLine(locLineDir, seedLocalPos,
408 lowLimit, upLimit,
color, kDashed, view));
412 const Amg::Vector3D barLinePos {
isBarrel ? testLocalY* Amg::Vector3D::UnitY() : testLocalZ* Amg::Vector3D::UnitZ()};
413 lowLimit =
isBarrel ? testLocalZ - Rwindow : testLocalY - Rwindow;
414 upLimit =
isBarrel ? testLocalZ + Rwindow : testLocalY + Rwindow;
415 outputContainer.emplace_back(
drawLine(barLineDir, barLinePos,
416 lowLimit, upLimit,
color, kDotted, view));
422 bool& drawnTrueLabel,
424 const View view)
const {
429 double lowEnd{canvas.corner(Edges::yLow)};
430 double highEnd{canvas.corner(Edges::yHigh)};
433 const Amg::Vector3D globDir {localToGlobalBucket.linear() * lineDir};
436 const double slopeRZ {(globPos.x()*globDir.x() + globPos.y()*globDir.y()) / (globPos.perp()*globDir.z())};
437 lineDir = Acts::makeDirectionFromAxisTangents(0., slopeRZ);
438 linePos = globPos.perp()* Amg::Vector3D::UnitY() + globPos.z() * Amg::Vector3D::UnitZ();
440 lowEnd = canvas.corner(Edges::xLow);
441 highEnd = canvas.corner(Edges::xHigh);
444 outputContainer.emplace_back(
drawLine(lineDir, linePos, lowEnd, highEnd,
445 truthColor, kDotted, view));
446 if (!drawnTrueLabel) {
448 drawnTrueLabel =
true;
455 const View view)
const {
463 re->measurementHash(simHit->identify()) :
464 re->layerHash(simHit->identify());
466 re->localToGlobalTransform(gctx, hash);
467 const Amg::Vector3D locPos = trf * xAOD::toEigen(simHit->localPosition());
468 const Amg::Vector3D locDir = trf.linear() * xAOD::toEigen(simHit->localDirection());
470 outputContainer.emplace_back(
drawArrow(locPos, locDir, truthColor, kDashed,
static_cast<int>(view)));
472 constexpr double arrowLength = 2.*Gaudi::Units::cm;
474 const Amg::Vector3D globDir {localToGlobalBucket.linear() * locDir};
476 const Amg::Vector3D end = globPos + (arrowLength / std::hypot(globDir.z(),globDir.perp()) ) * globDir;
477 auto arrow = view ==
View::objViewZR ? std::make_unique<TArrow>(globPos.z(), globPos.perp(), end.z(), end.perp(),0.01) :
478 std::make_unique<TArrow>(globPos.perp(), globPos.z(), end.perp(), end.z(),0.01);
479 arrow->SetLineColor(truthColor);
480 arrow->SetLineWidth(2);
481 arrow->SetLineStyle(kDashed);
482 outputContainer.emplace_back(std::move(arrow));
486 template<
class SpacePo
intType>
492 unsigned int fillStyle)
const {
496 if ((isEtaView && !hit.measuresEta()) || (view ==
View::objViewPhi && !hit.measuresPhi())) {
500 const Amg::Vector3D globalPos {localToGlobalBucket * localPos};
501 const auto expand = [&canvas, &hit](
double centerX,
double centerY) {
502 canvas.expandPad(centerX- hit.driftRadius(), centerY - hit.driftRadius());
503 canvas.expandPad(centerX+ hit.driftRadius(), centerY + hit.driftRadius());
507 expand(localPos[
static_cast<int>(view)], localPos.z());
509 expand(globalPos.z(), globalPos.perp());
511 expand(globalPos.perp(), globalPos.z());
516 constexpr int invalidCalibFill = 3305;
517 if constexpr (std::is_same_v<SpacePointType, SpacePoint>) {
521 if (dc->status() != Muon::MdtDriftCircleStatus::MdtStatusDriftTime) {
522 fillStyle = invalidCalibFill;
525 }
else if constexpr(std::is_same_v<SpacePointType, CalibratedSpacePoint>) {
526 underlyingSp = hit.spacePoint();
527 if (hit.fitState() == CalibratedSpacePoint::State::Valid) {
529 }
else if (hit.fitState() == CalibratedSpacePoint::State::FailedCalib) {
530 fillStyle = invalidCalibFill;
541 return globalPos.z()* Amg::Vector3D::UnitY() + globalPos.perp() * Amg::Vector3D::UnitZ();
543 return globalPos.z()* Amg::Vector3D::UnitZ() + globalPos.perp() * Amg::Vector3D::UnitY();
545 return Amg::Vector3D::Zero();
551 canvas.add(
drawDriftCircle(posInCanvas, dc->readoutElement()->innerTubeRadius(),
554 const int circColor =
isLabeled(*dc) ? truthColor : kBlue;
555 canvas.add(
drawDriftCircle(posInCanvas, hit.driftRadius(), circColor, fillStyle));
559 const int boxColor =
isLabeled(*meas) ? truthColor : kGreen +2;
560 const double boxWidth = 0.5*std::sqrt(12)*std::sqrt(underlyingSp->
covariance()[covIdx]);
561 canvas.add(
drawBox(posInCanvas, boxWidth, 0.5*meas->readoutElement()->gasGapPitch(),
562 boxColor, fillStyle, covIdx));
566 const int boxColor =
isLabeled(*meas) ? truthColor : kCyan + 2;
567 const double boxWidth = 0.5*std::sqrt(12)*std::sqrt(underlyingSp->
covariance()[covIdx]);
568 canvas.add(
drawBox(posInCanvas, boxWidth, 0.5*meas->readoutElement()->gasGapPitch(),
569 boxColor, fillStyle, covIdx));
573 const double boxWidth = 5*Gaudi::Units::mm;
574 canvas.add(
drawBox(posInCanvas, boxWidth, 10.*Gaudi::Units::mm, boxColor, fillStyle, covIdx));
580 const double boxWidth = 5*Gaudi::Units::mm;
581 canvas.add(
drawBox(posInCanvas, boxWidth, 10.*Gaudi::Units::mm, boxColor, fillStyle, covIdx));
584 ATH_MSG_WARNING(
"Please implement proper drawings of the new small wheel.. "<<__FILE__<<
":"<<__LINE__);
591 template<
class SpacePo
intType>
594 const std::vector<SpacePointType>& hitsToDraw,
596 const View view)
const {
598 SpacePointSet drawnPoints{};
599 for (
const SpacePointType& hit : hitsToDraw) {
602 for (
const SpacePointBucket::value_type& hit : bucket) {
604 if (drawnPoints.count(hit.get())) {
609 return drawnPoints.size() - drawnPoints.count(
nullptr) > 1;
614 const double highEnd,
617 const View view)
const {
619 using ParamDefs = MuonR4::SpacePoint::SeedingAux::FitParIndex;
620 auto makeLine = [](
const double x1,
const double y1,
const double x2,
const double y2,
const int color,
const int style){
621 auto line = std::make_unique<TLine>(x1, y1, x2, y2);
622 line->SetLineColor(
color);
623 line->SetLineWidth(2);
624 line->SetLineStyle(style);
630 if (std::abs(lineDirection.z()) < std::numeric_limits<double>::epsilon()) {
632 return makeLine(lowEnd, linePoint.z(), highEnd, linePoint.z(),
color, lineStyle);
635 linePoint +
Amg::intersect<3>(linePoint,lineDirection,Amg::Vector3D::UnitZ(), highEnd).value_or(0.)* lineDirection,
636 color, lineStyle,
static_cast<int>(view));
640 if (std::abs(lineDirection.y()) < std::numeric_limits<double>::epsilon()) {
644 return makeLine(lowEnd, linePoint.y(), highEnd, linePoint.y(),
color, lineStyle);
647 return makeLine(linePoint.y(), lowEnd, linePoint.y(), highEnd,
color, lineStyle);
649 }
else if (std::abs(lineDirection.z()) < std::numeric_limits<double>::epsilon()) {
653 return makeLine(linePoint.z(), lowEnd, linePoint.z(), highEnd,
color, lineStyle);
656 return makeLine(lowEnd, linePoint.z(), highEnd, linePoint.z(),
color, lineStyle);
659 const double slope {lineDirection.y() / lineDirection.z()};
660 const double intercept {linePoint.y() - slope * linePoint.z()};
661 const double Zlow {(lowEnd - intercept) / slope};
662 const double Zhigh {(highEnd - intercept) / slope};
665 return makeLine(Zlow, lowEnd, Zhigh, highEnd,
color, lineStyle);
668 return makeLine(lowEnd, Zlow, highEnd, Zhigh,
color, lineStyle);
const boost::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
This is a "hash" representation of an Identifier.
MuonReadoutElement is an abstract class representing the geometry of a muon detector.
bool barrel() const
Returns whether the sector is placed in the barrel.
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &gctx) const
Returns the local -> global tarnsformation from the sector.
std::string identString() const
Returns a string encoding the chamber index & the sector of the MS sector.
Data class to represent an eta maximum in hough space.
: 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
unsigned int bucketId() const
Returns the Identifier in the context of the MuonChamber.
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
const Cov_t & covariance() const
Returns the covariance array.
const MuonGMR4::SpectrometerSector * msSector() const
const xAOD::MuonMeasurement * secondaryMeasurement() const
const xAOD::MuonMeasurement * primaryMeasurement() const
const Amg::Vector3D & localPosition() const
Property holding a SG store/key/clid from which a ReadHandle is made.
std::string label(const std::string &format, int i)
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
SeedingAux::FitParIndex ParamDefs
Use the same parameter indices as used by the CompSpacePointAuxiliaries.
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.
std::unordered_set< const xAOD::MuonSimHit * > getMatchingSimHits(const xAOD::MuonSegment &segment)
: Returns all sim hits matched to a xAOD::MuonSegment
MuonValR4::IPatternVisualizationTool::PrimitiveVec PrimitiveVec
Lightweight algorithm to read xAOD MDT sim hits and (fast-digitised) drift circles from SG and fill a...
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< TLatex > drawLabel(const std::string &text, const double xPos, const double yPos, const double textSize=18, const bool useNDC=true, const int color=kBlack)
Create a TLatex label,.
std::vector< std::unique_ptr< TObject > > clone(const std::vector< std::unique_ptr< TObject > > &cloneMe)
std::unique_ptr< TEllipse > drawDriftCircle(const Amg::Vector3D ¢er, const double radius, const int color=kViolet, const int fillStyle=hollowFilling)
Create a TEllipse for drawing a drift circle.
constexpr int fullFilling
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< 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.
StIndex
enum to classify the different station layers in the muon spectrometer
bool isBarrel(const ChIndex index)
Returns true if the chamber index points to a barrel chamber.
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
MdtDriftCircle_v1 MdtDriftCircle
MuonSimHit_v1 MuonSimHit
Defined the version of the MuonSimHit.
RpcMeasurement_v1 RpcMeasurement
MuonSegment_v1 MuonSegment
Reference the current persistent version:
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.