ATLAS Offline Software
SpacePointMakerAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #include "SpacePointMakerAlg.h"
5 
10 #include "StoreGate/ReadHandle.h"
11 #include "StoreGate/WriteHandle.h"
12 #include <GaudiKernel/IMessageSvc.h>
13 #include <memory>
14 #include <type_traits>
21 
22 
23 #include "Acts/Surfaces/detail/LineHelper.hpp"
24 namespace {
25  inline std::vector<std::shared_ptr<unsigned>> matchCountVec(unsigned n) {
26  std::vector<std::shared_ptr<unsigned>> out{};
27  out.reserve(n);
28  for (unsigned p = 0; p < n ;++p) {
29  out.emplace_back(std::make_shared<unsigned>(0));
30  }
31  return out;
32  }
38  template<class MeasType>
39  Amg::Transform3D toChamberTransform(const ActsTrk::GeometryContext& gctx,
40  const Amg::Transform3D& sectorTrans,
41  const MeasType& meas) {
42  const MuonGMR4::MuonReadoutElement* reEle{meas.readoutElement()};
43  if constexpr(std::is_same_v<MeasType, xAOD::MdtDriftCircle>) {
44  return sectorTrans * reEle->localToGlobalTrans(gctx, meas.measurementHash());
45  } else {
46  return sectorTrans * reEle->localToGlobalTrans(gctx, meas.layerHash());
47  }
48  }
51  template <typename PrdType>
52  double sensorHalfLength(const PrdType& prd) {
53  const auto* re = prd.readoutElement();
54  if constexpr(std::is_same_v<PrdType, xAOD::MdtDriftCircle>) {
55  return 0.5 * re->activeTubeLength(prd.measurementHash());
56  } else if constexpr(std::is_same_v<PrdType, xAOD::RpcMeasurement>) {
57  return 0.5*(prd.measuresPhi() ? re->stripPhiLength() : re->stripEtaLength());
58  } else if constexpr(std::is_same_v<PrdType, xAOD::TgcStrip>) {
59  return 0.5 * re->sensorLayout(prd.layerHash())->design(prd.measuresPhi()).stripLength(prd.channelNumber());
60  } else if constexpr(std::is_same_v<PrdType, xAOD::MMCluster>) {
61  return 0.5* re->stripLayer(prd.layerHash()).design().stripLength(prd.channelNumber());
62  } else if constexpr(std::is_same_v<PrdType, xAOD::sTgcMeasurement>) {
63  return 0.5* re->stripLayer(prd.layerHash()).design().stripLength(prd.channelNumber());
64  }
65  return 0.;
66  }
67 }
68 
69 namespace MuonR4 {
70 
75  if (techIdx != other.techIdx) {
76  return static_cast<int>(techIdx) < static_cast<int>(other.techIdx);
77  }
78  if (stIdx != other.stIdx) {
79  return static_cast<int>(stIdx) < static_cast<int>(other.stIdx);
80  }
81  return eta < other.eta;
82 }
84  return measEta + measPhi + measEtaPhi;
85 }
87  m_idHelperSvc{idHelperSvc}{}
88 
90  std::lock_guard guard{m_mutex};
91  for (const SpacePoint& sp : spacePoints){
92  FieldKey key{};
93  key.stIdx = m_idHelperSvc->stationIndex(sp.identify());
94  key.techIdx = m_idHelperSvc->technologyIndex(sp.identify());
95  key.eta = m_idHelperSvc->stationEta(sp.identify());
96  StatField & stats = m_map[key];
97  if (sp.measuresEta() && sp.measuresPhi()) {
98  ++stats.measEtaPhi;
99  } else {
100  stats.measEta += sp.measuresEta();
101  stats.measPhi += sp.measuresPhi();
102  }
103  }
104 }
106  using KeyVal = std::pair<FieldKey, StatField>;
107  std::vector<KeyVal> sortedstats{};
108  sortedstats.reserve(m_map.size());
110  for (const auto & [key, stats] : m_map){
111  sortedstats.emplace_back(std::make_pair(key, stats));
112  }
113  std::stable_sort(sortedstats.begin(), sortedstats.end(), [](const KeyVal& a, const KeyVal&b) {
114  return a.second.allHits() > b.second.allHits();
115  });
116  msg<<MSG::ALWAYS<<"###########################################################################"<<endmsg;
117  for (const auto & [key, stats] : sortedstats) {
119  <<" "<<Muon::MuonStationIndex::stName(key.stIdx)
120  <<" "<<std::abs(key.eta)<<(key.eta < 0 ? "A" : "C")
121  <<" "<<std::setw(8)<<stats.measEtaPhi
122  <<" "<<std::setw(8)<<stats.measEta
123  <<" "<<std::setw(8)<<stats.measPhi<<endmsg;
124  }
125  msg<<MSG::ALWAYS<<"###########################################################################"<<endmsg;
126 
127 }
132 
133 
135  if (m_statCounter) {
136  m_statCounter->dumpStatisics(msgStream());
137  }
138  return StatusCode::SUCCESS;
139 }
142  ATH_CHECK(m_mdtKey.initialize(!m_mdtKey.empty()));
143  ATH_CHECK(m_rpcKey.initialize(!m_rpcKey.empty()));
144  ATH_CHECK(m_tgcKey.initialize(!m_tgcKey.empty()));
145  ATH_CHECK(m_mmKey.initialize(!m_mmKey.empty()));
146  ATH_CHECK(m_stgcKey.initialize(!m_stgcKey.empty()));
147  ATH_CHECK(m_idHelperSvc.retrieve());
149  if (m_doStat) {
150  m_statCounter = std::make_unique<SpacePointStatistics>(m_idHelperSvc.get());
151  }
152  return StatusCode::SUCCESS;
153 }
154 
155 template <>
156  bool SpacePointMakerAlg::passOccupancy2D(const std::vector<const xAOD::TgcStrip*>& etaHits,
157  const std::vector<const xAOD::TgcStrip*>& phiHits) const {
158  if (etaHits.empty() || phiHits.empty()) {
159  return false;
160  }
161  const MuonGMR4::TgcReadoutElement* re = etaHits[0]->readoutElement();
162  ATH_MSG_VERBOSE("Collected "<<etaHits.size()<<"/"<<phiHits.size()<<" hits in "<<m_idHelperSvc->toStringGasGap(etaHits[0]->identify()));
163  return ((1.*etaHits.size()) / ((1.*re->numChannels(etaHits[0]->measurementHash())))) < m_maxOccTgcEta &&
164  ((1.*phiHits.size()) / ((1.*re->numChannels(phiHits[0]->measurementHash())))) < m_maxOccTgcPhi;
165  }
166 template <>
167  bool SpacePointMakerAlg::passOccupancy2D(const std::vector<const xAOD::RpcMeasurement*>& etaHits,
168  const std::vector<const xAOD::RpcMeasurement*>& phiHits) const {
169  if (etaHits.empty() || phiHits.empty()) {
170  return false;
171  }
172  const MuonGMR4::RpcReadoutElement* re = etaHits[0]->readoutElement();
173  ATH_MSG_VERBOSE("Collected "<<etaHits.size()<<"/"<<phiHits.size()<<" hits in "<<m_idHelperSvc->toStringGasGap(etaHits[0]->identify()));
174  return ((1.*etaHits.size()) / (1.*re->nEtaStrips())) < m_maxOccRpcEta &&
175  ((1.*phiHits.size()) / (1.*re->nPhiStrips())) < m_maxOccRpcPhi;
176  }
177 
178 template <>
179  bool SpacePointMakerAlg::passOccupancy2D(const std::vector<const xAOD::sTgcMeasurement*>& etaHits,
180  const std::vector<const xAOD::sTgcMeasurement*>& phiHits) const {
181  if (etaHits.empty() || phiHits.empty()) {
182  return false;
183  }
184  const MuonGMR4::sTgcReadoutElement* re = etaHits[0]->readoutElement();
185  return ((1.*etaHits.size()) / (1.*re->numChannels(etaHits[0]->measurementHash()))) < m_maxOccStgcEta &&
186  ((1.*phiHits.size()) / (1.*re->numChannels(phiHits[0]->measurementHash()))) < m_maxOccStgcPhi;
187  }
188 template <>
189  bool SpacePointMakerAlg::passOccupancy2D(const std::vector<const xAOD::MMCluster*>& /*etaHits*/,
190  const std::vector<const xAOD::MMCluster*>& /*phiHits*/) const {
191  return false;
192  }
193 template <typename PrdType>
195  const Amg::Transform3D& sectorTrans,
196  const std::vector<const PrdType*>& prdsToFill,
197  std::vector<SpacePoint>& outColl) const {
198  if (prdsToFill.empty()) {
199  return;
200  }
201  const PrdType* refMeas = prdsToFill.front();
202  bool allSpArePhi{false};
203 
204  const Amg::Transform3D toSectorTrans = toChamberTransform(gctx, sectorTrans, *refMeas);
206  Amg::Vector3D sensorDir{Amg::Vector3D::Zero()}, toNextSen{Amg::Vector3D::Zero()};
208  if constexpr(std::is_same_v<PrdType, xAOD::RpcMeasurement> ||
209  std::is_same_v<PrdType, xAOD::TgcStrip>) {
210  allSpArePhi = refMeas->measuresPhi();
211  const auto& stripLayout = refMeas->readoutElement()->sensorLayout(refMeas->layerHash());
212  const auto& design = stripLayout->design(allSpArePhi);
213  sensorDir = toSectorTrans.rotation() * stripLayout->to3D(design.stripDir(), allSpArePhi);
214  toNextSen = toSectorTrans.rotation() * stripLayout->to3D(design.stripNormal(), allSpArePhi);
215  } else {
216  sensorDir = toSectorTrans.rotation().col(Amg::y);
217  toNextSen = toSectorTrans.rotation().col(Amg::x);
218  }
219  outColl.reserve(outColl.size() + prdsToFill.size());
220  for (const PrdType* prd: prdsToFill) {
221  SpacePoint& newSp = outColl.emplace_back(prd);
222  if constexpr (std::is_same_v<PrdType, xAOD::TgcStrip>) {
223  if (allSpArePhi) {
224  const auto& stripLayout = refMeas->readoutElement()->sensorLayout(refMeas->layerHash());
225  const auto& radialDesign = static_cast<const MuonGMR4::RadialStripDesign&>(stripLayout->design(allSpArePhi));
226  toNextSen = toSectorTrans.rotation() * stripLayout->to3D(radialDesign.stripNormal(prd->channelNumber()), allSpArePhi);
227  sensorDir = toSectorTrans.rotation() * stripLayout->to3D(radialDesign.stripDir(prd->channelNumber()), allSpArePhi);
228  }
229  }
230  newSp.setPosition(toSectorTrans * prd->localMeasurementPos());
231  newSp.setDirection(sensorDir, toNextSen);
232  auto cov = Acts::filledArray<double,3>(0.);
233  if (prd->numDimensions() == 2) {
234  if constexpr(std::is_same_v<PrdType, xAOD::RpcMeasurement>) {
235  cov[Acts::toUnderlying(CovIdx::etaCov)] = prd->template localCovariance<2>()(0,0);
236  cov[Acts::toUnderlying(CovIdx::phiCov)] = prd->template localCovariance<2>()(1,1);
237  } else if constexpr(std::is_same_v<PrdType, xAOD::sTgcMeasurement>) {
238  cov[Acts::toUnderlying(CovIdx::phiCov)] = prd->template localCovariance<2>()(0,0);
239  cov[Acts::toUnderlying(CovIdx::etaCov)] = prd->template localCovariance<2>()(1,1);
240  } else {
241  ATH_MSG_WARNING("Unsupported measurement type. "<<typeid(PrdType).name());
242  // Prevent division by zero later on.
243  cov[Acts::toUnderlying(CovIdx::phiCov)] = 1;
244  cov[Acts::toUnderlying(CovIdx::etaCov)] = 1;
245  }
246  } else {
248  if (newSp.measuresEta()) {
249  cov[Acts::toUnderlying(CovIdx::etaCov)] = prd->template localCovariance<1>()[0];
250  cov[Acts::toUnderlying(CovIdx::phiCov)] = Acts::square(sensorHalfLength(*prd));
251  } else {
252  cov[Acts::toUnderlying(CovIdx::phiCov)] = prd->template localCovariance<1>()[0];
253  cov[Acts::toUnderlying(CovIdx::etaCov)] = Acts::square(sensorHalfLength(*prd));
254  }
255  }
256  newSp.setCovariance(std::move(cov));
257  }
258 }
259 template <class ContType>
262  PreSortedSpacePointMap& fillContainer) const {
263  const ContType* measurementCont{nullptr};
264  ATH_CHECK(SG::get(measurementCont, key, ctx));
265  if (!measurementCont || measurementCont->empty()){
266  ATH_MSG_DEBUG("nothing to do");
267  return StatusCode::SUCCESS;
268  }
269  const ActsTrk::GeometryContext* gctx{nullptr};
270  ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
271 
272  using PrdType = typename ContType::const_value_type;
273  using PrdVec = std::vector<PrdType>;
274  xAOD::ChamberViewer viewer{*measurementCont};
275  do {
276  SpacePointsPerChamber& pointsInChamb = fillContainer[viewer.at(0)->readoutElement()->msSector()];
277  const Amg::Transform3D sectorTrans = viewer.at(0)->readoutElement()->msSector()->globalToLocalTrans(*gctx);
278  ATH_MSG_DEBUG("Fill space points for chamber "<<m_idHelperSvc->toStringDetEl(viewer.at(0)->identify()));
279  if constexpr( std::is_same_v<ContType, xAOD::MdtDriftCircleContainer>) {
280  pointsInChamb.etaHits.reserve(pointsInChamb.etaHits.capacity() + viewer.size());
281  for (const PrdType prd : viewer) {
282  Amg::Transform3D toChamberTrans{toChamberTransform(*gctx, sectorTrans, *prd)};
283  SpacePoint& sp{pointsInChamb.etaHits.emplace_back(prd)};
284  sp.setPosition(toChamberTrans*prd->localMeasurementPos());
285  sp.setDirection(toChamberTrans.rotation().col(Amg::z),
286  toChamberTrans.rotation().col(Amg::y));
287  std::array<double, 3> cov{Acts::filledArray<double,3>(0.)};
288  cov[Acts::toUnderlying(CovIdx::etaCov)] = prd->driftRadiusCov();
289  cov[Acts::toUnderlying(CovIdx::phiCov)] = Acts::square(sensorHalfLength(*prd));
290  if (ATH_UNLIKELY(prd->numDimensions() == 2)){
291  cov[Acts::toUnderlying(CovIdx::phiCov)] = static_cast<const xAOD::MdtTwinDriftCircle*>(prd)->posAlongWireCov();
292  }
293  sp.setCovariance(std::move(cov));
294  }
295  } else {
297  using EtaPhi2DHits = std::array<PrdVec, 3>;
298  std::vector<EtaPhi2DHits> hitsPerGasGap{};
299  for (const PrdType prd : viewer) {
300  ATH_MSG_VERBOSE("Create space point from "<<m_idHelperSvc->toString(prd->identify())
301  <<", hash: "<<prd->identifierHash());
302 
303  unsigned gapIdx = prd->gasGap() -1;
304  if constexpr (std::is_same_v<ContType, xAOD::RpcMeasurementContainer>) {
305  gapIdx = prd->readoutElement()->createHash(0, prd->gasGap(), prd->doubletPhi(), false);
306  }
307  if (hitsPerGasGap.size() <= gapIdx) {
308  hitsPerGasGap.resize(gapIdx + 1);
309  }
310  bool measPhi{false};
311  if constexpr(std::is_same_v<ContType, xAOD::sTgcMeasContainer>) {
313  measPhi = prd->channelType() == sTgcIdHelper::sTgcChannelTypes::Wire;
314  } else if constexpr(!std::is_same_v<ContType, xAOD::MMClusterContainer>) {
316  measPhi = prd->measuresPhi();
317  }
318 
319  if (prd->numDimensions() == 2) {
320  hitsPerGasGap[gapIdx][2].push_back(prd);
321  continue;
322  }
324  PrdVec& toPush = hitsPerGasGap[gapIdx][measPhi];
325  if (toPush.capacity() == toPush.size()) {
326  toPush.reserve(toPush.size() + m_capacityBucket);
327  }
328  toPush.push_back(prd);
329  }
330 
331  for (auto& [etaHits, phiHits, two2DHits] : hitsPerGasGap) {
332  ATH_MSG_DEBUG("Found "<<etaHits.size()<<"/"<<phiHits.size()<<" 1D and "<<two2DHits.size()<<" 2D hits in chamber "<<m_idHelperSvc->toStringDetEl(viewer.at(0)->identify()));
334  fillUncombinedSpacePoints(*gctx, sectorTrans, two2DHits, pointsInChamb.etaHits);
336  if (!passOccupancy2D(etaHits, phiHits)) {
337  fillUncombinedSpacePoints(*gctx, sectorTrans, etaHits, pointsInChamb.etaHits);
338  fillUncombinedSpacePoints(*gctx, sectorTrans, phiHits, pointsInChamb.phiHits);
339  continue;
340  }
341 
342  std::vector<std::shared_ptr<unsigned>> etaCounts{matchCountVec(etaHits.size())},
343  phiCounts{matchCountVec(phiHits.size())};
344  pointsInChamb.etaHits.reserve(pointsInChamb.etaHits.size() + etaHits.size()*phiHits.size());
346  const PrdType firstEta{etaHits.front()};
347  const PrdType firstPhi{phiHits.front()};
348 
349  const Amg::Transform3D toSectorTransEta = toChamberTransform(*gctx, sectorTrans, *firstEta);
350  const Amg::Transform3D toSectorTransPhi = toChamberTransform(*gctx, sectorTrans, *firstPhi);
351 
352  Amg::Vector3D toNextDir{Amg::Vector3D::Zero()}, sensorDir{Amg::Vector3D::Zero()};
353 
354  if constexpr (std::is_same_v<xAOD::RpcMeasurementContainer, ContType> ||
355  std::is_same_v<xAOD::TgcStripContainer, ContType>) {
356  const auto& stripLayout = firstEta->readoutElement()->sensorLayout(firstEta->layerHash());
357  const auto& design = stripLayout->design();
358  sensorDir = toSectorTransEta.rotation() * stripLayout->to3D(design.stripDir(), false);
359  toNextDir = toSectorTransEta.rotation() * stripLayout->to3D(design.stripNormal(), false);
360  } else {
361  toNextDir = toSectorTransEta.rotation().col(Amg::x);
362  sensorDir = toSectorTransEta.rotation().col(Amg::y);
363  }
364  using namespace Acts::detail::LineHelper;
365  for (unsigned etaP = 0; etaP < etaHits.size(); ++etaP) {
367  for (unsigned phiP = 0; phiP < phiHits.size(); ++ phiP) {
369  if constexpr(std::is_same_v<xAOD::TgcStripContainer, ContType>) {
370  if (!(etaHits[etaP]->bcBitMap() & phiHits[phiP]->bcBitMap())){
371  continue;
372  }
373  const auto& stripLay = phiHits[phiP]->readoutElement()->sensorLayout(phiHits[phiP]->layerHash());
374  const auto& radialDesign = static_cast<const MuonGMR4::RadialStripDesign&>(stripLay->design(true));
375  toNextDir = toSectorTransPhi.rotation() * stripLay->to3D(radialDesign.stripDir(phiHits[phiP]->channelNumber()), true);
376  }
377  SpacePoint& newSp = pointsInChamb.etaHits.emplace_back(etaHits[etaP], phiHits[phiP]);
378  newSp.setInstanceCounts(etaCounts[etaP], phiCounts[phiP]);
379 
380  auto spIsect = lineIntersect(toSectorTransEta*etaHits[etaP]->localMeasurementPos(), sensorDir,
381  toSectorTransPhi*phiHits[phiP]->localMeasurementPos(), toNextDir);
382  newSp.setPosition(spIsect.position());
383  newSp.setDirection(sensorDir, toNextDir);
384  auto cov = Acts::filledArray<double, 3>(0.);
385  cov[Acts::toUnderlying(CovIdx::etaCov)] = etaHits[etaP]->template localCovariance<1>()[0];
386  cov[Acts::toUnderlying(CovIdx::phiCov)] = phiHits[phiP]->template localCovariance<1>()[0];
387  newSp.setCovariance(std::move(cov));
388  ATH_MSG_VERBOSE("Created new space point "<<newSp);
389  }
390  }
391  }
392  }
393  } while (viewer.next());
394  return StatusCode::SUCCESS;
395 }
396 
397 
398 StatusCode SpacePointMakerAlg::execute(const EventContext& ctx) const {
399  PreSortedSpacePointMap preSortedContainer{};
400  ATH_CHECK(loadContainerAndSort(ctx, m_mdtKey, preSortedContainer));
401  ATH_CHECK(loadContainerAndSort(ctx, m_rpcKey, preSortedContainer));
402  ATH_CHECK(loadContainerAndSort(ctx, m_tgcKey, preSortedContainer));
403  ATH_CHECK(loadContainerAndSort(ctx, m_mmKey, preSortedContainer));
404  ATH_CHECK(loadContainerAndSort(ctx, m_stgcKey, preSortedContainer));
405  std::unique_ptr<SpacePointContainer> outContainer = std::make_unique<SpacePointContainer>();
406 
407  for (auto &[chamber, hitsPerChamber] : preSortedContainer){
408  ATH_MSG_DEBUG("Fill space points for chamber "<<chamber->identString() << " with "<<hitsPerChamber.etaHits.size()
409  <<" primary and "<<hitsPerChamber.phiHits.size()<<" phi space points.");
410  distributePointsAndStore(std::move(hitsPerChamber), *outContainer);
411  }
412  SG::WriteHandle writeHandle{m_writeKey, ctx};
413  ATH_CHECK(writeHandle.record(std::move(outContainer)));
414  return StatusCode::SUCCESS;
415 }
416 
418  SpacePointContainer& finalContainer) const {
419  SpacePointBucketVec splittedHits{};
420  splittedHits.emplace_back();
421  if (m_statCounter){
422  m_statCounter->addToStat(hitsPerChamber.etaHits);
423  m_statCounter->addToStat(hitsPerChamber.phiHits);
424 
425  }
426  distributePrimaryPoints(std::move(hitsPerChamber.etaHits), splittedHits);
427  splittedHits.erase(std::remove_if(splittedHits.begin(), splittedHits.end(),
428  [](const SpacePointBucket& bucket) {
429  return bucket.size() <= 1;
430  }), splittedHits.end());
431  distributePhiPoints(std::move(hitsPerChamber.phiHits), splittedHits);
432 
433  for (SpacePointBucket& bucket : splittedHits) {
434 
435  std::ranges::sort(bucket, MuonR4::SpacePointPerLayerSorter{});
436 
437  if (msgLvl(MSG::VERBOSE)){
438  std::stringstream spStr{};
439  for (const std::shared_ptr<SpacePoint>& sp : bucket){
440  spStr<<"SpacePoint: PrimaryMeas: " <<(*sp)<<std::endl;
441  }
442  ATH_MSG_VERBOSE("Created a bucket, printing all spacepoints..."<<std::endl<<spStr.str());
443  }
444  bucket.populateChamberLocations();
445  finalContainer.push_back(std::make_unique<SpacePointBucket>(std::move(bucket)));
446  }
447 
448 }
450  SpacePointBucketVec& splittedContainer) const{
451  for (SpacePoint& sp : spacePoints) {
452  auto phiPoint = std::make_shared<SpacePoint>(std::move(sp));
453  const double dY = std::sqrt(phiPoint->covariance()[Acts::toUnderlying(CovIdx::etaCov)]);
454  const double minY = phiPoint->localPosition().y() - dY;
455  const double maxY = phiPoint->localPosition().y() + dY;
456  for (SpacePointBucket& bucket : splittedContainer){
459  if (! (maxY < bucket.coveredMin() || bucket.coveredMax() < minY) ) {
460  bucket.emplace_back(phiPoint);
461  }
462  }
463  }
464 }
466  const double firstSpPos,
467  const SpacePointBucketVec& sortedPoints) const {
469  const double spY = spacePoint.localPosition().y();
470  if (spY - firstSpPos > m_maxBucketLength){
471  return true;
472  }
473 
474  if (sortedPoints.empty() || sortedPoints.back().empty()) {
475  return false;
476  }
477  return spY - sortedPoints.back().back()->localPosition().y() > m_spacePointWindow;
478 }
479 void SpacePointMakerAlg::newBucket(const SpacePoint& refSpacePoint,
480  SpacePointBucketVec& sortedPoints) const {
481  SpacePointBucket& newContainer = sortedPoints.emplace_back();
482  newContainer.setBucketId(sortedPoints.size() -1);
483 
485  SpacePointBucket& overlap{sortedPoints[sortedPoints.size() - 2]};
486  overlap.setCoveredRange(overlap.front()->localPosition().y(),
487  overlap.back()->localPosition().y());
488 
489  const double refBound = refSpacePoint.localPosition().y();
490 
492  for (const std::shared_ptr<SpacePoint>& pointInBucket : overlap | std::views::reverse) {
493  const double overlapPos = pointInBucket->localPosition().y() +
494  std::sqrt(pointInBucket->covariance()[Acts::toUnderlying(CovIdx::etaCov)]);
495  if (refBound - overlapPos < m_spacePointOverlap) {
496  newContainer.insert(newContainer.begin(), pointInBucket);
497  } else {
498  break;
499  }
500  }
501 
502 }
503 
505  SpacePointBucketVec& splittedHits) const {
506 
507  if (spacePoints.empty()) return;
508 
510  std::ranges::sort(spacePoints,
511  [] (const SpacePoint& a, const SpacePoint& b) {
512  return a.localPosition().y() < b.localPosition().y();
513  });
514 
515  double firstPointPos = spacePoints.front().localPosition().y();
516 
517  for (SpacePoint& toSort : spacePoints) {
518  ATH_MSG_VERBOSE("Add new primary space point "<<toSort);
519 
520  if (splitBucket(toSort, firstPointPos, splittedHits)){
521  newBucket(toSort, splittedHits);
522  firstPointPos = splittedHits.back().empty() ? toSort.localPosition().y() : splittedHits.back().front()->localPosition().y();
523  ATH_MSG_VERBOSE("New bucket: id " << splittedHits.back().bucketId() << " Coverage: " << firstPointPos);
524  }
525  std::shared_ptr<SpacePoint> spacePoint = std::make_shared<SpacePoint>(std::move(toSort));
526  splittedHits.back().emplace_back(spacePoint);
527  }
528  SpacePointBucket& lastBucket{splittedHits.back()};
529  lastBucket.setCoveredRange(lastBucket.front()->localPosition().y(),
530  lastBucket.back()->localPosition().y());
531 }
532 
533 }
MuonR4::SpacePoint::setCovariance
void setCovariance(Cov_t &&cov)
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:66
MuonR4::SpacePointMakerAlg::SpacePointStatistics::StatField::allHits
unsigned allHits() const
Helper method returning the sum of the three space point type counts.
Definition: SpacePointMakerAlg.cxx:83
UncalibratedMeasurement.h
MuonR4::SpacePointMakerAlg::PreSortedSpacePointMap
std::unordered_map< const MuonGMR4::SpectrometerSector *, SpacePointsPerChamber > PreSortedSpacePointMap
Container abrivation of the presorted space point container per MuonChambers.
Definition: SpacePointMakerAlg.h:93
MuonR4::SpacePointMakerAlg::SpacePointStatistics::FieldKey::operator<
bool operator<(const FieldKey &other) const
Definition: SpacePointMakerAlg.cxx:74
MuonR4::SpacePointMakerAlg::m_stgcKey
SG::ReadHandleKey< xAOD::sTgcMeasContainer > m_stgcKey
Definition: SpacePointMakerAlg.h:176
MuonR4::SpacePoint::setDirection
void setDirection(const Amg::Vector3D &sensorDir, const Amg::Vector3D &toNextSensor)
Setter for the direction of the measurement channel in the sector frame.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:67
MuonR4::SpacePointMakerAlg::SpacePointStatistics::addToStat
void addToStat(const std::vector< SpacePoint > &spacePoints)
Adds the vector of space points to the overall statistics.
Definition: SpacePointMakerAlg.cxx:89
MuonR4::SpacePointBucket
: The muon space point bucket represents a collection of points that will bre processed together in t...
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/MuonSpacePoint/SpacePointContainer.h:21
AthMsgStreamMacros.h
MuonR4::SpacePointPerLayerSorter
The SpacePointPerLayerSorter sort two given space points by their layer Identifier.
Definition: SpacePointPerLayerSorter.h:15
calibdata.chamber
chamber
Definition: calibdata.py:31
MuonR4::SpacePointMakerAlg::initialize
StatusCode initialize() override
Definition: SpacePointMakerAlg.cxx:140
MuonR4::SpacePointMakerAlg::execute
StatusCode execute(const EventContext &ctx) const override
Definition: SpacePointMakerAlg.cxx:398
MuonR4::SpacePointMakerAlg::distributePrimaryPoints
void distributePrimaryPoints(std::vector< SpacePoint > &&spacePoints, SpacePointBucketVec &splittedContainer) const
Distributes the vector of primary eta or eta + phi space points and fills them into the buckets.
Definition: SpacePointMakerAlg.cxx:504
Muon::MuonStationIndex::stName
const std::string & stName(StIndex index)
convert StIndex into a string
Definition: MuonStationIndex.cxx:104
MuonR4::SpacePointMakerAlg::splitBucket
bool splitBucket(const SpacePoint &spacePoint, const double firstSpPos, const SpacePointBucketVec &sortedPoints) const
Returns whether the space point is beyond the bucket boundary.
Definition: SpacePointMakerAlg.cxx:465
Amg::y
@ y
Definition: GeoPrimitives.h:35
MuonR4::SpacePointMakerAlg::m_maxOccStgcPhi
Gaudi::Property< double > m_maxOccStgcPhi
Definition: SpacePointMakerAlg.h:213
MuonR4::SpacePointBucket::populateChamberLocations
void populateChamberLocations()
populate the chamber location list.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePointContainer.cxx:23
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:200
MuonGMR4::MuonReadoutElement
The MuonReadoutElement is an abstract class representing the geometry representing the muon detector.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonReadoutElement.h:38
MuonR4::SpacePointBucket::setCoveredRange
void setCoveredRange(double min, double max)
set the range in the precision plane covered by the bucket
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePointContainer.cxx:16
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:70
MuonR4::SpacePointMakerAlg::SpacePointStatistics::m_idHelperSvc
const Muon::IMuonIdHelperSvc * m_idHelperSvc
Definition: SpacePointMakerAlg.h:78
MuonR4::SpacePointMakerAlg::SpacePointsPerChamber::etaHits
std::vector< SpacePoint > etaHits
Vector of all hits that contain an eta measurement including the ones which are combined with phi mea...
Definition: SpacePointMakerAlg.h:88
AthCommonMsg< Gaudi::Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
MuonR4::SpacePointMakerAlg::m_rpcKey
SG::ReadHandleKey< xAOD::RpcMeasurementContainer > m_rpcKey
Definition: SpacePointMakerAlg.h:167
MdtTwinDriftCircle.h
ATH_UNLIKELY
#define ATH_UNLIKELY(x)
Definition: AthUnlikelyMacros.h:17
MuonR4::SpacePointMakerAlg::distributePhiPoints
void distributePhiPoints(std::vector< SpacePoint > &&spacePoints, SpacePointBucketVec &splittedContainer) const
Distributs the vector phi space points into the buckets.
Definition: SpacePointMakerAlg.cxx:449
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::ReadHandleKey
Property holding a SG store/key/clid from which a ReadHandle is made.
Definition: StoreGate/StoreGate/ReadHandleKey.h:39
MuonR4::SpacePoint::CovIdx::etaCov
@ etaCov
trigbs_dumpHLTContentInBS.stats
stats
Definition: trigbs_dumpHLTContentInBS.py:91
MuonGMR4::RpcReadoutElement
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/RpcReadoutElement.h:17
MuonR4::SpacePointMakerAlg::m_mmKey
SG::ReadHandleKey< xAOD::MMClusterContainer > m_mmKey
Definition: SpacePointMakerAlg.h:173
RpcStrip.h
MuonR4::SpacePointMakerAlg::newBucket
void newBucket(const SpacePoint &refSp, SpacePointBucketVec &sortedPoints) const
Closes the current processed bucket and creates a new one.
Definition: SpacePointMakerAlg.cxx:479
DeMoUpdate.reverse
reverse
Definition: DeMoUpdate.py:563
GeoPrimitives.h
xAOD::ChamberViewer
Definition: ChamberViewer.h:59
WriteHandle.h
Handle class for recording to StoreGate.
Amg::z
@ z
Definition: GeoPrimitives.h:36
MuonR4::SpacePointMakerAlg::SpacePointBucketVec
std::vector< SpacePointBucket > SpacePointBucketVec
Abrivation of a MuonSapcePoint bucket vector.
Definition: SpacePointMakerAlg.h:96
MuonR4::SpacePointMakerAlg::SpacePointsPerChamber
: Helper struct to collect the space point per muon chamber, which are later sorted into the space po...
Definition: SpacePointMakerAlg.h:85
MuonR4::SpacePointMakerAlg::m_tgcKey
SG::ReadHandleKey< xAOD::TgcStripContainer > m_tgcKey
Definition: SpacePointMakerAlg.h:170
MuonR4::SpacePointMakerAlg::m_writeKey
SG::WriteHandleKey< SpacePointContainer > m_writeKey
Definition: SpacePointMakerAlg.h:183
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
MuonR4::SpacePointBucket::setBucketId
void setBucketId(unsigned int id)
sets the Identifier of the MuonSpacePointBucket in context of the associated muonChamber
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePointContainer.cxx:20
MuonR4::SpacePointMakerAlg::m_maxOccStgcEta
Gaudi::Property< double > m_maxOccStgcEta
Definition: SpacePointMakerAlg.h:211
EventPrimitivesToStringConverter.h
TrigConf::MSGTC::ALWAYS
@ ALWAYS
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStream.h:29
SG::get
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Definition: ReadCondHandle.h:287
beamspotman.n
n
Definition: beamspotman.py:727
MuonR4::SpacePointMakerAlg::SpacePointStatistics::StatField
Helper struct to count the space-points in each detector category.
Definition: SpacePointMakerAlg.h:57
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Amg::x
@ x
Definition: GeoPrimitives.h:34
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
MuonR4::SpacePointMakerAlg::SpacePointsPerChamber::phiHits
std::vector< SpacePoint > phiHits
Vector of all space points that are built from single phi hits.
Definition: SpacePointMakerAlg.h:90
MuonR4::SpacePointMakerAlg::m_maxOccTgcEta
Gaudi::Property< double > m_maxOccTgcEta
Definition: SpacePointMakerAlg.h:206
xAOD::MdtTwinDriftCircle_v1
Definition: MdtTwinDriftCircle_v1.h:12
MuonR4::SpacePointMakerAlg::SpacePointStatistics::dumpStatisics
void dumpStatisics(MsgStream &msg) const
Print the statistics table of the built space points per category into the log-file / console.
Definition: SpacePointMakerAlg.cxx:105
MuonGMR4::MuonReadoutElement::localToGlobalTrans
const Amg::Transform3D & localToGlobalTrans(const ActsTrk::GeometryContext &ctx) const
Returns the local to global transformation into the ATLAS coordinate system.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MuonReadoutElement.cxx:81
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MuonR4::SpacePointMakerAlg::m_geoCtxKey
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
Definition: SpacePointMakerAlg.h:179
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
ActsTrk::GeometryContext
Definition: GeometryContext.h:28
Muon::MuonStationIndex::technologyName
const std::string & technologyName(TechnologyIndex index)
convert LayerIndex into a string
Definition: MuonStationIndex.cxx:169
F600IntegrationConfig.spacePoints
spacePoints
Definition: F600IntegrationConfig.py:122
MeasurementDefs.h
DataVector
Derived DataVector<T>.
Definition: DataVector.h:795
MuonR4::SpacePointMakerAlg::m_maxOccTgcPhi
Gaudi::Property< double > m_maxOccTgcPhi
Definition: SpacePointMakerAlg.h:208
MuonR4::SpacePoint
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/MuonSpacePoint/SpacePoint.h:24
MuonR4::SpacePointMakerAlg::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: SpacePointMakerAlg.h:181
MuonR4::SpacePointMakerAlg::SpacePointStatistics::FieldKey::techIdx
TechIdx_t techIdx
Definition: SpacePointMakerAlg.h:73
MuonR4::SpacePointMakerAlg::SpacePointStatistics::FieldKey::stIdx
StIdx_t stIdx
Definition: SpacePointMakerAlg.h:72
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
MuonR4::SpacePoint::CovIdx::phiCov
@ phiCov
MuonR4::SpacePointMakerAlg::loadContainerAndSort
StatusCode loadContainerAndSort(const EventContext &ctx, const SG::ReadHandleKey< ContType > &key, PreSortedSpacePointMap &fillContainer) const
Retrieve an uncalibrated measurement container <ContType> and fill the hits into the presorted space ...
Definition: SpacePointMakerAlg.cxx:260
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:76
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
ChamberViewer.h
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MuonGMR4::sTgcReadoutElement
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/sTgcReadoutElement.h:20
MuonR4::SpacePointMakerAlg::m_mdtKey
SG::ReadHandleKey< xAOD::MdtDriftCircleContainer > m_mdtKey
Definition: SpacePointMakerAlg.h:164
MuonR4
This header ties the generic definitions in this package.
Definition: HoughEventData.h:16
MuonR4::SpacePoint::setInstanceCounts
void setInstanceCounts(std::shared_ptr< unsigned > etaCounts, std::shared_ptr< unsigned > phiCounts)
Set the number of space points built with the same eta / phi prd.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:100
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
MuonR4::SpacePointMakerAlg::m_capacityBucket
Gaudi::Property< unsigned > m_capacityBucket
Definition: SpacePointMakerAlg.h:198
MuonR4::SpacePoint::localPosition
const Amg::Vector3D & localPosition() const
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:50
MuonR4::SpacePointMakerAlg::passOccupancy2D
bool passOccupancy2D(const std::vector< const PrdType * > &etaHits, const std::vector< const PrdType * > &phiHits) const
: Check whether the occupancy cuts of hits in a gasGap are surpassed.
MuonR4::SpacePointMakerAlg::m_maxBucketLength
Gaudi::Property< double > m_maxBucketLength
Definition: SpacePointMakerAlg.h:188
MuonR4::SpacePointMakerAlg::m_spacePointWindow
Gaudi::Property< double > m_spacePointWindow
Definition: SpacePointMakerAlg.h:185
MuonR4::SpacePointMakerAlg::SpacePointStatistics::SpacePointStatistics
SpacePointStatistics(const Muon::IMuonIdHelperSvc *idHelperSvc)
Standard constructor.
Definition: SpacePointMakerAlg.cxx:86
a
TList * a
Definition: liststreamerinfos.cxx:10
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
y
#define y
MuonR4::SpacePoint::measuresEta
bool measuresEta() const
: Does the space point contain an eta measurement
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:94
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
re
const boost::regex re(r_e)
MuonR4::SpacePointMakerAlg::finalize
StatusCode finalize() override
Definition: SpacePointMakerAlg.cxx:134
AthCommonMsg< Gaudi::Algorithm >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
GeoPrimitivesToStringConverter.h
Muon::IMuonIdHelperSvc
Interface for Helper service that creates muon Identifiers and can be used to print Identifiers.
Definition: IMuonIdHelperSvc.h:27
MuonR4::SpacePointMakerAlg::m_doStat
Gaudi::Property< bool > m_doStat
Definition: SpacePointMakerAlg.h:195
MuonR4::SpacePoint::setPosition
void setPosition(const Amg::Vector3D &pos)
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/SpacePoint.cxx:73
MuonR4::SpacePoint::CovIdx
CovIdx
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/MuonSpacePoint/SpacePoint.h:30
MuonR4::SpacePointMakerAlg::m_maxOccRpcEta
Gaudi::Property< double > m_maxOccRpcEta
Definition: SpacePointMakerAlg.h:201
MuonR4::SpacePointMakerAlg::fillUncombinedSpacePoints
void fillUncombinedSpacePoints(const ActsTrk::GeometryContext &gctx, const Amg::Transform3D &sectorTrans, const std::vector< const PrdType * > &prdsToFill, std::vector< SpacePoint > &outColl) const
Fills all space points that are beloni.
Definition: SpacePointMakerAlg.cxx:194
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
ReadHandle.h
Handle class for reading from StoreGate.
SpacePointMakerAlg.h
MuonGMR4::RadialStripDesign
Definition: RadialStripDesign.h:23
MuonR4::SpacePointMakerAlg::SpacePointStatistics::FieldKey::eta
int eta
Definition: SpacePointMakerAlg.h:74
SpacePointPerLayerSorter.h
MuonGMR4::TgcReadoutElement
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/TgcReadoutElement.h:19
MuonR4::SpacePointMakerAlg::distributePointsAndStore
void distributePointsAndStore(SpacePointsPerChamber &&hitsPerChamber, SpacePointContainer &finalContainer) const
Distribute the premade spacepoints per chamber into their individual SpacePoint buckets.
Definition: SpacePointMakerAlg.cxx:417
MuonR4::SpacePointMakerAlg::SpacePointStatistics::FieldKey
Helper struct to define the counting categories.
Definition: SpacePointMakerAlg.h:69
MuonR4::SpacePointMakerAlg::m_spacePointOverlap
Gaudi::Property< double > m_spacePointOverlap
Definition: SpacePointMakerAlg.h:191
xAOD::layerHash
IdentifierHash layerHash(const UncalibratedMeasurement *meas)
Returns the layer hash from an uncalibrated meaurement.
Definition: MuonSpectrometer/MuonPhaseII/Event/xAOD/xAODMuonPrepData/Root/UtilFunctions.cxx:126
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
MuonR4::SpacePointMakerAlg::m_maxOccRpcPhi
Gaudi::Property< double > m_maxOccRpcPhi
Definition: SpacePointMakerAlg.h:203