109 return StatusCode::SUCCESS;
112 const std::vector<const InDetCandidateToTagMap*>& tagMaps, OutputData& outputData)
const {
116 std::vector<const MuonCombined::MuonCandidate*> resolvedMuonCandidates;
120 resolveOverlaps(ctx, muonCandidates, tagMaps, resolvedInDetCandidates, resolvedMuonCandidates);
125 unsigned int numIdCan = resolvedInDetCandidates.size();
126 unsigned int numMuCan = muonCandidates ? muonCandidates->
size() : 0;
127 ATH_MSG_DEBUG(
"Creating xAOD::Muons from: " << numIdCan <<
" indet candidates and " << numMuCan <<
" muon candidates ");
130 ATH_MSG_DEBUG(
"MuonCandidates : overlap removal " << muonCandidates->
size() <<
" in, " << resolvedMuonCandidates.size()
134 for (InDetCandidateTags& can : resolvedInDetCandidates) {
147 create(ctx, *can, outputData);
157 if (msgLvl(MSG::VERBOSE) && outputData.clusterContainer) {
158 ATH_MSG_VERBOSE(
"Associated clusters : " << outputData.clusterContainer->size());
165 ATH_MSG_DEBUG(
"MuonCreatorTool::create(...) No extrapolated track - aborting. Will not create Muon.");
170 xAOD::Muon* muon = outputData.muonContainer->push_back(std::make_unique<xAOD::Muon>());
173 muon->setAuthor(xAOD::Muon::Author::MuidSA);
174 muon->setMuonType(xAOD::Muon::MuonType::MuonStandAlone);
175 muon->addAllAuthor(xAOD::Muon::Author::MuidSA);
180 using TrackParticleType = xAOD::Muon::TrackParticleType;
181 if (
m_requireMSOEforSA && !muon->trackParticle(TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle)) {
182 ATH_MSG_DEBUG(
"Creation of track particle for SA muon failed, removing it");
183 outputData.muonContainer->pop_back();
189 outputData.muonContainer->pop_back();
193 const xAOD::TrackParticle* track = muon->trackParticle(TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle);
194 if (!track) track = muon->primaryTrackParticle();
195 std::unique_ptr<Trk::CaloExtension> caloExtension =
m_caloExtTool->caloExtension(ctx, *track);
197 ATH_MSG_DEBUG(
"failed to get a calo extension for this SA muon, discard it");
198 outputData.muonContainer->pop_back();
202 ATH_MSG_DEBUG(
"failed to retrieve any calo layers for this SA muon, discard it");
203 outputData.muonContainer->pop_back();
218 addMuGirl(ctx, muon,
nullptr, outputData);
222 acc_nUnspoiledCscHits(muon) = 0;
223 acc_MuonSpectrometerPt(muon) = -1;
224 acc_InnerDetectorPt(muon) = -1;
226 acc_ET_Core(muon) = 0;
227 acc_ET_EMCore(muon) = 0;
228 acc_ET_TileCore(muon) = 0;
229 acc_ET_HECCore(muon) = 0;
235 if (candidate.second.empty()) {
236 ATH_MSG_DEBUG(
"MuonCreatorTool::create(...) - InDetCandidate with empty combinedDataTags. Aborting. Will not create Muon.");
239 const std::vector<const TagBase*>&
tags = candidate.second;
242 if (muGirlLowBetaTag) {
243 ATH_MSG_DEBUG(
"Track has only a MuGirlLowBetaTag but Staus are not being built, so will not create muon");
250 outputData.muonContainer->push_back(muon);
256 muon->setTrackParticleLink(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle, candidate.first->indetTrackParticleLink());
257 ATH_MSG_DEBUG(
"Adding InDet Track: pt " << candidate.first->indetTrackParticle().pt() <<
" eta "
258 << candidate.first->indetTrackParticle().eta() <<
" phi "
259 << candidate.first->indetTrackParticle().phi());
273 if (muGirlLowBetaTag) {
276 muon->setAuthor(tag->author());
277 muon->setMuonType(tag->type());
279 if (tag->type() == xAOD::Muon::MuonType::Combined) {
283 if (outputData.slowMuonContainer) {
284 xAOD::SlowMuon* slowMuon = outputData.slowMuonContainer->push_back(std::make_unique<xAOD::SlowMuon>());
289 ATH_MSG_DEBUG(
"slowMuon muonContainer size " << outputData.muonContainer->size());
291 if (slowMuon && muonLink.
isValid()) {
301 if (muGirlLowBetaTag)
continue;
305 ATH_MSG_DEBUG(
"MuonCreatorTool first muon tag: author=" << tag->author() <<
" type=" << tag->type());
306 muon->setAuthor(tag->author());
307 muon->setMuonType(tag->type());
309 if (candidate.first->isSiliconAssociated()) {
310 muon->setMuonType(xAOD::Muon::MuonType::SiliconAssociatedForwardMuon);
315 muon->addAllAuthor(tag->author());
318 xAOD::Muon::MuonType
type = tag->type();
319 if (
type == xAOD::Muon::MuonType::Combined) {
326 addMuGirl(ctx, *muon, muGirlTag, outputData);
328 if (!(cbFitTag || stacoTag || muGirlTag)) {
ATH_MSG_WARNING(
"Unknown combined tag "); }
330 }
else if (
type == xAOD::Muon::MuonType::SegmentTagged) {
335 addMuGirl(ctx, *muon, muGirlTag, outputData);
337 if (!(segTag || muGirlTag)) {
ATH_MSG_WARNING(
"Unknown segment-tagged tag "); }
338 }
else if (
type == xAOD::Muon::MuonType::CaloTagged) {
350 outputData.muonContainer->pop_back();
358 bool haveEloss = muon->parameter(eLoss, xAOD::Muon::ParamDef::EnergyLoss);
359 if (!haveEloss || eLoss == 0) {
368 ATH_MSG_DEBUG(
"Done creating muon with " << acc_nUnspoiledCscHits(*muon) <<
" unspoiled csc hits");
374 const StacoTag* tag, OutputData& outputData)
const {
386 acc_phi0(muon) = -999;
387 acc_theta(muon) = -999;
388 acc_qOverP(muon) = -999;
389 acc_qOverPerr(muon) = -999.;
393 ATH_MSG_DEBUG(
"Adding Staco Muon " << tag->author() <<
" type " << tag->type());
395 if (!muon.trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)) {
399 const Trk::Track* msTrack = tag->muonCandidate().extrapolatedTrack() ? tag->muonCandidate().extrapolatedTrack()
400 : &tag->muonCandidate().muonSpectrometerTrack();
406 if (idSummary) summary += *idSummary;
407 if (msSummary) summary += *msSummary;
413 if (outputData.combinedTrackParticleContainer) {
415 xAOD::muon, outputData.combinedTrackParticleContainer);
421 std::vector<float> dummy_cov(15, 0.);
425 outputData.combinedTrackParticleContainer->size() - 1);
426 if (link.isValid()) {
428 ATH_MSG_DEBUG(
"Adding statistical combination: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi "
430 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::CombinedTrackParticle, link);
436 std::bitset<xAOD::NumberOfTrackRecoInfo> pattern;
442 (*accessor)( *tp ) = (*accessor)( id_track_particle );
445 (*accessor)( *tp ) = (*accessor)( id_track_particle );
456 muon.setParameter(5, xAOD::Muon::ParamDef::msInnerMatchDOF);
457 muon.setParameter(
static_cast<float>(tag->matchChi2()), xAOD::Muon::ParamDef::msInnerMatchChi2);
460 acc_d0(muon) = tag->combinedParameters().parameters()[
Trk::d0];
461 acc_z0(muon) = tag->combinedParameters().parameters()[
Trk::z0];
462 acc_phi0(muon) = tag->combinedParameters().parameters()[
Trk::phi0];
463 acc_theta(muon) = tag->combinedParameters().parameters()[
Trk::theta];
464 acc_qOverP(muon) = tag->combinedParameters().parameters()[
Trk::qOverP];
467 ATH_MSG_DEBUG(
"Done adding Staco Muon " << tag->author() <<
" type " << tag->type());
471 OutputData& outputData)
const {
477 ATH_MSG_DEBUG(
"Adding Combined fit Muon " << tag->author() <<
" type " << tag->type());
478 if (!muon.trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)) {
480 if (outputData.combinedTrackParticleContainer) {
483 ctx, tag->combinedTrackLink(), *outputData.combinedTrackParticleContainer, outputData.combinedTrackCollection);
485 if (link.isValid()) {
487 ATH_MSG_DEBUG(
"Adding combined fit: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi " << (*link)->phi());
488 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::CombinedTrackParticle, link);
494 addMuonCandidate(ctx, tag->muonCandidate(), muon, outputData, tag->updatedExtrapolatedTrackLink());
497 const float inner_chi2 = tag->matchChi2();
498 muon.setParameter(tag->matchDoF(), xAOD::Muon::ParamDef::msInnerMatchDOF);
499 muon.setParameter(inner_chi2, xAOD::Muon::ParamDef::msInnerMatchChi2);
501 ATH_MSG_DEBUG(
"Done adding Combined Fit Muon " << tag->author() <<
" type " << tag->type());
508 OutputData& outputData)
const {
514 ATH_MSG_DEBUG(
"Adding MuGirlLowBeta Muon " << tag->author() <<
" type " << tag->type());
518 if (slowMuon && stauExtras) {
541 std::vector<uint8_t>& eTechVec = eTechAcc(*slowMuon);
542 std::vector<unsigned int>& idVec = idAcc(*slowMuon);
543 std::vector<float>& mToFVec = mToFAcc(*slowMuon);
544 std::vector<float>& xVec = xAcc(*slowMuon);
545 std::vector<float>& yVec = yAcc(*slowMuon);
546 std::vector<float>& zVec = zAcc(*slowMuon);
547 std::vector<float>& eVec = eAcc(*slowMuon);
548 std::vector<float>& errorVec = errorAcc(*slowMuon);
549 std::vector<float>& shiftVec = shiftAcc(*slowMuon);
550 std::vector<float>& propagationTimeVec = propTimeAcc(*slowMuon);
551 std::vector<uint8_t>& passesMDTBetaCutVec = hitPassesMDTBetaCutAcc(*slowMuon);
553 for (
const auto& hit : stauExtras->
hits) {
554 eTechVec.push_back(hit.eTech);
555 idVec.push_back(hit.id.get_identifier32().get_compact());
556 mToFVec.push_back(hit.mToF);
557 xVec.push_back(hit.x);
558 yVec.push_back(hit.y);
559 zVec.push_back(hit.z);
560 eVec.push_back(hit.e);
561 errorVec.push_back(hit.error);
562 shiftVec.push_back(hit.shift);
563 propagationTimeVec.push_back(hit.propagationTime);
564 passesMDTBetaCutVec.push_back(hit.passesMDTBetaCut ? uint8_t{1} : uint8_t{0});
572 std::vector<int>& adcVec = adcAcc(*slowMuon);
573 std::vector<float>& rdriftVec = rdriftAcc(*slowMuon);
577 adcVec.push_back(extraMDTinfo.adc);
578 rdriftVec.push_back(extraMDTinfo.rdrift);
586 if (!muon.trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle) && tag->combinedTrack()) {
588 if (outputData.combinedTrackParticleContainer) {
591 ctx, tag->combinedTrackLink(), *outputData.combinedTrackParticleContainer, outputData.combinedTrackCollection);
593 if (link.isValid()) {
594 ATH_MSG_DEBUG(
"Adding MuGirlLowBeta: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi " << (*link)->phi());
595 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::CombinedTrackParticle, link);
597 ATH_MSG_WARNING(
"Creating of MuGirlLowBeta TrackParticle Link failed");
601 if (outputData.xaodSegmentContainer) {
603 std::vector<ElementLink<xAOD::MuonSegmentContainer>> segments;
606 if (link.isValid()) {
607 segments.push_back(link);
608 ATH_MSG_DEBUG(
"Adding MuGirlLowBeta: xaod::MuonSegment px " << (*link)->px() <<
" py " << (*link)->py() <<
" pz "
613 muon.setMuonSegmentLinks(segments);
623 ATH_MSG_DEBUG(
"Adding MuGirl Muon " << tag->author() <<
" type " << tag->type());
625 if (!muon.trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle) && tag->combinedTrack()) {
627 if (outputData.combinedTrackParticleContainer) {
630 ctx, tag->combinedTrackLink(), *outputData.combinedTrackParticleContainer, outputData.combinedTrackCollection);
632 if (link.isValid()) {
634 ATH_MSG_DEBUG(
"Adding MuGirl: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi " << (*link)->phi());
635 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::CombinedTrackParticle, link);
640 if (outputData.extrapolatedTrackParticleContainer && tag->updatedExtrapolatedTrack()) {
644 outputData.extrapolatedTrackCollection);
646 if (link.isValid()) {
647 ATH_MSG_DEBUG(
"Adding MuGirl: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi " << (*link)->phi());
648 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle, link);
653 if (outputData.xaodSegmentContainer) {
656 std::vector<ElementLink<xAOD::MuonSegmentContainer>> segments;
659 if (link.isValid()) {
660 segments.push_back(link);
661 ATH_MSG_DEBUG(
"Adding MuGirl: xaod::MuonSegment px " << (*link)->px() <<
" py " << (*link)->py() <<
" pz "
666 muon.setMuonSegmentLinks(segments);
669 ATH_MSG_DEBUG(
"Done Adding MuGirl Muon " << tag->author() <<
" type " << tag->type());
675 using enum xAOD::Muon::ParamDef;
676 muon.setParameter(-1.f, segmentDeltaEta);
677 muon.setParameter(-1.f, segmentDeltaPhi);
678 muon.setParameter(-1.f, segmentChi2OverDoF);
682 ATH_MSG_DEBUG(
"Adding Segment Tag Muon " << tag->author() <<
" type " << tag->type());
684 std::vector<ElementLink<xAOD::MuonSegmentContainer>> segments;
685 bool foundseg =
false;
686 for (
const auto& info : tag->segmentsInfo()) {
691 if (muon.author() == xAOD::Muon::Author::MuTagIMO) {
693 if (seglink.
isValid()) segments.push_back(seglink);
697 muon.setParameter(
static_cast<float>(info.dtheta), xAOD::Muon::ParamDef::segmentDeltaEta);
698 muon.setParameter(
static_cast<float>(info.dphi), xAOD::Muon::ParamDef::segmentDeltaPhi);
699 muon.setParameter(
static_cast<float>(info.segment->fitQuality()->chiSquared() / info.segment->fitQuality()->numberDoF()),
700 xAOD::Muon::ParamDef::segmentChi2OverDoF);
702 }
else if (muon.author() != xAOD::Muon::Author::MuTagIMO)
706 if (muon.author() == xAOD::Muon::Author::MuTagIMO) muon.setMuonSegmentLinks(segments);
716 mu.setParameter(0.f, xAOD::Muon::ParamDef::CaloMuonScore);
717 mu.setParameter(
static_cast<int>(0xFF), xAOD::Muon::ParamDef::CaloMuonIDTag);
721 acc_ET_Core(mu) = 0.0;
722 acc_ElType(mu) = -999.0;
723 acc_ElFSREnergy(mu) = -999.0;
728 ATH_MSG_DEBUG(
"Adding Calo Muon with author " << tag->author() <<
", type " << tag->type() <<
", CaloMuonScore "
729 << tag->caloMuonScore());
730 mu.setParameter(
static_cast<float>(tag->caloMuonScore()), xAOD::Muon::ParamDef::CaloMuonScore);
731 mu.setParameter(
static_cast<int>(tag->caloMuonIdTag()), xAOD::Muon::ParamDef::CaloMuonIDTag);
736 acc_ET_Core(mu) = tag->etCore();
737 acc_ElType(mu) = tag->energyLossType();
738 acc_ElFSREnergy(mu) = tag->fsrCandidateEnergy();
744 const EventContext& ctx,
749 if (trackCollection) {
772 const OutputData& outData)
const {
773 if (outData.xaodSegmentContainer && outData.tagToSegmentAssocMap) {
776 unsigned int link = outData.tagToSegmentAssocMap->linkIndex(trkSeg);
777 if (link >= outData.xaodSegmentContainer->size()) {
789 if (!muon.nMuonSegments()) {
790 std::vector< ElementLink<xAOD::MuonSegmentContainer>> segments;
793 if (link.isValid()) {
794 segments.push_back(link);
795 ATH_MSG_DEBUG(
"Adding MuGirl: xaod::MuonSegment px " << (*link)->px() <<
" py " << (*link)->py() <<
" pz "
801 muon.setMuonSegmentLinks(segments);
804 if (muon.trackParticle(xAOD::Muon::TrackParticleType::MuonSpectrometerTrackParticle)) {
return; }
808 if (muon.author() != xAOD::Muon::Author::MuGirl)
809 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::MuonSpectrometerTrackParticle, candidate.
muonSpectrometerTrackLink());
812 if (!outputData.extrapolatedTrackParticleContainer || (!candidate.
extrapolatedTrack() && !meLink.
isValid())) {
return; }
817 ATH_MSG_DEBUG(
"There is no extrapolated track associated to the MuonCandidate.");
818 if (muon.author() == xAOD::Muon::Author::MuidCo) {
822 ctx, meLink, *outputData.extrapolatedTrackParticleContainer, outputData.extrapolatedTrackCollection);
823 if (link.isValid()) {
824 ATH_MSG_DEBUG(
"Adding standalone fit (refitted): pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi "
826 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle, link);
827 float fieldInt =
m_trackQuery->fieldIntegral(**meLink, ctx).betweenSpectrometerMeasurements();
828 muon.setParameter(fieldInt, xAOD::Muon::ParamDef::spectrometerFieldIntegral);
830 acc_nUnspoiledCscHits(muon) = nunspoiled;
834 if (!extrapolatedTrack)
ATH_MSG_WARNING(
"Track doesn't have extrapolated track. Skipping");
837 "Track doesn't have perigee parameters on extrapolated "
844 if (muon.muonType() != xAOD::Muon::MuonType::MuonStandAlone) {
846 if (outputData.msOnlyExtrapolatedTrackParticleContainer) {
852 outputData.msOnlyExtrapolatedTrackCollection);
854 if (link.isValid()) {
855 ATH_MSG_DEBUG(
"Adding MS-only extrapolated track: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi "
858 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::MSOnlyExtrapolatedMuonSpectrometerTrackParticle, link);
860 ATH_MSG_WARNING(
"failed to create MS-only extrapolated track particle");
864 ctx, meLink, *outputData.extrapolatedTrackParticleContainer, outputData.extrapolatedTrackCollection);
865 if (link.isValid()) {
866 ATH_MSG_DEBUG(
"Adding standalone fit (refitted): pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi "
868 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle, link);
869 float fieldInt =
m_trackQuery->fieldIntegral(**meLink, ctx).betweenSpectrometerMeasurements();
870 muon.setParameter(fieldInt, xAOD::Muon::ParamDef::spectrometerFieldIntegral);
872 acc_nUnspoiledCscHits(muon) = nunspoiled;
876 if (muon.author() == xAOD::Muon::Author::MuGirl && muon.trackParticle(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle)) {
882 outputData.msOnlyExtrapolatedTrackCollection);
884 if (link.isValid()) {
885 ATH_MSG_DEBUG(
"Adding MS-only extrapolated track to MuGirl muon: pt "
886 << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi " << (*link)->phi());
888 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::MSOnlyExtrapolatedMuonSpectrometerTrackParticle, link);
891 muon.setParameter(fieldInt, xAOD::Muon::ParamDef::spectrometerFieldIntegral);
896 outputData.extrapolatedTrackCollection);
898 if (link.isValid()) {
899 ATH_MSG_DEBUG(
"Adding standalone fit (un-refitted): pt " << (*link)->pt() <<
" eta " << (*link)->eta()
900 <<
" phi " << (*link)->phi());
902 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle, link);
905 muon.setParameter(fieldInt, xAOD::Muon::ParamDef::spectrometerFieldIntegral);
913 outputData.extrapolatedTrackCollection);
915 if (link.isValid()) {
916 ATH_MSG_DEBUG(
"Adding standalone fit: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi " << (*link)->phi());
918 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle, link);
921 muon.setParameter(fieldInt, xAOD::Muon::ParamDef::spectrometerFieldIntegral);
923 acc_nUnspoiledCscHits(muon) = nunspoiled;
932 const std::vector<const InDetCandidateToTagMap*>& tagMaps)
const {
933 resolvedInDetCandidates.clear();
935 if (!tag_map)
continue;
936 for (
const auto& combined_tag : *tag_map) {
937 const TagBase* tag = combined_tag.second.get();
939 if (muGirlLowBetaTag) { resolvedInDetCandidates.emplace_back(combined_tag.first, std::vector<const TagBase*>{tag}); }
944 if (msgLvl(MSG::DEBUG)) {
945 ATH_MSG_DEBUG(
"ID candidates: " << tagMaps.size() <<
" after stau selection " << resolvedInDetCandidates.size());
946 for (
const InDetCandidateTags& candidate : resolvedInDetCandidates) {
947 msg(MSG::DEBUG) <<
"ID candidate staus: " << candidate.first->toString() <<
endmsg;
953 std::stable_sort(resolvedInDetCandidates.begin(), resolvedInDetCandidates.end(),
954 [](
const InDetCandidateTags&
a,
const InDetCandidateTags& b) {
955 return a.first->indetTrackParticle().pt() > b.first->indetTrackParticle().pt();
960 const std::vector<const InDetCandidateToTagMap*>& tagMaps,
962 std::vector<const MuonCombined::MuonCandidate*>& resolvedMuonCandidates)
const {
963 resolvedMuonCandidates.clear();
964 resolvedInDetCandidates.clear();
966 std::unique_ptr<const TrackCollection> resolvedTracks;
967 std::vector<std::unique_ptr<Trk::Track>> garbage_collection;
974 if (!tag_map)
continue;
975 for (
const auto& comb_tag : *tag_map) {
976 const TagBase* tag = comb_tag.second.get();
980 InDetCandidateTagsMap::iterator itr =
981 std::find_if(inDetCandidateMap.begin(), inDetCandidateMap.end(),
982 [&comb_tag](
const InDetCandidateTags& to_test) { return (*to_test.first) == (*comb_tag.first); });
983 if (itr != inDetCandidateMap.end())
984 itr->second.emplace_back(tag);
986 inDetCandidateMap.emplace_back(std::make_pair(comb_tag.first, std::vector<const TagBase*>{tag}));
993 if (!inDetCandidateMap.empty()) {
999 resolvedInDetCandidates.reserve(inDetCandidateMap.size());
1000 caloMuons.reserve(inDetCandidateMap.size());
1001 for (InDetCandidateTags& comb_tag : inDetCandidateMap) {
1003 if (comb_tag.second.size() == 1 && comb_tag.second.front()->type() == xAOD::Muon::MuonType::CaloTagged) {
1004 caloMuons.emplace_back(std::move(comb_tag));
1006 resolvedInDetCandidates.emplace_back(std::move(comb_tag));
1008 inDetCandidateMap.clear();
1011 if (msgLvl(MSG::DEBUG)) {
1012 ATH_MSG_DEBUG(
"Found " << resolvedInDetCandidates.size() <<
" inner detector tags in event "
1013 << ctx.eventID().event_number());
1014 for (
const InDetCandidateTags& candidate : resolvedInDetCandidates) {
1015 std::stringstream
tags;
1016 for (
const TagBase* tag : candidate.second)
tags <<
" " << tag->toString();
1017 ATH_MSG_DEBUG(
"ID candidate: " << candidate.first->toString() <<
" " <<
tags.str());
1023 to_resolve.reserve(resolvedInDetCandidates.size());
1024 garbage_collection.reserve(resolvedInDetCandidates.size());
1028 std::map<const Trk::Track*, InDetCandidateTags> trackInDetCandLinks;
1030 for (InDetCandidateTags& candidate : resolvedInDetCandidates) {
1032 const TagBase* primaryTag = candidate.second[0];
1039 trackInDetCandLinks[to_resolve.
back()] = std::move(candidate);
1045 if (!segments.empty()) {
1047 garbage_collection.emplace_back(
1050 to_resolve.
push_back(garbage_collection.back().get());
1052 trackInDetCandLinks[garbage_collection.back().get()] = std::move(candidate);
1056 resolvedInDetCandidates.clear();
1062 for (
const Trk::Track* track : *resolvedTracks) {
1063 std::map<const Trk::Track*, InDetCandidateTags>::iterator trackCandLink = trackInDetCandLinks.find(track);
1064 if (trackCandLink == trackInDetCandLinks.end()) {
1065 ATH_MSG_WARNING(
"Unable to find internal link between MS track and ID candidate!");
1068 resolvedInDetCandidates.push_back(std::move(trackCandLink->second));
1072 if (msgLvl(MSG::VERBOSE)) {
1074 << resolvedInDetCandidates.size() <<
" trackCandLinks: " << trackInDetCandLinks.size()
1075 <<
" to_resolve: " << to_resolve.size() <<
" resolvedTracks: " << resolvedTracks->size());
1076 for (
const InDetCandidateTags& candidate : resolvedInDetCandidates) {
1077 ATH_MSG_DEBUG(
"ID candidate: " << candidate.first->toString() <<
" " << candidate.second[0]->toString());
1080 for (
const InDetCandidateTags& candidate : caloMuons) {
1081 ATH_MSG_DEBUG(
"ID candidate: " << candidate.first->toString() <<
" " << candidate.second[0]->toString());
1085 resolvedInDetCandidates.insert(resolvedInDetCandidates.end(), caloMuons.begin(), caloMuons.end());
1088 std::stable_sort(resolvedInDetCandidates.begin(), resolvedInDetCandidates.end(),
1089 [](
const InDetCandidateTags&
a,
const InDetCandidateTags& b) {
1090 return a.first->indetTrackParticle().pt() > b.first->indetTrackParticle().pt();
1096 if (!muonCandidates) {
return; }
1098 if (msgLvl(MSG::DEBUG)) {
1104 if (resolvedTracks) { resolvedTracks2.
assign(resolvedTracks->begin(), resolvedTracks->end()); }
1106 std::set<const MuonCandidate*> used_candidates;
1107 for (
const InDetCandidateTags& indet_cand : resolvedInDetCandidates) {
1108 for (
const TagBase* tag : indet_cand.second) {
1110 if (tag->author() == xAOD::Muon::Author::MuidCo) {
1113 }
else if (tag->author() == xAOD::Muon::Author::STACO && indet_cand.second[0] == tag) {
1122 std::map<const Trk::Track*, const MuonCandidate*> trackMuonCandLinks;
1124 const Trk::Track* track = candidate->primaryTrack();
1125 if (used_candidates.count(candidate)) {
1129 used_candidates.insert(candidate);
1131 trackMuonCandLinks[track] = candidate;
1138 for (
const Trk::Track* track : *resolvedTracks) {
1139 auto trackCandLink = trackMuonCandLinks.find(track);
1140 if (trackCandLink != trackMuonCandLinks.end()) resolvedMuonCandidates.push_back(trackCandLink->second);
1144 if (msgLvl(MSG::DEBUG)) {
1145 ATH_MSG_DEBUG(
"Muon candidates: " << muonCandidates->
size() <<
" after ambiguity solving " << resolvedMuonCandidates.size());
1146 for (
const MuonCandidate* candidate : resolvedMuonCandidates) {
1147 msg(MSG::DEBUG) <<
"Muon candidate: " << candidate->toString() <<
endmsg;
1153 const std::vector<const Muon::MuonSegment*>& segments,
1157 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
1161 double momentum{1e8},
charge{0.};
1162 std::unique_ptr<const Trk::TrackParameters> pars{
m_edmHelperSvc->createTrackParameters(*seg, momentum,
charge)};
1164 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0);
1167 std::unique_ptr<Trk::TrackParameters> exPars{
m_propagator->propagateParameters(
1169 if (!exPars) {
ATH_MSG_VERBOSE(
"Could not propagate Track to segment surface"); }
1172 trackStateOnSurfaces->push_back(trackState);
1178 info.setPatternRecognitionInfo(author);
1179 std::unique_ptr<Trk::Track> newtrack =
1180 std::make_unique<Trk::Track>(info, std::move(trackStateOnSurfaces), (indetTrack.
fitQuality())->uniqueClone());
1191 setP4(muon, *primary);
1192 const float qOverP = primary->qOverP();
1193 if (qOverP != 0.0) {
1194 muon.setCharge(qOverP > 0 ? 1. : -1.);
1196 ATH_MSG_WARNING(
"MuonCreatorTool::dressMuon - trying to set qOverP, but value from muon.primaryTrackParticle ["
1197 <<
"] is zero. Setting charge=0.0. The eta/phi of the muon is: " << muon.eta() <<
" / " << muon.phi());
1198 muon.setCharge(0.0);
1208 muon.setParameter(curvatureSignificance, xAOD::Muon::ParamDef::scatteringCurvatureSignificance);
1210 muon.setParameter(neighbourSignificance, xAOD::Muon::ParamDef::scatteringNeighbourSignificance);
1211 ATH_MSG_VERBOSE(
"Got curvatureSignificance " << curvatureSignificance <<
" and neighbourSignificance "
1212 << neighbourSignificance);
1217 muon.setParameter(momentumBalanceSignificance, xAOD::Muon::ParamDef::momentumBalanceSignificance);
1218 ATH_MSG_VERBOSE(
"Got momentumBalanceSignificance " << momentumBalanceSignificance);
1223 muon.setParameter(meanDeltaADC, xAOD::Muon::ParamDef::meanDeltaADCCountsMDT);
1228 acc_MuonSpectrometerPt(muon) = muon.pt();
1229 acc_InnerDetectorPt(muon) = muon.pt();
1240 if (muon.trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)) {
1241 trk = muon.trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)->track();
1243 if (!trk && muon.trackParticle(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle)) {
1244 trk = muon.trackParticle(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle)->track();
1250 ATH_MSG_VERBOSE(
"Couldn't find matching track which might have energy loss.");
1256 const xAOD::TrackParticle* trkPart = muon.trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle);
1258 ATH_MSG_WARNING(
"Missing ID track particle link in addEnergyLossToMuon!");
1273 for (; it != itEnd; ++it) {
1274 if ((*it)->trackParameters()) {
1280 ATH_MSG_WARNING(
"Missing ID TSOS with track parameters in addEnergyLossToMuon!");
1285 std::vector<const Trk::TrackStateOnSurface*>* caloTSOS =
m_caloMaterialProvider->getCaloTSOS(*((*it)->trackParameters()), *trk);
1296 std::vector<const Trk::TrackStateOnSurface*>::const_iterator it2 = caloTSOS->begin();
1297 std::vector<const Trk::TrackStateOnSurface*>::const_iterator itEnd2 = caloTSOS->end();
1298 for (; it2 != itEnd2; ++it2)
delete *it2;
1305 using enum xAOD::Muon::ParamDef;
1306 muon.setParameter(0.f, EnergyLoss);
1307 muon.setParameter(0.f, ParamEnergyLoss);
1308 muon.setParameter(0.f, MeasEnergyLoss);
1309 muon.setParameter(0.f, EnergyLossSigma);
1310 muon.setParameter(0.f, MeasEnergyLossSigma);
1311 muon.setParameter(0.f, ParamEnergyLossSigmaPlus);
1312 muon.setParameter(0.f, ParamEnergyLossSigmaMinus);
1313 muon.setParameter(0.f, FSR_CandidateEnergy);
1315 muon.setEnergyLossType(xAOD::Muon::EnergyLossType::Parametrized);
1321 unsigned int numEnergyLossPerTrack = 0;
1322 bool problem =
false;
1323 for (
const auto* tsos : *tsosVector) {
1325 if (!meot)
continue;
1328 if (!caloEnergy)
continue;
1329 ++numEnergyLossPerTrack;
1330 using enum xAOD::Muon::ParamDef;
1332 muon.setParameter(
static_cast<float>(caloEnergy->
deltaE()), EnergyLoss);
1333 muon.setParameter(
static_cast<float>(caloEnergy->
deltaEParam()), ParamEnergyLoss);
1334 muon.setParameter(
static_cast<float>(caloEnergy->
deltaEMeas()), MeasEnergyLoss);
1335 muon.setParameter(
static_cast<float>(caloEnergy->
sigmaDeltaE()), EnergyLossSigma);
1336 muon.setParameter(
static_cast<float>(caloEnergy->
sigmaDeltaEMeas()), MeasEnergyLossSigma);
1337 muon.setParameter(
static_cast<float>(caloEnergy->
sigmaPlusDeltaEParam()), ParamEnergyLossSigmaPlus);
1338 muon.setParameter(
static_cast<float>(caloEnergy->
sigmaMinusDeltaEParam()), ParamEnergyLossSigmaMinus);
1340 muon.setEnergyLossType(
static_cast<xAOD::Muon::EnergyLossType
>(caloEnergy->
energyLossType()));
1341 muon.setParameter(
static_cast<float>(caloEnergy->
fsrCandidateEnergy()), FSR_CandidateEnergy);
1343 if (numEnergyLossPerTrack > 1) {
1354 if (!tp || !clusterContainer) {
1368 if (!inputCaloExt) {
1371 std::unique_ptr<Trk::CaloExtension> caloExtension =
m_caloExtTool->caloExtension(ctx, *tp);
1372 if (!caloExtension) {
1376 if (caloExtension->caloLayerIntersections().empty())
1377 ATH_MSG_DEBUG(
"Received a caloExtension object without track extrapolation");
1379 cluster =
m_cellCollector.collectCells(*caloExtension, caloDDMgr, *container, *clusterContainer);
1381 cluster =
m_cellCollector.collectCells(*inputCaloExt, caloDDMgr, *container, *clusterContainer);
1384 ATH_MSG_DEBUG(
"Failed to create cluster from ParticleCellAssociation");
1387 ATH_MSG_DEBUG(
" New cluster: eta " << cluster->
eta() <<
" phi " << cluster->
phi() <<
" cells " << cluster->
size());
1392 muon.setClusterLink(clusterLink);
1396 caloNoise = noiseH.
cptr();
1399 std::vector<float> etcore(4, 0);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
double charge(const T &p)
Helper class to provide constant type-safe access to aux data.
DataVector adapter that acts like it holds const pointers.
Helper class to provide type-safe access to aux data.
DataVector< MuonCombined::MuonCandidate > MuonCandidateCollection
This typedef represents a collection of MuonCandidate objects.
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
This class provides the client interface for accessing the detector description information common to...
class extending the basic Trk::EnergyLoss to describe the measured or parameterised muon energy loss ...
CaloEnergy::EnergyLossType energyLossType(void) const
Accessor methods.
double sigmaMinusDeltaEParam() const
get parametrised energy loss minus error
double deltaEMeas() const
get measured energy loss
double sigmaDeltaEMeas() const
get measured energy loss error
double deltaEParam() const
get parametrised energy loss
double sigmaPlusDeltaEParam() const
get parametrised energy loss plus error
float fsrCandidateEnergy() const
FSR Candidate Energy.
DataVector adapter that acts like it holds const pointers.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
ElementProxy back()
Access the last element in the collection as an lvalue.
const DV * asDataVector() const
Return a pointer to this object, as a const DataVector.
void assign(InputIterator first, InputIterator last)
Assign from iterators.
const_reverse_iterator rend() const noexcept
Return a const_reverse_iterator pointing at the beginning of the collection.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const PtrVector & stdcont() const
Return the underlying std::vector of the container.
const_reverse_iterator rbegin() const noexcept
Return a const_reverse_iterator pointing past the end of the collection.
std::reverse_iterator< const_iterator > const_reverse_iterator
size_type size() const noexcept
Returns the number of elements in the collection.
ElementLink implementation for ROOT usage.
bool isValid() const
Check if the element can be found.
TagBase implementation for a calo tag.
TagBase implementation for a combined fit.
const MuonCandidate & muonCandidate() const
access to MuonCandidate
const xAOD::TrackParticle & indetTrackParticle() const
access TrackParticle
TagBase implementation for a combined fit.
TagBase implementation for a combined fit.
std::string toString() const
print candidate to string
const ElementLink< TrackCollection > & extrapolatedTrackLink() const
access extrapolated track element link
const std::vector< const Muon::MuonSegment * > & getSegments() const
returns the vector of associated muon segments
const ElementLink< xAOD::TrackParticleContainer > & muonSpectrometerTrackLink() const
access spectrometer track, always there
const Trk::Track * extrapolatedTrack() const
access extrapolated track, can be zero if back extrapolation failed
TagBase implementation for a segment tagger.
TagBase implementation for a combined fit.
const MuonCandidate & muonCandidate() const
access to MuonCandidate
base-class for combined reconstruction output Provides access to MuonType and Author
virtual const Trk::Track * primaryTrack() const
access to primary muon system track, zero if non available
virtual std::vector< const Muon::MuonSegment * > associatedSegments() const
access to associated segments, empty vector if non available
This is the common class for 3D segments used in the muon spectrometer.
lightweight return data-object for (mainly indet) scattering angle analysis by track query
double curvatureSignificance(void) const
ScatteringAngleSignificance inline accessor: significance of maximum curvature discontinuity.
double neighbourSignificance(void) const
ScatteringAngleSignificance inline accessor: maximum significance of neighbouring scatterers.
Helper class to provide type-safe access to aux data.
const_pointer_type cptr()
Tracking class to hold the extrapolation through calorimeter Layers Both the caloEntryLayerIntersecti...
This class describes energy loss material effects in the ATLAS tracking EDM.
double sigmaDeltaE() const
returns the symmatric error
double deltaE() const
returns the
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
magnetic field properties to steer the behavior of the extrapolation
represents the full description of deflection and e-loss of a track in material.
const EnergyLoss * energyLoss() const
returns the energy loss object.
This class is the pure abstract base class for all fittable tracking measurements.
Contains information about the 'fitter' of this track.
@ Unknown
Track fitter not defined.
@ MuTag
Tracks produced by MuTag.
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
A summary of the information contained by a track.
int get(const SummaryType &type) const
returns the summary information for the passed SummaryType.
const Trk::TrackStates * trackStateOnSurfaces() const
return a pointer to a const DataVector of const TrackStateOnSurfaces.
const TrackInfo & info() const
Returns a const ref to info of a const tracks.
const Perigee * perigeeParameters() const
return Perigee.
const Trk::TrackSummary * trackSummary() const
Returns a pointer to the const Trk::TrackSummary owned by this const track (could be nullptr).
const FitQuality * fitQuality() const
return a pointer to the fit quality const-overload
virtual double eta() const
The pseudorapidity ( ) of the particle.
size_t size() const
size method (forwarded from CaloClusterCellLink obj)
virtual double phi() const
The azimuthal angle ( ) of the particle.
void setMuonLink(const ElementLink< MuonContainer > &muonLink)
Sets.
void setNRpcHits(int nRpcHits)
Sets.
void setNTileCells(int nTileCells)
Sets.
void setAnn(float ann)
Sets.
void setMdtInfo(float mdtBetaAvg, float mdtBetaRms, float mdtBetaChi2, int mdtBetaDof)
Sets.
void setBeta(float beta)
Sets.
void setBetaT(float betaT)
Sets.
void setRpcInfo(float rpcBetaAvg, float rpcBetaRms, float rpcBetaChi2, int rpcBetaDof)
Sets.
void setCaloInfo(float caloBetaAvg, float caloBetaRms, float caloBetaChi2, int caloBetaDof)
Sets.
void setTrackParameterCovarianceMatrix(unsigned int index, std::vector< float > &cov)
Set the cov matrix of the parameter at 'index', using a vector of floats.
void setTrackLink(const ElementLink< TrackCollection > &track)
Set the link to the original track.
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.
void setPatternRecognitionInfo(const std::bitset< xAOD::NumberOfTrackRecoInfo > &patternReco)
Method setting the pattern recognition algorithm, using a bitset.
std::vector< std::string > tags
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 ...
The MuonTagToSegMap is an auxillary construct that links the MuonSegments associated with a combined ...
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
@ NoField
Field is set to 0., 0., 0.,.
@ numberOfCscUnspoiltEtaHits
number of unspoilt CSC eta measurements (all CSC phi measurements are by definition spoilt).
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
SlowMuon_v1 SlowMuon
Reference the current persistent version:
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
Muon_v1 Muon
Reference the current persistent version:
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.
@ STACO
Tracks produced by STACO.