31 std::string removeNonAlphaNum(std::string
str) {
32 str.erase(std::remove_if(
str.begin(),
str.end(),
33 [](
const unsigned char c){
34 return !std::isalnum(c);
39 std::vector<const MuonR4::SpacePoint*> ret{};
40 std::transform(bucket.begin(), bucket.end(), std::back_inserter(ret),
41 [](
const MuonR4::SpacePointBucket::value_type& sp){ return sp.get();});
44 constexpr
int truthColor = kOrange +2;
45 constexpr
int parLineColor = kRed;
46 using SpacePointSet = std::unordered_set<const MuonR4::SpacePoint*>;
48 yLow = 0, yHigh, zLow, zHigh
55 using namespace SegmentFit;
65 return StatusCode::FAILURE;
71 m_outFile = std::make_unique<TFile>( (
m_allCanName +
".root").c_str(),
"RECREATE");
78 ATH_MSG_INFO(
"Hits linked to the following segment decorations are considered as truth");
81 if (decorName.empty()) {
83 return StatusCode::FAILURE;
96 return StatusCode::SUCCESS;
100 return StatusCode::SUCCESS;
109 return !decor(hit).empty();
114 std::vector<const xAOD::UncalibratedMeasurement*> measurements{};
115 measurements.reserve(2*
hits.size());
117 measurements.push_back(hit->primaryMeasurement());
118 if(hit->secondaryMeasurement()) {
119 measurements.push_back(hit->secondaryMeasurement());
128 for (
const SegLink_t& link : decor(*hit)) {
129 truthSegs.insert(*link);
137 const Acts::HoughTransformUtils::HoughAxisRanges& axisRanges,
138 const MaximumVec& maxima,
139 const std::string& extraLabel)
const {
145 const Acts::HoughTransformUtils::HoughAxisRanges& axisRanges,
146 const MaximumVec& maxima,
147 const std::string& extraLabel,
155 std::lock_guard guard{
s_mutex};
160 if (accumulator.getNonEmptyBins().empty()) {
165 auto accHisto = std::make_unique<TH2F>(
"AccumulatorHisto",
"histo",
166 accumulator.nBinsX(), axisRanges.xMin, axisRanges.xMax,
167 accumulator.nBinsY(), axisRanges.yMin, axisRanges.yMax);
169 accHisto->SetDirectory(
nullptr);
171 accHisto->GetYaxis()->SetTitle( std::string{
m_accumlIsEta ?
"y_{0}" :
"x_{0}"}.c_str());
173 std::vector<const SpacePoint*> spacePointsInAcc{};
174 for (
const std::size_t
bin : accumulator.getNonEmptyBins()) {
175 const auto [xBin, yBin] = accumulator.axisBins(
bin);
176 const SpacePointSet& hitsInBin{accumulator.hitIds(xBin, yBin)};
177 spacePointsInAcc.insert(spacePointsInAcc.end(),hitsInBin.begin(), hitsInBin.end());
178 accHisto->SetBinContent(xBin+1, yBin+1, accumulator.nHits(
bin));
189 auto truthMarker = std::make_unique<TMarker>(
tan, icept, kFullCrossX);
190 truthMarker->SetMarkerColor(truthColor);
191 truthMarker->SetMarkerSize(8);
192 primitives.push_back(std::move(truthMarker));
194 for (
const auto& maximum : maxima) {
195 auto maxMarker = std::make_unique<TMarker>(maximum.x, maximum.y, kFullTriangleUp);
196 maxMarker->SetMarkerColor(parLineColor);
197 maxMarker->SetMarkerSize(8);
198 primitives.push_back(std::move(maxMarker));
201 std::stringstream canvasName{};
202 canvasName<<
name()<<
"_"<<ctx.eventID().event_number()<<
"_"<<m_canvCounter;
203 auto canvas = std::make_unique<TCanvas>(canvasName.str().c_str(),
206 accHisto->Draw(
"COLZ");
207 for (
auto& prim : primitives) {
210 primitives.push_back(std::move(accHisto));
212 primitives.push_back(std::move(
canvas));
222 const std::string& extraLabel)
const {
228 const std::string& extraLabel,
236 std::lock_guard guard{
s_mutex};
247 std::array<double, 4> canvasDim{};
248 const std::size_t parsedPrimSize{primitives.size()};
255 primitives.resize(parsedPrimSize);
257 if (!
drawHits(*seed.parentBucket(), seed.getHitsInMax(), primitives, canvasDim,
view)) {
263 truthColor, kDotted,
view));
265 primitives.push_back(
drawLine(seed.parameters(), canvasDim[Edges::zLow], canvasDim[Edges::zHigh],
266 parLineColor, kDashed,
view));
268 writeChi2(seed.parameters(), seed.getHitsInMax(), primitives);
270 std::stringstream legendLabel{};
273 legendLabel<<
"Event: "<<ctx.eventID().event_number()<<
", chamber : "<<
m_idHelperSvc->toStringChamber(seed.getHitsInMax().front()->identify())
275 <<
", nDoF: "<<nDoF<<
", #"<<(
view ==
objViewEta ?
"eta" :
"phi")<<
"-view";;
277 if (!extraLabel.empty()) {
278 legendLabel<<
" ("<<extraLabel<<
")";
280 primitives.push_back(
drawLabel(legendLabel.str(), 0.1, 0.96));
284 for (PrimitivePtr& prim : primitives) {
287 saveCanvas(ctx, seed.getHitsInMax().front()->identify(), *
canvas, extraLabel);
297 const std::string& extraLabel)
const {
303 const std::string& extraLabel,
310 std::lock_guard guard{
s_mutex};
315 std::array<double, 4> canvasDim{};
320 const std::size_t parsedPrimSize{primitives.size()};
327 primitives.resize(parsedPrimSize);
328 if (!
drawHits(bucket, bucket, primitives, canvasDim,
view)) {
331 bool drawnTrueLabel{
false};
334 truthColor, kDotted,
view));
335 if (!drawnTrueLabel) {
337 drawnTrueLabel =
true;
341 std::stringstream legendLabel{};
342 legendLabel<<
"Event: "<<ctx.eventID().event_number()
343 <<
", chamber : "<<
m_idHelperSvc->toStringChamber(bucket.front()->identify())
345 if (!extraLabel.empty()) {
346 legendLabel<<
" ("<<extraLabel<<
")";
348 primitives.push_back(
drawLabel(legendLabel.str(), 0.2, 0.96));
350 for (PrimitivePtr& prim : primitives) {
353 saveCanvas(ctx, bucket.front()->identify(), *
can, extraLabel);
364 const std::string& extraLabel)
const {
371 const std::string& extraLabel,
378 std::lock_guard guard{
s_mutex};
400 std::array<double, 4> canvasDim{};
401 const std::size_t parsedPrimSize{primitives.size()};
408 primitives.resize(parsedPrimSize);
411 primitives, canvasDim,
view)) {
416 truthColor, kDotted,
view));
420 primitives.push_back(
drawLine(segPars, canvasDim[Edges::zLow], canvasDim[Edges::zHigh],
421 parLineColor, kDashed,
view));
424 std::stringstream legendLabel{};
426 legendLabel<<
"Event: "<<ctx.eventID().event_number() <<
", chamber : "<<
m_idHelperSvc->toStringChamber(canvasId)
430 if (!extraLabel.empty()) {
431 legendLabel<<
" ("<<extraLabel<<
")";
433 primitives.push_back(
drawLabel(legendLabel.str(), 0.1, 0.96));
437 for (PrimitivePtr& prim : primitives) {
448 template<
class SpacePo
intType>
451 std::array<double, 4>& canvasDim,
const unsigned int view,
452 unsigned int fillStyle)
const {
454 static_assert(std::is_same_v<SpacePointType, SpacePoint> ||
455 std::is_same_v<SpacePointType, CalibratedSpacePoint>,
"Only usual & calibrated space points are supported");
462 canvasDim[Edges::yLow] =
std::min(canvasDim[Edges::yLow], hit.positionInChamber()[
view] - hit.driftRadius());
463 canvasDim[Edges::yHigh] =
std::max(canvasDim[Edges::yHigh], hit.positionInChamber()[
view] + hit.driftRadius());
464 canvasDim[Edges::zLow] =
std::min(canvasDim[Edges::zLow], hit.positionInChamber().z() - hit.driftRadius());
465 canvasDim[Edges::zHigh] =
std::max(canvasDim[Edges::zHigh], hit.positionInChamber().z() + hit.driftRadius());
470 constexpr
int invalidCalibFill = 3305;
471 if constexpr (std::is_same_v<SpacePointType, SpacePoint>) {
476 fillStyle = invalidCalibFill;
479 }
else if constexpr(std::is_same_v<SpacePointType, CalibratedSpacePoint>) {
480 underlyingSp = hit.spacePoint();
481 if (hit.fitState() == CalibratedSpacePoint::State::Valid) {
483 }
else if (hit.fitState() == CalibratedSpacePoint::State::FailedCalib) {
484 fillStyle = invalidCalibFill;
492 primitives.push_back(
drawDriftCircle(hit.positionInChamber(), dc->readoutElement()->innerTubeRadius(),
496 primitives.push_back(
drawDriftCircle(hit.positionInChamber(), hit.driftRadius(), circColor, fillStyle));
500 const int boxColor =
isTruthMatched(*meas) ? truthColor : kGreen +2;
501 const double boxWidth = 0.5*std::sqrt(12)*underlyingSp->uncertainty()[
view];
502 primitives.push_back(
drawBox(hit.positionInChamber(), boxWidth, 0.5*meas->readoutElement()->gasGapPitch(),
503 boxColor, fillStyle));
506 const auto* meas{
static_cast<const xAOD::TgcStrip*
>(underlyingSp->primaryMeasurement())};
507 const int boxColor =
isTruthMatched(*meas) ? truthColor : kCyan + 2;
508 const double boxWidth = 0.5*std::sqrt(12)*underlyingSp->uncertainty()[
view];
509 primitives.push_back(
drawBox(hit.positionInChamber(), boxWidth, 0.5*meas->readoutElement()->gasGapPitch(),
510 boxColor, fillStyle));
515 ATH_MSG_WARNING(
"Please implement proper drawings of the new small wheel.. "<<__FILE__<<
":"<<__LINE__);
521 template<
class SpacePo
intType>
523 const std::vector<SpacePointType>& hitsToDraw,
524 std::vector<PrimitivePtr>& primitives,
525 std::array<double, 4>& canvasDim,
526 unsigned int view)
const {
528 canvasDim[Edges::yLow] = canvasDim[Edges::zLow] = 100. *
Gaudi::Units::m;
529 canvasDim[Edges::yHigh] = canvasDim[Edges::zHigh] = -100. *
Gaudi::Units::m;
532 for (
const SpacePointType& hit : hitsToDraw) {
536 for (
const SpacePointBucket::value_type& hit : bucket) {
538 if (drawnPoints.count(hit.get())) {
545 double height = (canvasDim[Edges::zHigh] - canvasDim[Edges::zLow])*
m_canvasExtraScale;
549 const double midPointX = 0.5 * (canvasDim[Edges::yHigh] + canvasDim[Edges::yLow]);
550 const double midPointY = 0.5 * (canvasDim[Edges::zHigh] + canvasDim[Edges::zLow]);
551 canvasDim[Edges::yLow] = midPointX - 0.5 *
width;
552 canvasDim[Edges::zLow] = midPointY - 0.5 * height;
553 canvasDim[Edges::yHigh] = midPointX + 0.5 *
width;
554 canvasDim[Edges::zHigh] = midPointY + 0.5 * height;
555 return drawnPoints.size() - drawnPoints.count(
nullptr) > 1;
557 template<
class SpacePo
intType>
559 const std::vector<SpacePointType>&
hits,
561 const double legX,
double startLegY,
562 const double endLegY)
const {
565 for (
const SpacePointType& hit :
hits) {
568 if constexpr( std::is_same_v<SpacePointType, Segment::MeasType>) {
569 underlyingSp = hit->spacePoint();
571 std::nullopt, *hit, msgStream());
578 std::stringstream legendstream{};
579 switch(hit->type()) {
583 legendstream<<
"ML: "<<idHelper.multilayer(hitId);
584 legendstream<<
", TL: "<<idHelper.tubeLayer(hitId);
585 legendstream<<
", T: "<<idHelper.tube(hitId);
586 legendstream<<
", "<<(
driftSign == -1 ?
"L" :
"R");
590 legendstream<<
"DR: "<<idHelper.doubletR(hitId);
591 legendstream<<
" DZ: "<<idHelper.doubletZ(hitId);
592 legendstream<<
", GAP: "<<idHelper.gasGap(hitId);
593 legendstream<<
", #eta/#phi: "<<(hit->measuresEta() ?
"si" :
"nay")
594 <<
"/"<<(hit->measuresPhi() ?
"si" :
"nay");
598 legendstream<<
"ST: "<<
m_idHelperSvc->stationNameString(hitId);
599 legendstream<<
", GAP: "<<idHelper.gasGap(hitId);
600 legendstream<<
", #eta/#phi: "<<(hit->measuresEta() ?
"si" :
"nay")
601 <<
"/"<<(hit->measuresPhi() ?
"si" :
"nay");
605 legendstream<<
"ML: "<<idHelper.multilayer(hitId);
606 legendstream<<
", GAP: "<<idHelper.gasGap(hitId);
607 legendstream<<
", stereo: "<<(idHelper.isStereo(hitId)?
"si" :
"nay");
611 legendstream<<
"ML: "<<idHelper.multilayer(hitId);
612 legendstream<<
", GAP: "<<idHelper.gasGap(hitId);
613 switch (idHelper.channelType(hitId)) {
614 case sTgcIdHelper::sTgcChannelTypes::Strip:
615 legendstream<<
", strip";
617 case sTgcIdHelper::sTgcChannelTypes::Wire:
618 legendstream<<
", wire";
620 case sTgcIdHelper::sTgcChannelTypes::Pad:
621 legendstream<<
", pad";
632 primitives.push_back(
drawLabel(legendstream.str(), legX, startLegY, 14));
634 if (startLegY<= endLegY) {
640 if (!m_outFile)
return;
650 const std::array<double, 4>& canvasDim,
651 const int view)
const {
652 std::stringstream canvasName{};
653 canvasName<<
name()<<
"_"<<ctx.eventID().event_number()<<
"_"<<m_canvCounter;
654 ATH_MSG_VERBOSE(
"Create new canvas "<<canvasName.str()<<
" "<<canvasDim);
657 TH1F* frame =
canvas->DrawFrame(canvasDim[Edges::yLow],canvasDim[Edges::zLow], canvasDim[Edges::yHigh], canvasDim[Edges::zHigh]);
659 frame->GetYaxis()->SetTitle(
"z [mm]");
665 const std::string& extraLabel)
const {
667 std::stringstream canvasName{};
668 canvasName<<
m_canvasPrefix.value()<<
"_"<<ctx.eventID().event_number()<<
"_"<<(m_canvCounter++)<<
"_"
673 if (!extraLabel.empty()) canvasName<<
"_"<<removeNonAlphaNum(extraLabel);
681 m_outFile->WriteObject(&
canvas, canvasName.str().c_str());