20#include "Acts/Utilities/Helpers.hpp"
21#include "Acts/Surfaces/RectangleBounds.hpp"
22#include "Acts/Surfaces/TrapezoidBounds.hpp"
23#include "Acts/Surfaces/PlaneSurface.hpp"
24#include "Acts/Surfaces/StrawSurface.hpp"
25#include "Acts/Visualization/GeometryView3D.hpp"
38 constexpr int truthColor = kOrange +2;
39 constexpr int parLineColor = kRed;
40 using SpacePointSet = std::unordered_set<const MuonR4::SpacePoint*>;
45 using namespace MuonR4;
63 ATH_MSG_INFO(
"Hits linked to the following segment decorations are considered as truth");
66 if (decorName.empty()) {
68 return StatusCode::FAILURE;
81 return StatusCode::SUCCESS;
90 return !decor(hit).empty();
95 std::vector<const xAOD::UncalibratedMeasurement*> measurements{};
96 measurements.reserve(2* hits.size());
98 measurements.push_back(hit->primaryMeasurement());
99 if(hit->secondaryMeasurement()) {
100 measurements.push_back(hit->secondaryMeasurement());
109 for (
const SegLink_t& link : decor(*hit)) {
110 truthSegs.insert(*link);
138 const Acts::HoughTransformUtils::HoughAxisRanges& axisRanges,
139 const MaximumVec& maxima,
140 const std::string& extraLabel)
const {
146 const Acts::HoughTransformUtils::HoughAxisRanges& axisRanges,
147 const MaximumVec& maxima,
148 const std::string& extraLabel,
155 if (accumulator.getNonEmptyBins().empty()) {
160 auto accHisto = std::make_unique<TH2F>(
"AccumulatorHisto",
"histo",
161 accumulator.nBinsX(), axisRanges.xMin, axisRanges.xMax,
162 accumulator.nBinsY(), axisRanges.yMin, axisRanges.yMax);
163 accHisto->SetDirectory(
nullptr);
165 std::vector<const SpacePoint*> spacePointsInAcc{};
166 for (
const std::size_t
bin : accumulator.getNonEmptyBins()) {
167 const auto [xBin, yBin] = accumulator.axisBins(
bin);
168 auto hitIds = accumulator.hitIds(xBin, yBin);
169 spacePointsInAcc.insert(spacePointsInAcc.end(),hitIds.begin(), hitIds.end());
170 accHisto->SetBinContent(xBin+1, yBin+1, accumulator.nHits(
bin));
182 canvas->expandPad(axisRanges.xMin, axisRanges.yMin);
183 canvas->expandPad(axisRanges.xMax, axisRanges.yMax);
184 canvas->setAxisTitles(std::format(
"tan#{}",
m_accumlIsEta ?
"beta" :
"#alpha"),
186 canvas->add(std::move(accHisto),
"HIST SAME");
192 auto truthMarker = std::make_unique<TMarker>(tan, icept, kFullCrossX);
193 truthMarker->SetMarkerColor(truthColor);
194 truthMarker->SetMarkerSize(8);
195 canvas->add(std::move(truthMarker));
196 canvas->add(
drawLabel(std::format(
"true parameters: {:}",
199 for (
const auto& maximum : maxima) {
200 auto maxMarker = std::make_unique<TMarker>(maximum.x, maximum.y, kFullTriangleUp);
201 maxMarker->SetMarkerColor(parLineColor);
202 maxMarker->SetMarkerSize(8);
203 canvas->add(std::move(maxMarker));
205 canvas->add(std::move(primitives));
210 const int view)
const {
222 re->measurementHash(simHit->identify()) :
223 re->layerHash(simHit->identify());
225 re->localToGlobalTransform(*geoCtx, hash);
226 const Amg::Vector3D locPos = trf * xAOD::toEigen(simHit->localPosition());
227 const Amg::Vector3D locDir = trf.linear() * xAOD::toEigen(simHit->localDirection());
228 canvas.add(
drawArrow(locPos, locDir, truthColor, kDashed, view));
233 const std::string& extraLabel)
const {
239 const std::string& extraLabel,
256 canvas->add(std::move(primitives));
264 canvas->setAxisTitles(std::format(
"{:} [mm]", view ==
objViewEta ?
'y' :
'x'),
"z [mm]");
266 if (!
drawHits(*seed.parentBucket(), seed.getHitsInMax(), *canvas, view)) {
271 canvas->corner(Edges::yLow), canvas->corner(Edges::yHigh),
272 truthColor, kDotted, view));
275 canvas->add(
drawLine(seed.parameters(), canvas->corner(Edges::yLow),
276 canvas->corner(Edges::yHigh), parLineColor, kDashed, view));
278 writeChi2(seed.parameters(), seed.getHitsInMax(), *canvas);
280 std::string legendLabel = std::format(
"Event: {:}, chamber : {:}, #{:}-view ({:})",
281 ctx.eventID().event_number(),
282 m_idHelperSvc->toStringChamber(seed.getHitsInMax().front()->identify()),
285 canvas->add(
drawLabel(legendLabel, 0.1, 0.96));
292 const std::string& extraLabel)
const {
298 const std::string& extraLabel,
314 canvas->add(std::move(primitives));
321 canvas->setAxisTitles(std::format(
"{:} [mm]", view ==
objViewEta ?
'y' :
'x'),
"z [mm]");
323 if (!
drawHits(bucket, bucket, *canvas, view)) {
326 bool drawnTrueLabel{
false};
329 canvas->corner(Edges::yLow), canvas->corner(Edges::yHigh),
330 truthColor, kDotted, view));
331 if (!drawnTrueLabel) {
333 drawnTrueLabel =
true;
338 std::string legendLabel = std::format(
"Event: {:}, chamber : {:}, #{:}-view ({:})",
339 ctx.eventID().event_number(),
343 canvas->add(
drawLabel(legendLabel, 0.15, 0.96));
349 const std::string& extraLabel)
const {
356 const std::string& extraLabel,
376 canvas->add(std::move(primitives));
386 canvas->setAxisTitles(std::format(
"{:} [mm]", view ==
objViewEta ?
'y' :
'x'),
"z [mm]");
393 truthColor, kDotted, view));
398 canvas->add(
drawLine(segPars, canvas->corner(Edges::yLow), canvas->corner(Edges::yHigh),
399 parLineColor, kDashed, view));
402 std::string legendLabel=std::format(
"Event: {:}, chamber: {:}, #chi^{{2}} / nDoF: {:.2f} ({:d}), #{:}-view (:)",
403 ctx.eventID().event_number(),
m_idHelperSvc->toStringChamber(canvasId),
404 segment.
chi2() /std::max(1u, segment.
nDoF()), segment.
nDoF(),
405 view ==
objViewEta ?
"eta" :
"phi", extraLabel);
407 canvas->add(
drawLabel(legendLabel, 0.2, 0.96));
414 const std::string& extraLabel)
const {
420 Acts::ObjVisualization3D visualHelper{};
424 measurements[1]->spacePoint();
425 auto chamberId =
sp->identify();
428 double pathLength{1.*Gaudi::Units::m};
429 Acts::GeometryView3D::drawSegment(visualHelper,
433 std::string fileName = std::format(
"Event_{:}_chamber_{:}_{:}",
434 ctx.eventID().event_number(),
m_idHelperSvc->toStringChamber(chamberId), extraLabel);
435 visualHelper.write(fileName +
".obj");
441 const std::string& extraLabel)
const {
447 Acts::ObjVisualization3D visualHelper{};
450 measVec[1]->spacePoint();
451 auto chamberId =
sp->identify();
452 std::string fileName = std::format(
"Event_{:}_chamber_{:}_{:}",
453 ctx.eventID().event_number(),
m_idHelperSvc->toStringChamber(chamberId), extraLabel);
454 visualHelper.write(fileName +
".obj");
459 Acts::ObjVisualization3D& visualHelper)
const {
463 measVec[1]->spacePoint();
468 double dX{0.}, dY{0.};
470 for(
const auto& meas : measVec){
474 if(meas->dimension() == 2){
479 const double hZ = std::sqrt(meas->covariance()[Acts::toUnderlying(CovIdx::phiCov)]);
480 auto bounds = std::make_unique<Acts::LineBounds>(dR, hZ);
482 const Acts::Transform3 trf = Acts::Transform3(
483 Acts::Translation3(globalPos) *locToGlob.rotation());
484 auto surface = Acts::Surface::makeShared<Acts::StrawSurface>(trf, std::move(bounds));
485 Acts::GeometryView3D::drawSurface(visualHelper, *surface, geoCtx.
context());
489 dX = std::sqrt(meas->covariance()[Acts::toUnderlying(CovIdx::phiCov)]);
490 dY = std::sqrt(meas->covariance()[Acts::toUnderlying(CovIdx::etaCov)]);
491 auto bounds = std::make_unique<Acts::RectangleBounds>(dX, dY);
493 const Acts::Transform3 trf = Acts::Transform3(
494 Acts::Translation3(globalPos) *locToGlob.rotation());
496 auto surf = Acts::Surface::makeShared<Acts::PlaneSurface>(trf,std::move(bounds));
497 Acts::GeometryView3D::drawSurface(visualHelper, *surf, geoCtx.
context());
502 const SpacePoint* underlyingSp{meas->spacePoint()};
509 template<
class SpacePo
intType>
512 const unsigned int view,
513 unsigned int fillStyle)
const {
521 canvas.expandPad(hit.localPosition()[view] - hit.driftRadius(),
522 hit.localPosition().z() - hit.driftRadius());
523 canvas.expandPad(hit.localPosition()[view] + hit.driftRadius(),
524 hit.localPosition().z() + hit.driftRadius());
529 constexpr int invalidCalibFill = 3305;
530 if constexpr (std::is_same_v<SpacePointType, SpacePoint>) {
534 if (dc->status() != Muon::MdtDriftCircleStatus::MdtStatusDriftTime) {
535 fillStyle = invalidCalibFill;
538 }
else if constexpr(std::is_same_v<SpacePointType, CalibratedSpacePoint>) {
539 underlyingSp = hit.spacePoint();
540 if (hit.fitState() == CalibratedSpacePoint::State::Valid) {
542 }
else if (hit.fitState() == CalibratedSpacePoint::State::FailedCalib) {
543 fillStyle = invalidCalibFill;
551 canvas.add(
drawDriftCircle(hit.localPosition(), dc->readoutElement()->innerTubeRadius(),
554 const int circColor =
isLabeled(*dc) ? truthColor : kBlue;
555 canvas.add(
drawDriftCircle(hit.localPosition(), 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()[view]);
561 canvas.add(
drawBox(hit.localPosition(), boxWidth, 0.5*meas->readoutElement()->gasGapPitch(),
562 boxColor, fillStyle));
566 const int boxColor =
isLabeled(*meas) ? truthColor : kCyan + 2;
567 const double boxWidth = 0.5*std::sqrt(12)*std::sqrt(underlyingSp->
covariance()[view]);
568 canvas.add(
drawBox(hit.localPosition(), boxWidth, 0.5*meas->readoutElement()->gasGapPitch(),
569 boxColor, fillStyle));
573 const double boxWidth = 5*Gaudi::Units::mm;
574 canvas.add(
drawBox(hit.localPosition(), boxWidth, 10.*Gaudi::Units::mm, boxColor, fillStyle));
580 const double boxWidth = 5*Gaudi::Units::mm;
581 canvas.add(
drawBox(hit.localPosition(), boxWidth, 10.*Gaudi::Units::mm, boxColor, fillStyle));
584 ATH_MSG_WARNING(
"Please implement proper drawings of the new small wheel.. "<<__FILE__<<
":"<<__LINE__);
591 template<
class SpacePo
intType>
593 const std::vector<SpacePointType>& hitsToDraw,
595 unsigned int view)
const {
597 SpacePointSet drawnPoints{};
598 for (
const SpacePointType& hit : hitsToDraw) {
602 for (
const SpacePointBucket::value_type& hit : bucket) {
604 if (drawnPoints.count(hit.get())) {
610 return drawnPoints.size() - drawnPoints.count(
nullptr) > 1;
612 template<
class SpacePo
intType>
614 const std::vector<SpacePointType>& hits,
616 const double legX,
double startLegY,
617 const double endLegY)
const {
618 const auto [pos, dir] =
makeLine(pars);
620 for (
const SpacePointType& hit : hits) {
622 bool displayChi2{
true};
623 if constexpr(std::is_same_v<SpacePointType, Segment::MeasType>) {
624 underlyingSp = hit->spacePoint();
625 displayChi2 = (hit->fitState() == CalibratedSpacePoint::State::Valid);
630 std::string legendstream{};
631 switch(hit->type()) {
633 const int driftSign{SeedingAux::strawSign(pos, dir, *hit)};
635 legendstream = std::format(
"ML: {:1d}, TL: {:1d}, T: {:3d}, {:}",
637 idHelper.
tube(hitId), driftSign == -1 ?
"L" :
"R");
641 legendstream= std::format(
"DR: {:1d}, DZ: {:1d}, GAP: {:1d}, #eta/#phi: {:}/{:}",
643 hit->measuresEta() ?
"si" :
"nay", hit->measuresPhi() ?
"si" :
"nay");
647 legendstream = std::format(
"ST: {:}, GAP: {:1d}, #eta/#phi: {:}/{:}",
649 hit->measuresEta() ?
"si" :
"nay", hit->measuresPhi() ?
"si" :
"nay");
654 const MuonGMR4::StripDesign& design = clus->readoutElement()->stripLayer(clus->layerHash()).design();
655 legendstream = std::format(
"ML: {:1d}, GAP: {:1d}, {:}", idHelper.
multilayer(hitId), idHelper.
gasGap(hitId),
660 legendstream = std::format(
"ML: {:1d}, GAP: {:1d}, #eta/#phi: {:}/{:}",
662 hit->measuresEta() ?
"si" :
"nay", hit->measuresPhi() ?
"si" :
"nay");
665 legendstream =
"Ext. constaint";
671 const double chi2 = SeedingAux::chi2Term(pos, dir,*hit);
672 legendstream+=std::format(
", #chi^{{2}}: {:.2f}",
chi2);
674 legendstream+=
", #chi^{2}: ---";
676 canvas.add(
drawLabel(legendstream, legX, startLegY, 14));
678 if (startLegY<= endLegY) {
const boost::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
Acts::GeometryContext context() const
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
MuonReadoutElement is an abstract class representing the geometry of a muon detector.
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
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.
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.
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.
std::vector< MeasType > MeasVec
const SegmentSeed * parent() const
Returns the seed out of which the segment was built.
const MeasVec & measurements() const
Returns the associated measurements.
double chi2() const
Returns the chi2 of the segment fit.
const Amg::Vector3D & position() const
Returns the global segment position.
const Amg::Vector3D & direction() const
Returns the global segment direction.
: 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
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)
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 ¢er, const double radius, const int color=kViolet, const int fillStyle=hollowFilling)
Create a TEllipse for drawing a drift circle.
std::unique_ptr< TLatex > drawLabel(const std::string &text, const double xPos, const double yPos, const unsigned int fontSize=18, const bool useNDC=true)
Create a TLatex label,.
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.
void drawMeasurement(const ActsTrk::GeometryContext &gctx, const xAOD::UncalibratedMeasurement *meas, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewSensitive)
Draw an uncalibrated measurement inside the obj file.
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
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.