10 #include "GaudiKernel/ConcurrencyFlags.h"
38 std::ostringstream sout;
39 sout <<
" sector " <<
intersection.layerSurface.sector <<
" "
45 MuonStauRecoTool::MuonStauRecoTool(
const std::string&
type,
const std::string&
name,
const IInterface*
parent) :
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();
137 if (!muonSystemExtension)
msg(
MSG::INFO) <<
" failed muonSystemExtension";
142 if (!muonSystemExtension) {
return; }
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);
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)
266 if (!mdtCalibConstants.isValid()) {
268 throw std::runtime_error(
"Failed to retrieve calibration constants");
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));
333 float ix =
pars->position().x();
334 float iy =
pars->position().y();
335 float iz =
pars->position().z();
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;
355 er = std::sqrt(
tres *
tres + trackTimeRes * trackTimeRes);
357 time =
driftTime - TlocR + tofShiftFromBeta;
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));
389 candidate.
stauHits.emplace_back(
MuGirlNS::StauHit(tech, time + tof, ix, iy, iz,
id,
ie, er,
sh, isEta, propTime));
399 std::vector<const Muon::MuonClusterOnTrack*>
clusters;
409 auto pos = rpcPrdsPerChamber.find(chamberId);
410 if (
pos == rpcPrdsPerChamber.end()) {
412 rpcPrdsPerChamber[chamberId] = std::make_tuple(
pars,
clusters, RpcClVec());
414 rpcPrdsPerChamber[chamberId] = std::make_tuple(
pars, RpcClVec(),
clusters);
416 RpcClVec& clVec = measuresPhi ? std::get<1>(
pos->second) : std::get<2>(
pos->second);
426 float ix =
pars->position().x();
427 float iy =
pars->position().y();
428 float iz =
pars->position().z();
435 candidate.
stauHits.push_back(
MuGirlNS::StauHit(tech, time + tof, ix, iy, iz,
id,
ie, er,
sh, isEta, propTime));
443 std::vector<const Muon::MuonClusterOnTrack*> calibratedClusters;
444 for (
const auto* cluster :
clusters) {
446 if (
cl) calibratedClusters.push_back(
cl);
448 if (calibratedClusters.empty())
return;
451 for (
const auto*
cl : calibratedClusters)
delete cl;
452 if (!
result.valid)
return;
459 float ix =
pars.position().x();
460 float iy =
pars.position().y();
461 float iz =
pars.position().z();
472 <<
" diff " << std::abs(
beta - betaSeed));
477 candidate.stauHits.push_back(
MuGirlNS::StauHit(tech, time + tof, ix, iy, iz,
id,
ie, er,
sh, isEta, propTime));
481 RpcClPerChMap::const_iterator chit = rpcPrdsPerChamber.begin();
482 RpcClPerChMap::const_iterator chit_end = rpcPrdsPerChamber.end();
485 for (; chit != chit_end; ++chit) {
487 const RpcClVec& phiClusters = std::get<1>(chit->second);
488 const RpcClVec& etaClusters = std::get<2>(chit->second);
489 insertRpcs(*
pars, phiClusters, candidate,
hits);
490 insertRpcs(*
pars, etaClusters, candidate,
hits);
505 MdtChamberLayerData::const_iterator mit = mdtDataPerChamberLayer.begin();
506 MdtChamberLayerData::const_iterator mit_end = mdtDataPerChamberLayer.end();
507 for (; mit != mit_end; ++mit) {
509 <<
" hits " << mit->second.size());
510 if (mit->second.size() < 4)
continue;
516 ATH_MSG_WARNING(
"MdtReadoutElement should always have a PlaneSurface as reference surface");
533 std::vector<std::pair<std::shared_ptr<const Muon::MdtDriftCircleOnTrack>,
const Trk::TrackParameters*>> indexLookUp;
535 for (
const auto&
entry : mit->second) {
540 std::unique_ptr<const Muon::MdtDriftCircleOnTrack> calibratedMdt(
542 if (!calibratedMdt) {
549 <<
" r_track " <<
pars.parameters()[
Trk::locR] <<
" residual "
572 dcs.push_back(dcOnTrack);
573 indexLookUp.emplace_back(std::move(calibratedMdt), &
pars);
578 for (
unsigned int i = 0;
i < dcs.size(); ++
i) {
587 segment.hitsOnTrack(dcs.size());
588 unsigned int ndofFit =
segment.ndof();
589 if (ndofFit < 1)
continue;
590 double chi2NdofSegmentFit =
segment.chi2() / ndofFit;
591 bool hasDropHit =
false;
592 unsigned int dropDepth = 0;
594 ATH_MSG_DEBUG(
"DropHits failed, fit chi2/ndof " << chi2NdofSegmentFit);
603 if (
i >=
segment.dcs().size())
continue;
611 if (index < 0 || index >= (
int)indexLookUp.size()) {
612 ATH_MSG_WARNING(
" lookup of TrackParameters and MdtDriftCircleOnTrack failed " <<
index <<
" range: 0 - "
613 << indexLookUp.size() - 1);
621 std::shared_ptr<const Muon::MdtDriftCircleOnTrack> calibratedMdt(
623 if (!calibratedMdt.get()) {
630 float ix =
pars->position().x();
631 float iy =
pars->position().y();
632 float iz =
pars->position().z();
647 auto data = mdtCalibConstants->getCalibData(
id, msgStream());
648 const auto& rtRelation =
data->rtRelation;
649 float drdt = rtRelation->rt()->driftVelocity(
driftTime);
650 float rres = rtRelation->rtRes()->resolution(
driftTime);
651 float tres = rres / drdt;
652 float TlocR = rtRelation->tr()->driftTime(std::abs(
locR)).value_or(0.);
653 float trackTimeRes = errR / drdt;
654 float tofShiftFromBeta = 0.;
655 er = std::sqrt(
tres *
tres + trackTimeRes * trackTimeRes);
657 time =
driftTime - TlocR + tofShiftFromBeta;
666 << chi2NdofSegmentFit <<
" ndof " << std::setw(2) << ndofFit;
668 msg(
MSG::DEBUG) <<
" after outlier " << std::setw(5) << chi2NdofSegmentFit <<
" ndof " << std::setw(2) << ndofFit;
669 msg(
MSG::DEBUG) <<
" driftR " << std::setw(4) << dc.
r() <<
" rline " << std::setw(5) << rline <<
" residual "
670 << std::setw(5) <<
res <<
" pull " << std::setw(4) <<
pull <<
" time " << std::setw(3) << time
671 <<
" beta" << std::setw(2) <<
beta <<
" err " << std::setw(3) << er <<
" intrinsic " << std::setw(3)
672 <<
tres <<
" track " << std::setw(3) << trackTimeRes;
677 if (!isSelected)
continue;
680 candidate.stauHits.emplace_back(
MuGirlNS::MDTT_STAU_HIT, time + tof, ix, iy, iz,
id,
ie, er,
sh, isEta, propTime);
688 ATH_MSG_DEBUG(
" extractTimeMeasurementsFromTrack: extracted " << candidate.stauHits.size() <<
" time measurements "
689 <<
" status fit " << betaFitResult.
status <<
" beta "
690 << betaFitResult.
beta <<
" chi2/ndof " << betaFitResult.
chi2PerDOF());
692 candidate.finalBetaFitResult = betaFitResult;
703 std::vector<ElementLink<Trk::SegmentCollection>> segmentLinks;
708 segmentLinks.push_back(segLink);
719 std::unique_ptr<MuGirlNS::StauExtras> stauExtras = std::make_unique<MuGirlNS::StauExtras>();
728 tag->setStauExtras(std::move(stauExtras));
734 <<
" candidate: beta fit result: beta " << candidate.
betaFitResult.
beta <<
" chi2/ndof "
739 <<
" track " <<
m_printer->print(**comblink) << std::endl
753 std::map<const Trk::Track*, std::shared_ptr<Candidate>> trackCandidateLookup;
757 tracks.push_back(
track);
758 trackCandidateLookup[
track] = candidate;
763 if (tracks.empty())
return false;
764 if (tracks.size() == 1)
return true;
768 if (!resolvedTracks || resolvedTracks->empty()) {
772 const Trk::Track* selectedTrack = resolvedTracks->front();
775 auto pos = trackCandidateLookup.find(selectedTrack);
776 if (
pos == trackCandidateLookup.end()) {
782 std::shared_ptr<Candidate> candidate =
pos->second;
790 <<
" candidate: beta fit result: beta " << candidate->
betaFitResult.
beta <<
" chi2/ndof "
809 std::pair<std::unique_ptr<const Muon::MuonCandidate>, std::unique_ptr<Trk::Track>>
result =
817 candidate->muonCandidate = std::move(
result.first);
818 candidate->combinedTrack = std::move(
result.second);
822 combinedCandidates.push_back(candidate);
840 <<
" candidate: beta fit result: " << candidate->betaFitResult.beta <<
" chi2/ndof "
841 << candidate->betaFitResult.chi2PerDOF();
842 if (candidate->finalBetaFitResult.status != 0)
843 msg(
MSG::INFO) <<
" MDTT beta fit result: " << candidate->finalBetaFitResult.beta <<
" chi2/ndof "
844 << candidate->finalBetaFitResult.chi2PerDOF();
845 msg(
MSG::INFO) <<
" layers with segments" << candidate->allLayers.size() << std::endl
846 <<
" track " <<
m_printer->print(*candidate->combinedTrack) << std::endl
847 <<
m_printer->printStations(*candidate->combinedTrack);
859 LayerDataVec::const_iterator
it = associatedData.
layerData.begin();
860 LayerDataVec::const_iterator it_end = associatedData.
layerData.end();
861 for (;
it != it_end; ++
it) {
863 for (
const auto& maximumData :
it->maximumDataVec) {
865 if (!maximumData->betaSeeds.empty()) seedMaximumDataVec.push_back(maximumData);
868 ATH_MSG_DEBUG(
"Creating candidates from seeds " << seedMaximumDataVec.size());
870 if (seedMaximumDataVec.empty()) {
876 auto SortMaximumDataVec = [](
const std::shared_ptr<MaximumData>&
max1,
const std::shared_ptr<MaximumData>& max2) {
877 return max1->maximum->max < max2->maximum->max;
879 std::stable_sort(seedMaximumDataVec.begin(), seedMaximumDataVec.end(), SortMaximumDataVec);
883 std::set<const MaximumData*> usedMaximumData;
886 for (; sit != sit_end; ++sit) {
888 if (usedMaximumData.count(sit->get()))
continue;
889 usedMaximumData.insert(sit->get());
893 for (
const auto& betaSeed : (*sit)->betaSeeds) { newCandidates.push_back(std::make_shared<Candidate>(betaSeed)); }
898 for (
auto& newCandidate : newCandidates) {
900 newCandidate->betaFitResult =
fitter.fitWithOutlierLogic(newCandidate->hits);
902 << newCandidate->hits.size() <<
" status " << newCandidate->betaFitResult.status <<
" beta "
903 << newCandidate->betaFitResult.beta <<
" chi2/ndof " << newCandidate->betaFitResult.chi2PerDOF());
905 if (newCandidate->betaFitResult.status != 0) {
906 newCandidate->combinedTrack =
nullptr;
922 <<
" candidate: beta seed " << candidate->betaSeed.beta <<
" beta fit result: beta "
923 << candidate->betaFitResult.beta <<
" chi2/ndof " << candidate->betaFitResult.chi2PerDOF() <<
" layers "
924 << candidate->layerDataVec.size();
925 for (
const auto& layerData : candidate->layerDataVec)
928 << layerData.maximumDataVec.size();
937 MuonStauRecoTool::LayerDataVec::const_iterator
it,
938 MuonStauRecoTool::LayerDataVec::const_iterator it_end)
const {
947 unsigned int nextensions = 0;
960 if (nextensions == 0)
961 theCandidate = candidate.get();
963 std::shared_ptr<Candidate> newCandidate = std::make_shared<Candidate>(candidate->betaSeed);
966 theCandidate = newCandidate.get();
967 newCandidates.emplace_back(std::move(newCandidate));
975 theCandidate->
hits.insert(theCandidate->
hits.end(), newhits.begin(), newhits.end());
977 usedMaximumData.insert(maximumData.get());
979 ATH_MSG_DEBUG(
" adding maximumData: candidate hits " << theCandidate->
hits.size() <<
" LayerDataVec "
987 ATH_MSG_DEBUG(
" extendCandidates done, new candidates " << newCandidates.size());
1008 if (layerData.maximumDataVec.empty())
continue;
1010 associatedData.
layerData.push_back(layerData);
1013 for (
auto& maximum : layerData.maximumDataVec) {
1018 std::vector<std::shared_ptr<const Muon::MuonSegment>> t0fittedSegments;
1020 if (t0fittedSegments.empty())
continue;
1032 msg(
MSG::INFO) <<
" Summary::extractTimeMeasurements ";
1038 for (
const auto& layerData : associatedData.
layerData) {
1039 unsigned int nmaxWithBeta = 0;
1040 for (
const auto& maximumData : layerData.maximumDataVec) {
1041 if (!maximumData->betaSeeds.empty()) ++nmaxWithBeta;
1045 << layerData.maximumDataVec.size() <<
" maxima with beta seeds " << nmaxWithBeta;
1051 return !associatedData.
layerData.empty();
1056 unsigned int nstart =
hits.size();
1062 << std::abs(
beta - seed->beta));
1063 if (std::abs(
beta - seed->beta) >
cut)
return;
1073 float time = rpc.time;
1074 float error = rpc.error;
1083 if (!seg->hasFittedT0())
continue;
1084 float time = seg->time();
1085 float error = seg->errorTime();
1093 float smallestResidual = FLT_MAX;
1095 if (!seg->hasFittedT0())
continue;
1096 float distance = seg->globalPosition().mag();
1097 float time = seg->time();
1103 bestSegment = seg.get();
1113 return nstart !=
hits.size();
1126 float chi2ndof =
result.chi2PerDOF();
1128 ATH_MSG_DEBUG(
" fitting beta for maximum: time measurements " <<
hits.size() <<
" status " <<
result.status <<
" beta "
1129 <<
result.beta <<
" chi2/ndof " << chi2ndof);
1134 std::vector<std::shared_ptr<const Muon::MuonSegment>>& segments,
1135 const ToolHandle<Muon::IMuonPRDSelectionTool>& muonPRDSelectionTool,
1136 const ToolHandle<Muon::IMuonSegmentMaker>& segmentMaker,
1139 const std::vector<std::shared_ptr<const Muon::MuonClusterOnTrack>>& phiClusterOnTracks = maximumData.
phiClusterOnTracks;
1143 std::vector<const Muon::MdtDriftCircleOnTrack*>& mdts,
1146 if (mdt) mdts.push_back(mdt);
1151 std::vector<const Muon::MuonClusterOnTrack*>&
clusters) {
1153 if (cluster)
clusters.push_back(cluster);
1157 std::vector<const Muon::MdtDriftCircleOnTrack*> mdts;
1158 std::vector<const Muon::MuonClusterOnTrack*>
clusters;
1161 clusters.reserve(phiClusterOnTracks.size());
1163 for (
const auto& phiClusterOnTrack : phiClusterOnTracks) {
clusters.push_back(phiClusterOnTrack->clone()); }
1167 MuonHough::HitVec::const_iterator hit = maximum.
hits.begin();
1168 MuonHough::HitVec::const_iterator hit_end = maximum.
hits.end();
1169 for (; hit != hit_end; ++hit) {
1170 ATH_MSG_DEBUG(
"hit x,y_min,y_max,w = " << (*hit)->x <<
"," << (*hit)->ymin <<
"," << (*hit)->ymax <<
"," << (*hit)->w);
1173 for (
const auto& prd : (*hit)->tgc->etaCluster) handleCluster(*prd,
clusters);
1174 }
else if ((*hit)->prd) {
1192 if (mdts.size() > 2) {
1200 for (; sit != sit_end; ++sit) {
1205 segments.push_back(std::shared_ptr<const Muon::MuonSegment>(mseg));
1210 for (
const auto* hit : mdts)
delete hit;
1211 for (
const auto* hit :
clusters)
delete hit;
1218 std::map<Identifier, std::vector<const Muon::RpcPrepData*>> rpcPrdsPerChamber;
1225 rpcPrdsPerChamber[chamberId].push_back(rpcPrd);
1230 MuonHough::HitVec::const_iterator hit = maximum.
hits.begin();
1231 MuonHough::HitVec::const_iterator hit_end = maximum.
hits.end();
1232 for (; hit != hit_end; ++hit) {
1233 if ((*hit)->tgc || !(*hit)->prd || !
m_idHelperSvc->isRpc((*hit)->prd->identify()))
continue;
1234 addRpc((*hit)->prd);
1238 for (
const auto& rot : maximumData.
phiClusterOnTracks) { addRpc(rot->prepRawData()); }
1241 if (rpcPrdsPerChamber.empty())
return;
1243 std::map<Identifier, std::vector<const Muon::RpcPrepData*>>
::iterator chit = rpcPrdsPerChamber.begin();
1244 std::map<Identifier, std::vector<const Muon::RpcPrepData*>>
::iterator chit_end = rpcPrdsPerChamber.end();
1245 for (; chit != chit_end; ++chit) {
1248 if (!clustering.
cluster(chit->second)) {
1254 <<
" eta clusters " << clustering.
clustersEta.size() <<
" phi clusters " << clustering.
clustersPhi.size());
1261 const std::vector<Muon::RpcClusterObj>& clusterObjects,
1264 for (
const auto& cluster : clusterObjects) {
1265 if (cluster.hitList.empty() || !cluster.hitList.front()) {
1270 << cluster.hitList.size());
1273 std::vector<const Muon::MuonClusterOnTrack*>
clusters;
1274 for (
const auto* rpc : cluster.hitList) {
1291 if (rcl) rpcTimeMeasurement.
rpcClusters.push_back(std::shared_ptr<const Muon::RpcClusterOnTrack>(rcl));
1293 rpcTimeMeasurements.push_back(rpcTimeMeasurement);
1313 if (!houghDataPerSectorVec.isValid()) {
1319 if (
static_cast<int>(houghDataPerSectorVec->vec.size()) <= sector - 1) {
1321 <<
" larger than the available sectors in the Hough tool: " << houghDataPerSectorVec->vec.size());
1330 if (houghDataPerSector.
maxVec.size() <= layHash) {
1331 ATH_MSG_WARNING(
" houghDataPerSector.maxVec.size() smaller than hash " << houghDataPerSector.
maxVec.size() <<
" hash "
1336 if (maxVec.empty())
return;
1342 float phi =
intersection.trackParameters->position().phi();
1348 float errx =
intersection.trackParameters->covariance() ?
1350 float x = barrelLike ?
z :
r;
1351 float y = barrelLike ?
r :
z;
1352 float theta = std::atan2(
y,
x);
1356 ATH_MSG_DEBUG(
" Got Phi Hough maxima " << phiMaxVec.size() <<
" phi " << phi);
1360 std::vector<std::shared_ptr<const Muon::MuonClusterOnTrack>>&
clusters) {
1362 if (cluster)
clusters.push_back(std::move(cluster));
1367 std::vector<std::shared_ptr<const Muon::MuonClusterOnTrack>> phiClusterOnTracks;
1368 Muon::MuonLayerHoughTool::PhiMaximumVec::const_iterator pit = phiMaxVec.begin();
1369 Muon::MuonLayerHoughTool::PhiMaximumVec::const_iterator pit_end = phiMaxVec.end();
1370 for (; pit != pit_end; ++pit) {
1372 for (
const std::shared_ptr<MuonHough::PhiHit>& hit : maximum.
hits) {
1388 <<
"," <<
y <<
") errorx " << errx <<
" "
1389 <<
" angle " << theta);
1392 for (
const auto& mit : maxVec) {
1394 if (std::find_if(maximum.
hits.begin(),maximum.
hits.end(),
1395 [](
const std::shared_ptr<MuonHough::Hit>& hit){
1396 return hit->prd && (hit->prd->type(Trk::PrepRawDataType::sTgcPrepData) ||
1397 hit->prd->type(Trk::PrepRawDataType::MMPrepData));
1398 }) != maximum.
hits.end())
continue;
1400 float residualTheta = maximum.
theta - theta;
1407 const float pullUncert = std::sqrt(errx * errx + maxwidth * maxwidth / 12.);
1408 float pull =
residual / (pullUncert > std::numeric_limits<float>::epsilon() ? pullUncert : 1.) ;
1411 <<
" pull " <<
pull <<
" angle " << maximum.
theta <<
" residual " << residualTheta);
1416 if (std::abs(
pull) > 5)
continue;
1434 return std::abs(
beta) > 0 ? dist * inverseSpeedOfLight /
beta : 1.e12;
1439 return time != 0. ? dist * inverseSpeedOfLight / time : 20.;
1444 ATH_MSG_WARNING(
"You are calling the non thread-safe MuonRecoValidationTool with multiple threads, will most likely crash");
1452 float chi2ndof = -1.;
1453 if (candidate->finalBetaFitResult.status != 0) {
1454 ntimes = candidate->stauHits.size();
1455 beta = candidate->finalBetaFitResult.beta;
1456 chi2ndof = candidate->finalBetaFitResult.chi2PerDOF();
1457 }
else if (candidate->betaFitResult.status != 0) {
1458 ntimes = candidate->hits.size();
1459 beta = candidate->betaFitResult.beta;
1460 chi2ndof = candidate->betaFitResult.chi2PerDOF();
1463 beta = candidate->betaSeed.beta;
1466 if (candidate->combinedTrack)
ATH_MSG_DEBUG(
"candidate has combined track");
1467 m_recoValidationTool->addMuonCandidate(indetTrackParticle, candidate->muonCandidate.get(), candidate->combinedTrack.get(),