30 std::string
print(
const std::vector<MuPatSegment*>& segVec) {
38 s <<
"Track:" <<
print(track.segments());
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;
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)) {
97 result =
findTracks(ctx, chamberSegments, stationSegments);
104 if (coll.empty())
return false;
111 std::unique_ptr<MuPatSegment> aSeg =
m_candidateTool->createSegInfo(ctx, *segment);
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);
150 std::vector<MuPatSegment*>& segments = chamberSegments[
toInt(ChIndex::BEE)];
151 if (!segments.empty()) {
152 chambersWithSegments.insert(ChIndex::BEE);
153 stationsWithSegments.insert(StIndex::BE);
154 std::vector<MuPatSegment*>& segs = stationSegments[
toInt(StIndex::BE)];
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));
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;
321 for (
unsigned int i = 0; i <
m_strategies.size(); ++i) {
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()) {
392 msg(
m_doSummary ? MSG::INFO : MSG::DEBUG) <<
"For strategy: " << strategy.getName() <<
" segments are: ";
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);
415 for (
unsigned int lit = 0; lit < occupancy.size(); ++lit) { seeds.push_back(occupancy[lit].second); }
417 seeds = strategy.seeds();
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++;
462 ATH_MSG_VERBOSE(
"New seed " << sin <<
" segments in cone " << 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()));
480 if (msgLvl(MSG::DEBUG) && !result.empty()) {
481 msg(MSG::DEBUG) <<
"Initial track collection for strategy: " << strategy.getName() <<
" " <<
m_candidateTool->print(result)
488 resultAll.insert(resultAll.end(), std::make_move_iterator(result.begin()), std::make_move_iterator(result.end()));
495 SegCol& emSegments = stationSegments[
toInt(StIndex::EM)];
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(ctx, resultAll); }
542 const unsigned int layer,
const SegColVec_t& segs)
const {
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));
646 std::unique_ptr<TrackCollection>
MuonTrackSteering::selectTracks(
const EventContext& ctx, std::vector<std::unique_ptr<MuPatTrack> >& candidates,
bool takeOwnership)
const {
647 std::unique_ptr<TrackCollection> result = takeOwnership ?std::make_unique<TrackCollection>() : std::make_unique<TrackCollection>(
SG::VIEW_ELEMENTS);
648 result->reserve(candidates.size());
649 for (std::unique_ptr<MuPatTrack>& cit : candidates) {
650 auto & thisTrack = cit->track();
661 result->push_back(track);
667 for (std::unique_ptr<MuPatTrack>& cit : candidates) {
m_trackRefineTool->refine(ctx, *cit); }
673 std::vector<std::unique_ptr<MuPatTrack> >& tracks,
676 std::unique_ptr<TrackCollection> trkColl(
selectTracks(ctx, tracks,
false));
677 if (!trkColl || trkColl->empty()) {
return; }
679 std::unique_ptr<const TrackCollection> resolvedTracks(
m_ambiTool->process(trkColl.get()));
680 if (!resolvedTracks) {
return; }
682 ATH_MSG_DEBUG(
" resolved track candidates: old size " << trkColl->size() <<
" new size " << resolvedTracks->size());
684 std::vector<std::unique_ptr<MuPatTrack> >
::iterator pat = tracks.begin();
685 for (; pat != tracks.end();) {
687 for (
const Trk::Track* rtrk : *resolvedTracks) {
688 if (&(*pat)->track() == rtrk) {
694 pat = tracks.erase(pat);
705 for (
unsigned int i = 0; i < strategy.size(); ++i) {
706 std::unique_ptr<const MuonTrackSteeringStrategy> holder =
decodeStrategy(strategy[i]);
716 return StatusCode::SUCCESS;
722 const std::string delims(
" \t[],;");
729 std::vector<std::string> options;
733 typedef std::vector<std::string> ChamberGroup;
734 std::vector<ChamberGroup> sequence;
737 bool success =
false;
738 std::unique_ptr<const MuonTrackSteeringStrategy> result;
740 std::string::size_type
length = strategy.length();
743 std::string::size_type begIdx, endIdx;
744 begIdx = strategy.find_first_not_of(delims);
745 if (std::string::npos != begIdx) {
746 endIdx = strategy.find(
':', begIdx);
747 if (std::string::npos != endIdx) {
748 seqStr = strategy.substr(endIdx + 1,
length - endIdx - 1);
749 std::string nameopt = strategy.substr(begIdx, endIdx - begIdx);
750 std::string::size_type bi = nameopt.find(
'[');
751 if (std::string::npos != bi) {
752 name = nameopt.substr(0, bi);
755 std::string::size_type ei = nameopt.find(
']', bi);
756 if (std::string::npos == ei) { ei = nameopt.length(); }
757 std::string inputOpt = nameopt.substr(bi + 1, ei - bi - 1);
764 if (msgLvl(MSG::DEBUG)) {
765 ATH_MSG_DEBUG(
"From strat: " << strategy <<
" with success " << success <<
" end " << endIdx <<
" beg " << begIdx
766 <<
" Name: " << name <<
" options: ");
767 for (std::vector<std::string>::iterator oit = options.begin(); oit != options.end(); ++oit)
768 msg(MSG::DEBUG) <<
" " << *oit <<
endmsg;
774 endIdx = strategy.find(
';', begIdx);
775 std::string::size_type lstIdx = endIdx;
776 if (std::string::npos == endIdx) { lstIdx = strategy.length(); }
777 std::string grpString = strategy.substr(begIdx, lstIdx - begIdx);
779 success = success &&
decodeList(grpString, group);
780 sequence.push_back(group);
782 }
while (std::string::npos != endIdx && success);
786 std::vector<std::vector<ChIndex> > path;
787 for (
unsigned int i = 0; i < sequence.size(); ++i) {
788 std::vector<ChIndex> idxGrp;
789 for (
unsigned int j = 0; j < sequence[i].size(); ++j) {
791 if (ChIndex::ChUnknown == idx) {
794 idxGrp.push_back(idx);
797 path.push_back(idxGrp);
799 result = std::make_unique<MuonTrackSteeringStrategy>(name, options, path);
809 std::string::size_type begIdx = 0;
810 std::string::size_type endIdx = 0;
812 endIdx = input.find(
',', begIdx);
813 std::string::size_type lstIdx = endIdx;
814 if (std::string::npos == endIdx) { lstIdx = input.length(); }
815 std::string item = input.substr(begIdx, lstIdx - begIdx);
816 list.push_back(item);
818 }
while (std::string::npos != endIdx);
Scalar perp() const
perp method - perpendicular length
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
Scalar deltaR(const MatrixBase< Derived > &vec) const
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
size_t size() const
Number of registered mappings.
static const Attributes_t empty
std::vector< const Trk::PrepRawData * > PrepVec
const MuPatHitList & hitList() const
returns a reference to the hit list
const MeasVec & phiHits() const
return all phi hits on the entry
segment candidate object.
bool isMdt
true for MDT, false for CSC
const MuonSegment * segment
const MuonSegmentQuality * segQuality
bool isStrict() const
Returns true if the segment was created using strict criteria.
This is the common class for 3D segments used in the muon spectrometer.
virtual const Amg::Vector3D & globalPosition() const override final
global position
const std::vector< std::vector< MuonStationIndex::ChIndex > > & getAll() const
const std::string & getName() const
ToolHandle< MooTrackBuilder > m_mooBTool
std::unique_ptr< TrackCollection > selectTracks(const EventContext &ctx, std::vector< std::unique_ptr< MuPatTrack > > &candidates, bool takeOwnership=true) const
std::vector< MuPatSegment * > SegCol
std::unique_ptr< const MuonTrackSteeringStrategy > decodeStrategy(const std::string &strategy) const
std::array< SegCol, MuonStationIndex::toInt(MuonStationIndex::ChIndex::ChIndexMax)> ChSegCol_t
Helper container to sort the segments by chamber index.
std::set< MuonStationIndex::ChIndex > ChSet
std::unique_ptr< TrackCollection > find(const EventContext &ctx, const MuonSegmentCollection &coll) const override
find tracks starting from a MuonSegmentCollection
static bool decodeList(const std::string &input, std::vector< std::string > &list)
ToolHandle< Trk::ITrackAmbiguityProcessorTool > m_ambiTool
ToolHandle< MooCandidateMatchingTool > m_candidateMatchingTool
void solveAmbiguities(const EventContext &ctx, std::vector< std::unique_ptr< MuPatTrack > > &tracks, const MuonTrackSteeringStrategy *strat=nullptr) const
Resolve ambiguities among tracks for a single strategy This allows a strategy-specific ambiguity solv...
ToolHandle< Muon::MuonTrackSelectorTool > m_trackSelector
PublicToolHandle< MuonEDMPrinterTool > m_printer
void combineOverlapSegments(const EventContext &ctx, std::vector< MuPatSegment * > &ch1, std::vector< MuPatSegment * > &ch2, StSegCol_t &stationSegments, StSet &stationsWithSegments, GarbageContainer &trash_bin) const
bool extractSegments(const EventContext &ctx, const MuonSegmentCollection &coll, ChSegCol_t &chamberSegments, StSegCol_t &stationSegments, ChSet &chambersWithSegments, StSet &stationsWithSegments, GarbageContainer &trash_bin) const
virtual StatusCode initialize() override
initialize method, method taken from bass-class AlgTool
bool m_outputSingleStationTracks
ToolHandle< IMuonTrackBuilder > m_trackBTool
std::array< int, 3 > m_segQCut
Required segment quality for seed, 2nd, and other segments.
ToolHandle< IMuonHoleRecoveryTool > m_muonHoleRecoverTool
StatusCode decodeStrategyVector(const std::vector< std::string > &strategy)
void refineTracks(const EventContext &ctx, std::vector< std::unique_ptr< MuPatTrack > > &candidates) const
std::vector< std::unique_ptr< MuPatTrack > > extendWithLayer(const EventContext &ctx, MuPatTrack &candidate, const SegColVec_t &segcol, unsigned int nextlayer, const unsigned int endlayer, int cutLevel=0) const
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
ToolHandle< IMuonTrackRefiner > m_trackRefineTool
std::vector< std::unique_ptr< const MuonTrackSteeringStrategy > > m_strategies
ToolHandle< MuPatCandidateTool > m_candidateTool
MuonTrackSteering(const std::string &, const std::string &, const IInterface *)
default AlgTool constructor
bool m_combinedSLOverlaps
std::vector< std::unique_ptr< MuPatTrack > > findTrackFromSeed(const EventContext &ctx, MuPatSegment &seedSeg, const MuonTrackSteeringStrategy &strat, const unsigned int layer, const SegColVec_t &segs) const
Find tracks starting from a good segment.
std::array< SegCol, MuonStationIndex::toInt(MuonStationIndex::StIndex::StIndexMax)> StSegCol_t
Helper container to sort the segments by station index.
std::vector< SegCol > SegColVec_t
std::unique_ptr< TrackCollection > findTracks(const EventContext &ctx, ChSegCol_t &chamberSegments, StSegCol_t &stationSegments) const
actual find method
std::vector< std::string > m_stringStrategies
ToolHandle< Trk::IExtendedTrackSummaryTool > m_trackSummaryTool
std::set< MuonStationIndex::StIndex > StSet
ToolHandle< IMuonSegmentFittingTool > m_segmentFitter
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
double chiSquared() const
returns the of the overall track fit
StIndex
enum to classify the different station layers in the muon spectrometer
ChIndex chIndex(const std::string &index)
convert ChIndex name string to enum
StIndex toStationIndex(ChIndex index)
convert ChIndex into StIndex
constexpr int toInt(const EnumType enumVal)
ChIndex
enum to classify the different chamber layers in the muon spectrometer
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
std::shared_ptr< MuPatHit > MuPatHitPtr
std::string print(const MuPatSegment &)
std::vector< const Muon::MuonSegment * > MuonSegmentCollection
static const MooTrackBuilder::PrepVec emptyPhiHits
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
void push_back(std::unique_ptr< MuonSegment > seg)