30 std::string
print(
const std::vector<MuPatSegment*>& segVec) {
42 std::string
print(
const std::vector<std::unique_ptr<MuPatTrack> >& tracks) {
44 for (
const std::unique_ptr<MuPatTrack>&
tit : tracks)
s << std::endl <<
print(*
tit);
49 using namespace MuonStationIndex;
51 base_class(
t,
n,
p), m_combinedSLOverlaps(false) {
53 declareProperty(
"StrategyList",
m_stringStrategies,
"List of strategies to be used by the track steering");
54 declareProperty(
"SegSeedQCut",
m_segQCut[0] = -2,
"Required quality for segments to be a seed");
55 declareProperty(
"Seg2ndQCut",
m_segQCut[1] = -2,
"Required quality for segments to be the second on a track");
56 declareProperty(
"SegOtherQCut",
m_segQCut[2] = -2,
"Required quality for segments to be added to a track");
81 return StatusCode::SUCCESS;
88 std::unique_ptr<TrackCollection>
result = std::make_unique<TrackCollection>();
92 ChSet chambersWithSegments;
93 StSet stationsWithSegments;
95 if (
extractSegments(ctx, coll, chamberSegments, stationSegments, chambersWithSegments, stationsWithSegments, trash_bin)) {
104 if (coll.empty())
return false;
116 StIndex stIndex = aSeg->stIndex;
117 if (
chIndex == ChIndex::ChUnknown || stIndex == StIndex::StUnknown) {
121 chambersWithSegments.insert(
chIndex);
122 stationsWithSegments.insert(stIndex);
124 std::vector<MuPatSegment*>& segments = chamberSegments[
toInt(
chIndex)];
125 segments.push_back(aSeg.get());
127 std::vector<MuPatSegment*>& segments2 = stationSegments[
toInt(stIndex)];
128 segments2.push_back(aSeg.get());
135 stationsWithSegments, trash_bin);
137 stationsWithSegments, trash_bin);
139 stationsWithSegments, trash_bin);
141 stationsWithSegments, trash_bin);
143 stationsWithSegments, trash_bin);
145 stationsWithSegments, trash_bin);
147 stationsWithSegments, trash_bin);
149 stationsWithSegments, trash_bin);
151 if (!segments.empty()) {
155 segs.insert(segs.end(), segments.begin(), segments.end());
167 if (ch1.empty() && ch2.empty())
return;
170 StIndex stIndex = !ch1.empty() ? ch1.front()->stIndex : ch2.front()->stIndex;
172 SegCol& stationVec = stationSegments[
toInt(stIndex)];
175 std::vector<bool> wasMatched2(ch2.size(),
false);
180 int qualityLevel1 = ch1.size() > 5 ? 1 : 2;
181 if (sit1->quality < qualityLevel1) {
182 ATH_MSG_VERBOSE(
"resolveSLOverlaps::bad segment1 q: " << sit1->quality <<
" cut " << qualityLevel1 << std::endl
184 stationVec.push_back(sit1);
188 bool wasMatched1 =
false;
191 int qualityLevel2 = ch2.size() > 5 ? 1 : 2;
198 if (sit2->quality < qualityLevel2) {
199 ATH_MSG_VERBOSE(
"resolveSLOverlaps::bad segment2: q " << sit2->quality <<
" cut " << qualityLevel2 << std::endl
203 if (sit1->quality < 2 && sit2->quality < 2) {
204 ATH_MSG_VERBOSE(
"resolveSLOverlaps:: combination of insufficient quality " << std::endl
205 <<
" q1 " << sit1->quality <<
" q2 "
211 <<
m_printer->print(*sit1->segment) << std::endl
215 ATH_MSG_VERBOSE(
" overlap combination rejected based on matching" << std::endl <<
m_printer->print(*sit2->segment));
221 std::unique_ptr<MuonSegment> newseg{
m_mooBTool->combineToSegment(ctx, *sit1, *sit2, emptyPhiHits)};
235 std::unique_ptr<MuPatSegment> segInfo =
m_candidateTool->createSegInfo(ctx, *newseg);
237 if (!segInfo || segInfo->quality < 2 || (segInfo->quality < sit1->quality || segInfo->quality < sit2->quality)) {
242 int shared_eta = 0, shared_phi = 0;
248 if (hit_ch1->info().id == hit_ch2->info().id) {
249 if (hit_ch1->info().measuresPhi)
257 if (sit1->etaHits().size() + sit2->etaHits().size() - shared_eta - segInfo->etaHits().size() > 1) {
258 ATH_MSG_VERBOSE(
"resolveSLOverlaps::more than one eta measurement removed, dropping track "
264 int phiHitDiff = sit1->phiHits().size() + sit2->phiHits().size() - shared_phi - segInfo->phiHits().size();
265 if (phiHitDiff > 1 || (sit1->phiHits().size() + sit2->phiHits().size() > 0 && segInfo->phiHits().empty())) {
266 ATH_MSG_VERBOSE(
"resolveSLOverlaps::more than one phi measurement removed, dropping track "
273 double cosPointingAngle = (newseg->globalPosition().x() * newseg->globalDirection().x() +
274 newseg->globalPosition().y() * newseg->globalDirection().y()) /
275 (newseg->globalPosition().perp() * newseg->globalDirection().perp());
276 if (cosPointingAngle < 0.995) {
277 ATH_MSG_VERBOSE(
"resolveSLOverlaps: rejected due to too large pointing angle " << std::endl
281 ATH_MSG_VERBOSE(
"created SL overlap segment: cos pointing " << cosPointingAngle << std::endl
286 wasMatched2[idx_ch2] =
true;
289 stationVec.push_back(segInfo.get());
296 if (!wasMatched1) { stationVec.push_back(sit1); }
300 for (
unsigned int i = 0;
i < wasMatched2.size(); ++
i) {
301 if (!wasMatched2[
i]) { stationVec.push_back(ch2[
i]); }
305 if (!stationVec.empty()) { stationsWithSegments.insert(stIndex); }
318 std::vector<std::unique_ptr<MuPatTrack> > resultAll;
326 std::vector<std::unique_ptr<MuPatTrack> >
result;
333 std::set<StIndex> stations;
335 for (
unsigned int lit = 0; lit <
strategy.getAll().
size(); ++lit) {
336 std::vector<ChIndex> chambers =
strategy.getCh(lit);
341 for (
unsigned int chin = 0; chin < chambers.size(); ++chin) {
346 if (stations.count(stIndex))
continue;
347 SegCol& segments = stationSegments[
toInt(stIndex)];
353 for (
unsigned int iseg = 0; iseg < segments.size(); iseg++) {
354 double thetaSeg = std::abs((*segments[iseg]).
segment->globalPosition().theta());
357 if ((0.74159 > thetaSeg && thetaSeg > 0.51159) || (2.63 > thetaSeg && thetaSeg > 2.40))
358 mySegColVec[lit].push_back(segments[iseg]);
361 mySegColVec[lit].insert(mySegColVec[lit].
end(), segments.begin(), segments.end());
364 stations.insert(stIndex);
369 for (
unsigned int chin = 0; chin < chambers.size(); ++chin) {
370 SegCol& segments = chamberSegments[
toInt(chambers[chin])];
372 mySegColVec[lit].insert(mySegColVec[lit].
end(), segments.begin(), segments.end());
379 for (
unsigned int lit = 0; lit < mySegColVec.size(); ++lit) {
384 bool hasSegments =
false;
385 for (
unsigned int lit = 0; lit < mySegColVec.size(); ++lit) {
386 if (!mySegColVec[lit].empty()) {
393 for (
unsigned int lit = 0; lit < mySegColVec.size(); ++lit)
394 for (
unsigned int sit = 0; sit < mySegColVec[lit].size(); ++sit)
405 std::vector<unsigned int> seeds;
410 std::vector<std::pair<int, unsigned int> > occupancy;
411 for (
unsigned int lit = 0; lit < mySegColVec.size(); ++lit) {
412 occupancy.emplace_back(mySegColVec[lit].
size(), lit);
414 std::stable_sort(occupancy.begin(), occupancy.end());
415 for (
unsigned int lit = 0; lit < occupancy.size(); ++lit) { seeds.push_back(occupancy[lit].
second); }
419 for (
unsigned int j = 0; j < mySegColVec.size(); ++j) seeds.push_back(j);
426 for (
unsigned int lin = 0; lin < seeds.size(); ++lin) {
428 ATH_MSG_VERBOSE(
"New seed layer " << lin <<
" segments in layer " << mySegColVec[lin].
size());
430 for (
unsigned int sin = 0;
sin < mySegColVec[lin].size();
sin++) {
431 seedSeg = mySegColVec[lin].operator[](
sin);
432 if (!seedSeg)
continue;
435 if (cutSeeds && seedSeg->
usedInFit)
continue;
446 for (
unsigned int sin2 = 0; sin2 < mySegColVec[lin].size(); sin2++) {
447 if (
sin == sin2)
continue;
457 double deltaEta = std::abs(etaSeed - etaSeg);
460 if (
deltaR < 0.35) segsInCone++;
466 std::vector<std::unique_ptr<MuPatTrack> >
found =
470 if (!
found.empty()) {
471 result.insert(
result.end(), std::make_move_iterator(
found.begin()), std::make_move_iterator(
found.end()));
488 resultAll.insert(resultAll.end(), std::make_move_iterator(
result.begin()), std::make_move_iterator(
result.end()));
497 if (!emSegments.empty()) {
500 if (!sit->tracks().empty())
continue;
503 if (sit->quality < 2)
continue;
506 std::unique_ptr<Trk::Track> segmentTrack(
m_segmentFitter->fit(*sit->segment));
510 if (recoveredTrack) segmentTrack.swap(recoveredTrack);
517 std::unique_ptr<MuPatTrack>
can =
m_candidateTool->createCandidate(*sit, segmentTrack);
519 resultAll.push_back(std::move(
can));
528 if (!resultAll.empty()) {
534 std::unique_ptr<TrackCollection> finalTrack =
nullptr;
535 if (!resultAll.empty()) { finalTrack =
selectTracks(resultAll); }
544 std::vector<std::unique_ptr<MuPatTrack> >
result;
546 const unsigned int endLayer = strat.
getAll().size();
548 for (
unsigned int ilayer = 0; ilayer < strat.
getAll().
size(); ++ilayer) {
549 if (ilayer ==
layer)
continue;
551 if (segs[ilayer].empty())
continue;
553 std::vector<MuPatSegment*> matchedSegs;
554 bool tightCuts =
false;
557 double phiSeed = (seedSeg.
segment)->globalPosition().phi();
558 double etaSeed = (seedSeg.
segment)->globalPosition().eta();
561 for (
unsigned int j = 0; j < segs[ilayer].size(); j++) {
562 double phiSeg = (*segs[ilayer][j]).
segment->globalPosition().phi();
563 double etaSeg = (*segs[ilayer][j]).
segment->globalPosition().eta();
566 double deltaEta = std::abs(etaSeed - etaSeg);
569 if (
deltaR < 0.35) segsInCone++;
573 for (
unsigned int j = 0; j < segs[ilayer].size(); ++j) {
576 if (
isMatched) matchedSegs.push_back(segs[ilayer][j]);
578 if (matchedSegs.empty())
continue;
583 std::vector<std::unique_ptr<MuPatTrack> > tracks;
588 tracks =
m_trackBTool->find(ctx, seedSeg, segs[ilayer]);
589 if (!tracks.empty()) {
591 if (ilayer + 1 == strat.
getAll().size()) {
592 result.insert(
result.end(), std::make_move_iterator(tracks.begin()), std::make_move_iterator(tracks.end()));
597 for (std::unique_ptr<MuPatTrack>& cit : tracks) {
598 unsigned int nextLayer = ilayer + 1;
599 if (nextLayer < strat.
getAll().size()) {
600 int cutLevel = tightCuts ? 1 : 0;
601 std::vector<std::unique_ptr<MuPatTrack> > nextTracks =
603 if (!nextTracks.empty()) {
604 result.insert(
result.end(), std::make_move_iterator(nextTracks.begin()),
605 std::make_move_iterator(nextTracks.end()));
607 result.push_back(std::move(cit));
619 unsigned int nextlayer,
const unsigned int endlayer,
620 int cutLevel)
const {
621 std::vector<std::unique_ptr<MuPatTrack> >
result;
622 if (nextlayer < endlayer) {
623 for (; nextlayer != endlayer; nextlayer++) {
624 if (segs[nextlayer].empty())
continue;
626 std::vector<std::unique_ptr<MuPatTrack> > nextTracks =
m_trackBTool->find(ctx, candidate, segs[nextlayer]);
627 if (!nextTracks.empty()) {
628 for (std::unique_ptr<MuPatTrack>& cit : nextTracks) {
629 std::vector<std::unique_ptr<MuPatTrack> > nextTracks2 =
631 if (!nextTracks2.empty()) {
632 result.insert(
result.end(), std::make_move_iterator(nextTracks2.begin()),
633 std::make_move_iterator(nextTracks2.end()));
635 result.push_back(std::move(cit));
647 std::unique_ptr<TrackCollection>
result = takeOwnership ?std::make_unique<TrackCollection>() : std::make_unique<TrackCollection>(
SG::VIEW_ELEMENTS);
649 for (std::unique_ptr<MuPatTrack>& cit :
candidates) {
650 auto & thisTrack = cit->track();
675 std::unique_ptr<TrackCollection> trkColl(
selectTracks(tracks,
false));
676 if (!trkColl || trkColl->
empty()) {
return; }
678 std::unique_ptr<const TrackCollection> resolvedTracks(
m_ambiTool->process(trkColl.get()));
679 if (!resolvedTracks) {
return; }
681 ATH_MSG_DEBUG(
" resolved track candidates: old size " << trkColl->
size() <<
" new size " << resolvedTracks->
size());
683 std::vector<std::unique_ptr<MuPatTrack> >
::iterator pat = tracks.begin();
684 for (;
pat != tracks.end();) {
686 for (
const Trk::Track* rtrk : *resolvedTracks) {
687 if (&(*pat)->track() == rtrk) {
704 for (
unsigned int i = 0;
i <
strategy.size(); ++
i) {
715 return StatusCode::SUCCESS;
721 const std::string delims(
" \t[],;");
728 std::vector<std::string>
options;
732 typedef std::vector<std::string> ChamberGroup;
733 std::vector<ChamberGroup> sequence;
736 bool success =
false;
737 std::unique_ptr<const MuonTrackSteeringStrategy>
result;
742 std::string::size_type begIdx, endIdx;
743 begIdx =
strategy.find_first_not_of(delims);
744 if (std::string::npos != begIdx) {
745 endIdx =
strategy.find(
':', begIdx);
746 if (std::string::npos != endIdx) {
748 std::string nameopt =
strategy.substr(begIdx, endIdx - begIdx);
749 std::string::size_type bi = nameopt.find(
'[');
750 if (std::string::npos != bi) {
751 name = nameopt.substr(0, bi);
754 std::string::size_type ei = nameopt.find(
']', bi);
755 if (std::string::npos == ei) { ei = nameopt.length(); }
756 std::string inputOpt = nameopt.substr(bi + 1, ei - bi - 1);
764 ATH_MSG_DEBUG(
"From strat: " <<
strategy <<
" with success " << success <<
" end " << endIdx <<
" beg " << begIdx
765 <<
" Name: " <<
name <<
" options: ");
773 endIdx =
strategy.find(
';', begIdx);
774 std::string::size_type lstIdx = endIdx;
775 if (std::string::npos == endIdx) { lstIdx =
strategy.length(); }
776 std::string grpString =
strategy.substr(begIdx, lstIdx - begIdx);
779 sequence.push_back(
group);
781 }
while (std::string::npos != endIdx && success);
785 std::vector<std::vector<ChIndex> >
path;
786 for (
unsigned int i = 0;
i < sequence.size(); ++
i) {
787 std::vector<ChIndex> idxGrp;
788 for (
unsigned int j = 0; j < sequence[
i].size(); ++j) {
790 if (ChIndex::ChUnknown ==
idx) {
793 idxGrp.push_back(
idx);
796 path.push_back(idxGrp);
808 std::string::size_type begIdx = 0;
809 std::string::size_type endIdx = 0;
811 endIdx = input.find(
',', begIdx);
812 std::string::size_type lstIdx = endIdx;
813 if (std::string::npos == endIdx) { lstIdx = input.length(); }
814 std::string
item = input.substr(begIdx, lstIdx - begIdx);
817 }
while (std::string::npos != endIdx);