10#include "GaudiKernel/ConcurrencyFlags.h"
31 constexpr double inverseSpeedOfLight = 1 / Gaudi::Units::c_light;
38 std::ostringstream sout;
39 sout <<
" sector " <<
intersection.layerSurface.sector <<
" "
70 return StatusCode::SUCCESS;
79 extend(inDetCandidates, tagMap, combTracks, meTracks, segments, ctx);
84 const EventContext& ctx)
const {
87 if (meTracks)
ATH_MSG_DEBUG(
"Not currently creating ME tracks for staus");
91 std::unique_ptr<MuonStauRecoTool::TruthInfo>
95 truthParticleLinkAcc(
"truthParticleLink");
99 return std::make_unique<TruthInfo>((*truthLink)->pdgId(), (*truthLink)->m(), (*truthLink)->p4().Beta());
108 ATH_MSG_DEBUG(
" skip silicon associated track for extension ");
121 std::unique_ptr<TruthInfo> truthInfo(
getTruth(indetTrackParticle));
125 ATH_MSG_DEBUG(
"Truth reconstruction enabled: skipping ID track with pdgId: " << (truthInfo ? truthInfo->pdgId : 0));
134 msg(MSG::INFO) <<
" ID track: pt " << indetTrackParticle.
pt() <<
" eta " << indetTrackParticle.
eta() <<
" phi "
135 << indetTrackParticle.
phi();
136 if (truthInfo)
msg(MSG::INFO) << truthInfo->toString();
137 if (!muonSystemExtension)
msg(MSG::INFO) <<
" failed muonSystemExtension";
142 if (!muonSystemExtension) {
return; }
187 addTag(indetCandidate, *candidates.front(), tagMap, combTracks, segments);
196 for (
auto& candidate : candidates) {
197 ATH_MSG_DEBUG(
" candidate: betaseed beta" << candidate->betaSeed.beta <<
", error" << candidate->betaSeed.error
198 <<
" layerDataVec size" << candidate->layerDataVec.size() <<
" hits size"
199 << candidate->hits.size());
201 float beta = candidate->betaFitResult.beta;
203 for (
const auto& layerData : candidate->layerDataVec) {
205 std::vector<std::shared_ptr<const Muon::MuonSegment>> segments;
208 for (
const auto& maximumData : layerData.maximumDataVec) {
214 if (segments.empty())
continue;
222 std::vector<std::shared_ptr<const Muon::MuonSegment>> selectedSegments;
226 for (
const auto& seg : selectedSegments)
m_recoValidationTool->add(layerData.intersection, *seg, 3);
230 candidate->allLayers.emplace_back(layerData.intersection, std::move(selectedSegments));
234 if (!candidate->allLayers.empty()) refinedCandidates.push_back(candidate);
238 candidates = refinedCandidates;
242 msg(MSG::INFO) <<
" Summary::refineCandidates ";
243 if (candidates.empty())
244 msg(MSG::INFO) <<
" No candidated found ";
246 msg(MSG::INFO) <<
" candidates " << candidates.size();
248 for (
const auto& candidate : candidates) {
249 msg(MSG::INFO) << std::endl
250 <<
" candidate: beta fit result: beta " << candidate->betaFitResult.beta <<
" chi2/ndof "
251 << candidate->betaFitResult.chi2PerDOF() <<
" layers with segments" << candidate->allLayers.size();
252 for (
const auto& layer : candidate->allLayers)
253 msg(MSG::INFO) << std::endl
259 return !candidates.empty();
266 if (!mdtCalibConstants.
isValid()) {
268 throw std::runtime_error(
"Failed to retrieve calibration constants");
272 if (!combinedTrack)
return;
284 ATH_MSG_WARNING(
" track without states, cannot extractTimeMeasurementsFromTrack ");
291 typedef std::vector<const Muon::MuonClusterOnTrack*> RpcClVec;
292 using RpcClPerChMap = std::map<Identifier, std::tuple<const Trk::TrackParameters*, RpcClVec, RpcClVec>>;
293 RpcClPerChMap rpcPrdsPerChamber;
295 using MdtTubeData = std::pair<const Trk::TrackParameters*, const Muon::MdtDriftCircleOnTrack*>;
296 using MdtTubeDataVec = std::vector<MdtTubeData>;
297 using MdtChamberLayerData = std::map<int, MdtTubeDataVec>;
298 MdtChamberLayerData mdtDataPerChamberLayer;
303 for (; tsit != tsit_end; ++tsit) {
325 if (
stName[2] ==
'R') { chIndexWithBIR += 1000; }
327 mdtDataPerChamberLayer[chIndexWithBIR].push_back(std::make_pair(pars, mdt));
330 float distance = pars->position().mag();
333 float ix = pars->position().x();
334 float iy = pars->position().y();
335 float iz = pars->position().z();
345 float locR = pars->parameters()[
Trk::locR];
347 auto data = mdtCalibConstants->getCalibData(
id, msgStream());
348 const auto& rtRelation =
data->rtRelation;
349 float drdt = rtRelation->rt()->driftVelocity(driftTime);
350 float rres = rtRelation->rtRes()->resolution(driftTime);
351 float tres = rres / drdt;
352 float TlocR = rtRelation->tr()->driftTime(std::abs(locR)).value_or(0.);
353 float trackTimeRes = errR / drdt;
354 float tofShiftFromBeta =
calculateTof(betaSeed, distance) - tof;
355 er = std::sqrt(tres * tres + trackTimeRes * trackTimeRes);
357 time = driftTime - TlocR + tofShiftFromBeta;
358 propTime = driftTime;
362 std::unique_ptr<const Trk::TrackParameters> unbiasedPars(
365 float locRu = unbiasedPars->parameters()[
Trk::locR];
366 float TlocRu = rtRelation->tr()->driftTime(std::abs(locRu)).value_or(0.);
367 float errRu = unbiasedPars->covariance() ?
Amg::error(*unbiasedPars->covariance(),
Trk::locR) : 0.3;
368 float trackTimeResu = errRu / drdt;
370 time = driftTime - TlocRu + tofShiftFromBeta;
371 er = std::sqrt(tres * tres + trackTimeResu * trackTimeResu);
373 ATH_MSG_VERBOSE(
" Got unbiased parameters: r " << locR <<
" ur " << locRu <<
" err " << errR <<
" uerr "
374 << errRu <<
" terr " << trackTimeRes <<
" terru "
380 <<
" TlocR " << TlocR <<
" diff " << driftTime - TlocR <<
" tofShift " << tofShiftFromBeta
381 <<
" time " << time <<
" err " << er <<
" intrinsic " << tres <<
" track " << trackTimeRes);
385 << beta <<
" diff " << std::abs(beta - betaSeed));
388 candidate.
stauHits.emplace_back(
MuGirlNS::StauHit(tech, time + tof, ix, iy, iz,
id, ie, er,
sh, isEta, propTime,
false));
399 candidate.
stauHits.emplace_back(
MuGirlNS::StauHit(tech, time + tof, ix, iy, iz,
id, ie, er,
sh, isEta, propTime,
true));
409 std::vector<const Muon::MuonClusterOnTrack*> clusters;
415 if (rpc) clusters.push_back(rpc);
419 auto pos = rpcPrdsPerChamber.find(chamberId);
420 if (pos == rpcPrdsPerChamber.end()) {
422 rpcPrdsPerChamber[chamberId] = std::make_tuple(pars, clusters, RpcClVec());
424 rpcPrdsPerChamber[chamberId] = std::make_tuple(pars, RpcClVec(), clusters);
426 RpcClVec& clVec = measuresPhi ? std::get<1>(pos->second) : std::get<2>(pos->second);
427 clVec.insert(clVec.end(), clusters.begin(), clusters.end());
433 float distance = pars->position().mag();
436 float ix = pars->position().x();
437 float iy = pars->position().y();
438 float iz = pars->position().z();
445 candidate.
stauHits.push_back(
MuGirlNS::StauHit(tech, time + tof, ix, iy, iz,
id, ie, er,
sh, isEta, propTime));
451 if (clusters.empty())
return;
453 std::vector<const Muon::MuonClusterOnTrack*> calibratedClusters;
454 for (
const auto* cluster : clusters) {
456 if (cl) calibratedClusters.push_back(cl);
458 if (calibratedClusters.empty())
return;
461 for (
const auto* cl : calibratedClusters)
delete cl;
462 if (!
result.valid)
return;
467 float distance = pars.position().mag();
469 float ix = pars.position().x();
470 float iy = pars.position().y();
471 float iz = pars.position().z();
482 <<
" diff " << std::abs(beta - betaSeed));
487 candidate.
stauHits.push_back(
MuGirlNS::StauHit(tech, time + tof, ix, iy, iz,
id, ie, er,
sh, isEta, propTime));
491 RpcClPerChMap::const_iterator chit = rpcPrdsPerChamber.begin();
492 RpcClPerChMap::const_iterator chit_end = rpcPrdsPerChamber.end();
495 for (; chit != chit_end; ++chit) {
497 const RpcClVec& phiClusters = std::get<1>(chit->second);
498 const RpcClVec& etaClusters = std::get<2>(chit->second);
499 insertRpcs(*pars, phiClusters, candidate, hits);
500 insertRpcs(*pars, etaClusters, candidate, hits);
515 MdtChamberLayerData::const_iterator mit = mdtDataPerChamberLayer.begin();
516 MdtChamberLayerData::const_iterator mit_end = mdtDataPerChamberLayer.end();
517 for (; mit != mit_end; ++mit) {
519 <<
" hits " << mit->second.size());
520 if (mit->second.size() < 4)
continue;
526 ATH_MSG_WARNING(
"MdtReadoutElement should always have a PlaneSurface as reference surface");
543 std::vector<std::pair<std::shared_ptr<const Muon::MdtDriftCircleOnTrack>,
const Trk::TrackParameters*>> indexLookUp;
545 for (
const auto& entry : mit->second) {
550 std::unique_ptr<const Muon::MdtDriftCircleOnTrack> calibratedMdt(
552 if (!calibratedMdt) {
559 <<
" r_track " << pars.parameters()[
Trk::locR] <<
" residual "
571 double r = std::abs(calibratedMdt->driftRadius());
582 dcs.push_back(dcOnTrack);
583 indexLookUp.emplace_back(std::move(calibratedMdt), &pars);
588 for (
unsigned int i = 0; i < dcs.size(); ++i) {
598 unsigned int ndofFit = segment.
ndof();
599 if (ndofFit < 1)
continue;
600 double chi2NdofSegmentFit = segment.
chi2() / ndofFit;
601 bool hasDropHit =
false;
602 unsigned int dropDepth = 0;
603 if (!segmentFinder.
dropHits(segment, hasDropHit, dropDepth)) {
604 ATH_MSG_DEBUG(
"DropHits failed, fit chi2/ndof " << chi2NdofSegmentFit);
605 if (
msgLvl(MSG::VERBOSE)) {
608 segmentFinder.
dropHits(segment, hasDropHit, dropDepth);
613 if (i >= segment.
dcs().size())
continue;
618 double pull =
res / err;
621 if (index < 0 || index >= (
int)indexLookUp.size()) {
622 ATH_MSG_WARNING(
" lookup of TrackParameters and MdtDriftCircleOnTrack failed " <<
index <<
" range: 0 - "
623 << indexLookUp.size() - 1);
631 std::shared_ptr<const Muon::MdtDriftCircleOnTrack> calibratedMdt(
633 if (!calibratedMdt.get()) {
637 float distance = pars->position().mag();
640 float ix = pars->position().x();
641 float iy = pars->position().y();
642 float iz = pars->position().z();
654 float driftTime = calibratedMdt->driftTime();
657 auto data = mdtCalibConstants->getCalibData(
id, msgStream());
658 const auto& rtRelation =
data->rtRelation;
659 float drdt = rtRelation->rt()->driftVelocity(driftTime);
660 float rres = rtRelation->rtRes()->resolution(driftTime);
661 float tres = rres / drdt;
662 float TlocR = rtRelation->tr()->driftTime(std::abs(locR)).value_or(0.);
663 float trackTimeRes = errR / drdt;
664 float tofShiftFromBeta = 0.;
665 er = std::sqrt(tres * tres + trackTimeRes * trackTimeRes);
667 time = driftTime - TlocR + tofShiftFromBeta;
668 propTime = driftTime;
675 msg(MSG::DEBUG) <<
m_idHelperSvc->toString(
id) << std::setprecision(2) <<
" segment: after fit " << std::setw(5)
676 << chi2NdofSegmentFit <<
" ndof " << std::setw(2) << ndofFit;
677 if (segment.
ndof() != ndofFit)
678 msg(MSG::DEBUG) <<
" after outlier " << std::setw(5) << chi2NdofSegmentFit <<
" ndof " << std::setw(2) << ndofFit;
679 msg(MSG::DEBUG) <<
" driftR " << std::setw(4) << dc.
r() <<
" rline " << std::setw(5) << rline <<
" residual "
680 << std::setw(5) <<
res <<
" pull " << std::setw(4) << pull <<
" time " << std::setw(3) << time
681 <<
" beta" << std::setw(2) << beta <<
" err " << std::setw(3) << er <<
" intrinsic " << std::setw(3)
682 << tres <<
" track " << std::setw(3) << trackTimeRes;
683 if (!isSelected)
msg(MSG::DEBUG) <<
" outlier";
684 msg(MSG::DEBUG) << std::setprecision(5) <<
endmsg;
689 candidate.
stauHits.emplace_back(
MuGirlNS::StauHit(
MuGirlNS::MDTT_STAU_HIT, time + tof, ix, iy, iz,
id, ie, er,
sh, isEta, propTime,
false));
699 hits.emplace_back(distance, time, er);
700 candidate.
stauHits.emplace_back(
MuGirlNS::MDTT_STAU_HIT, time + tof, ix, iy, iz,
id, ie, er,
sh, isEta, propTime,
true);
708 ATH_MSG_DEBUG(
" extractTimeMeasurementsFromTrack: extracted " << candidate.
stauHits.size() <<
" time measurements "
709 <<
" status fit " << betaFitResult.
status <<
" beta "
710 << betaFitResult.
beta <<
" chi2/ndof " << betaFitResult.
chi2PerDOF());
723 std::vector<ElementLink<Trk::SegmentCollection>> segmentLinks;
724 for (
const auto& layer : candidate.
allLayers) {
725 for (
const auto& segment : layer.segments) {
728 segmentLinks.push_back(segLink);
739 std::unique_ptr<MuGirlNS::StauExtras> stauExtras = std::make_unique<MuGirlNS::StauExtras>();
742 stauExtras->hits = candidate.
stauHits;
748 tag->setStauExtras(std::move(stauExtras));
752 msg(MSG::INFO) <<
" Summary::addTag ";
753 msg(MSG::INFO) << std::endl
754 <<
" candidate: beta fit result: beta " << candidate.
betaFitResult.
beta <<
" chi2/ndof "
756 for (
const auto& segment : segmentLinks)
msg(MSG::INFO) << std::endl <<
" " <<
m_printer->print(**segment);
758 msg(MSG::INFO) << std::endl
759 <<
" track " <<
m_printer->print(**comblink) << std::endl
765 tagMap->
addEntry(&indetCandidate, tag);
769 ATH_MSG_DEBUG(
"Resolving ambiguities: candidates " << candidates.size());
773 std::map<const Trk::Track*, std::shared_ptr<Candidate>> trackCandidateLookup;
774 for (
const auto& candidate : candidates) {
775 Trk::Track* track = candidate->combinedTrack.get();
778 trackCandidateLookup[track] = candidate;
783 if (tracks.
empty())
return false;
784 if (tracks.
size() == 1)
return true;
788 if (!resolvedTracks || resolvedTracks->empty()) {
792 const Trk::Track* selectedTrack = resolvedTracks->front();
795 auto pos = trackCandidateLookup.find(selectedTrack);
796 if (pos == trackCandidateLookup.end()) {
802 std::shared_ptr<Candidate> candidate = pos->second;
804 candidates.push_back(candidate);
808 msg(MSG::INFO) <<
" Summary::resolveAmbiguities ";
809 msg(MSG::INFO) << std::endl
810 <<
" candidate: beta fit result: beta " << candidate->betaFitResult.beta <<
" chi2/ndof "
811 << candidate->betaFitResult.chi2PerDOF() <<
" layers with segments" << candidate->allLayers.size() << std::endl
812 <<
" track " <<
m_printer->print(*candidate->combinedTrack) << std::endl
813 <<
m_printer->printStations(*candidate->combinedTrack);
827 for (
auto& candidate : candidates) {
829 std::pair<std::unique_ptr<const Muon::MuonCandidate>, std::unique_ptr<Trk::Track>>
result =
837 candidate->muonCandidate = std::move(
result.first);
838 candidate->combinedTrack = std::move(
result.second);
842 combinedCandidates.push_back(candidate);
848 candidates = combinedCandidates;
852 msg(MSG::INFO) <<
" Summary::combineCandidates ";
853 if (candidates.empty())
854 msg(MSG::INFO) <<
" No candidated found ";
856 msg(MSG::INFO) <<
" candidates " << candidates.size();
858 for (
const auto& candidate : candidates) {
859 msg(MSG::INFO) << std::endl
860 <<
" candidate: beta fit result: " << candidate->betaFitResult.beta <<
" chi2/ndof "
861 << candidate->betaFitResult.chi2PerDOF();
862 if (candidate->finalBetaFitResult.status != 0)
863 msg(MSG::INFO) <<
" MDTT beta fit result: " << candidate->finalBetaFitResult.beta <<
" chi2/ndof "
864 << candidate->finalBetaFitResult.chi2PerDOF();
865 msg(MSG::INFO) <<
" layers with segments" << candidate->allLayers.size() << std::endl
866 <<
" track " <<
m_printer->print(*candidate->combinedTrack) << std::endl
867 <<
m_printer->printStations(*candidate->combinedTrack);
872 return !candidates.empty();
879 LayerDataVec::const_iterator it = associatedData.
layerData.begin();
880 LayerDataVec::const_iterator it_end = associatedData.
layerData.end();
881 for (; it != it_end; ++it) {
883 for (
const auto& maximumData : it->maximumDataVec) {
885 if (!maximumData->betaSeeds.empty()) seedMaximumDataVec.push_back(maximumData);
888 ATH_MSG_DEBUG(
"Creating candidates from seeds " << seedMaximumDataVec.size());
890 if (seedMaximumDataVec.empty()) {
896 auto SortMaximumDataVec = [](
const std::shared_ptr<MaximumData>& max1,
const std::shared_ptr<MaximumData>& max2) {
897 return max1->maximum->max < max2->maximum->max;
899 std::stable_sort(seedMaximumDataVec.begin(), seedMaximumDataVec.end(), SortMaximumDataVec);
903 std::set<const MaximumData*> usedMaximumData;
904 MaximumDataVec::iterator sit = seedMaximumDataVec.begin();
905 MaximumDataVec::iterator sit_end = seedMaximumDataVec.end();
906 for (; sit != sit_end; ++sit) {
908 if (usedMaximumData.count(sit->get()))
continue;
909 usedMaximumData.insert(sit->get());
913 for (
const auto& betaSeed : (*sit)->betaSeeds) { newCandidates.push_back(std::make_shared<Candidate>(betaSeed)); }
918 for (
auto& newCandidate : newCandidates) {
920 newCandidate->betaFitResult = fitter.fitWithOutlierLogic(newCandidate->hits);
922 << newCandidate->hits.size() <<
" status " << newCandidate->betaFitResult.status <<
" beta "
923 << newCandidate->betaFitResult.beta <<
" chi2/ndof " << newCandidate->betaFitResult.chi2PerDOF());
925 if (newCandidate->betaFitResult.status != 0) {
926 newCandidate->combinedTrack =
nullptr;
927 candidates.push_back(newCandidate);
934 msg(MSG::INFO) <<
" Summary::createCandidates ";
935 if (candidates.empty())
936 msg(MSG::INFO) <<
" No candidated found ";
938 msg(MSG::INFO) <<
" candidates " << candidates.size();
940 for (
const auto& candidate : candidates) {
941 msg(MSG::INFO) << std::endl
942 <<
" candidate: beta seed " << candidate->betaSeed.beta <<
" beta fit result: beta "
943 << candidate->betaFitResult.beta <<
" chi2/ndof " << candidate->betaFitResult.chi2PerDOF() <<
" layers "
944 << candidate->layerDataVec.size();
945 for (
const auto& layerData : candidate->layerDataVec)
946 msg(MSG::INFO) << std::endl
948 << layerData.maximumDataVec.size();
953 return !candidates.empty();
957 MuonStauRecoTool::LayerDataVec::const_iterator it,
958 MuonStauRecoTool::LayerDataVec::const_iterator it_end)
const {
965 for (
auto& candidate : candidates) {
967 unsigned int nextensions = 0;
980 if (nextensions == 0)
981 theCandidate = candidate.get();
983 std::shared_ptr<Candidate> newCandidate = std::make_shared<Candidate>(candidate->betaSeed);
984 newCandidate->layerDataVec = layerDataVec;
985 newCandidate->hits = hits;
986 theCandidate = newCandidate.get();
987 newCandidates.emplace_back(std::move(newCandidate));
995 theCandidate->
hits.insert(theCandidate->
hits.end(), newhits.begin(), newhits.end());
997 usedMaximumData.insert(maximumData.get());
999 ATH_MSG_DEBUG(
" adding maximumData: candidate hits " << theCandidate->
hits.size() <<
" LayerDataVec "
1000 << theCandidate->
layerDataVec.size() <<
" nextensions "
1007 ATH_MSG_DEBUG(
" extendCandidates done, new candidates " << newCandidates.size());
1010 candidates.insert(candidates.end(), newCandidates.begin(), newCandidates.end());
1014 if (it != it_end)
extendCandidates(candidates, usedMaximumData, it, it_end);
1030 associatedData.
layerData.push_back(layerData);
1038 std::vector<std::shared_ptr<const Muon::MuonSegment>> t0fittedSegments;
1040 if (t0fittedSegments.empty())
continue;
1052 msg(MSG::INFO) <<
" Summary::extractTimeMeasurements ";
1054 msg(MSG::INFO) <<
" No layers associated ";
1056 msg(MSG::INFO) <<
" Associated layers " << associatedData.
layerData.size();
1058 for (
const auto& layerData : associatedData.
layerData) {
1059 unsigned int nmaxWithBeta = 0;
1060 for (
const auto& maximumData : layerData.maximumDataVec) {
1061 if (!maximumData->betaSeeds.empty()) ++nmaxWithBeta;
1063 msg(MSG::INFO) << std::endl
1065 << layerData.maximumDataVec.size() <<
" maxima with beta seeds " << nmaxWithBeta;
1071 return !associatedData.
layerData.empty();
1076 unsigned int nstart = hits.size();
1078 auto addHit = [&](
float distance,
float time,
float error,
float cut) {
1081 ATH_MSG_VERBOSE(
" matching hit: distance " << distance <<
" time " << time <<
" beta" << beta <<
" diff "
1082 << std::abs(beta - seed->beta));
1083 if (std::abs(beta - seed->beta) > cut)
return;
1085 ATH_MSG_VERBOSE(
" addHit: distance " << distance <<
" time " << time <<
" beta"
1088 if (
error != 0.) hits.emplace_back(distance, time,
error);
1093 float time = rpc.time;
1094 float error = rpc.error;
1103 if (!seg->hasFittedT0())
continue;
1104 float time = seg->time();
1105 float error = seg->errorTime();
1113 float smallestResidual = FLT_MAX;
1115 if (!seg->hasFittedT0())
continue;
1116 float distance = seg->globalPosition().mag();
1117 float time = seg->time();
1119 float residual = std::abs(beta - seed->beta);
1121 if (residual < smallestResidual) {
1122 smallestResidual = residual;
1123 bestSegment = seg.get();
1131 ATH_MSG_VERBOSE(
" extractTimeHits done: added " << hits.size() - nstart <<
" hits");
1133 return nstart != hits.size();
1146 float chi2ndof =
result.chi2PerDOF();
1148 ATH_MSG_DEBUG(
" fitting beta for maximum: time measurements " << hits.size() <<
" status " <<
result.status <<
" beta "
1149 <<
result.beta <<
" chi2/ndof " << chi2ndof);
1154 std::vector<std::shared_ptr<const Muon::MuonSegment>>& segments,
1155 const ToolHandle<Muon::IMuonPRDSelectionTool>& muonPRDSelectionTool,
1156 const ToolHandle<Muon::IMuonSegmentMaker>& segmentMaker,
1159 const std::vector<std::shared_ptr<const Muon::MuonClusterOnTrack>>& phiClusterOnTracks = maximumData.
phiClusterOnTracks;
1163 std::vector<const Muon::MdtDriftCircleOnTrack*>& mdts,
1166 if (mdt) mdts.push_back(mdt);
1171 std::vector<const Muon::MuonClusterOnTrack*>& clusters) {
1173 if (cluster) clusters.push_back(cluster);
1177 std::vector<const Muon::MdtDriftCircleOnTrack*> mdts;
1178 std::vector<const Muon::MuonClusterOnTrack*> clusters;
1181 clusters.reserve(phiClusterOnTracks.size());
1183 for (
const auto& phiClusterOnTrack : phiClusterOnTracks) { clusters.push_back(phiClusterOnTrack->clone()); }
1187 MuonHough::HitVec::const_iterator hit = maximum.
hits.begin();
1188 MuonHough::HitVec::const_iterator hit_end = maximum.
hits.end();
1189 for (; hit != hit_end; ++hit) {
1190 ATH_MSG_DEBUG(
"hit x,y_min,y_max,w = " << (*hit)->x <<
"," << (*hit)->ymin <<
"," << (*hit)->ymax <<
"," << (*hit)->w);
1193 for (
const auto& prd : (*hit)->tgc->etaCluster) handleCluster(*prd, clusters);
1194 }
else if ((*hit)->prd) {
1212 if (mdts.size() > 2) {
1215 segmentMaker->find(
intersection.trackParameters->position(),
intersection.trackParameters->momentum(), mdts, clusters,
1216 !clusters.empty(), segColl.get(),
intersection.trackParameters->momentum().mag(), 0, beta);
1220 for (; sit != sit_end; ++sit) {
1225 segments.push_back(std::shared_ptr<const Muon::MuonSegment>(mseg));
1230 for (
const auto* hit : mdts)
delete hit;
1231 for (
const auto* hit : clusters)
delete hit;
1238 std::map<Identifier, std::vector<const Muon::RpcPrepData*>> rpcPrdsPerChamber;
1245 rpcPrdsPerChamber[chamberId].push_back(rpcPrd);
1250 MuonHough::HitVec::const_iterator hit = maximum.
hits.begin();
1251 MuonHough::HitVec::const_iterator hit_end = maximum.
hits.end();
1252 for (; hit != hit_end; ++hit) {
1253 if ((*hit)->tgc || !(*hit)->prd || !
m_idHelperSvc->isRpc((*hit)->prd->identify()))
continue;
1254 addRpc((*hit)->prd);
1258 for (
const auto& rot : maximumData.
phiClusterOnTracks) { addRpc(rot->prepRawData()); }
1261 if (rpcPrdsPerChamber.empty())
return;
1263 std::map<Identifier, std::vector<const Muon::RpcPrepData*>>
::iterator chit = rpcPrdsPerChamber.begin();
1264 std::map<Identifier, std::vector<const Muon::RpcPrepData*>>
::iterator chit_end = rpcPrdsPerChamber.end();
1265 for (; chit != chit_end; ++chit) {
1268 if (!clustering.
cluster(chit->second)) {
1274 <<
" eta clusters " << clustering.
clustersEta.size() <<
" phi clusters " << clustering.
clustersPhi.size());
1281 const std::vector<Muon::RpcClusterObj>& clusterObjects,
1284 for (
const auto& cluster : clusterObjects) {
1285 if (cluster.hitList.empty() || !cluster.hitList.front()) {
1290 << cluster.hitList.size());
1293 std::vector<const Muon::MuonClusterOnTrack*> clusters;
1294 for (
const auto* rpc : cluster.hitList) {
1297 clusters.push_back(rot);
1309 for (
const auto* cl : clusters) {
1311 if (rcl) rpcTimeMeasurement.
rpcClusters.push_back(std::shared_ptr<const Muon::RpcClusterOnTrack>(rcl));
1313 rpcTimeMeasurements.push_back(rpcTimeMeasurement);
1316 for (
const auto* cl : clusters)
delete cl;
1333 if (!houghDataPerSectorVec.
isValid()) {
1339 if (
static_cast<int>(houghDataPerSectorVec->vec.size()) <= sector - 1) {
1341 <<
" larger than the available sectors in the Hough tool: " << houghDataPerSectorVec->vec.size());
1350 if (houghDataPerSector.
maxVec.size() <= layHash) {
1351 ATH_MSG_WARNING(
" houghDataPerSector.maxVec.size() smaller than hash " << houghDataPerSector.
maxVec.size() <<
" hash "
1356 if (maxVec.empty())
return;
1368 float errx =
intersection.trackParameters->covariance() ?
1370 float x = barrelLike ?
z :
r;
1371 float y = barrelLike ?
r :
z;
1372 float theta = std::atan2(
y,
x);
1376 ATH_MSG_DEBUG(
" Got Phi Hough maxima " << phiMaxVec.size() <<
" phi " <<
phi);
1380 std::vector<std::shared_ptr<const Muon::MuonClusterOnTrack>>& clusters) {
1382 if (cluster) clusters.push_back(std::move(cluster));
1387 std::vector<std::shared_ptr<const Muon::MuonClusterOnTrack>> phiClusterOnTracks;
1388 Muon::MuonLayerHoughTool::PhiMaximumVec::const_iterator pit = phiMaxVec.begin();
1389 Muon::MuonLayerHoughTool::PhiMaximumVec::const_iterator pit_end = phiMaxVec.end();
1390 for (; pit != pit_end; ++pit) {
1392 for (
const std::shared_ptr<MuonHough::PhiHit>& hit : maximum.
hits) {
1395 Identifier id = hit->tgc->phiCluster.front()->identify();
1397 for (
const Muon::MuonCluster* prd : hit->tgc->phiCluster) handleCluster(*prd, phiClusterOnTracks);
1402 handleCluster(
static_cast<const Muon::MuonCluster&
>(*hit->prd), phiClusterOnTracks);
1408 <<
"," <<
y <<
") errorx " << errx <<
" "
1409 <<
" angle " <<
theta);
1412 for (
const auto& mit : maxVec) {
1414 if (std::find_if(maximum.
hits.begin(),maximum.
hits.end(),
1415 [](
const std::shared_ptr<MuonHough::Hit>& hit){
1416 return hit->prd && (hit->prd->type(Trk::PrepRawDataType::sTgcPrepData) ||
1417 hit->prd->type(Trk::PrepRawDataType::MMPrepData));
1418 }) != maximum.
hits.end())
continue;
1419 float residual = maximum.
pos -
x;
1427 const float pullUncert = std::sqrt(errx * errx + maxwidth * maxwidth / 12.);
1428 float pull = residual / (pullUncert > std::numeric_limits<float>::epsilon() ? pullUncert : 1.) ;
1430 ATH_MSG_DEBUG(
" Hough maximum " << maximum.
max <<
" position (" << refPos <<
"," << maximum.
pos <<
") residual " << residual
1431 <<
" pull " << pull <<
" angle " << maximum.
theta <<
" residual " << residualTheta);
1436 if (std::abs(pull) > 5)
continue;
1454 return std::abs(beta) > 0 ? dist * inverseSpeedOfLight / beta : 1.e12;
1459 return time != 0. ? dist * inverseSpeedOfLight / time : 20.;
1463 if (Gaudi::Concurrency::ConcurrencyFlags::numThreads() > 1) {
1464 ATH_MSG_WARNING(
"You are calling the non thread-safe MuonRecoValidationTool with multiple threads, will most likely crash");
1469 for (
const auto& candidate : candidates) {
1472 float chi2ndof = -1.;
1473 if (candidate->finalBetaFitResult.status != 0) {
1474 ntimes = candidate->stauHits.size();
1475 beta = candidate->finalBetaFitResult.beta;
1476 chi2ndof = candidate->finalBetaFitResult.chi2PerDOF();
1477 }
else if (candidate->betaFitResult.status != 0) {
1478 ntimes = candidate->hits.size();
1479 beta = candidate->betaFitResult.beta;
1480 chi2ndof = candidate->betaFitResult.chi2PerDOF();
1483 beta = candidate->betaSeed.beta;
1486 if (candidate->combinedTrack)
ATH_MSG_DEBUG(
"candidate has combined track");
1487 m_recoValidationTool->addMuonCandidate(indetTrackParticle, candidate->muonCandidate.get(), candidate->combinedTrack.get(),
1488 ntimes, beta, chi2ndof, stage);
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
Helper class to provide constant type-safe access to aux data.
char data[hepevt_bytes_allocation_ATLAS]
DataVector< MuonCombined::InDetCandidate > InDetCandidateCollection
This typedef represents a collection of InDetCandidate objects.
std::pair< std::vector< unsigned int >, bool > res
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
bool msgLvl(const MSG::Level lvl) const
DataModel_detail::const_iterator< DataVector > const_iterator
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DataModel_detail::iterator< DataVector > iterator
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
ElementLink implementation for ROOT usage.
bool isValid() const
Test to see if the link can be dereferenced.
void addEntry(const InDetCandidate *idcand, TagBase *tag)
bool isSiliconAssociated() const
Returns true if this candidate was formed from a special far forward InDet track.
const xAOD::TrackParticle & indetTrackParticle() const
access TrackParticle
const Muon::MuonSystemExtension * getExtension() const
TagBase implementation for a combined fit.
virtual const Trk::Surface & surface() const override final
Return surface associated with this detector element.
virtual Amg::Transform3D GlobalToAmdbLRSTransform() const
Class for competing MuonClusters, it extends the Trk::CompetingRIOsOnTrack base class.
const std::vector< const MuonClusterOnTrack * > & containedROTs() const
returns the vector of SCT_ClusterOnTrack objects .
Class to represent the calibrated clusters created from CSC strips.
virtual const CscPrepData * prepRawData() const override final
Returns the CscPrepData - is a CscPrepData in this scope.
double time() const
Returns the time.
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
double driftRadius() const
Returns the value of the drift radius.
double driftTime() const
Returns the value of the drift time used to obtain the drift radius.
virtual const Trk::StraightLineSurface & associatedSurface() const override final
Returns the surface on which this measurement was taken.
virtual const MdtPrepData * prepRawData() const override final
Returns the PrepRawData used to create this corrected measurement.
Class to represent measurements from the Monitored Drift Tubes.
int adc() const
Returns the ADC (typically range is 0 to 250)
Base class for Muon cluster RIO_OnTracks.
Class representing clusters in the muon system.
void setStrategy(Strategy)
Select the strategy to be used - only one can be set at a time.
void setParameter(CreationParameter, bool value)
@ Segment
Treating a segment or a track.
This is the common class for 3D segments used in the muon spectrometer.
virtual const Amg::Vector3D & globalPosition() const override final
global position
Tracking class to hold the extrapolation from a particle from the calo entry to the end of muon syste...
const std::vector< Intersection > & layerIntersections() const
access to the intersections with the layers.
Class to represent calibrated clusters formed from RPC strips.
float time() const
Return the time (ns)
Class to represent RPC measurements.
std::vector< Hit > HitVec
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
class representing a drift circle meaurement on segment
void residual(double res)
set residual
void errorTrack(double error)
set track error
virtual bool fit(Segment &result, const Line &line, const DCOnTrackVec &dcs, double t0Seed=-99999.) const
This class represents a drift time measurement.
unsigned int index() const
double r() const
access to drift radius
const LocVec2D & position() const
access to local position
double dr() const
access to error drift radius
@ InTime
drift time too small to be compatible with drift spectrum
Implementation of 2 dimensional vector class.
void setMaxDropDepth(int max)
bool dropHits(Segment &segment, bool &hasDroppedHit, unsigned int &dropDepth) const
void setDeltaCut(double cut)
void debugLevel(int debugLevel)
void setChi2DropCut(double chi2)
void hitsOnTrack(unsigned int hitsOnTrack)
const Line & line() const
const DCOnTrackVec & dcs() const
unsigned int ndof() const
represents the three-dimensional global direction with respect to a planar surface frame.
double angleYZ() const
access method for angle of local YZ projection
This class is the pure abstract base class for all fittable tracking measurements.
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
virtual bool type(MeasurementBaseType::Type type) const =0
Interface method checking the type.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
virtual Intersection straightLineIntersection(const Amg::Vector3D &pos, const Amg::Vector3D &dir, bool forceDir, Trk::BoundaryCheck bchk) const override final
fast straight line intersection schema - standard: provides closest intersection and (signed) path le...
void globalToLocalDirection(const Amg::Vector3D &glodir, Trk::LocalDirection &locdir) const
This method transforms the global direction to a local direction wrt the plane.
Identifier identify() const
return the identifier
Identifier identify() const
return the identifier -extends MeasurementBase
Base class for all TrackSegment implementations, extends the common MeasurementBase.
float errorTime() const
access to the error on the measured time
float time() const
access to the measured time
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const override final
Specified for StraightLineSurface: LocalToGlobal method without dynamic memory allocation.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
const Trk::Track * track() const
Returns a pointer (which can be NULL) to the Trk::Track which was used to make this TrackParticle.
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
const std::string selection
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
The MuonTagToSegMap is an auxillary construct that links the MuonSegments associated with a combined ...
std::string printIntersectionToString(const Muon::MuonSystemExtension::Intersection &intersection)
const std::string & layerName(LayerIndex index)
convert LayerIndex into a string
DetectorRegionIndex
enum to classify the different layers in the muon spectrometer
constexpr int toInt(const EnumType enumVal)
unsigned int sectorLayerHash(DetectorRegionIndex detectorRegionIndex, LayerIndex layerIndex)
create a hash out of region and layer
const std::string & stName(StIndex index)
convert StIndex into a string
const std::string & chName(ChIndex index)
convert ChIndex into a string
const std::string & regionName(DetectorRegionIndex index)
convert DetectorRegionIndex into a string
LayerIndex
enum to classify the different layers in the muon spectrometer
ChIndex
enum to classify the different chamber layers in the muon spectrometer
std::bitset< 23 > MuonDriftCircleErrorStrategyInput
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
std::vector< bool > HitSelection
std::vector< DCOnTrack > DCOnTrackVec
DataVector< const Trk::TrackStateOnSurface > TrackStates
DataVector< Trk::Segment > SegmentCollection
ParametersBase< TrackParametersDim, Charged > TrackParameters
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
const Muon::MdtPrepDataContainer * mdtPrds
struct representing the maximum in the hough space
const MuonLayerHough * hough
RegionDescriptor m_descriptor
RegionPhiMaximumVec phiMaxVec
std::vector< RpcClusterObj > clustersEta
bool cluster(const std::vector< const RpcPrepData * > &col)
std::vector< RpcClusterObj > clustersPhi
simple struct holding the fit result
float chi2PerDOF() const
chi2/ndof, return 0 if ndof == 0 or status == 0
float beta
status flag (0 = failed, 1 = ok)
simple struct holding the input to the fit