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->trackParticle(xAOD::Muon::TrackParticleType::Primary);
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 if (accessor->isAvailable(id_track_particle)) {
443 (*accessor)( *tp ) = (*accessor)( id_track_particle );
447 if (accessor->isAvailable(id_track_particle)) {
448 (*accessor)( *tp ) = (*accessor)( id_track_particle );
460 muon.setParameter(5, xAOD::Muon::ParamDef::msInnerMatchDOF);
461 muon.setParameter(
static_cast<float>(tag->matchChi2()), xAOD::Muon::ParamDef::msInnerMatchChi2);
464 acc_d0(muon) = tag->combinedParameters().parameters()[
Trk::d0];
465 acc_z0(muon) = tag->combinedParameters().parameters()[
Trk::z0];
466 acc_phi0(muon) = tag->combinedParameters().parameters()[
Trk::phi0];
467 acc_theta(muon) = tag->combinedParameters().parameters()[
Trk::theta];
468 acc_qOverP(muon) = tag->combinedParameters().parameters()[
Trk::qOverP];
471 ATH_MSG_DEBUG(
"Done adding Staco Muon " << tag->author() <<
" type " << tag->type());
475 OutputData& outputData)
const {
481 ATH_MSG_DEBUG(
"Adding Combined fit Muon " << tag->author() <<
" type " << tag->type());
482 if (!muon.trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)) {
484 if (outputData.combinedTrackParticleContainer) {
487 ctx, tag->combinedTrackLink(), *outputData.combinedTrackParticleContainer, outputData.combinedTrackCollection);
489 if (link.isValid()) {
491 ATH_MSG_DEBUG(
"Adding combined fit: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi " << (*link)->phi());
492 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::CombinedTrackParticle, link);
498 addMuonCandidate(ctx, tag->muonCandidate(), muon, outputData, tag->updatedExtrapolatedTrackLink());
501 const float inner_chi2 = tag->matchChi2();
502 muon.setParameter(tag->matchDoF(), xAOD::Muon::ParamDef::msInnerMatchDOF);
503 muon.setParameter(inner_chi2, xAOD::Muon::ParamDef::msInnerMatchChi2);
505 ATH_MSG_DEBUG(
"Done adding Combined Fit Muon " << tag->author() <<
" type " << tag->type());
512 OutputData& outputData)
const {
518 ATH_MSG_DEBUG(
"Adding MuGirlLowBeta Muon " << tag->author() <<
" type " << tag->type());
522 if (slowMuon && stauExtras) {
545 std::vector<uint8_t>& eTechVec = eTechAcc(*slowMuon);
546 std::vector<unsigned int>& idVec = idAcc(*slowMuon);
547 std::vector<float>& mToFVec = mToFAcc(*slowMuon);
548 std::vector<float>& xVec = xAcc(*slowMuon);
549 std::vector<float>& yVec = yAcc(*slowMuon);
550 std::vector<float>& zVec = zAcc(*slowMuon);
551 std::vector<float>& eVec = eAcc(*slowMuon);
552 std::vector<float>& errorVec = errorAcc(*slowMuon);
553 std::vector<float>& shiftVec = shiftAcc(*slowMuon);
554 std::vector<float>& propagationTimeVec = propTimeAcc(*slowMuon);
555 std::vector<uint8_t>& passesMDTBetaCutVec = hitPassesMDTBetaCutAcc(*slowMuon);
557 for (
const auto& hit : stauExtras->
hits) {
558 eTechVec.push_back(hit.eTech);
559 idVec.push_back(hit.id.get_identifier32().get_compact());
560 mToFVec.push_back(hit.mToF);
561 xVec.push_back(hit.x);
562 yVec.push_back(hit.y);
563 zVec.push_back(hit.z);
564 eVec.push_back(hit.e);
565 errorVec.push_back(hit.error);
566 shiftVec.push_back(hit.shift);
567 propagationTimeVec.push_back(hit.propagationTime);
568 passesMDTBetaCutVec.push_back(hit.passesMDTBetaCut ? uint8_t{1} : uint8_t{0});
576 std::vector<int>& adcVec = adcAcc(*slowMuon);
577 std::vector<float>& rdriftVec = rdriftAcc(*slowMuon);
581 adcVec.push_back(extraMDTinfo.adc);
582 rdriftVec.push_back(extraMDTinfo.rdrift);
590 if (!muon.trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle) && tag->combinedTrack()) {
592 if (outputData.combinedTrackParticleContainer) {
595 ctx, tag->combinedTrackLink(), *outputData.combinedTrackParticleContainer, outputData.combinedTrackCollection);
597 if (link.isValid()) {
598 ATH_MSG_DEBUG(
"Adding MuGirlLowBeta: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi " << (*link)->phi());
599 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::CombinedTrackParticle, link);
601 ATH_MSG_WARNING(
"Creating of MuGirlLowBeta TrackParticle Link failed");
605 if (outputData.xaodSegmentContainer) {
607 std::vector<ElementLink<xAOD::MuonSegmentContainer>> segments;
610 if (link.isValid()) {
611 segments.push_back(link);
612 ATH_MSG_DEBUG(
"Adding MuGirlLowBeta: xaod::MuonSegment px " << (*link)->px() <<
" py " << (*link)->py() <<
" pz "
617 muon.setMuonSegmentLinks(segments);
627 ATH_MSG_DEBUG(
"Adding MuGirl Muon " << tag->author() <<
" type " << tag->type());
629 if (!muon.trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle) && tag->combinedTrack()) {
631 if (outputData.combinedTrackParticleContainer) {
634 ctx, tag->combinedTrackLink(), *outputData.combinedTrackParticleContainer, outputData.combinedTrackCollection);
636 if (link.isValid()) {
638 ATH_MSG_DEBUG(
"Adding MuGirl: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi " << (*link)->phi());
639 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::CombinedTrackParticle, link);
644 if (outputData.extrapolatedTrackParticleContainer && tag->updatedExtrapolatedTrack()) {
648 outputData.extrapolatedTrackCollection);
650 if (link.isValid()) {
651 ATH_MSG_DEBUG(
"Adding MuGirl: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi " << (*link)->phi());
652 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle, link);
657 if (outputData.xaodSegmentContainer) {
660 std::vector<ElementLink<xAOD::MuonSegmentContainer>> segments;
663 if (link.isValid()) {
664 segments.push_back(link);
665 ATH_MSG_DEBUG(
"Adding MuGirl: xaod::MuonSegment px " << (*link)->px() <<
" py " << (*link)->py() <<
" pz "
670 muon.setMuonSegmentLinks(segments);
673 ATH_MSG_DEBUG(
"Done Adding MuGirl Muon " << tag->author() <<
" type " << tag->type());
679 using enum xAOD::Muon::ParamDef;
680 muon.setParameter(-1.f, segmentDeltaEta);
681 muon.setParameter(-1.f, segmentDeltaPhi);
682 muon.setParameter(-1.f, segmentChi2OverDoF);
686 ATH_MSG_DEBUG(
"Adding Segment Tag Muon " << tag->author() <<
" type " << tag->type());
688 std::vector<ElementLink<xAOD::MuonSegmentContainer>> segments;
689 bool foundseg =
false;
690 for (
const auto& info : tag->segmentsInfo()) {
695 if (muon.author() == xAOD::Muon::Author::MuTagIMO) {
697 if (seglink.
isValid()) segments.push_back(seglink);
701 muon.setParameter(
static_cast<float>(info.dtheta), xAOD::Muon::ParamDef::segmentDeltaEta);
702 muon.setParameter(
static_cast<float>(info.dphi), xAOD::Muon::ParamDef::segmentDeltaPhi);
703 muon.setParameter(
static_cast<float>(info.segment->fitQuality()->chiSquared() / info.segment->fitQuality()->numberDoF()),
704 xAOD::Muon::ParamDef::segmentChi2OverDoF);
706 }
else if (muon.author() != xAOD::Muon::Author::MuTagIMO)
710 if (muon.author() == xAOD::Muon::Author::MuTagIMO) muon.setMuonSegmentLinks(segments);
720 mu.setParameter(0.f, xAOD::Muon::ParamDef::CaloMuonScore);
721 mu.setParameter(
static_cast<int>(0xFF), xAOD::Muon::ParamDef::CaloMuonIDTag);
725 acc_ET_Core(mu) = 0.0;
726 acc_ElType(mu) = -999.0;
727 acc_ElFSREnergy(mu) = -999.0;
732 ATH_MSG_DEBUG(
"Adding Calo Muon with author " << tag->author() <<
", type " << tag->type() <<
", CaloMuonScore "
733 << tag->caloMuonScore());
734 mu.setParameter(
static_cast<float>(tag->caloMuonScore()), xAOD::Muon::ParamDef::CaloMuonScore);
735 mu.setParameter(
static_cast<int>(tag->caloMuonIdTag()), xAOD::Muon::ParamDef::CaloMuonIDTag);
740 acc_ET_Core(mu) = tag->etCore();
741 acc_ElType(mu) = tag->energyLossType();
742 acc_ElFSREnergy(mu) = tag->fsrCandidateEnergy();
748 const EventContext& ctx,
753 if (trackCollection) {
776 const OutputData& outData)
const {
777 if (outData.xaodSegmentContainer && outData.tagToSegmentAssocMap) {
780 unsigned int link = outData.tagToSegmentAssocMap->linkIndex(trkSeg);
781 if (link >= outData.xaodSegmentContainer->size()) {
793 if (!muon.nMuonSegments()) {
794 std::vector< ElementLink<xAOD::MuonSegmentContainer>> segments;
797 if (link.isValid()) {
798 segments.push_back(link);
799 ATH_MSG_DEBUG(
"Adding MuGirl: xaod::MuonSegment px " << (*link)->px() <<
" py " << (*link)->py() <<
" pz "
805 muon.setMuonSegmentLinks(segments);
808 if (muon.trackParticle(xAOD::Muon::TrackParticleType::MuonSpectrometerTrackParticle)) {
return; }
812 if (muon.author() != xAOD::Muon::Author::MuGirl)
813 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::MuonSpectrometerTrackParticle, candidate.
muonSpectrometerTrackLink());
816 if (!outputData.extrapolatedTrackParticleContainer || (!candidate.
extrapolatedTrack() && !meLink.
isValid())) {
return; }
821 ATH_MSG_DEBUG(
"There is no extrapolated track associated to the MuonCandidate.");
822 if (muon.author() == xAOD::Muon::Author::MuidCo) {
826 ctx, meLink, *outputData.extrapolatedTrackParticleContainer, outputData.extrapolatedTrackCollection);
827 if (link.isValid()) {
828 ATH_MSG_DEBUG(
"Adding standalone fit (refitted): pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi "
830 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle, link);
831 float fieldInt =
m_trackQuery->fieldIntegral(**meLink, ctx).betweenSpectrometerMeasurements();
832 muon.setParameter(fieldInt, xAOD::Muon::ParamDef::spectrometerFieldIntegral);
834 acc_nUnspoiledCscHits(muon) = nunspoiled;
838 if (!extrapolatedTrack)
ATH_MSG_WARNING(
"Track doesn't have extrapolated track. Skipping");
841 "Track doesn't have perigee parameters on extrapolated "
848 if (muon.muonType() != xAOD::Muon::MuonType::MuonStandAlone) {
850 if (outputData.msOnlyExtrapolatedTrackParticleContainer) {
856 outputData.msOnlyExtrapolatedTrackCollection);
858 if (link.isValid()) {
859 ATH_MSG_DEBUG(
"Adding MS-only extrapolated track: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi "
862 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::MSOnlyExtrapolatedMuonSpectrometerTrackParticle, link);
864 ATH_MSG_WARNING(
"failed to create MS-only extrapolated track particle");
868 ctx, meLink, *outputData.extrapolatedTrackParticleContainer, outputData.extrapolatedTrackCollection);
869 if (link.isValid()) {
870 ATH_MSG_DEBUG(
"Adding standalone fit (refitted): pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi "
872 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle, link);
873 float fieldInt =
m_trackQuery->fieldIntegral(**meLink, ctx).betweenSpectrometerMeasurements();
874 muon.setParameter(fieldInt, xAOD::Muon::ParamDef::spectrometerFieldIntegral);
876 acc_nUnspoiledCscHits(muon) = nunspoiled;
880 if (muon.author() == xAOD::Muon::Author::MuGirl && muon.trackParticle(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle)) {
886 outputData.msOnlyExtrapolatedTrackCollection);
888 if (link.isValid()) {
889 ATH_MSG_DEBUG(
"Adding MS-only extrapolated track to MuGirl muon: pt "
890 << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi " << (*link)->phi());
892 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::MSOnlyExtrapolatedMuonSpectrometerTrackParticle, link);
895 muon.setParameter(fieldInt, xAOD::Muon::ParamDef::spectrometerFieldIntegral);
900 outputData.extrapolatedTrackCollection);
902 if (link.isValid()) {
903 ATH_MSG_DEBUG(
"Adding standalone fit (un-refitted): pt " << (*link)->pt() <<
" eta " << (*link)->eta()
904 <<
" phi " << (*link)->phi());
906 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle, link);
909 muon.setParameter(fieldInt, xAOD::Muon::ParamDef::spectrometerFieldIntegral);
917 outputData.extrapolatedTrackCollection);
919 if (link.isValid()) {
920 ATH_MSG_DEBUG(
"Adding standalone fit: pt " << (*link)->pt() <<
" eta " << (*link)->eta() <<
" phi " << (*link)->phi());
922 muon.setTrackParticleLink(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle, link);
925 muon.setParameter(fieldInt, xAOD::Muon::ParamDef::spectrometerFieldIntegral);
927 acc_nUnspoiledCscHits(muon) = nunspoiled;
936 const std::vector<const InDetCandidateToTagMap*>& tagMaps)
const {
937 resolvedInDetCandidates.clear();
939 if (!tag_map)
continue;
940 for (
const auto& combined_tag : *tag_map) {
941 const TagBase* tag = combined_tag.second.get();
943 if (muGirlLowBetaTag) { resolvedInDetCandidates.emplace_back(combined_tag.first, std::vector<const TagBase*>{tag}); }
948 if (msgLvl(MSG::DEBUG)) {
949 ATH_MSG_DEBUG(
"ID candidates: " << tagMaps.size() <<
" after stau selection " << resolvedInDetCandidates.size());
950 for (
const InDetCandidateTags& candidate : resolvedInDetCandidates) {
951 msg(MSG::DEBUG) <<
"ID candidate staus: " << candidate.first->toString() <<
endmsg;
957 std::stable_sort(resolvedInDetCandidates.begin(), resolvedInDetCandidates.end(),
958 [](
const InDetCandidateTags&
a,
const InDetCandidateTags& b) {
959 return a.first->indetTrackParticle().pt() > b.first->indetTrackParticle().pt();
964 const std::vector<const InDetCandidateToTagMap*>& tagMaps,
966 std::vector<const MuonCombined::MuonCandidate*>& resolvedMuonCandidates)
const {
967 resolvedMuonCandidates.clear();
968 resolvedInDetCandidates.clear();
970 std::unique_ptr<const TrackCollection> resolvedTracks;
971 std::vector<std::unique_ptr<Trk::Track>> garbage_collection;
978 if (!tag_map)
continue;
979 for (
const auto& comb_tag : *tag_map) {
980 const TagBase* tag = comb_tag.second.get();
984 InDetCandidateTagsMap::iterator itr =
985 std::find_if(inDetCandidateMap.begin(), inDetCandidateMap.end(),
986 [&comb_tag](
const InDetCandidateTags& to_test) { return (*to_test.first) == (*comb_tag.first); });
987 if (itr != inDetCandidateMap.end())
988 itr->second.emplace_back(tag);
990 inDetCandidateMap.emplace_back(std::make_pair(comb_tag.first, std::vector<const TagBase*>{tag}));
997 if (!inDetCandidateMap.empty()) {
1003 resolvedInDetCandidates.reserve(inDetCandidateMap.size());
1004 caloMuons.reserve(inDetCandidateMap.size());
1005 for (InDetCandidateTags& comb_tag : inDetCandidateMap) {
1007 if (comb_tag.second.size() == 1 && comb_tag.second.front()->type() == xAOD::Muon::MuonType::CaloTagged) {
1008 caloMuons.emplace_back(std::move(comb_tag));
1010 resolvedInDetCandidates.emplace_back(std::move(comb_tag));
1012 inDetCandidateMap.clear();
1015 if (msgLvl(MSG::DEBUG)) {
1016 ATH_MSG_DEBUG(
"Found " << resolvedInDetCandidates.size() <<
" inner detector tags in event "
1017 << ctx.eventID().event_number());
1018 for (
const InDetCandidateTags& candidate : resolvedInDetCandidates) {
1019 std::stringstream
tags;
1020 for (
const TagBase* tag : candidate.second)
tags <<
" " << tag->toString();
1021 ATH_MSG_DEBUG(
"ID candidate: " << candidate.first->toString() <<
" " <<
tags.str());
1027 to_resolve.reserve(resolvedInDetCandidates.size());
1028 garbage_collection.reserve(resolvedInDetCandidates.size());
1032 std::map<const Trk::Track*, InDetCandidateTags> trackInDetCandLinks;
1034 for (InDetCandidateTags& candidate : resolvedInDetCandidates) {
1036 const TagBase* primaryTag = candidate.second[0];
1043 trackInDetCandLinks[to_resolve.
back()] = std::move(candidate);
1049 if (!segments.empty()) {
1051 garbage_collection.emplace_back(
1054 to_resolve.
push_back(garbage_collection.back().get());
1056 trackInDetCandLinks[garbage_collection.back().get()] = std::move(candidate);
1060 resolvedInDetCandidates.clear();
1066 for (
const Trk::Track* track : *resolvedTracks) {
1067 std::map<const Trk::Track*, InDetCandidateTags>::iterator trackCandLink = trackInDetCandLinks.find(track);
1068 if (trackCandLink == trackInDetCandLinks.end()) {
1069 ATH_MSG_WARNING(
"Unable to find internal link between MS track and ID candidate!");
1072 resolvedInDetCandidates.push_back(std::move(trackCandLink->second));
1076 if (msgLvl(MSG::VERBOSE)) {
1078 << resolvedInDetCandidates.size() <<
" trackCandLinks: " << trackInDetCandLinks.size()
1079 <<
" to_resolve: " << to_resolve.size() <<
" resolvedTracks: " << resolvedTracks->size());
1080 for (
const InDetCandidateTags& candidate : resolvedInDetCandidates) {
1081 ATH_MSG_DEBUG(
"ID candidate: " << candidate.first->toString() <<
" " << candidate.second[0]->toString());
1084 for (
const InDetCandidateTags& candidate : caloMuons) {
1085 ATH_MSG_DEBUG(
"ID candidate: " << candidate.first->toString() <<
" " << candidate.second[0]->toString());
1089 resolvedInDetCandidates.insert(resolvedInDetCandidates.end(), caloMuons.begin(), caloMuons.end());
1092 std::stable_sort(resolvedInDetCandidates.begin(), resolvedInDetCandidates.end(),
1093 [](
const InDetCandidateTags&
a,
const InDetCandidateTags& b) {
1094 return a.first->indetTrackParticle().pt() > b.first->indetTrackParticle().pt();
1100 if (!muonCandidates) {
return; }
1102 if (msgLvl(MSG::DEBUG)) {
1108 if (resolvedTracks) { resolvedTracks2.
assign(resolvedTracks->begin(), resolvedTracks->end()); }
1110 std::set<const MuonCandidate*> used_candidates;
1111 for (
const InDetCandidateTags& indet_cand : resolvedInDetCandidates) {
1112 for (
const TagBase* tag : indet_cand.second) {
1114 if (tag->author() == xAOD::Muon::Author::MuidCo) {
1117 }
else if (tag->author() == xAOD::Muon::Author::STACO && indet_cand.second[0] == tag) {
1126 std::map<const Trk::Track*, const MuonCandidate*> trackMuonCandLinks;
1128 const Trk::Track* track = candidate->primaryTrack();
1129 if (used_candidates.count(candidate)) {
1133 used_candidates.insert(candidate);
1135 trackMuonCandLinks[track] = candidate;
1142 for (
const Trk::Track* track : *resolvedTracks) {
1143 auto trackCandLink = trackMuonCandLinks.find(track);
1144 if (trackCandLink != trackMuonCandLinks.end()) resolvedMuonCandidates.push_back(trackCandLink->second);
1148 if (msgLvl(MSG::DEBUG)) {
1149 ATH_MSG_DEBUG(
"Muon candidates: " << muonCandidates->
size() <<
" after ambiguity solving " << resolvedMuonCandidates.size());
1150 for (
const MuonCandidate* candidate : resolvedMuonCandidates) {
1151 msg(MSG::DEBUG) <<
"Muon candidate: " << candidate->toString() <<
endmsg;
1157 const std::vector<const Muon::MuonSegment*>& segments,
1161 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
1165 double momentum{1e8},
charge{0.};
1166 std::unique_ptr<const Trk::TrackParameters> pars{
m_edmHelperSvc->createTrackParameters(*seg, momentum,
charge)};
1168 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern(0);
1171 std::unique_ptr<Trk::TrackParameters> exPars{
m_propagator->propagateParameters(
1173 if (!exPars) {
ATH_MSG_VERBOSE(
"Could not propagate Track to segment surface"); }
1176 trackStateOnSurfaces->push_back(trackState);
1182 info.setPatternRecognitionInfo(author);
1183 std::unique_ptr<Trk::Track> newtrack =
1184 std::make_unique<Trk::Track>(info, std::move(trackStateOnSurfaces), (indetTrack.
fitQuality())->uniqueClone());
1193 const xAOD::TrackParticle* primary = muon.trackParticle(xAOD::Muon::TrackParticleType::Primary);
1195 setP4(muon, *primary);
1196 const float qOverP = primary->qOverP();
1197 if (qOverP != 0.0) {
1198 muon.setCharge(qOverP > 0 ? 1. : -1.);
1200 ATH_MSG_WARNING(
"MuonCreatorTool::dressMuon - trying to set qOverP, but value from muon.primaryTrackParticle ["
1201 <<
"] is zero. Setting charge=0.0. The eta/phi of the muon is: " << muon.eta() <<
" / " << muon.phi());
1202 muon.setCharge(0.0);
1212 muon.setParameter(curvatureSignificance, xAOD::Muon::ParamDef::scatteringCurvatureSignificance);
1214 muon.setParameter(neighbourSignificance, xAOD::Muon::ParamDef::scatteringNeighbourSignificance);
1215 ATH_MSG_VERBOSE(
"Got curvatureSignificance " << curvatureSignificance <<
" and neighbourSignificance "
1216 << neighbourSignificance);
1221 muon.setParameter(momentumBalanceSignificance, xAOD::Muon::ParamDef::momentumBalanceSignificance);
1222 ATH_MSG_VERBOSE(
"Got momentumBalanceSignificance " << momentumBalanceSignificance);
1227 muon.setParameter(meanDeltaADC, xAOD::Muon::ParamDef::meanDeltaADCCountsMDT);
1232 acc_MuonSpectrometerPt(muon) = muon.pt();
1233 acc_InnerDetectorPt(muon) = muon.pt();
1244 if (muon.trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)) {
1245 trk = muon.trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)->track();
1247 if (!trk && muon.trackParticle(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle)) {
1248 trk = muon.trackParticle(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle)->track();
1254 ATH_MSG_VERBOSE(
"Couldn't find matching track which might have energy loss.");
1260 const xAOD::TrackParticle* trkPart = muon.trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle);
1262 ATH_MSG_WARNING(
"Missing ID track particle link in addEnergyLossToMuon!");
1277 for (; it != itEnd; ++it) {
1278 if ((*it)->trackParameters()) {
1284 ATH_MSG_WARNING(
"Missing ID TSOS with track parameters in addEnergyLossToMuon!");
1289 std::vector<const Trk::TrackStateOnSurface*>* caloTSOS =
m_caloMaterialProvider->getCaloTSOS(*((*it)->trackParameters()), *trk);
1300 std::vector<const Trk::TrackStateOnSurface*>::const_iterator it2 = caloTSOS->begin();
1301 std::vector<const Trk::TrackStateOnSurface*>::const_iterator itEnd2 = caloTSOS->end();
1302 for (; it2 != itEnd2; ++it2)
delete *it2;
1309 using enum xAOD::Muon::ParamDef;
1310 muon.setParameter(0.f, EnergyLoss);
1311 muon.setParameter(0.f, ParamEnergyLoss);
1312 muon.setParameter(0.f, MeasEnergyLoss);
1313 muon.setParameter(0.f, EnergyLossSigma);
1314 muon.setParameter(0.f, MeasEnergyLossSigma);
1315 muon.setParameter(0.f, ParamEnergyLossSigmaPlus);
1316 muon.setParameter(0.f, ParamEnergyLossSigmaMinus);
1317 muon.setParameter(0.f, FSR_CandidateEnergy);
1319 muon.setEnergyLossType(xAOD::Muon::EnergyLossType::Parametrized);
1325 unsigned int numEnergyLossPerTrack = 0;
1326 bool problem =
false;
1327 for (
const auto* tsos : *tsosVector) {
1329 if (!meot)
continue;
1332 if (!caloEnergy)
continue;
1333 ++numEnergyLossPerTrack;
1334 using enum xAOD::Muon::ParamDef;
1336 muon.setParameter(
static_cast<float>(caloEnergy->
deltaE()), EnergyLoss);
1337 muon.setParameter(
static_cast<float>(caloEnergy->
deltaEParam()), ParamEnergyLoss);
1338 muon.setParameter(
static_cast<float>(caloEnergy->
deltaEMeas()), MeasEnergyLoss);
1339 muon.setParameter(
static_cast<float>(caloEnergy->
sigmaDeltaE()), EnergyLossSigma);
1340 muon.setParameter(
static_cast<float>(caloEnergy->
sigmaDeltaEMeas()), MeasEnergyLossSigma);
1341 muon.setParameter(
static_cast<float>(caloEnergy->
sigmaPlusDeltaEParam()), ParamEnergyLossSigmaPlus);
1342 muon.setParameter(
static_cast<float>(caloEnergy->
sigmaMinusDeltaEParam()), ParamEnergyLossSigmaMinus);
1344 muon.setEnergyLossType(
static_cast<xAOD::Muon::EnergyLossType
>(caloEnergy->
energyLossType()));
1345 muon.setParameter(
static_cast<float>(caloEnergy->
fsrCandidateEnergy()), FSR_CandidateEnergy);
1347 if (numEnergyLossPerTrack > 1) {
1357 const xAOD::TrackParticle* tp = muon.trackParticle(xAOD::Muon::TrackParticleType::Primary);
1358 if (!tp || !clusterContainer) {
1372 if (!inputCaloExt) {
1375 std::unique_ptr<Trk::CaloExtension> caloExtension =
m_caloExtTool->caloExtension(ctx, *tp);
1376 if (!caloExtension) {
1380 if (caloExtension->caloLayerIntersections().empty())
1381 ATH_MSG_DEBUG(
"Received a caloExtension object without track extrapolation");
1383 cluster =
m_cellCollector.collectCells(*caloExtension, caloDDMgr, *container, *clusterContainer);
1385 cluster =
m_cellCollector.collectCells(*inputCaloExt, caloDDMgr, *container, *clusterContainer);
1388 ATH_MSG_DEBUG(
"Failed to create cluster from ParticleCellAssociation");
1391 ATH_MSG_DEBUG(
" New cluster: eta " << cluster->
eta() <<
" phi " << cluster->
phi() <<
" cells " << cluster->
size());
1396 muon.setClusterLink(clusterLink);
1400 caloNoise = noiseH.
cptr();
1403 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.