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)) {
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(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));
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();
667 for (std::unique_ptr<MuPatTrack>& cit : candidates) {
m_trackRefineTool->refine(ctx, *cit); }
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) {
693 pat = tracks.erase(pat);
704 for (
unsigned int i = 0; i < strategy.size(); ++i) {
705 std::unique_ptr<const MuonTrackSteeringStrategy> holder =
decodeStrategy(strategy[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;
739 std::string::size_type
length = strategy.length();
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) {
747 seqStr = strategy.substr(endIdx + 1,
length - endIdx - 1);
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);
763 if (msgLvl(MSG::DEBUG)) {
764 ATH_MSG_DEBUG(
"From strat: " << strategy <<
" with success " << success <<
" end " << endIdx <<
" beg " << begIdx
765 <<
" Name: " << name <<
" options: ");
766 for (std::vector<std::string>::iterator oit = options.begin(); oit != options.end(); ++oit)
767 msg(MSG::DEBUG) <<
" " << *oit <<
endmsg;
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);
778 success = success &&
decodeList(grpString, group);
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);
798 result = std::make_unique<MuonTrackSteeringStrategy>(name, options, path);
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);
815 list.push_back(item);
817 }
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)
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(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
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
void solveAmbiguities(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...
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)