ATLAS Offline Software
MsTrackSeeder.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
9 
10 #include "Acts/Utilities/Helpers.hpp"
11 #include "Acts/Surfaces/detail/LineHelper.hpp"
12 #include "Acts/Definitions/Units.hpp"
13 #include "GaudiKernel/PhysicalConstants.h"
14 namespace {
15  using namespace Acts::UnitLiterals;
16  constexpr double inDeg(const double a) {
17  return a / 1._degree;
18  }
22  constexpr int ringSector(const int sector) {
23  constexpr int nSectors = Muon::MuonStationIndex::numberOfSectors();
24  return sector == 0 ? nSectors : (sector > nSectors ? 1 : sector);
25  }
27  constexpr int ringOverlap(const int sector) {
28  constexpr int nSectors = 2*Muon::MuonStationIndex::numberOfSectors();
29  return sector > nSectors ? 1 : sector;
30  }
32  void average(const Amg::Vector3D& segPos, std::optional<Amg::Vector3D>& posSlot) {
33  if (!posSlot) {
34  posSlot = segPos;
35  } else {
36  posSlot = 0.5 * ((*posSlot) + segPos);
37  }
38  }
40  inline Amg::Vector3D dirForBField(const xAOD::MuonSegment& seg,
41  const double circPhi) {
42  //if (seg.nPhiLayers() > 0) {
43  // return seg.direction();
44  //}
45  const double theta = std::atan2(Acts::fastHypot(seg.px(), seg.py()), seg.pz());
46  return Acts::makeDirectionFromPhiTheta(circPhi, theta);
47  }
48  std::string print(const Amg::Vector3D& v){
49  return std::format("r: {:.2f}, z: {:.2f}, phi: {:.2f}, theta: {:.2f}",
50  v.perp(), v.z(), inDeg((v.phi())), inDeg(v.theta()));
51  }
52 
53  float reducedChi2(const xAOD::MuonSegment& seg) {
54  return seg.chiSquared() / std::max(1.f, seg.numberDoF());
55  }
56  std::string print(const xAOD::MuonSegment& seg) {
57  return std::format("{:}, nPrecHits: {:}, nPhiHits: {:}", MuonR4::printID(seg),
58  seg.nPrecisionHits(), seg.nPhiLayers());
59  }
60  static const Muon::MuonSectorMapping sectorMap{};
61 }
62 
63 namespace MuonR4{
66  std::string to_string(const SectorProjector proj){
67  using enum SectorProjector;
68  switch (proj) {
69  case leftOverlap:
70  return "overlap with left sector";
71  case center:
72  return "sector center";
73  case rightOverlap:
74  return "overlap with right sector";
75  default:
76  return "";
77  }
78  }
79 
80  MsTrackSeeder::MsTrackSeeder(const std::string& msgName, Config&& cfg):
81  AthMessaging{msgName},
82  m_cfg{std::move(cfg)}{
83  auto& v{m_cfg.fieldExtpSteps};
84  v.insert(0.); v.insert(1.);
85  if (std::ranges::any_of(v, [](const double x){
86  return x < 0. || x > 1.;
87  })) {
88  THROW_EXCEPTION("Found invalid extrapolation steps.");
89  }
90  }
91 
92 
93  double MsTrackSeeder::projectedPhi(const int sector,
94  const SectorProjector proj) {
95  return sectorMap.sectorOverlapPhi(sector, ringSector(sector + Acts::toUnderlying(proj)));
96  }
99  return m_cfg.detMgr->getSectorEnvelope(segment.chamberIndex(),
100  segment.sector(),
101  segment.etaIndex());
102  }
105  const MsTrackSeed& refSeed) {
106 
107  int doubSector = 2 * seg.sector();
108  constexpr int nSectors = 2*Muon::MuonStationIndex::numberOfSectors();
109  if (refSeed.sector() == nSectors && doubSector ==2) {
111  } else if (refSeed.sector() == 1 && doubSector == nSectors) {
113  }
114  return static_cast<SectorProjector>(refSeed.sector() - doubSector );
115  }
117  const xAOD::MuonSegment& segment,
118  const MsTrackSeed& seed) const {
119  return projectOntoSector(gctx, segment, projectorFromSeed(segment, seed));
120  }
122  const xAOD::MuonSegment& segment,
123  const SectorProjector proj) const {
125  const double sectorPhi{projectedPhi(segment.sector(), proj)};
126  ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Project onto "<<to_string(proj)<<" in "
127  <<envelope(segment)->identString());
128  return projectOntoPhiPlane(gctx, segment, sectorPhi);
129  }
131  const xAOD::MuonSegment& segment,
132  const double projectPhi) const {
133  using enum SectorProjector;
134  const Amg::Vector3D segPos3D{segment.position()};
137  const Amg::Vector3D dirAlongTube{envelope(segment)->localToGlobalTrans(gctx).linear().col(0)};
138  ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Project onto phi: "<<inDeg(projectPhi));
139  const Amg::Vector3D radialDir = Amg::getRotateZ3D(projectPhi) * Amg::Vector3D::UnitX();
140  using namespace Acts::detail::LineHelper;
142  const auto isect = lineIntersect<3>(segPos3D.z()*Amg::Vector3D::UnitZ(), radialDir,
143  segPos3D, dirAlongTube);
144  using namespace Muon::MuonStationIndex;
145  ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Projected "<<printID(segment)
146  <<" segment in @"<<Amg::toString(segPos3D)<<" + "
147  <<Amg::toString(segment.direction())<<", chi2: "<<(segment.chiSquared() / std::max(1.f, segment.numberDoF()))
148  <<", nDoF: "<<segment.numberDoF()<<" --> "<<Amg::toString(isect.position()));
149  return isect.position();
150  }
152  const xAOD::MuonSegment& segment,
153  const Location loc,
154  const SectorProjector proj) const {
156  const Amg::Vector3D pos{projectOntoSector(gctx, segment, proj)};
157  const Amg::Vector3D dir{segment.direction()};
158 
159  const Amg::Vector2D projPos{pos.perp(), pos.z()};
160  const Amg::Vector2D projDir{dir.perp(), dir.z()};
161 
162  double lambda{0.};
163  if (Location::Barrel == loc) {
164  lambda = Amg::intersect<2>(projPos, projDir, Amg::Vector2D::UnitX(),
165  m_cfg.barrelRadius).value_or(10. * Gaudi::Units::km);
166  } else {
167  lambda = Amg::intersect<2>(projPos, projDir, Amg::Vector2D::UnitY(),
168  sign(projPos[1])* m_cfg.endcapDiscZ).value_or(10. * Gaudi::Units::km);
169  }
170  return projPos + lambda * projDir;
171  }
173  const Location loc) const {
174  using enum Location;
175  if (loc == Barrel && std::abs(projPos[1]) > std::min(m_cfg.endcapDiscZ, m_cfg.barrelLength)) {
176  ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Position "<<Amg::toString(projPos)<<
177  " exceeds cylinder boundaries ("<<m_cfg.barrelRadius<<", "
179  return false;
180  } else if (loc == Endcap && (0 > projPos[0] || projPos[0] > m_cfg.endcapDiscRadius)) {
181  ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Position "<<Amg::toString(projPos)<<
182  " exceeds endcap boundaries ("<<m_cfg.endcapDiscRadius<<", "<<(sign(projPos[1])*m_cfg.endcapDiscZ)<<")");
183  return false;
184  }
185  return true;
186  }
187  std::optional<double> MsTrackSeeder::calculateRadius(VecOpt_t&& pI, VecOpt_t&& pM, VecOpt_t&& pO,
188  const Amg::Vector3D& planeNorm) const {
189  if (!pI || !pM || !pO) {
190  return std::nullopt;
191  }
192  const Amg::Vector3D leverL = (*pO) - (*pI);
193 
194  ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Construct sagitta from "
195  <<"\n --- Inner: "<<print(*pI) <<"\n --- Middle: "<<print(*pM)
196  <<"\n --- Outer: "<<print(*pO));
197  if (std::abs(planeNorm.dot(leverL)) > Acts::s_onSurfaceTolerance ||
198  std::abs(planeNorm.dot( (*pM) - (*pI))) > Acts::s_onSurfaceTolerance) {
199  THROW_EXCEPTION("The lever arm is in the bending plane: "<<Amg::toString(planeNorm)
200  <<", "<<Amg::toString(leverL.unit())<<", "<<Amg::toString( ((*pM) - (*pI)).unit()));
201  }
202  const Amg::Vector3D sagittaDir = leverL.cross(planeNorm).unit();
203  std::optional<double> sagitta = Amg::intersect<3>(*pI, leverL.unit(), *pM, sagittaDir);
204  ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Estimated sagitta: "<<(sagitta ?
205  std::to_string(sagitta.value_or(0.)) : "---")<<", lever arm: "
206  <<(leverL.mag() / Gaudi::Units::m)<<" [m]" );
207  if (!sagitta) {
208  return std::nullopt;
209  }
218  return leverL.dot(leverL) / (8. * (*sagitta));
219  }
221  const AtlasFieldCacheCondObj& magField,
222  const MsTrackSeed& seed) const {
223 
224  MagField::AtlasFieldCache fieldCache{};
225  magField.getInitializedCache(fieldCache);
226 
228  double circPhi{0.};
229  unsigned nSegsWithPhi{0};
230  for (const xAOD::MuonSegment* segment : seed.segments()) {
231  if (segment->nPhiLayers() > 0) {
232  circPhi += std::atan2(segment->y(), segment->x());
233  ++nSegsWithPhi;
234  }
235  }
236  if (!nSegsWithPhi){
237  circPhi = projectedPhi(seed.segments()[0]->sector(),
238  projectorFromSeed(*seed.segments()[0], seed));
239  } else {
240  circPhi /=nSegsWithPhi;
241  }
242  auto layerPos{Acts::filledArray<VecOpt_t, 6>(std::nullopt)};
243  double avgBField{0.}, avgTheta{0.};
244  const xAOD::TruthParticle* truthMuon{nullptr};
245  const Amg::Vector3D planeNorm = Acts::makeDirectionFromPhiTheta(circPhi+ 90._degree, 90._degree);
246 
247  {
248  Amg::Vector3D projPos = projectOntoPhiPlane(gctx, *seed.segments()[0], circPhi);
249  Amg::Vector3D projDir = dirForBField(*seed.segments()[0], circPhi);
251  unsigned nBFieldPoints{0};
252  const unsigned nSeedSeg = seed.segments().size();
253  using namespace Muon::MuonStationIndex;
254  for (unsigned int s = 0; s < nSeedSeg; ++s) {
255  avgTheta += projDir.theta();
257  const xAOD::MuonSegment& segment{*seed.segments()[s]};
258  if (!truthMuon) {
260  }
261  switch (toStationIndex(segment.chamberIndex())) {
262  using enum StIndex;
263  case BI:
264  case BE:{
265  average(projPos, layerPos[0]);
266  break;
267  } case BM: {
268  average(projPos, layerPos[1]);
269  break;
270  } case BO: {
271  average(projPos, layerPos[2]);
272  break;
273  } case EI:
274  case EE: {
275  average(projPos, layerPos[3]);
276  break;
277  } case EM : {
278  average(projPos, layerPos[4]);
279  break;
280  } case EO : {
281  average(projPos, layerPos[5]);
282  break;
283  } default: {
284  break;
285  }
286  }
287  if (s + 1 == nSeedSeg) {
288  break;
289  }
291  Amg::Vector3D nextDir = dirForBField(*seed.segments()[s+1], circPhi);
292  Amg::Vector3D nextPos = projectOntoPhiPlane(gctx, *seed.segments()[s+1], circPhi);
293 
294  for (double fieldStep : m_cfg.fieldExtpSteps) {
295  /* The */
296  if (fieldStep == 0. && s > 0) {
297  continue;
298  }
299  const Amg::Vector3D extPos = (1. -fieldStep) * projPos + fieldStep * nextPos;
300  const Amg::Vector3D extDir = ((1. -fieldStep) * projDir + fieldStep * nextDir).unit();
301  // const Amg::Vector3D loc
302  fieldCache.getField(extPos.data(), locField.data());
303  const double localB = extDir.cross(locField).mag();
304 
305  ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Segment "<<s<<", step: "<<fieldStep
306  <<", position: "<<Amg::toString(extPos)<<", dir: "<<Amg::toString(extDir)
307  <<" --> localB: "<<(localB * 1000.)<<" T."
308  <<", B: "<<Amg::toString(locField* 1000.)
309  <<", PxB:"<<Amg::toString(extDir.cross(locField).unit())
310  <<", planeNorm: "<<Amg::toString(planeNorm));
311  avgBField += localB;
312  ++nBFieldPoints;
313  }
314  projPos = std::move(nextPos);
315  projDir = std::move(nextDir);
316  }
317  avgBField /= std::max(nBFieldPoints, 1u);
318  ATH_MSG_DEBUG(__func__<<"() "<<__LINE__<<" - averaged field: "<<(avgBField * 1000.)
319  <<" T, number of points: "<<nBFieldPoints<<".");
320  }
321  avgTheta /= seed.segments().size();
323  std::optional<double> barrelR = calculateRadius(std::move(layerPos[0]),
324  std::move(layerPos[1]),
325  std::move(layerPos[2]), planeNorm);
327  std::optional<double> endcapR = calculateRadius(std::move(layerPos[3]),
328  std::move(layerPos[4]),
329  std::move(layerPos[5]), planeNorm);
331  if (!barrelR && !endcapR) {
332  return 5.*Gaudi::Units::TeV;
333  }
334  const double r = 0.5* (barrelR.value_or(*endcapR) +
335  endcapR.value_or(*barrelR));
337  const double P = 0.3* Gaudi::Units::GeV* avgBField * r / std::abs(std::sin(avgTheta));
338 
339  ATH_MSG_DEBUG(__func__<<"() "<<__LINE__<<" - Estimated radius "<<r / Gaudi::Units::m<<" [m] --> P: "<<
340  (P / Gaudi::Units::GeV)<<" [GeV]");
341 
342  if (truthMuon && sign(P) != truthMuon->charge() && truthMuon->abseta() < 2.5 &&
343  (truthMuon->abseta() < 1.3 || truthMuon->abseta() > 1.4) ) {
344  ATH_MSG_WARNING("Invalid charge, pT: "<<(truthMuon->pt() / Gaudi::Units::GeV)<<" [GeV], eta: "
345  <<truthMuon->eta()<<", phi: "<<(truthMuon->phi() / 1._degree)<<", q: "<<truthMuon->charge());
346  }
347  return P;
348  }
350  const xAOD::MuonSegment* segment,
351  const Location loc,
352  TreeRawVec_t& outContainer) const {
353 
354  const int segSector = segment->sector();
357  const int projSector = ringSector(segSector + Acts::toUnderlying(proj));
358  if (segment->nPhiLayers() > 0 && proj != SectorProjector::center &&
359  !sectorMap.insideSector(projSector, segment->position().phi())) {
360  ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Segment @"<<Amg::toString(segment->position())
361  <<" is not in sector "<<projSector<<" which is "<<to_string(proj) <<" to "<<segment->sector());
362  continue;
363  }
364  const Amg::Vector2D refPoint{expressOnCylinder(gctx, *segment, loc, proj)};
365  if (!withinBounds(refPoint, loc)) {
366  continue;
367  }
368  using enum SeedCoords;
369  std::array<double, 3> coords{};
373  const int treeSector = 2*segSector + Acts::toUnderlying(proj);
374  coords[Acts::toUnderlying(eSector)] = ringOverlap(treeSector);
377  coords[Acts::toUnderlying(eDetSection)] = Acts::toUnderlying(loc) * sign(refPoint[1]);
379  coords[Acts::toUnderlying(ePosOnCylinder)] = refPoint[Location::Barrel == loc];
380  ATH_MSG_VERBOSE("Add segment "<<print(*segment)<<", seed quality: "
381  <<m_cfg.selector->passSeedingQuality(Gaudi::Hive::currentContext(), *detailedSegment(*segment))
382  <<" with "<<coords<<" to the search tree");
383  outContainer.emplace_back(std::move(coords), segment);
384  }
385  }
387  const xAOD::MuonSegmentContainer& segments) const{
388  TreeRawVec_t rawData{};
389  rawData.reserve(3*segments.size());
390  for (const xAOD::MuonSegment* segment : segments){
391  appendSegment(gctx, segment, Location::Barrel, rawData);
392  appendSegment(gctx, segment, Location::Endcap, rawData);
393  }
394  ATH_MSG_VERBOSE("Create a new tree with "<<rawData.size()<<" entries. ");
395  return SearchTree_t{std::move(rawData)};
396  }
397  std::unique_ptr<MsTrackSeedContainer> MsTrackSeeder::findTrackSeeds(const EventContext& ctx,
398  const ActsTrk::GeometryContext& gctx,
399  const xAOD::MuonSegmentContainer& segments) const {
400  SearchTree_t orderedSegs{constructTree(gctx, segments)};
401  MsTrackSeedContainer trackSeeds{};
402  using enum SeedCoords;
403  for (const auto& [coords, seedCandidate] : orderedSegs) {
406  const Segment* recoSeedCandidate = detailedSegment(*seedCandidate);
407  if (!m_cfg.selector->passSeedingQuality(ctx, *recoSeedCandidate)){
408  continue;
409  }
411  SearchTree_t::range_t selectRange{};
414  selectRange[Acts::toUnderlying(eDetSection)].shrink(coords[Acts::toUnderlying(eDetSection)] - 0.1,
415  coords[Acts::toUnderlying(eDetSection)] + 0.1);
417  selectRange[Acts::toUnderlying(ePosOnCylinder)].shrink(coords[Acts::toUnderlying(ePosOnCylinder)] - m_cfg.seedHalfLength,
418  coords[Acts::toUnderlying(ePosOnCylinder)] + m_cfg.seedHalfLength);
420  selectRange[Acts::toUnderlying(eSector)].shrink(coords[Acts::toUnderlying(eSector)] -0.25,
421  coords[Acts::toUnderlying(eSector)] +0.25);
422 
423  MsTrackSeed newSeed{static_cast<Location>(std::abs(coords[Acts::toUnderlying(eDetSection)])),
424  static_cast<int>(coords[Acts::toUnderlying(eSector)])};
426  ATH_MSG_VERBOSE("Search for compatible segments to "<<print(*seedCandidate)<<".");
427  orderedSegs.rangeSearchMapDiscard(selectRange, [&](
428  const SearchTree_t::coordinate_t& /*coords*/,
429  const xAOD::MuonSegment* extendWithMe) {
431  const Segment* extendCandidate = detailedSegment(*extendWithMe);
432  if (!m_cfg.selector->compatibleForTrack(ctx, *recoSeedCandidate, *extendCandidate)) {
433  ATH_MSG_VERBOSE("Segment "<<print(*extendWithMe)<<" is not compatible.");
434  return;
435  }
436  auto itr = std::ranges::find_if(newSeed.segments(), [extendWithMe](const xAOD::MuonSegment* onSeed){
437  return extendWithMe->chamberIndex() == onSeed->chamberIndex();
438  });
439  if (itr == newSeed.segments().end()){
440  ATH_MSG_VERBOSE("Add segment "<<print(*extendWithMe)<<" to seed.");
441  newSeed.addSegment(extendWithMe);
442  } else if (reducedChi2(**itr) > reducedChi2(*extendWithMe) &&
443  (*itr)->nPhiLayers() <= extendWithMe->nPhiLayers()) {
444  newSeed.replaceSegment(*itr, extendWithMe);
445  }
446  });
448  if (newSeed.segments().empty()) {
449  continue;
450  }
451  newSeed.addSegment(seedCandidate);
453  const double r = newSeed.location() == Location::Barrel ? m_cfg.barrelRadius
454  : coords[Acts::toUnderlying(ePosOnCylinder)];
455  const double z = newSeed.location() == Location::Barrel ? coords[Acts::toUnderlying(ePosOnCylinder)]
456  : coords[Acts::toUnderlying(eDetSection)]* m_cfg.endcapDiscZ;
457  const int secCoord = coords[Acts::toUnderlying(eSector)];
458 
459  const double phi = sectorMap.sectorOverlapPhi( (secCoord - secCoord % 2) / 2, (secCoord + secCoord % 2) / 2 );
460  Amg::Vector3D pos = r * Acts::makeDirectionFromPhiTheta(phi, 90._degree)
461  + z * Amg::Vector3D::UnitZ();
462 
463  newSeed.setPosition(std::move(pos));
464  ATH_MSG_VERBOSE("Add new seed "<<newSeed);
465  trackSeeds.emplace_back(std::move(newSeed));
466  }
467  ATH_MSG_VERBOSE("Found in total "<<trackSeeds.size()<<" before overlap removal");
468  return resolveOverlaps(std::move(trackSeeds));
469  }
470  std::unique_ptr<MsTrackSeedContainer>
472 
474  std::ranges::sort(unresolved, [](const MsTrackSeed& a, const MsTrackSeed&b) {
475  return a.segments().size() > b.segments().size();
476  });
477  auto outputSeeds = std::make_unique<MsTrackSeedContainer>();
478  outputSeeds->reserve(unresolved.size());
479  std::ranges::copy_if(std::move(unresolved), std::back_inserter(*outputSeeds),
480  [this, &outputSeeds](const MsTrackSeed& testMe) {
482  std::ranges::find_if(*outputSeeds, [&testMe](const MsTrackSeed& good) {
483  if (ringOverlap(good.sector() - testMe.sector()) > 1) {
484  return false;
485  }
486  return std::ranges::find_if(testMe.segments(),
487  [&good](const xAOD::MuonSegment* segInTest) {
488  return std::ranges::find(good.segments(), segInTest) != good.segments().end();
489  }) != testMe.segments().end();
490  });
492  if (test_itr == outputSeeds->end()) {
493  ATH_MSG_VERBOSE("Add new seed "<<testMe);
494  return true;
495  }
497  if ( (*test_itr).segments().size() < testMe.segments().size()){
498  (*test_itr) = testMe;
499  }
500  return false;
501  });
502  return outputSeeds;
503  }
504 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
MuonR4::MsTrackSeed::Location::Barrel
@ Barrel
MuonR4::printID
std::string printID(const xAOD::MuonSegment &seg)
Print the chamber ID of a segment, e.g.
Definition: TrackingHelpers.cxx:15
xAOD::MuonSegment_v1::numberDoF
float numberDoF() const
Returns the numberDoF.
beamspotman.r
def r
Definition: beamspotman.py:672
MuonSimHitHelpers.h
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:17
MuonR4::ISegmentSelectionTool::passSeedingQuality
virtual bool passSeedingQuality(const EventContext &ctx, const Segment &segment) const =0
Returns whether a segment provides enough mdt & phi measurements to use it for track finding seeding.
MuonGMR4::SpectrometerSector
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
Definition: SpectrometerSector.h:40
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
xAOD::MuonSegment_v1::direction
Amg::Vector3D direction() const
Returns the direction as Amg::Vector.
Definition: MuonSegment_v1.cxx:18
vtune_athena.format
format
Definition: vtune_athena.py:14
drawFromPickle.average
def average(lst)
Definition: drawFromPickle.py:38
MuonR4::getTruthMatchedParticle
const xAOD::TruthParticle * getTruthMatchedParticle(const xAOD::MuonSegment &segment)
Returns the particle truth-matched to the segment.
Definition: MuonSimHitHelpers.cxx:107
AtlasFieldCacheCondObj
Definition: AtlasFieldCacheCondObj.h:19
MuonR4::MsTrackSeeder::Config::barrelRadius
double barrelRadius
The radius of the barrel cylinder to seed.
Definition: MsTrackSeeder.h:34
MuonR4::MsTrackSeeder::withinBounds
bool withinBounds(const Amg::Vector2D &projPos, const Location loc) const
Returns whether the expression on the cylinder is within the surface bounds.
Definition: MsTrackSeeder.cxx:172
Muon::MuonStationIndex
Definition: MuonStationIndex.h:13
xAOD::MuonSegment_v1::chiSquared
float chiSquared() const
MuonR4::MsTrackSeeder::findTrackSeeds
std::unique_ptr< MsTrackSeedContainer > findTrackSeeds(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegmentContainer &segments) const
Constructs the MS track seeds from the segment container.
Definition: MsTrackSeeder.cxx:397
MuonR4::MsTrackSeeder::Config::barrelLength
double barrelLength
The maximum length of the barrel cylinder, if not capped by the placement of the endcap discs.
Definition: MsTrackSeeder.h:37
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
MuonGMR4::SpectrometerSector::localToGlobalTrans
const Amg::Transform3D & localToGlobalTrans(const ActsTrk::GeometryContext &gctx) const
Returns the local -> global tarnsformation from the sector.
Definition: SpectrometerSector.cxx:75
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
MuonR4::MsTrackSeed
Definition: MsTrackSeed.h:18
DMTest::P
P_v1 P
Definition: P.h:23
MuonR4::MsTrackSeeder::projectorFromSeed
static SectorProjector projectorFromSeed(const xAOD::MuonSegment &seg, const MsTrackSeed &refSeed)
Returns the Sector projector within the context of a MsTrackSeed.
Definition: MsTrackSeeder.cxx:104
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
MuonR4::ISegmentSelectionTool::compatibleForTrack
virtual bool compatibleForTrack(const EventContext &ctx, const Segment &segA, const Segment &segB) const =0
Returns whether a segment passes the base selection quality in order to be picked up onto a track.
MuonR4::SectorProjector
MsTrackSeeder::SectorProjector SectorProjector
Definition: MsTrackSeeder.cxx:65
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:75
MuonR4::Segment
Placeholder for what will later be the muon segment EDM representation.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonPatternEvent/MuonPatternEvent/Segment.h:19
MsTrackSeeder.h
MuonR4::MsTrackSeeder::SearchTree_t
Acts::KDTree< 3, const xAOD::MuonSegment *, double, std::array, 6 > SearchTree_t
Definition of the search tree class.
Definition: MsTrackSeeder.h:54
xAOD::MuonSegment_v1
Class describing a MuonSegment.
Definition: MuonSegment_v1.h:33
xAOD::MuonSegment_v1::pz
float pz() const
Returns the pz.
xAOD::MuonSegment_v1::px
float px() const
MuonR4::MsTrackSeed::Location::Endcap
@ Endcap
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
MuonR4::to_string
std::string to_string(const SectorProjector proj)
Definition: MsTrackSeeder.cxx:66
MuonR4::MsTrackSeeder::Config::endcapDiscZ
double endcapDiscZ
Position of the endcap discs.
Definition: MsTrackSeeder.h:39
x
#define x
python.SystemOfUnits.TeV
float TeV
Definition: SystemOfUnits.py:176
MatrixUtils.h
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
MuonR4::MsTrackSeeder::calculateRadius
std::optional< double > calculateRadius(VecOpt_t &&pI, VecOpt_t &&pM, VecOpt_t &&pO, const Amg::Vector3D &planeNorm) const
Calculates the radius of the bending circle from three points using the sagitta.
Definition: MsTrackSeeder.cxx:187
Muon::MuonStationIndex::numberOfSectors
constexpr unsigned numberOfSectors()
return total number of sectors
Definition: MuonStationIndex.h:118
MuonR4::MsTrackSeed::Location
Location
Enum defining whether the seed is made in the endcap / barrel.
Definition: MsTrackSeed.h:21
MuonR4::detailedSegment
const Segment * detailedSegment(const xAOD::MuonSegment &seg)
Helper function to navigate from the xAOD::MuonSegment to the MuonR4::Segment.
Definition: TrackingHelpers.cxx:22
Amg::getRotateZ3D
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Definition: GeoPrimitivesHelpers.h:270
MuonR4::MsTrackSeeder::SeedCoords
SeedCoords
Abrivation of the seed coordinates.
Definition: MsTrackSeeder.h:66
MuonR4::MsTrackSeeder::m_cfg
Config m_cfg
Definition: MsTrackSeeder.h:176
Muon::MuonStationIndex::toStationIndex
StIndex toStationIndex(ChIndex index)
convert ChIndex into StIndex
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
AtlasFieldCacheCondObj::getInitializedCache
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
Definition: AtlasFieldCacheCondObj.h:32
MuonR4::MsTrackSeeder::expressOnCylinder
Amg::Vector2D expressOnCylinder(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment &segment, const Location loc, const SectorProjector proj) const
Expresses the segment on the cylinder surface.
Definition: MsTrackSeeder.cxx:151
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
MuonR4::MsTrackSeeder::projectedPhi
static double projectedPhi(const int sector, const SectorProjector proj)
Returns the projected phi for a given sector and projector.
Definition: MsTrackSeeder.cxx:93
MuonR4::MsTrackSeeder::appendSegment
void appendSegment(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment *segment, const Location loc, TreeRawVec_t &outContainer) const
Append the to the raw data container.
Definition: MsTrackSeeder.cxx:349
z
#define z
MuonR4::MsTrackSeeder::envelope
const MuonGMR4::SpectrometerSector * envelope(const xAOD::MuonSegment &segment) const
Returns the spectrometer envelope associated to the segment (Coord system where the parameter are exp...
Definition: MsTrackSeeder.cxx:98
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:37
MuonR4::MsTrackSeeder::TreeRawVec_t
SearchTree_t::vector_t TreeRawVec_t
Abbrivation of the KDTree raw data vector.
Definition: MsTrackSeeder.h:160
xAOD::MuonSegment_v1::py
float py() const
Returns the py.
MuonR4::MsTrackSeeder::VecOpt_t
std::optional< Amg::Vector3D > VecOpt_t
Definition: MsTrackSeeder.h:58
AnalysisUtils::copy_if
Out copy_if(In first, const In &last, Out res, const Pred &p)
Definition: IFilterUtils.h:30
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
hist_file_dump.f
f
Definition: hist_file_dump.py:140
MuonR4::MsTrackSeeder::Location
MsTrackSeed::Location Location
Enum toggling whether the segment is in the endcap or barrel.
Definition: MsTrackSeeder.h:56
MuonR4::MsTrackSeeder::SectorProjector::center
@ center
Project the segment onto the overlap with the previous sector.
ActsTrk::GeometryContext
Definition: GeometryContext.h:28
Muon::MuonStationIndex::StIndex::EE
@ EE
python.SystemOfUnits.km
float km
Definition: SystemOfUnits.py:110
DataVector
Derived DataVector<T>.
Definition: DataVector.h:795
xAOD::MuonSegment_v1::nPhiLayers
int nPhiLayers() const
Returns the number of phi layers.
make_coralServer_rep.proj
proj
Definition: make_coralServer_rep.py:48
MuonR4::MsTrackSeeder::Config::fieldExtpSteps
std::set< double > fieldExtpSteps
Steps between two segments to integrate the magnetic field.
Definition: MsTrackSeeder.h:51
beamspotman.dir
string dir
Definition: beamspotman.py:619
Muon::MuonStationIndex::StIndex::BO
@ BO
Muon::MuonStationIndex::StIndex
StIndex
enum to classify the different station layers in the muon spectrometer
Definition: MuonStationIndex.h:23
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:26
xAOD::MuonSegment_v1::position
Amg::Vector3D position() const
Returns the position as Amg::Vector.
Definition: MuonSegment_v1.cxx:15
TrackingHelpers.h
xAOD::MuonSegment_v1::nPrecisionHits
int nPrecisionHits() const
MuonR4::MsTrackSeeder::Config::detMgr
const MuonGMR4::MuonDetectorManager * detMgr
Detector manager to fetch the sector enevelope transforms.
Definition: MsTrackSeeder.h:46
MuonR4::MsTrackSeeder::projectOntoSector
Amg::Vector3D projectOntoSector(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment &segment, const SectorProjector proj) const
Projects the segment's position onto the sector centre or onto the overlap point with one of the neig...
Definition: MsTrackSeeder.cxx:121
MuonR4::sign
constexpr double sign(const double x)
Returns the sign of a number.
Definition: MatrixUtils.h:11
Muon::MuonStationIndex::StIndex::BE
@ BE
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:76
MuonR4::MsTrackSeeder::Config::endcapDiscRadius
double endcapDiscRadius
Radius of the endcap discs.
Definition: MsTrackSeeder.h:41
MuonR4::SearchTree_t
MsTrackSeeder::SearchTree_t SearchTree_t
Definition: MsTrackSeeder.cxx:64
MuonR4::MsTrackSeeder::Config::seedHalfLength
double seedHalfLength
Maximum separation of point on the cylinder to be picked up onto a seed.
Definition: MsTrackSeeder.h:44
WriteCaloSwCorrections.cfg
cfg
Definition: WriteCaloSwCorrections.py:23
MuonR4::MsTrackSeeder::estimateQtimesP
double estimateQtimesP(const ActsTrk::GeometryContext &gctx, const AtlasFieldCacheCondObj &magField, const MsTrackSeed &seed) const
Estimate the q /p of the seed candidate from the contained segments.
Definition: MsTrackSeeder.cxx:220
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
THROW_EXCEPTION
#define THROW_EXCEPTION(MESSAGE)
Definition: throwExcept.h:10
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
python.TruthMuonD3PDObject.truthMuon
truthMuon
Definition: TruthMuonD3PDObject.py:51
MuonR4
This header ties the generic definitions in this package.
Definition: HoughEventData.h:16
MuonR4::MsTrackSeeder::Config::selector
const ISegmentSelectionTool * selector
Pointer to the segement selection tool which compares two segments for their compatibilitiy.
Definition: MsTrackSeeder.h:49
python.PyAthena.v
v
Definition: PyAthena.py:154
MuonR4::MsTrackSeeder::SectorProjector::rightOverlap
@ rightOverlap
Project the segment onto the sector centre.
ReadBchFromCool.good
good
Definition: ReadBchFromCool.py:433
MuonSectorMapping.h
a
TList * a
Definition: liststreamerinfos.cxx:10
xAOD::MuonSegment_v1::sector
int sector() const
MuonR4::MsTrackSeed::sector
int sector() const
Returns the seed's sector.
Definition: MsTrackSeed.h:55
xAOD::MuonSegment_v1::etaIndex
int etaIndex() const
Returns the eta index, which corresponds to stationEta in the offline identifiers (and the ).
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
MuonR4::MsTrackSeedContainer
std::vector< MsTrackSeed > MsTrackSeedContainer
Definition: MsTrackSeed.h:63
MagField::AtlasFieldCache
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
Definition: AtlasFieldCache.h:43
MuonR4::MsTrackSeeder::SectorProjector
SectorProjector
Enumeration to select the sector projection.
Definition: MsTrackSeeder.h:60
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
MuonR4::MsTrackSeeder::resolveOverlaps
std::unique_ptr< MsTrackSeedContainer > resolveOverlaps(MsTrackSeedContainer &&unresolved) const
Removes exact duplciates or partial subsets of the MsTrackSeeds.
Definition: MsTrackSeeder.cxx:471
MuonR4::MsTrackSeeder::constructTree
SearchTree_t constructTree(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegmentContainer &segments) const
Construct a complete search tree from a MuonSegment container.
Definition: MsTrackSeeder.cxx:386
Muon::MuonSectorMapping
Definition: MuonSectorMapping.h:20
MuonR4::MsTrackSeeder::Config
Configuration object.
Definition: MsTrackSeeder.h:32
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Muon::MuonStationIndex::StIndex::BI
@ BI
Muon::MuonStationIndex::StIndex::BM
@ BM
MuonR4::MsTrackSeeder::SectorProjector::leftOverlap
@ leftOverlap
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
xAOD::MuonSegment_v1::chamberIndex
::Muon::MuonStationIndex::ChIndex chamberIndex() const
Returns the chamber index.
Muon::MuonStationIndex::StIndex::EI
@ EI
MuonGMR4::MuonDetectorManager::getSectorEnvelope
const SpectrometerSector * getSectorEnvelope(const Identifier &channelId) const
Retrieves the spectrometer envelope enclosing the channel's readout element.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MuonDetectorManager.cxx:198
python.SystemOfUnits.m
float m
Definition: SystemOfUnits.py:106
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
MuonR4::MsTrackSeeder::MsTrackSeeder
MsTrackSeeder(const std::string &msgName, Config &&cfg)
Standard constructor.
Definition: MsTrackSeeder.cxx:80
MuonR4::MsTrackSeeder::projectOntoPhiPlane
Amg::Vector3D projectOntoPhiPlane(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment &segment, const double projectPhi) const
Definition: MsTrackSeeder.cxx:130
MuonR4::MsTrackSeed::segments
const std::vector< const xAOD::MuonSegment * > & segments() const
Returns the vector of associated segments.
Definition: MsTrackSeed.cxx:43