6 #include "GaudiKernel/SystemOfUnits.h"
15 #include "Acts/Utilities/Enumerate.hpp"
16 #include "GaudiKernel/PhysicalConstants.h"
30 using simHitSet = std::unordered_set<const xAOD::MuonSimHit*>;
48 template <
class SpType>
61 m_tree.addBranch(std::make_unique<EventInfoBranch>(m_tree, infoOpts));
63 ATH_CHECK(m_truthSegmentKey.initialize(!m_truthSegmentKey.empty()));
66 ATH_CHECK(m_inHoughSegmentSeedKeys.initialize());
67 ATH_CHECK(m_spKey.initialize(m_writeSpacePoints));
68 if (m_writeSpacePoints) {
69 m_spTester = std::make_unique<SpacePointTesterModule>(m_tree, m_spKey.key(), msgLevel());
70 m_tree.addBranch(m_spTester);
72 m_tree.disableBranch(m_spMatchedToPattern.name());
73 m_tree.disableBranch(m_spMatchedToSegment.name());
79 ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
81 return StatusCode::SUCCESS;
89 using namespace SegmentFit;
92 const std::vector<int> truthSigns = SeedingAux::strawSigns(trueLine, recoSeg.
measurements());
93 const std::vector<int> recoSigns = SeedingAux::strawSigns(recoLine, recoSeg.
measurements());
94 for (
unsigned int s = 0 ;
s < truthSigns.size(); ++
s) {
95 same += (truthSigns[
s] != 0) && truthSigns[
s] == recoSigns[
s];
99 std::vector<ObjectMatching>
104 std::vector<ObjectMatching> allAssociations{};
105 std::unordered_set<const SegmentSeed*> usedSeeds{};
106 std::unordered_set<const Segment*> usedSegs{};
112 std::vector<simHitSet> truthHitsVec{}, seedSimHitVec{}, segmentSimHitVec{};
124 ObjectMatching & matchedWithTruth = allAssociations.emplace_back();
126 matchedWithTruth.
chamber = m_detMgr->getSectorEnvelope((*truthHits.begin())->identify());
128 std::vector<std::pair<const SegmentSeed*, unsigned>> matchedSeeds{};
135 if (seed->msSector() != matchedWithTruth.
chamber) {
138 const simHitSet& seedHits{seedSimHitVec[seedIdx]};
139 unsigned int matchedHits =
countMatched(truthHits, seedHits);
143 matchedSeeds.emplace_back(std::make_pair(seed, matchedHits));
146 std::vector<std::pair<const Segment*, unsigned>> matchedSegs{};
153 const simHitSet& segmentHits{segmentSimHitVec[segmentIdx]};
154 unsigned int matchedHits =
countMatched(truthHits, segmentHits);
158 matchedSegs.emplace_back(std::make_pair(
segment,matchedHits));
164 std::ranges::sort(matchedSegs,
165 [
this, &truth, &gctx](
const std::pair<const Segment*, unsigned>& segA,
166 const std::pair<const Segment*, unsigned>& segB){
167 if (segA.second != segB.second)
return segA.second > segB.second;
168 return countOnSameSide(gctx, *truth, *segA.first) > countOnSameSide(gctx, *truth, *segB.first);
171 std::ranges::sort(matchedSeeds, [](
const std::pair<const SegmentSeed*, unsigned>& seedA,
172 const std::pair<const SegmentSeed*, unsigned>& seedB) {
173 return seedA.second > seedB.second;
180 for (
const auto& [
matched, nMatchedHits] : matchedSegs) {
184 usedSeeds.insert(
matched->parent());
189 for (
const auto& [seed , nHits] : matchedSeeds) {
194 usedSeeds.insert(seed);
204 for (
const Segment* seg: *segmentContainer) {
206 if (usedSegs.count(seg)) {
210 match.chamber = seg->msSector();
211 match.matchedSegments = {seg};
212 match.matchedSeeds = {seg->parent()};
214 usedSeeds.insert(seg->parent());
218 if (usedSeeds.count(seed)) {
222 match.chamber = seed->msSector();
223 match.matchedSeeds = {seed};
225 return allAssociations;
230 return StatusCode::SUCCESS;
234 const EventContext & ctx = Gaudi::Hive::currentContext();
246 segmentSeeds.insert(segmentSeeds.end(),readSegmentSeeds->begin(), readSegmentSeeds->end());
251 segments.insert(segments.end(),readSegments->begin(), readSegments->end());
256 ATH_MSG_DEBUG(
"Succesfully retrieved input collections. Seeds: "<<segmentSeeds.size()
257 <<
", segments: "<<segments.size() <<
", truth segments: "<<(readTruthSegments? readTruthSegments->size() : -1)<<
".");
258 std::vector<ObjectMatching>
objects = matchWithTruth(gctx, readTruthSegments, segmentSeeds.asDataVector(),
259 segments.asDataVector());
261 fillChamberInfo(
obj.chamber);
262 fillTruthInfo(gctx,
obj.truthSegment);
264 fillSegmentInfo(gctx,
obj);
267 return StatusCode::SUCCESS;
270 m_out_chamberIndex = Acts::toUnderlying(msSector->
chamberIndex());
271 m_out_stationSide = msSector->
side();
277 m_out_hasTruth =
true;
283 m_out_gen_Eta = segDir.eta();
284 m_out_gen_Phi = segDir.phi();
285 m_out_gen_Pt = acc_pt(*
segment);
286 m_out_gen_Q = acc_charge(*
segment);
298 m_out_gen_y0 = chamberPos.y();
299 m_out_gen_x0 = chamberPos.x();
300 m_out_gen_time =
segment->t0();
310 const Amg::Vector3D chamberPos = localToChamber * xAOD::toEigen(hit->localPosition());
311 minYhit =
std::min(chamberPos.y(), minYhit);
312 maxYhit =
std::max(chamberPos.y(), maxYhit);
314 m_out_gen_minYhit = minYhit;
315 m_out_gen_maxYhit = maxYhit;
317 ATH_MSG_DEBUG(
"A true max on chamber index "<<m_out_chamberIndex.getVariable()<<
" side "<<m_out_stationSide.getVariable()<<
" phi "<<m_out_stationPhi.getVariable()<<
" with "
318 <<m_out_gen_nMDTHits.getVariable()<<
" MDT and "<<m_out_gen_nRPCHits.getVariable()+m_out_gen_nTGCHits.getVariable()<<
" trigger hits is at "
319 <<m_out_gen_tantheta.getVariable()<<
" and "<<m_out_gen_y0.getVariable());
324 m_out_nSpacePoints = bucket.size();
325 m_out_nPrecSpacePoints = std::ranges::count_if(bucket, [](
const SpacePointBucket::value_type& sp){
328 m_out_nPhiSpacePoints = std::ranges::count_if(bucket, [](
const SpacePointBucket::value_type& sp){
329 return sp->measuresPhi();
331 if (!m_visionTool.isEnabled()){
334 m_out_nTrueSpacePoints = std::ranges::count_if(bucket,[
this](
const SpacePointBucket::value_type& sp){
335 return m_visionTool->isLabeled(*sp);
337 m_out_nTruePrecSpacePoints = std::ranges::count_if(bucket,[
this](
const SpacePointBucket::value_type& sp){
338 return isPrecHit(*sp) && m_visionTool->isLabeled(*sp);
340 m_out_nTruePhiSpacePoints = std::ranges::count_if(bucket,[
this](
const SpacePointBucket::value_type& sp){
341 return sp->measuresPhi() && m_visionTool->isLabeled(*sp);
346 m_out_seed_n =
obj.matchedSeeds.size();
347 for (
const auto [iseed, seed] : Acts::enumerate(
obj.matchedSeeds)){
349 fillBucketInfo(*seed->parentBucket());
351 double minYhit = m_out_bucketEnd.getVariable();
352 double maxYhit = m_out_bucketStart.getVariable();
353 for (
const SpacePoint* hit : seed->getHitsInMax()){
354 minYhit =
std::min(hit->localPosition().y(),minYhit);
355 maxYhit =
std::max(hit->localPosition().y(),maxYhit);
357 m_out_seed_minYhit.push_back(minYhit);
358 m_out_seed_maxYhit.push_back(maxYhit);
360 m_out_seed_hasPhiExtension.push_back(seed->hasPhiExtension());
361 m_out_seed_nMatchedHits.push_back(
countMatched(
obj.truthSegment, seed));
362 m_out_seed_y0.push_back(seed->interceptY());
363 m_out_seed_tantheta.push_back(seed->tanTheta());
364 if (seed->hasPhiExtension()){
365 m_out_seed_x0.push_back(seed->interceptX());
366 m_out_seed_tanphi.push_back(seed->tanPhi());
368 m_out_seed_x0.push_back(-999);
369 m_out_seed_tanphi.push_back(-999);
372 m_out_seed_nHits.push_back(seed->getHitsInMax().size());
373 unsigned nMdtSeed{0}, nRpcSeed{0}, nTgcSeed{0}, nMmSeed{0}, nsTgcSeed{0};
374 unsigned nPrecHits{0}, nEtaHits{0}, nPhiHits{0}, nTrueHits{0}, nTruePrecHits{0}, nTrueEtaHits{0}, nTruePhiHits{0};
375 std::vector<unsigned char>
matched{};
376 for (
const HoughHitType & houghSP: seed->getHitsInMax()){
377 if (m_writeSpacePoints){
378 unsigned treeIdx = m_spTester->push_back(*houghSP);
379 if (treeIdx >=
matched.size()){
385 nPhiHits += houghSP->measuresPhi();
386 nEtaHits += houghSP->measuresEta();
388 if (m_visionTool.isEnabled()) {
389 nTrueHits += m_visionTool->isLabeled(*houghSP);
390 nTruePrecHits += m_visionTool->isLabeled(*houghSP) &&
isPrecHit(*houghSP);
391 nTruePhiHits += m_visionTool->isLabeled(*houghSP) && houghSP->measuresPhi();
392 nTrueEtaHits += m_visionTool->isLabeled(*houghSP) && houghSP->measuresEta();
394 switch (houghSP->type()) {
399 nRpcSeed+=houghSP->measuresEta();
400 nRpcSeed+=houghSP->measuresPhi();
403 nTgcSeed+=houghSP->measuresEta();
404 nTgcSeed+=houghSP->measuresPhi();
407 nsTgcSeed += houghSP->measuresEta();
408 nsTgcSeed += houghSP->measuresPhi();
414 ATH_MSG_WARNING(
"Technology "<<houghSP->identify() <<
" not yet implemented");
417 m_out_seed_nMdt.push_back(nMdtSeed);
418 m_out_seed_nRpc.push_back(nRpcSeed);
419 m_out_seed_nTgc.push_back(nTgcSeed);
420 m_out_seed_nsTgc.push_back(nsTgcSeed);
421 m_out_seed_nMm.push_back(nMmSeed);
423 m_out_seed_nPrecHits.push_back(nPrecHits);
424 m_out_seed_nEtaHits.push_back(nEtaHits);
425 m_out_seed_nPhiHits.push_back(nPhiHits);
427 m_out_seed_nTrueHits.push_back(nTrueHits);
428 m_out_seed_nTruePrecHits.push_back(nTruePrecHits);
429 m_out_seed_nTrueEtaHits.push_back(nTrueEtaHits);
430 m_out_seed_nTruePhiHits.push_back(nTruePhiHits);
432 m_out_seed_ledToSegment.push_back(
obj.matchedSeedFoundSegment.at(iseed));
433 if (m_writeSpacePoints) {
434 m_spMatchedToPattern[iseed] = std::move(
matched);
441 using namespace SegmentFit;
443 m_out_segment_n =
obj.matchedSegments.size();
445 m_out_segment_hasPhi.push_back(std::ranges::find_if(
segment->measurements(), [](
const auto& meas){ return meas->measuresPhi();})
446 !=
segment->measurements().end());
447 m_out_segment_fitIter.push_back(
segment->nFitIterations());
449 m_out_segment_chi2.push_back(
segment->chi2());
450 m_out_segment_nDoF.push_back(
segment->nDoF());
451 m_out_segment_hasTimeFit.push_back(
segment->hasTimeFit());
453 m_out_segment_err_x0.push_back(
segment->covariance()(Acts::toUnderlying(ParamDefs::x0), Acts::toUnderlying(ParamDefs::x0)));
454 m_out_segment_err_y0.push_back(
segment->covariance()(Acts::toUnderlying(ParamDefs::y0), Acts::toUnderlying(ParamDefs::y0)));
461 m_out_segment_y0.push_back(locPos.y());
462 m_out_segment_x0.push_back(locPos.x());
463 m_out_segment_time.push_back(
segment->segementT0() +
segment->position().mag() * c_inv);
465 unsigned nMdtHits{0}, nRpcEtaHits{0}, nRpcPhiHits{0}, nTgcEtaHits{0}, nTgcPhiHits{0},
466 nMmEtaHits{0}, nMmStereoHits{0}, nStgcStripHits{0},nStgcWireHits{0}, nStgcPadHits{0};
467 unsigned nTrueHits{0}, nTruePrecHits{0}, nTrueEtaHits{0}, nTruePhiHits{0};
472 std::vector<unsigned char>
matched;
473 for (
const auto & meas :
segment->measurements()){
476 minYhit =
std::min(meas->localPosition().y(),minYhit);
477 maxYhit =
std::max(meas->localPosition().y(),maxYhit);
478 if (m_writeSpacePoints) {
479 unsigned treeIdx = m_spTester->push_back(*meas->spacePoint());
480 if (treeIdx >=
matched.size()){
485 if (m_visionTool.isEnabled()) {
486 nTrueHits += m_visionTool->isLabeled(*meas->spacePoint());
487 nTruePrecHits +=
isPrecHit(*meas) && m_visionTool->isLabeled(*meas->spacePoint());
488 nTrueEtaHits += meas->measuresEta() && m_visionTool->isLabeled(*meas->spacePoint());
489 nTruePhiHits += meas->measuresPhi() && m_visionTool->isLabeled(*meas->spacePoint());
491 switch (meas->type()) {
496 nRpcEtaHits += meas->measuresEta();
497 nRpcPhiHits += meas->measuresPhi();
500 nTgcEtaHits += meas->measuresEta();
501 nTgcPhiHits += meas->measuresPhi();
504 const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
505 nMmEtaHits += !idHelper.
isStereo(meas->spacePoint()->identify());
506 nMmStereoHits += !idHelper.isStereo(meas->spacePoint()->identify());
509 const auto* prd =
static_cast<const xAOD::sTgcMeasurement*
>(meas->spacePoint()->primaryMeasurement());
510 nStgcStripHits += prd->
channelType() == sTgcIdHelper::sTgcChannelTypes::Strip;
511 nStgcWireHits += prd->channelType() == sTgcIdHelper::sTgcChannelTypes::Wire;
512 nStgcPadHits += prd->channelType() == sTgcIdHelper::sTgcChannelTypes::Pad;
515 nStgcWireHits += prd->
channelType() == sTgcIdHelper::sTgcChannelTypes::Wire;
516 nStgcPadHits += prd->channelType() == sTgcIdHelper::sTgcChannelTypes::Pad;
523 m_out_segment_nMdtHits.push_back(nMdtHits);
524 m_out_segment_nRpcEtaHits.push_back(nRpcEtaHits);
525 m_out_segment_nRpcPhiHits.push_back(nRpcPhiHits);
526 m_out_segment_nTgcEtaHits.push_back(nTgcEtaHits);
527 m_out_segment_nTgcPhiHits.push_back(nTgcPhiHits);
529 m_out_segment_nMmEtaHits.push_back(nMmEtaHits);
530 m_out_segment_nMmStereoHits.push_back(nMmStereoHits);
531 m_out_segment_nsTgcStripHits.push_back(nStgcStripHits);
532 m_out_segment_nsTgcWireHits.push_back(nStgcWireHits);
533 m_out_segment_nsTgcPadpHits.push_back(nStgcPadHits);
536 m_out_segment_nTrueHits.push_back(nTrueHits);
537 m_out_segment_nTruePrecHits.push_back(nTruePrecHits);
538 m_out_segment_nTruePhiHits.push_back(nTruePhiHits);
539 m_out_segment_nTrueEtaHits.push_back(nTrueEtaHits);
541 m_out_segment_minYhit.push_back(minYhit);
542 m_out_segment_maxYhit.push_back(maxYhit);
543 if (m_writeSpacePoints) {
544 m_spMatchedToSegment.push_back(std::move(
matched));