32 std::string removeNonAlphaNum(std::string
str) {
33 str.erase(std::remove_if(
str.begin(),
str.end(),
34 [](
const unsigned char c){
35 return !std::isalnum(c);
40 std::vector<const MuonR4::SpacePoint*> ret{};
41 std::transform(bucket.begin(), bucket.end(), std::back_inserter(ret),
42 [](
const MuonR4::SpacePointBucket::value_type& sp){ return sp.get();});
45 constexpr
int truthColor = kOrange +2;
46 constexpr
int parLineColor = kRed;
47 using SpacePointSet = std::unordered_set<const MuonR4::SpacePoint*>;
49 yLow = 0, yHigh, zLow, zHigh
56 using namespace SegmentFit;
66 return StatusCode::FAILURE;
72 m_outFile = std::make_unique<TFile>( (
m_allCanName +
".root").c_str(),
"RECREATE");
76 gROOT->SetStyle(
"ATLAS");
77 TStyle* plotStyle = gROOT->GetStyle(
"ATLAS");
78 plotStyle->SetOptTitle(0);
79 plotStyle->SetHistLineWidth(1.);
80 plotStyle->SetPalette(kViridis);
84 ATH_MSG_INFO(
"Hits linked to the following segment decorations are considered as truth");
87 if (decorName.empty()) {
89 return StatusCode::FAILURE;
102 return StatusCode::SUCCESS;
106 return StatusCode::SUCCESS;
115 return !decor(hit).empty();
120 std::vector<const xAOD::UncalibratedMeasurement*> measurements{};
121 measurements.reserve(2*
hits.size());
123 measurements.push_back(hit->primaryMeasurement());
124 if(hit->secondaryMeasurement()) {
125 measurements.push_back(hit->secondaryMeasurement());
134 for (
const SegLink_t& link : decor(*hit)) {
135 truthSegs.insert(*link);
142 const double yLow =
can.GetPad(0)->GetUymin();
143 const double yHigh =
can.GetPad(0)->GetUymax();
144 for (
auto& prim : primitives) {
145 const TObject &primRef = *prim;
146 if (
typeid(primRef) ==
typeid(TLine)){
147 TLine*
line =
static_cast<TLine*
>(prim.get());
151 const Amg::Vector3D newHigh = linePoint + Amg::intersect<3>(linePoint, lineDir, Amg::Vector3D::UnitY(), yHigh).value_or(0.) * lineDir;
152 const Amg::Vector3D newLow = linePoint + Amg::intersect<3>(linePoint, lineDir, Amg::Vector3D::UnitY(), yLow).value_or(0.) * lineDir;
153 line->SetX1(newLow.x());
154 line->SetY1(newLow.y());
155 line->SetX2(newHigh.x());
156 line->SetY2(newHigh.y());
164 const Acts::HoughTransformUtils::HoughAxisRanges& axisRanges,
165 const MaximumVec& maxima,
166 const std::string& extraLabel)
const {
172 const Acts::HoughTransformUtils::HoughAxisRanges& axisRanges,
173 const MaximumVec& maxima,
174 const std::string& extraLabel,
182 std::lock_guard guard{
s_mutex};
188 if (accumulator.getNonEmptyBins().empty()) {
193 auto accHisto = std::make_unique<TH2F>(
"AccumulatorHisto",
"histo",
194 accumulator.nBinsX(), axisRanges.xMin, axisRanges.xMax,
195 accumulator.nBinsY(), axisRanges.yMin, axisRanges.yMax);
197 accHisto->SetDirectory(
nullptr);
199 accHisto->GetYaxis()->SetTitle( std::string{
m_accumlIsEta ?
"y_{0}" :
"x_{0}"}.c_str());
201 std::vector<const SpacePoint*> spacePointsInAcc{};
202 for (
const std::size_t
bin : accumulator.getNonEmptyBins()) {
203 const auto [xBin, yBin] = accumulator.axisBins(
bin);
204 const SpacePointSet& hitsInBin{accumulator.hitIds(xBin, yBin)};
205 spacePointsInAcc.insert(spacePointsInAcc.end(),hitsInBin.begin(), hitsInBin.end());
206 accHisto->SetBinContent(xBin+1, yBin+1, accumulator.nHits(
bin));
217 auto truthMarker = std::make_unique<TMarker>(
tan, icept, kFullCrossX);
218 truthMarker->SetMarkerColor(truthColor);
219 truthMarker->SetMarkerSize(8);
220 primitives.push_back(std::move(truthMarker));
223 for (
const auto& maximum : maxima) {
224 auto maxMarker = std::make_unique<TMarker>(maximum.x, maximum.y, kFullTriangleUp);
225 maxMarker->SetMarkerColor(parLineColor);
226 maxMarker->SetMarkerSize(8);
227 primitives.push_back(std::move(maxMarker));
232 std::stringstream canvasName{};
233 canvasName<<
name()<<
"_"<<ctx.eventID().event_number()<<
"_"<<m_canvCounter;
234 auto canvas = std::make_unique<TCanvas>(canvasName.str().c_str(),
236 canvas->GetPad(0)->SetRightMargin(0.12);
237 canvas->GetPad(0)->SetTopMargin(0.12);
239 accHisto->Draw(
"COLZ");
241 primitives.push_back(std::move(accHisto));
243 primitives.push_back(std::move(
canvas));
253 const std::string& extraLabel)
const {
259 const std::string& extraLabel,
267 std::lock_guard guard{
s_mutex};
279 std::array<double, 4> canvasDim{};
280 const std::size_t parsedPrimSize{primitives.size()};
287 primitives.resize(parsedPrimSize);
289 if (!
drawHits(*seed.parentBucket(), seed.getHitsInMax(), primitives, canvasDim,
view)) {
295 truthColor, kDotted,
view));
297 primitives.push_back(
drawLine(seed.parameters(), canvasDim[Edges::zLow], canvasDim[Edges::zHigh],
298 parLineColor, kDashed,
view));
300 writeChi2(seed.parameters(), seed.getHitsInMax(), primitives);
302 std::stringstream legendLabel{};
305 legendLabel<<
"Event: "<<ctx.eventID().event_number()<<
", chamber : "<<
m_idHelperSvc->toStringChamber(seed.getHitsInMax().front()->identify())
309 if (!extraLabel.empty()) {
310 legendLabel<<
" ("<<extraLabel<<
")";
312 primitives.push_back(
drawLabel(legendLabel.str(), 0.1, 0.96));
321 saveCanvas(ctx, seed.getHitsInMax().front()->identify(), *
canvas, extraLabel);
331 const std::string& extraLabel)
const {
337 const std::string& extraLabel,
344 std::lock_guard guard{
s_mutex};
350 std::array<double, 4> canvasDim{};
355 const std::size_t parsedPrimSize{primitives.size()};
362 primitives.resize(parsedPrimSize);
363 if (!
drawHits(bucket, bucket, primitives, canvasDim,
view)) {
366 bool drawnTrueLabel{
false};
369 truthColor, kDotted,
view));
370 if (!drawnTrueLabel) {
372 drawnTrueLabel =
true;
376 std::stringstream legendLabel{};
377 legendLabel<<
"Event: "<<ctx.eventID().event_number()
378 <<
", chamber : "<<
m_idHelperSvc->toStringChamber(bucket.front()->identify())
380 if (!extraLabel.empty()) {
381 legendLabel<<
" ("<<extraLabel<<
")";
383 primitives.push_back(
drawLabel(legendLabel.str(), 0.2, 0.96));
391 saveCanvas(ctx, bucket.front()->identify(), *
can, extraLabel);
402 const std::string& extraLabel)
const {
409 const std::string& extraLabel,
416 std::lock_guard guard{
s_mutex};
439 std::array<double, 4> canvasDim{};
440 const std::size_t parsedPrimSize{primitives.size()};
447 primitives.resize(parsedPrimSize);
450 primitives, canvasDim,
view)) {
455 truthColor, kDotted,
view));
462 primitives.push_back(
drawLine(segPars, canvasDim[Edges::zLow], canvasDim[Edges::zHigh],
463 parLineColor, kDashed,
view));
466 std::stringstream legendLabel{};
468 legendLabel<<
"Event: "<<ctx.eventID().event_number() <<
", chamber : "<<
m_idHelperSvc->toStringChamber(canvasId)
472 if (!extraLabel.empty()) {
473 legendLabel<<
" ("<<extraLabel<<
")";
475 primitives.push_back(
drawLabel(legendLabel.str(), 0.2, 0.96));
489 template<
class SpacePo
intType>
492 std::array<double, 4>& canvasDim,
const unsigned int view,
493 unsigned int fillStyle)
const {
495 static_assert(std::is_same_v<SpacePointType, SpacePoint> ||
496 std::is_same_v<SpacePointType, CalibratedSpacePoint>,
"Only usual & calibrated space points are supported");
503 canvasDim[Edges::yLow] =
std::min(canvasDim[Edges::yLow], hit.positionInChamber()[
view] - hit.driftRadius());
504 canvasDim[Edges::yHigh] =
std::max(canvasDim[Edges::yHigh], hit.positionInChamber()[
view] + hit.driftRadius());
505 canvasDim[Edges::zLow] =
std::min(canvasDim[Edges::zLow], hit.positionInChamber().z() - hit.driftRadius());
506 canvasDim[Edges::zHigh] =
std::max(canvasDim[Edges::zHigh], hit.positionInChamber().z() + hit.driftRadius());
511 constexpr
int invalidCalibFill = 3305;
512 if constexpr (std::is_same_v<SpacePointType, SpacePoint>) {
517 fillStyle = invalidCalibFill;
520 }
else if constexpr(std::is_same_v<SpacePointType, CalibratedSpacePoint>) {
521 underlyingSp = hit.spacePoint();
522 if (hit.fitState() == CalibratedSpacePoint::State::Valid) {
524 }
else if (hit.fitState() == CalibratedSpacePoint::State::FailedCalib) {
525 fillStyle = invalidCalibFill;
533 primitives.push_back(
drawDriftCircle(hit.positionInChamber(), dc->readoutElement()->innerTubeRadius(),
536 const int circColor =
isLabeled(*dc) ? truthColor : kBlue;
537 primitives.push_back(
drawDriftCircle(hit.positionInChamber(), hit.driftRadius(), circColor, fillStyle));
541 const int boxColor =
isLabeled(*meas) ? truthColor : kGreen +2;
542 const double boxWidth = 0.5*std::sqrt(12)*underlyingSp->uncertainty()[
view];
543 primitives.push_back(
drawBox(hit.positionInChamber(), boxWidth, 0.5*meas->readoutElement()->gasGapPitch(),
544 boxColor, fillStyle));
547 const auto* meas{
static_cast<const xAOD::TgcStrip*
>(underlyingSp->primaryMeasurement())};
548 const int boxColor =
isLabeled(*meas) ? truthColor : kCyan + 2;
549 const double boxWidth = 0.5*std::sqrt(12)*underlyingSp->uncertainty()[
view];
550 primitives.push_back(
drawBox(hit.positionInChamber(), boxWidth, 0.5*meas->readoutElement()->gasGapPitch(),
551 boxColor, fillStyle));
554 const auto* meas{
static_cast<const xAOD::MMCluster*
>(underlyingSp->primaryMeasurement())};
555 const int boxColor =
isLabeled(*meas) ? truthColor : kAquamarine;
558 boxColor, fillStyle));
563 ATH_MSG_WARNING(
"Please implement proper drawings of the new small wheel.. "<<__FILE__<<
":"<<__LINE__);
569 template<
class SpacePo
intType>
571 const std::vector<SpacePointType>& hitsToDraw,
572 std::vector<PrimitivePtr>& primitives,
573 std::array<double, 4>& canvasDim,
574 unsigned int view)
const {
576 canvasDim[Edges::yLow] = canvasDim[Edges::zLow] = 100. *
Gaudi::Units::m;
577 canvasDim[Edges::yHigh] = canvasDim[Edges::zHigh] = -100. *
Gaudi::Units::m;
580 for (
const SpacePointType& hit : hitsToDraw) {
584 for (
const SpacePointBucket::value_type& hit : bucket) {
586 if (drawnPoints.count(hit.get())) {
595 for (
auto & prim : primitives){
596 TBox* theBox =
dynamic_cast<TBox*
>(prim.get());
598 canvasDim[Edges::zLow] =
std::min(canvasDim[Edges::zLow], theBox->GetY1());
599 canvasDim[Edges::zHigh] =
std::max(canvasDim[Edges::zHigh], theBox->GetY2());
604 double height = (canvasDim[Edges::zHigh] - canvasDim[Edges::zLow])*
m_canvasExtraScale;
608 const double midPointX = 0.5 * (canvasDim[Edges::yHigh] + canvasDim[Edges::yLow]);
609 const double midPointY = 0.5 * (canvasDim[Edges::zHigh] + canvasDim[Edges::zLow]);
610 canvasDim[Edges::yLow] = midPointX - 0.5 *
width;
611 canvasDim[Edges::zLow] = midPointY - 0.5 * height;
612 canvasDim[Edges::yHigh] = midPointX + 0.5 *
width;
613 canvasDim[Edges::zHigh] = midPointY + 0.5 * height;
614 return drawnPoints.size() - drawnPoints.count(
nullptr) > 1;
616 template<
class SpacePo
intType>
618 const std::vector<SpacePointType>&
hits,
620 const double legX,
double startLegY,
621 const double endLegY)
const {
624 for (
const SpacePointType& hit :
hits) {
627 if constexpr( std::is_same_v<SpacePointType, Segment::MeasType>) {
628 underlyingSp = hit->spacePoint();
630 std::nullopt, *hit, msgStream());
637 std::string legendstream{};
638 switch(hit->type()) {
642 legendstream =
std::format(
"ML: {:1d}, TL: {:1d}, T: {:3d}, {:}",
643 idHelper.multilayer(hitId), idHelper.tubeLayer(hitId),
644 idHelper.tube(hitId),
driftSign == -1 ?
"L" :
"R");
648 legendstream=
std::format(
"DR: {:1d}, DZ: {:1d}, GAP: {:1d}, #eta/#phi: {:}/{:}",
649 idHelper.doubletR(hitId), idHelper.doubletZ(hitId), idHelper.gasGap(hitId),
650 hit->measuresEta() ?
"si" :
"nay", hit->measuresPhi() ?
"si" :
"nay");
654 legendstream =
std::format(
"ST: {:}, GAP: {:1d}, #eta/#phi: {:}/{:}",
655 m_idHelperSvc->stationNameString(hitId), idHelper.gasGap(hitId),
656 hit->measuresEta() ?
"si" :
"nay", hit->measuresPhi() ?
"si" :
"nay");
660 const auto* clus =
static_cast<const xAOD::MMCluster*
>(underlyingSp->primaryMeasurement());
661 const MuonGMR4::StripDesign& design = clus->readoutElement()->stripLayer(clus->layerHash()).design();
662 legendstream =
std::format(
"ML: {:1d}, GAP: {:1d}, {:}", idHelper.multilayer(hitId), idHelper.gasGap(hitId),
667 legendstream =
std::format(
"ML: {:1d}, GAP: {:1d}, #eta/#phi: {:}/{:}",
668 idHelper.multilayer(hitId), idHelper.gasGap(hitId),
669 hit->measuresEta() ?
"si" :
"nay", hit->measuresPhi() ?
"si" :
"nay");
676 primitives.push_back(
drawLabel(legendstream, legX, startLegY, 14));
678 if (startLegY<= endLegY) {
684 if (!m_outFile)
return;
694 const std::array<double, 4>& canvasDim,
695 const int view)
const {
696 std::stringstream canvasName{};
697 canvasName<<
name()<<
"_"<<ctx.eventID().event_number()<<
"_"<<m_canvCounter;
698 ATH_MSG_VERBOSE(
"Create new canvas "<<canvasName.str()<<
" "<<canvasDim);
701 TH1F* frame =
canvas->DrawFrame(canvasDim[Edges::yLow],canvasDim[Edges::zLow], canvasDim[Edges::yHigh], canvasDim[Edges::zHigh]);
703 frame->GetYaxis()->SetTitle(
"z [mm]");
709 const std::string& extraLabel)
const {
711 std::stringstream canvasName{};
712 canvasName<<
m_canvasPrefix.value()<<
"_"<<ctx.eventID().event_number()<<
"_"<<(m_canvCounter++)<<
"_"
717 if (!extraLabel.empty()) canvasName<<
"_"<<removeNonAlphaNum(extraLabel);
725 m_outFile->WriteObject(&
canvas, canvasName.str().c_str());