ATLAS Offline Software
MuonLayerHoughTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include "AtlasHepMC/GenEvent.h"
8 #include "CxxUtils/sincos.h"
9 #include "GaudiKernel/ConcurrencyFlags.h"
20 namespace Muon {
21 
22  MuonLayerHoughTool::MuonLayerHoughTool(const std::string& type, const std::string& name, const IInterface* parent) :
24  declareInterface<IMuonHoughPatternFinderTool>(this);
25  }
26 
28  ATH_CHECK(m_idHelperSvc.retrieve());
29  m_ntechnologies = m_idHelperSvc->mdtIdHelper().technologyNameIndexMax() + 1;
30  ATH_CHECK(m_printer.retrieve());
32  ATH_CHECK(m_truthNames.initialize());
33 
34  // initialize cuts, if only one cut, use make_pair to avoid compiler issues, format is (position, cut)
37  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 5.9)}); // old values: 6.9; optimized: 7.9
39  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 5.9)}); // old values: 6.9; optimized: 7.9
41  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 4.9)}); // old values: 7.9; optimized: 7.9
43  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 4.9)}); // old values: 7.9; optimized: 7.9
45  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 4.9)}); // old values: 4.9; optimized: 5.9
47  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 4.9)}); // old values: 4.9; optimized: 5.9
49  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 3.9)}); // old values: 5.9; optimized: 5.9
51  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 5.9)}); // old values: 6.9; optimized: 7.9
53  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 5.9)}); // old values: 6.9; optimized: 7.9
55  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 4.9)}); // old values: 7.9; optimized: 5.9
57  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 4.9)}); // old values: 7.9; optimized: 5.9
59  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 4.9)}); // old values: 4.9; optimized: 5.9
61  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 4.9)}); // old values: 4.9; optimized: 5.9
63  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 4.9)}); // old values: 4.9; optimized: 5.9
65  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 4.9)}); // old values: 4.9; optimized: 5.9
66 
69  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 1.9)}); // old values: 2.9; optimized: 3.9
71  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 2.9)}); // old values: 2.9; optimized: 3.9
73  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 1.9)}); // old values: 4.9; optimized: 2.9
75  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 2.9)}); // old values: 4.9; optimized: 2.9
77  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 1.9)}); // old values: 2.9; optimized: 2.9
79  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 2.9)}); // old values: 2.9; optimized: 2.9
81  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 1.9)}); // old values: 3.9; optimized: 2.9
83  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 1.9)}); // old values: 4.9; optimized: 3.9
85  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 1.9)}); // old values: 4.9; optimized: 3.9
87  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 2.9)}); // old values: 5.9; optimized: 2.9
89  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 2.9)}); // old values: 5.9; optimized: 2.9
91  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 2.9)}); // old values: 2.9; optimized: 2.9
93  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 2.9)}); // old values: 2.9; optimized: 2.9
95  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 2.9)}); // old values: 2.9; optimized: 2.9
97  MuonHough::MuonLayerHoughSelector({std::make_pair(0, 2.9)}); // old values: 2.9; optimized: 2.9
98 
99  return StatusCode::SUCCESS;
100  }
101 
102  std::pair<std::unique_ptr<MuonPatternCombinationCollection>, std::unique_ptr<HoughDataPerSectorVec>> MuonLayerHoughTool::find(
103  const std::vector<const MdtPrepDataCollection*>& mdtCols, const std::vector<const CscPrepDataCollection*>& cscCols,
104  const std::vector<const TgcPrepDataCollection*>& tgcCols, const std::vector<const RpcPrepDataCollection*>& rpcCols,
105  const MuonSegmentCombinationCollection*, const EventContext& ctx) const {
106 
108  State state;
109  ATH_MSG_DEBUG("MuonLayerHoughTool::find");
110 
111  // create structure to hold data per sector and set the sector indices
112  state.houghDataPerSectorVec->vec.resize(16);
113  for (unsigned int i = 0; i < state.houghDataPerSectorVec->vec.size(); ++i) state.houghDataPerSectorVec->vec[i].sector = i + 1;
114 
115  // return DetectorRegionIndex and sectorLayerHash
116  auto getHashes = [this](const Identifier& id) {
117  MuonStationIndex::DetectorRegionIndex regionIndex = m_idHelperSvc->regionIndex(id);
118  MuonStationIndex::LayerIndex layerIndex = m_idHelperSvc->layerIndex(id);
119  unsigned int sectorLayerHash = MuonStationIndex::sectorLayerHash(regionIndex, layerIndex);
120  return std::make_pair(regionIndex, sectorLayerHash);
121  };
122 
123  for (const MdtPrepDataCollection* col : mdtCols) {
124  if (!col) continue;
125  Identifier id = col->identify();
126  int sector = m_idHelperSvc->sector(id);
127  auto hashes = getHashes(id);
128  fill(ctx, state.truthHits, *col, state.houghDataPerSectorVec->vec[sector - 1].hitVec[hashes.second]);
129  }
130 
131  for (const RpcPrepDataCollection* col : rpcCols) {
132  if (!col) continue;
133  Identifier id = col->identify();
134  int sector = m_idHelperSvc->sector(id);
135  auto hashes = getHashes(id);
136  fill(ctx, state.truthHits, *col, state.houghDataPerSectorVec->vec[sector - 1].hitVec[hashes.second],
137  state.houghDataPerSectorVec->vec[sector - 1].phiHitVec[hashes.first]);
138  }
139  for (const CscPrepDataCollection* col : cscCols) {
140  if (!col) continue;
141  const Identifier id = col->identify();
142  int sector = m_idHelperSvc->sector(id);
143  auto hashes = getHashes(id);
144  fill(ctx, state.truthHits, *col, state.houghDataPerSectorVec->vec[sector - 1].hitVec[hashes.second],
145  state.houghDataPerSectorVec->vec[sector - 1].phiHitVec[hashes.first]);
146  }
147  auto hashInSector = [this](IdentifierHash hash, int sector, unsigned int sectorLayerHash) {
148  const std::vector<IdentifierHash>& hashes =
149  m_collectionsPerSector[sector - 1].technologyRegionHashVecs[MuonStationIndex::TGC][sectorLayerHash];
150  return std::binary_search(hashes.begin(), hashes.end(), hash);
151  };
152 
153  for (const TgcPrepDataCollection* col : tgcCols) {
154  if (!col) continue;
155  Identifier id = col->identify();
156  int sector = m_idHelperSvc->sector(id);
157  auto hashes = getHashes(id);
158  // fill current sector
159  fill(ctx, state.truthHits, state.houghDataPerSectorVec->tgcClusteringObjs, *col,
160  state.houghDataPerSectorVec->vec[sector - 1].hitVec[hashes.second],
161  state.houghDataPerSectorVec->vec[sector - 1].phiHitVec[hashes.first], sector);
162 
163  // fill neighbours if in overlap
164  int neighbourSectorDown = sector == 1 ? 16 : sector - 1;
165  if (hashInSector(col->identifyHash(), neighbourSectorDown, hashes.second))
166  fill(ctx, state.truthHits, state.houghDataPerSectorVec->tgcClusteringObjs, *col,
167  state.houghDataPerSectorVec->vec[neighbourSectorDown - 1].hitVec[hashes.second],
168  state.houghDataPerSectorVec->vec[neighbourSectorDown - 1].phiHitVec[hashes.first], neighbourSectorDown);
169 
170  int neighbourSectorUp = sector == 16 ? 1 : sector + 1;
171  if (hashInSector(col->identifyHash(), neighbourSectorUp, hashes.second))
172  fill(ctx, state.truthHits, state.houghDataPerSectorVec->tgcClusteringObjs, *col,
173  state.houghDataPerSectorVec->vec[neighbourSectorUp - 1].hitVec[hashes.second],
174  state.houghDataPerSectorVec->vec[neighbourSectorUp - 1].phiHitVec[hashes.first], neighbourSectorUp);
175  }
176 
177  return analyse(state);
178  }
179 
180  std::pair<std::unique_ptr<MuonPatternCombinationCollection>, std::unique_ptr<HoughDataPerSectorVec>> MuonLayerHoughTool::find(
181  const MdtPrepDataContainer* mdtCont, const CscPrepDataContainer* cscCont, const TgcPrepDataContainer* tgcCont,
182  const RpcPrepDataContainer* rpcCont, const sTgcPrepDataContainer* stgcCont, const MMPrepDataContainer* mmCont,
183  const EventContext& ctx) const {
185  State state;
186  ATH_MSG_DEBUG("MuonLayerHoughTool::analyse");
187 
188  state.houghDataPerSectorVec->vec.resize(16);
189 
190  // loops over all sectors, contains hashes for technology and region and chamber (?)
191  for (const CollectionsPerSector& sit : m_collectionsPerSector) {
192  ATH_MSG_DEBUG("analyse: Filling hits sector " << sit.sector);
193 
194  HoughDataPerSector& houghData = state.houghDataPerSectorVec->vec[sit.sector - 1];
195  houghData.sector = sit.sector;
196 
197  // fill hits for this sector -> hitsVec and PhiHitsVec are known now
198  fillHitsPerSector(ctx, state, sit.sector, sit, mdtCont, cscCont, tgcCont, rpcCont, stgcCont, mmCont);
199  }
200  return analyse(state);
201  }
202 
203  std::pair<std::unique_ptr<MuonPatternCombinationCollection>, std::unique_ptr<HoughDataPerSectorVec>> MuonLayerHoughTool::analyse(
204  State& state) const {
205  auto patternCombis = std::make_unique<MuonPatternCombinationCollection>();
206 
207  // loop over data and fill the hough transform
208  for (auto& houghData : state.houghDataPerSectorVec->vec) {
209  ATH_MSG_DEBUG("analyse: Filling Hough sector " << houghData.sector);
210 
211  // loop over all possible station layers in the sector and run the eta transform
212  for (unsigned int layerHash = 0; layerHash < MuonStationIndex::sectorLayerHashMax(); ++layerHash) {
213  // get hits for layer, skip empty layers
214  HitVec& hits = houghData.hitVec[layerHash];
215  if (hits.empty()) continue;
216 
217  // decompose hash, calculate indices etc
218  auto regionLayer = MuonStationIndex::decomposeSectorLayerHash(layerHash);
219  MuonStationIndex::DetectorRegionIndex region = regionLayer.first;
220  MuonStationIndex::LayerIndex layer = regionLayer.second;
222 
223  // get Hough transform
225  state.houghDataPerSectorVec->detectorHoughTransforms.hough(houghData.sector, region, layer);
226 
227  ATH_MSG_DEBUG("analyse: Filling Summary: loc s" << houghData.sector << " " << MuonStationIndex::regionName(region) << " "
228  << MuonStationIndex::layerName(layer) << " -> stIndex: "
229  << MuonStationIndex::stName(index) << " etaHits: " << hits.size());
230 
231  // look for maxima using hough in eta per layer
232  if (!findMaxima(state.seedMaxima, hough, hits, houghData.maxVec[layerHash]) ||
233  houghData.maxVec[layerHash].empty())
234  continue;
235 
236  ++houghData.nlayersWithMaxima[region];
237  houghData.nmaxHitsInRegion[region] += houghData.maxVec[layerHash].front()->max;
238 
239  ATH_MSG_DEBUG("analyse: Eta maxima Summary: loc s"
240  << houghData.sector << " " << MuonStationIndex::regionName(region) << " "
242  << " hash: " << layerHash << " nMaxima: " << houghData.maxVec[layerHash].size());
243  } // loop over layerHash -> maxima per layer in eta are known now
244  } // loop over sectors
245 
246  if (m_useSeeds) {
247  std::vector<Road> roads;
248  buildRoads(state.seedMaxima, state.houghDataPerSectorVec->detectorHoughTransforms,
249  state.houghDataPerSectorVec, roads);
250 
251  // create association map
252  ATH_MSG_DEBUG("analyse: Building pattern combinations using roads " << roads.size());
253  for (auto& road : roads) {
254  std::map<MuonHough::MuonPhiLayerHough::Maximum*, MuonLayerHoughTool::MaximumVec> phiEtaAssMap;
255  MuonLayerHoughTool::RegionMaximumVec unassociatedEtaMaxima;
256 
257  int sector = road.seed->hough->m_descriptor.sector;
258  MuonStationIndex::ChIndex chIndex = road.seed->hough->m_descriptor.chIndex;
260  MuonStationIndex::DetectorRegionIndex region = road.seed->hough->m_descriptor.region;
261  ATH_MSG_DEBUG("analyse: Seeding new road: eta maxima "
262  << road.maxima.size() << " phi " << road.phiMaxima.size() << " seed : sector " << sector << " "
264  << " maximum " << road.seed->max << " position " << road.seed->pos << " angle " << road.seed->theta);
265 
266  if (road.phiMaxima.empty())
267  unassociatedEtaMaxima.push_back(road.maxima);
268  else {
269  for (auto& max : road.mergedPhiMaxima) { phiEtaAssMap[&max] = road.maxima; }
270  }
271  createPatternCombinations(phiEtaAssMap, *patternCombis);
272  createPatternCombinations(unassociatedEtaMaxima, *patternCombis);
273  }
274 
275  } else {
276  // now that the full hough transform is filled, order sectors by maxima
277  std::vector<HoughDataPerSector*> sectorData(state.houghDataPerSectorVec->vec.size());
278  for (unsigned int i = 0; i < state.houghDataPerSectorVec->vec.size(); ++i) sectorData[i] = &state.houghDataPerSectorVec->vec[i];
279  std::stable_sort(sectorData.begin(), sectorData.end(), SortHoughDataPerSector());
280 
281  std::vector<HoughDataPerSector*>::iterator spit = sectorData.begin();
282  std::vector<HoughDataPerSector*>::iterator spit_end = sectorData.end();
283  for (; spit != spit_end; ++spit) {
284  // get data for this sector
285  HoughDataPerSector& houghData = **spit;
286 
287  // loop over regions
288  for (int reg = 0; reg < MuonStationIndex::DetectorRegionIndexMax; ++reg) {
290 
291  // only run analysis on sectors with maxima
292  if (houghData.nlayersWithMaxima[region] == 0) continue;
293  ATH_MSG_DEBUG("Analyzing sector "
294  << (*spit)->sector << " " << MuonStationIndex::regionName(region) << " nmax " << (*spit)->maxEtaHits()
295  << " layers with eta maxima " << houghData.nlayersWithMaxima[region] << " hits "
296  << houghData.nmaxHitsInRegion[region] << " layers with phi maxima "
297  << houghData.nphilayersWithMaxima[region] << " hits " << houghData.nphimaxHitsInRegion[region]);
298 
299  // look for maxima in the overlap regions of sectors
301 
302  // layers in this region
303  int nlayers = MuonStationIndex::LayerIndexMax;
304 
305  // first link phi maxima with eta maxima
306  RegionMaximumVec unassociatedEtaMaxima(nlayers);
307  std::map<MuonHough::MuonPhiLayerHough::Maximum*, MaximumVec> phiEtaAssociations;
308  associateMaximaToPhiMaxima(region, houghData, phiEtaAssociations, unassociatedEtaMaxima);
309 
310  // create pattern combinations for combined patterns
311  createPatternCombinations(phiEtaAssociations, *patternCombis);
312 
313  // create pattern combinations for unassociated patterns
314  createPatternCombinations(unassociatedEtaMaxima, *patternCombis);
315  }
316  }
317  }
318 
319  ATH_MSG_DEBUG("Found " << patternCombis->size() << " pattern combinations " << std::endl << m_printer->print(*patternCombis));
320 
321  if (msgLvl(MSG::DEBUG)) {
322  ATH_MSG_DEBUG("Hough performance ");
324  ATH_MSG_DEBUG("Association performance ");
326  }
327 
328  return {std::move(patternCombis), std::move(state.houghDataPerSectorVec)};
329  }
330 
331  void MuonLayerHoughTool::buildRoads(MaximumVec& seedMaxima, MuonHough::MuonDetectorHough& detectorHoughTransforms,
332  std::unique_ptr<HoughDataPerSectorVec>& houghDataPerSectorVec,
333  std::vector<MuonLayerHoughTool::Road>& roads) const {
334  // sort maxima according to hits
335  std::stable_sort(seedMaxima.begin(), seedMaxima.end(),
336  [](const std::shared_ptr<MuonHough::MuonLayerHough::Maximum>& m1,
337  const std::shared_ptr<MuonHough::MuonLayerHough::Maximum>& m2) { return m1->max > m2->max; });
338  // loop over seed maxima (which are maxima) that pass certain thresholds detailed in cut_values
339  std::set<std::shared_ptr<MuonHough::MuonLayerHough::Maximum>> associatedMaxima;
340  for (const auto& seed : seedMaxima) {
341  // if this maximum is already in the set of associated maxima, do not do anything
342  if (associatedMaxima.count(seed)) continue;
343 
344  // maximum becomes our new seed
345 
346  // decomposing the locality information for the seed
347  int sector = seed->hough->m_descriptor.sector;
348  MuonStationIndex::ChIndex chIndex = seed->hough->m_descriptor.chIndex;
350  MuonStationIndex::DetectorRegionIndex region = seed->hough->m_descriptor.region;
351 
352  // creating new road with said seed
353  Road road(seed);
354  ATH_MSG_DEBUG(" New seed: sector " << seed->hough->m_descriptor.sector << " " << Muon::MuonStationIndex::regionName(region)
355  << " " << Muon::MuonStationIndex::layerName(layer) << " maximum " << seed->max
356  << " position " << seed->pos << " angle " << seed->theta << " ptr " << seed.get());
361  MuonHough::HitVec::const_iterator ref_itr = std::find_if(
362  seed->hits.begin(), seed->hits.end(), [](const std::shared_ptr<MuonHough::Hit>& hit) -> bool { return hit->prd; });
363 
364  const bool isNSW = ref_itr != seed->hits.end() &&
365  (m_idHelperSvc->issTgc((*ref_itr)->prd->identify()) || m_idHelperSvc->isMM((*ref_itr)->prd->identify()));
366  // extend seed within the current sector
367  // sector indices have an offset of -1 because the numbering of the sectors are from 1 to 16 but the indices in the vertices are
368  // of course 0 to 15
369  extendSeed(detectorHoughTransforms, road, houghDataPerSectorVec->vec[sector - 1]);
370 
371  // look for maxima in the overlap regions of sectors
372  int sectorN = sector - 1;
373  if (sectorN < 1) sectorN = 16;
374  int sectorP = sector + 1;
375  if (sectorP > 16) sectorP = 1;
376 
377  // associate the road with phi maxima
378  associatePhiMaxima(road, houghDataPerSectorVec->vec[sector - 1].phiMaxVec[region]);
379  //
380  if (m_addSectors && isNSW) {
381  extendSeed(detectorHoughTransforms, road, houghDataPerSectorVec->vec[sectorN - 1]);
382  associatePhiMaxima(road, houghDataPerSectorVec->vec[sectorN - 1].phiMaxVec[region]);
383  extendSeed(detectorHoughTransforms, road, houghDataPerSectorVec->vec[sectorP - 1]);
384  associatePhiMaxima(road, houghDataPerSectorVec->vec[sectorP - 1].phiMaxVec[region]);
385  }
386 
388  associatePhiMaxima(road, houghDataPerSectorVec->vec[sector - 1].phiMaxVec[road.neighbouringRegion]);
389  }
390  // if close to a sector boundary, try adding maxima in that sector as well
391  if (road.neighbouringSector != -1) {
392  ATH_MSG_DEBUG(" Adding neighbouring sector " << road.neighbouringSector);
393  extendSeed(detectorHoughTransforms, road,
394  houghDataPerSectorVec->vec[road.neighbouringSector - 1]);
395  associatePhiMaxima(road, houghDataPerSectorVec->vec[road.neighbouringSector - 1].phiMaxVec[region]);
396  }
397 
398  // finally deal with the case that we have both neighbouring region and sector
400  associatePhiMaxima(road, houghDataPerSectorVec->vec[road.neighbouringSector - 1].phiMaxVec[road.neighbouringRegion]);
401  }
402 
403  // merge phi maxima
404  mergePhiMaxima(road);
405 
406  // add maxima to seed exclusion list
407  associatedMaxima.insert(road.maxima.begin(), road.maxima.end());
408 
409  if (msgLevel(MSG::DEBUG)) {
410  ATH_MSG_DEBUG(" New road " << road.maxima.size());
411  for (const auto& max : road.maxima) {
412  MuonStationIndex::ChIndex chIndex = max->hough->m_descriptor.chIndex;
414  MuonStationIndex::DetectorRegionIndex region = max->hough->m_descriptor.region;
415  ATH_MSG_DEBUG(" Sector " << max->hough->m_descriptor.sector << " " << Muon::MuonStationIndex::regionName(region) << " "
416  << Muon::MuonStationIndex::layerName(layer) << " maximum " << max->max << " position "
417  << max->pos << " angle " << max->theta << " ptr " << max);
418  }
419  }
420  bool insert = true;
421  for (auto& oldRoad : roads) {
422  std::vector<std::shared_ptr<MuonHough::MuonLayerHough::Maximum>> intersection;
423  std::set_intersection(oldRoad.maximumSet.begin(), oldRoad.maximumSet.end(), road.maximumSet.begin(), road.maximumSet.end(),
424  std::back_inserter(intersection));
425  unsigned int intersectionSize = intersection.size();
426  unsigned int oldRoadSize = oldRoad.maximumSet.size();
427  unsigned int roadSize = road.maximumSet.size();
428  ATH_MSG_VERBOSE(" Overlap check " << intersectionSize << " old " << oldRoadSize << " new " << roadSize << " old ptr "
429  << oldRoad.seed);
430  if (intersectionSize == 0) continue;
431  if (intersectionSize == roadSize) {
432  insert = false; // discard
433  break;
434  } else if (intersectionSize == oldRoadSize) {
435  oldRoad = road; // replace
436  insert = false;
437  break;
438  }
439  }
440 
441  // add road to list
442  if (insert) roads.push_back(road);
443  }
444  }
445 
447  // input -> list of phiMaxima on road
448  // returns some mergedPhiMaxima -> is this "summed" over layers?
449 
450  auto maximaSortingLambda = [road](const std::shared_ptr<MuonHough::MuonPhiLayerHough::Maximum>& m1,
451  const std::shared_ptr<MuonHough::MuonPhiLayerHough::Maximum>& m2) {
452  if (m1->max != m2->max) return m1->max > m2->max;
453  // prefer the same sector as the seed sector
454  if (m1->sector != m2->sector) return m1->sector == road.seed->hough->m_descriptor.sector;
455 
456  if (m1->hits.size() != m2->hits.size()) return m1->hits.size() < m2->hits.size(); // least hits -> most collimated maximum
457 
458  if (m1->pos != m2->pos) return m1->pos < m2->pos;
459 
460  if (std::abs(m1->binposmax - m1->binposmin) == std::abs(m2->binposmax - m2->binposmin)) {
461  return (m1->binposmin) < (m2->binposmin);
462  }
463  return std::abs(m1->binposmax - m1->binposmin) < std::abs(m2->binposmax - m2->binposmin);
464  };
465 
466  std::stable_sort(road.phiMaxima.begin(), road.phiMaxima.end(), maximaSortingLambda);
467 
468  ATH_MSG_VERBOSE("Merging phi maxima " << road.phiMaxima.size());
469  std::set<MuonHough::MuonPhiLayerHough::Maximum*> associatedPhiMaxima;
470  for (auto pit = road.phiMaxima.begin(); pit != road.phiMaxima.end(); ++pit) { // loop over phi maxima
471  if (associatedPhiMaxima.count((*pit).get())) continue; // check if maximum is already in associatedPhiMaxima
472  associatedPhiMaxima.insert((*pit).get());
473  MuonHough::MuonPhiLayerHough::Maximum phiMaximum = **pit;
474  ATH_MSG_VERBOSE(" phi maxima " << phiMaximum.pos << " val " << phiMaximum.max);
475 
476  bool wasExtended = false;
477  for (auto pit1 = pit + 1; pit1 != road.phiMaxima.end(); ++pit1) {
478  if ((*pit1)->binposmax >= phiMaximum.binposmin && (*pit1)->binposmin <= phiMaximum.binposmax) {
479  ATH_MSG_VERBOSE(" merging maxima " << phiMaximum.pos << " val " << phiMaximum.max << " " << (*pit1)->pos << " val "
480  << (*pit1)->max);
481  phiMaximum.hits.insert(phiMaximum.hits.end(), (*pit1)->hits.begin(), (*pit1)->hits.end());
482  associatedPhiMaxima.insert((*pit1).get());
483  wasExtended = true;
484  }
485  }
486 
487  if (wasExtended) {
488  // refind maximum
489  MuonHough::MuonPhiLayerHough localHough(
490  60, -M_PI, M_PI, ((*pit)->hough ? (*pit)->hough->m_region : MuonStationIndex::DetectorRegionUnknown));
491  MuonHough::PhiHitVec hits = phiMaximum.hits;
492  /* too ambiguous producing irreproducibilities because of sorting by pointer value
493  std::stable_sort(hits.begin(),hits.end(),[]( const MuonHough::PhiHit* h1,
494  const MuonHough::PhiHit* h2 ){ return h1->layer < h2->layer; } );
495  */
496 
497  std::stable_sort(hits.begin(), hits.end(),
498  [](const std::shared_ptr<MuonHough::PhiHit>& h1, const std::shared_ptr<MuonHough::PhiHit>& h2) {
499  if (h1->layer != h2->layer) return h1->layer < h2->layer;
500  if (h1->w != h2->w) return h1->w > h2->w;
501  if (h1->r != h2->r) return h1->r < h2->r;
502 
503  const double dPhi1 = std::abs(h1->phimax - h1->phimin);
504  const double dPhi2 = std::abs(h2->phimax - h2->phimin);
505  if (dPhi1 != dPhi2) return dPhi1 < dPhi2;
506  if (h1->phimin == h2->phimin) return h1->phimax < h2->phimax;
507  return h1->phimin < h2->phimin;
508  });
509 
510  ATH_MSG_VERBOSE(" updating phi maximum " << phiMaximum.pos << " bin " << phiMaximum.binpos << " val " << phiMaximum.max
511  << " number of hits " << hits.size());
512  if (msgLvl(MSG::VERBOSE)) localHough.setDebug(true);
513  localHough.fillLayer2(hits);
514  localHough.findMaximum(phiMaximum, 0.9);
515  localHough.associateHitsToMaximum(phiMaximum, hits);
516  ATH_MSG_VERBOSE(" updated phi maxima " << phiMaximum.pos << " bin " << phiMaximum.binpos << " val " << phiMaximum.max
517  << " number of hits " << phiMaximum.hits.size());
518  phiMaximum.hough = (*pit)->hough; // set back pointer to transform
519  }
520  road.mergedPhiMaxima.push_back(phiMaximum);
521  }
522  }
523 
524  // maximum in middle layer
525  // says look in other layers
526  // if yes, combine them
527  // gets on road
528  // roads are combinations of maxima
529 
532  MuonLayerHoughTool::HoughDataPerSector& sectorData) const { // const {
533  if (!road.seed) return;
534 
535  RegionMaximumVec& maxVec = sectorData.maxVec;
536 
537  // gather locality information on seed
539  MuonStationIndex::LayerIndex seedLayer = Muon::MuonStationIndex::toLayerIndex(seed.hough->m_descriptor.chIndex);
540  MuonStationIndex::DetectorRegionIndex region = seed.hough->m_descriptor.region;
541 
542  // loop over layers in the same region as the seed ( inner, middle, outer)
543  for (int lay = 0; lay < Muon::MuonStationIndex::LayerIndexMax; ++lay) {
545  if (layer == seedLayer && seed.hough->m_descriptor.sector == sectorData.sector) continue;
546 
547  // untrue -> look in neighboring layer
548  // true -> look only in this layer
549  double distanceCut = layer == seedLayer ? 500. : (double)m_extrapolationDistance;
550 
551  unsigned int layerHash = MuonStationIndex::sectorLayerHash(region, layer);
552 
553  // fetching vector of maxima for given region and layer
554  const MaximumVec& maxima = maxVec[layerHash];
555  if (maxima.empty()) continue;
556 
557  ATH_MSG_DEBUG("Associating maxima in " << MuonStationIndex::regionName(region) << " " << MuonStationIndex::layerName(layer)
558  << " size " << maxima.size());
559  // loop over maxima in layer
560  for (const auto& candMaximum : maxima) {
561  // extrapolate seed to layer assuming a pointing straight line or parabolic
562  // add maximum to road if close enough
563  float yloc_diff = MuonHough::extrapolate(seed, *candMaximum, m_doParabolicExtrapolation);
564  if (std::abs(MuonHough::extrapolate(seed, *candMaximum, m_doParabolicExtrapolation)) < distanceCut) {
565  ATH_MSG_VERBOSE(" Adding maximum position " << candMaximum->pos << " intersect diff" << yloc_diff);
566  road.add(candMaximum);
567  } else {
568  ATH_MSG_VERBOSE(" Maximum position: y "
569  << candMaximum->pos << " x " << candMaximum->hough->m_descriptor.referencePosition << " seed y "
570  << seed.hough->m_descriptor.referencePosition << " x " << seed.pos << " intersect diff " << yloc_diff);
571  }
572  }
573  }
574 
575  // check if the maximum is close to the detector boundary, if yes look for maxima in the neighbouring region, skip BarrelExtended
576  if (seedLayer == MuonStationIndex::BarrelExtended) return;
577 
578  ATH_MSG_DEBUG("Checking Barrel/Endcap overlaps: min dist edge "
579  << seed.pos - seed.hough->m_descriptor.yMinRange << " max dist edge " << seed.pos - seed.hough->m_descriptor.yMaxRange
580  << " pos " << seed.pos << " range " << seed.hough->m_descriptor.yMinRange << " "
581  << seed.hough->m_descriptor.yMaxRange);
582 
583  if (std::abs(seed.pos - seed.hough->m_descriptor.yMinRange) < 4000. ||
584  std::abs(seed.pos - seed.hough->m_descriptor.yMaxRange) < 4000.) {
585  // asumes region is barrel and looks in adjacent regions (clever logic TM here)
587  if (region == MuonStationIndex::Barrel) {
588  if (seed.pos < 0)
589  neighbourRegion = MuonStationIndex::EndcapC;
590  else
591  neighbourRegion = MuonStationIndex::EndcapA;
592  } // in all other cases the neigbourRegion is definitely barrel
593 
594  // looping over all layers in neigbouring region
595  for (int lay = 0; lay < Muon::MuonStationIndex::LayerIndexMax; ++lay) {
597 
598  // skip barrel combinations with BEE
600 
601  double distanceCut = 1000.;
602 
603  // get maxima from neigboring region
604  unsigned int layerHash = MuonStationIndex::sectorLayerHash(neighbourRegion, layer);
605  const MaximumVec& maxima = maxVec[layerHash];
606  if (maxima.empty()) continue;
607  ATH_MSG_DEBUG("Associating maxima in neighbouring region " << MuonStationIndex::regionName(neighbourRegion) << " "
608  << MuonStationIndex::layerName(layer) << " hash " << layerHash
609  << " size " << maxima.size());
610 
611  // loop over maxima per layer
612  for (const auto& candMaximum : maxima) {
613  // extrapolate seed to layer assuming a pointing straight line, swap coordinates
614  float yloc_diff = MuonHough::extrapolate(seed, *candMaximum, m_doParabolicExtrapolation);
615  ATH_MSG_VERBOSE(" Maximum position: y "
616  << candMaximum->pos << " x " << candMaximum->hough->m_descriptor.referencePosition << " seed y "
617  << seed.hough->m_descriptor.referencePosition << " x " << seed.pos << " intersect diff " << yloc_diff);
618 
619  if (std::abs(yloc_diff) < distanceCut) {
620  road.add(candMaximum);
621  road.neighbouringRegion = neighbourRegion;
622  }
623  }
624  }
625  }
626 
627  // search for phiMaxima using the etaMaximum of the road in the current sector
628  std::set<const TgcClusterObj3D*> tgcClusters;
629  std::set<Identifier> triggerLayers;
630  const MaximumVec& maxima = road.maxima;
631  for (const auto& maximum : maxima) {
632  if (maximum->hough->m_descriptor.sector != sectorData.sector)
633  continue; // skip cases where a maximum on the road does not belong to the currently examined sector
634 
635  // gather tgcClusters associated to the hits of the maxima
636  for (auto ehit = maximum->hits.begin(); ehit != maximum->hits.end(); ++ehit) {
637  const MuonHough::Hit& etaHit = **ehit;
638  if (etaHit.tgc) {
639  if (!etaHit.tgc->phiCluster.empty()) tgcClusters.insert(etaHit.tgc);
640  } else if (etaHit.prd) {
641  triggerLayers.insert(m_idHelperSvc->gasGapId(etaHit.prd->identify()));
642  }
643  }
644  }
645 
646  MuonHough::MuonPhiLayerHough& phiHough =
647  detectorHoughTransforms.phiHough(region); // get phi transform in the same region as the seed
648 
649  // gather phiHits in sector that match the etaHits of the maximum
650  PhiHitVec phiHitsInMaximum;
651  PhiHitVec& phiHits = sectorData.phiHitVec[region];
652  for (const auto& phiHit : phiHits) {
653  if (phiHit->tgc) {
654  if (tgcClusters.find(phiHit->tgc) != tgcClusters.end()) phiHitsInMaximum.push_back(phiHit);
655  } else if (phiHit->prd) {
656  if (triggerLayers.find(m_idHelperSvc->gasGapId(phiHit->prd->identify())) != triggerLayers.end())
657  phiHitsInMaximum.push_back(phiHit);
658  }
659  }
660 
661  // fill phi hits
662  ATH_MSG_DEBUG("extendSeed: Filling s" << sectorData.sector << " " << MuonStationIndex::regionName(region) << " phiHitsInMaxima "
663  << phiHitsInMaximum.size() << " phi hits: " << phiHits.size());
664 
665  if (!findMaxima(phiHough, phiHitsInMaximum, sectorData.phiMaxVec[region], sectorData.sector) ||
666  sectorData.phiMaxVec[region].empty()) {
667  ATH_MSG_DEBUG("extendSeed: No phi maxima found in s" << sectorData.sector << " " << MuonStationIndex::regionName(region));
668  return;
669  }
670 
671  ++sectorData.nphilayersWithMaxima[region];
672  sectorData.nphimaxHitsInRegion[region] += sectorData.phiMaxVec[region].front()->max;
673 
674  ATH_MSG_DEBUG("extendSeed: Sector phiMaxima Summary: s" << sectorData.sector << " " << MuonStationIndex::regionName(region) << " "
675  << sectorData.nphilayersWithMaxima[region]
676  << " -> nPhiMaxima: " << sectorData.phiMaxVec[region].size()
677  << " max sum: " << sectorData.nphimaxHitsInRegion[region]);
678  }
679 
680  // phi hits are not separated into inner middle outer
681  // maxima found in road
683  ATH_MSG_DEBUG("associateMaximaToPhiMaxima: phi maxima " << phiMaxima.size());
684  if (!road.seed) return;
685 
686  // loop over phi maxima
687  for (const auto& pmaximum : phiMaxima) {
688  // reference to phi maximum
689 
690  ATH_MSG_DEBUG(" new phi maximum " << pmaximum->max << " hits " << pmaximum->hits.size());
691 
692  // precalculate the layers + TGC clusters and add them to a set for easy access
693  std::map<Identifier, std::pair<float, float>> triggerLayersPhiMinMax;
694  std::map<MuonStationIndex::StIndex, std::set<const TgcClusterObj3D*>> tgcClusters;
695 
696  // loop over hits
697  for (const auto& phiHit : pmaximum->hits) {
698  // two cases
699  // case 1: phiHit measured in TGC -> get phiHits from phiCluster
700  // case 2: phiHit is prepared raw data -> use phiHit to extend the triggerLayersPhinMinMax map
701  if (phiHit->tgc) {
702  if (phiHit->tgc->phiCluster.empty())
703  ATH_MSG_WARNING(" TGC 3D cluster without phi hits ");
704  else
705  tgcClusters[m_idHelperSvc->stationIndex(phiHit->tgc->phiCluster.front()->identify())].insert(phiHit->tgc);
706  } else if (phiHit->prd) {
707  Identifier gpId = m_idHelperSvc->gasGapId(phiHit->prd->identify());
708  auto mit = triggerLayersPhiMinMax.find(gpId);
709  if (mit == triggerLayersPhiMinMax.end())
710  triggerLayersPhiMinMax[gpId] = std::make_pair(phiHit->phimin, phiHit->phimax);
711  else {
712  mit->second.first = std::min(phiHit->phimin, mit->second.first);
713  mit->second.second = std::max(phiHit->phimax, mit->second.second);
714  }
715  }
716  }
717  // print out information on the triggerLayersPhiMinMax
718  if (msgLevel(MSG::VERBOSE)) {
719  ATH_MSG_DEBUG("Trigger layers " << triggerLayersPhiMinMax.size() << " tgc layers " << tgcClusters.size());
720  for (auto tgcit = triggerLayersPhiMinMax.begin(); tgcit != triggerLayersPhiMinMax.end(); ++tgcit) {
721  ATH_MSG_VERBOSE(" " << m_idHelperSvc->toString(tgcit->first));
722  }
723 
724  // loop over the stations and the contained tgcClusters found in the previous step, print out information
725  std::map<MuonStationIndex::StIndex, std::set<const TgcClusterObj3D*>>::const_iterator stit = tgcClusters.begin();
726  std::map<MuonStationIndex::StIndex, std::set<const TgcClusterObj3D*>>::const_iterator stit_end = tgcClusters.end();
727  for (; stit != stit_end; ++stit) {
728  std::set<const TgcClusterObj3D*>::const_iterator ttit = stit->second.begin();
729  std::set<const TgcClusterObj3D*>::const_iterator ttit_end = stit->second.end();
730  for (; ttit != ttit_end; ++ttit) {
731  ATH_MSG_VERBOSE(" " << m_idHelperSvc->toString((*ttit)->phiCluster.front()->identify()) << " nhits "
732  << (*ttit)->phiCluster.size());
733  }
734  }
735  }
736 
737  // check if there are matching maxima in neighbouring sectors, add maximum values if confirmation is found
738  // overlap counters
739  int noverlaps = 0;
740  int nNoOverlaps = 0;
741  float phimin{10}, phimax{-10};
742 
743  // loop over all maxima found on road
744  for (const auto& road_max : road.maxima) {
745  // get station information for maximum on road
746  MuonStationIndex::StIndex stIndex = MuonStationIndex::toStationIndex(road_max->hough->m_descriptor.chIndex);
747 
748  // loop over eta hits
749  for (const auto& etaHit : road_max->hits) {
750  if (etaHit->tgc) {
751  if (etaHit->tgc->etaCluster.empty())
752  ATH_MSG_WARNING(" TGC 3D cluster without eta hits ");
753  else {
754  if (tgcClusters[stIndex].count(etaHit->tgc)) {
755  // now loop over phi maximum and find phi hit
756  for (const auto& phiHit : pmaximum->hits) {
757  if (phiHit->tgc == etaHit->tgc) {
758  phimin = std::min(phiHit->phimin, phimin);
759  phimax = std::max(phiHit->phimax, phimax);
760  break;
761  }
762  }
763  ++noverlaps;
764  } else {
765  ++nNoOverlaps;
766  }
767  }
768  } else if (etaHit->prd) {
769  if (!m_idHelperSvc->isRpc(etaHit->prd->identify()) && !m_idHelperSvc->issTgc(etaHit->prd->identify())) continue;
770  Identifier gpId = m_idHelperSvc->gasGapId(etaHit->prd->identify());
771  auto mit = triggerLayersPhiMinMax.find(gpId);
772  if (mit == triggerLayersPhiMinMax.end())
773  ++nNoOverlaps;
774  else {
775  phimin = std::min(mit->second.first, phimin);
776  phimax = std::max(mit->second.second, phimax);
777  ++noverlaps;
778  }
779  }
780  } // loop over hits in maximum
781  } // loop over maxima in road
782 
783  // if overlaps are found, add the phi maximum in question to the road
784  if (noverlaps > 0) {
785  road.add(pmaximum);
786  // check if we are close to a sector boundary
787  std::vector<int> sectors;
788  m_sectorMapping.getSectors(phimin, sectors);
789  if (sectors.size() > 1) {
790  for (const int& sec : sectors) {
791  if (sec != road.seed->hough->m_descriptor.sector) road.neighbouringSector = sec;
792  }
793  } else {
794  std::vector<int> sectors;
795  m_sectorMapping.getSectors(phimax, sectors);
796  if (sectors.size() > 1) {
797  for (const int& sec : sectors) {
798  if (sec != road.seed->hough->m_descriptor.sector) road.neighbouringSector = sec;
799  }
800  }
801  }
802  }
803  ATH_MSG_DEBUG(" Overlap with Phi maximum: overlap " << noverlaps << " no overlap " << nNoOverlaps << " phimin " << phimin
804  << " phimax " << phimax << " neighbouring sector "
805  << road.neighbouringSector);
806  }
807  }
808 
809  // takes the maxima from a given sector and tries to associate it with the maxima of the adjacent sectors
812  std::vector<MuonLayerHoughTool::HoughDataPerSector>& houghDataPerSectorVec) const {
813  ATH_MSG_DEBUG(" looping over eta maxima");
814 
815  // now loop over eta maxima per layer
816  for (unsigned int regLay = 0; regLay < houghData.maxVec.size(); ++regLay) {
817  MaximumVec& maxima = houghData.maxVec[regLay];
818  int sector = houghData.sector;
819 
820  // loop over two neighbouring sectors
821  for (int i = 0; i < 2; ++i) {
822  // calculate neighbouring sector index
823  int sectorN = (i == 0) ? sector - 1 : sector + 1;
824  if (i == 0 && sector == 1) sectorN = 16;
825  if (i == 1 && sector == 16) sectorN = 1;
826 
827  MuonLayerHoughTool::HoughDataPerSector& houghDataN = houghDataPerSectorVec[sectorN - 1];
828 
829  MaximumVec& maximaN = houghDataN.maxVec[regLay];
830 
831  // loop over maxima in layer
832  for (const auto& maximum : maxima) {
833  // reference to maximum
834 
835  if (!maximum->hough) {
836  ATH_MSG_WARNING("Maximum without associated hough transform! ");
837  continue;
838  }
839 
840  // loop over maxima per layer in neighbouring sector
841  for (const auto& maximumN : maximaN) {
842  // reference to maximum
843  if (!maximumN->hough) {
844  ATH_MSG_WARNING("Maximum without associated hough transform! ");
845  continue;
846  }
847 
848  // calculate the position of the first maximum in the reference frame of the other sector
849  double rcor = maximumN->hough->m_descriptor.referencePosition *
850  m_sectorMapping.transformRToNeighboringSector(maximum->pos, sector, sectorN) /
851  maximum->hough->m_descriptor.referencePosition;
852  double dist = rcor - maximumN->pos;
853  ATH_MSG_DEBUG(" maximumN->hough " << maximumN->hough->m_descriptor.referencePosition << " maximum->hough "
854  << maximum->hough->m_descriptor.referencePosition << " maximumN->pos "
855  << maximumN->pos << " maximum->pos " << maximum->pos << rcor << " distance "
856  << dist);
857  if (std::abs(dist) > 100) continue;
858  houghData.maxAssociationMap[maximum.get()].push_back(maximumN);
859  houghDataN.associatedToOtherSector.insert(maximumN.get());
860 
861  ATH_MSG_DEBUG(" Found maximum in neighbouring sector: max " << maximum->max << " pos " << rcor << " maxN "
862  << maximumN->max << " pos " << maximumN->pos
863  << " distance " << dist);
864 
865  // loop over first and second maximum
866  for (int nn = 0; nn < 2; ++nn) {
867  // setting info for the debug-info objects of the hits
868  const auto& maxi = nn == 0 ? maximum : maximumN;
869  const auto& maxi2 = nn == 0 ? maximumN : maximum;
870  ATH_MSG_VERBOSE(" Maximum " << nn << " hits " << maxi->hits.size());
871  for (auto& hit : maxi->hits) {
872  if (hit->debugInfo()) {
873  hit->debugInfo()->phn = maxi2->max;
874  Identifier id = hit->tgc ? hit->tgc->etaCluster.front()->identify() : hit->prd->identify();
875  ATH_MSG_VERBOSE(" " << m_idHelperSvc->toString(id) << " setphn " << hit->debugInfo()->phn);
876  }
877  }
878  }
879  }
880  }
881  }
882  }
883  }
884 
887  std::map<MuonHough::MuonPhiLayerHough::Maximum*, MuonLayerHoughTool::MaximumVec>& phiEtaAssociations,
888  MuonLayerHoughTool::RegionMaximumVec& unassEtaMaxima) const {
889  std::set<std::shared_ptr<MuonHough::MuonLayerHough::Maximum>> associatedMaxima;
890 
891  PhiMaximumVec& phiMaxima = houghData.phiMaxVec[region];
892 
893  ATH_MSG_DEBUG("associateMaximaToPhiMaxima in sector " << houghData.sector << ": phi maxima " << phiMaxima.size()); // !!!!
894  // loop over phi maxima
895  for (const auto& phiMaximum : phiMaxima) {
896  // reference to phi maximum
897 
898  ATH_MSG_DEBUG(" Considering phi maximum " << phiMaximum->max << " hits " << phiMaximum->hits.size()); // !!!!
899 
900  // store associated maxima
901  MaximumVec associatedMaximaVec; // !!!!
902 
903  // precalculate the layers + TGC clusters and add them to a set for easy access
904  // std::map< Identifier,std::pair<double,double> > triggerLayersP;
905  std::set<Identifier> triggerLayers;
906  std::map<MuonStationIndex::StIndex, std::set<const TgcClusterObj3D*>> tgcClusters;
907 
908  // loop over hits
909  for (const auto& phiHit : phiMaximum->hits) {
910  if (phiHit->tgc) {
911  if (phiHit->tgc->phiCluster.empty())
912  ATH_MSG_WARNING(" TGC 3D cluster without phi hits ");
913  else
914  tgcClusters[m_idHelperSvc->stationIndex(phiHit->tgc->phiCluster.front()->identify())].insert(phiHit->tgc);
915  } else if (phiHit->prd) {
916  Identifier colId = phiHit->prd->identify();
917  Identifier layId = m_idHelperSvc->gasGapId(colId);
918  triggerLayers.insert(layId);
919  }
920  }
921  if (msgLvl(MSG::DEBUG)) {
922  ATH_MSG_DEBUG("Trigger layers " << triggerLayers.size() << " tgc layers " << tgcClusters.size());
923  for (const Identifier& id : triggerLayers) { ATH_MSG_VERBOSE(" " << m_idHelperSvc->toString(id)); }
924 
925  std::map<MuonStationIndex::StIndex, std::set<const TgcClusterObj3D*>>::const_iterator stit = tgcClusters.begin();
926  std::map<MuonStationIndex::StIndex, std::set<const TgcClusterObj3D*>>::const_iterator stit_end = tgcClusters.end();
927  for (; stit != stit_end; ++stit) {
928  std::set<const TgcClusterObj3D*>::const_iterator ttit = stit->second.begin();
929  std::set<const TgcClusterObj3D*>::const_iterator ttit_end = stit->second.end();
930  for (; ttit != ttit_end; ++ttit) {
931  ATH_MSG_VERBOSE(" " << m_idHelperSvc->toString((*ttit)->phiCluster.front()->identify()) << " nhits "
932  << (*ttit)->phiCluster.size());
933  }
934  }
935  }
936 
937  ATH_MSG_DEBUG(" looping over eta maxima");
938 
939  // now loop over eta maxima per layer
940  for (unsigned int lay = 0; lay < MuonStationIndex::LayerIndexMax; ++lay) {
942  unsigned int layerHash = MuonStationIndex::sectorLayerHash(region, layer);
943  MaximumVec& maxima = houghData.maxVec[layerHash];
944  if (maxima.empty()) continue;
946 
947  // loop over maxima per layer
948  for (const auto& maximum : maxima) {
949  // skip maxima that were already associated to a neighbouring sector
950  if (houghData.associatedToOtherSector.count(maximum.get())) continue;
951 
952  // check if there are matching maxima in neighbouring sectors, add maximum values if confirmation is found
953  float totmax = 0;
954  int ntrigconfirm = 0;
955  MaximumAssociationMap::iterator pos = houghData.maxAssociationMap.find(maximum.get());
956  if (pos != houghData.maxAssociationMap.end()) {
957  for (const auto& max_itr : pos->second) {
958  totmax = std::max(max_itr->max, totmax);
959  ntrigconfirm += max_itr->triggerConfirmed;
960  }
961  }
962  totmax += maximum->max;
963  ntrigconfirm += maximum->triggerConfirmed;
964 
965  ATH_MSG_DEBUG(" new eta maximum " << MuonStationIndex::stName(stIndex) << " val " << maximum->max
966  << " neightbour confirmed value " << totmax << " trigger confirmations "
967  << ntrigconfirm);
968 
969  // overlap counters
970  int nmmHits{0}, ntgcOverlaps{0}, nrpcOverlaps{0}, nstgcOverlaps{0}, nstgcNoOverlaps{0};
971 
972  // loop over hits
973  for (const auto& etaHit : maximum->hits) {
974  if (etaHit->tgc) {
975  if (tgcClusters[stIndex].count(etaHit->tgc))
976  ++ntgcOverlaps;
977 
978  } else if (etaHit->prd) {
979  Identifier layId = m_idHelperSvc->gasGapId(etaHit->prd->identify());
980  ATH_MSG_VERBOSE(" eta layer hit " << m_idHelperSvc->toString(layId));
981  if (m_idHelperSvc->isMM(layId)) ++nmmHits;
982  if (triggerLayers.count(layId)) {
983  if (m_idHelperSvc->isRpc(layId))
984  ++nrpcOverlaps;
985  else if (m_idHelperSvc->issTgc(layId))
986  ++nstgcOverlaps;
987  } else {
988  if (m_idHelperSvc->issTgc(layId))
989  ++nstgcNoOverlaps;
990  }
991  }
992  }
993 
994  // cuts on NSW endcap only for now
995  if (nmmHits + nstgcNoOverlaps + nstgcOverlaps > 0) {
996  // select
997  if (maximum->pos < 1200.) {
998  if (totmax < 8) {
999  ATH_MSG_DEBUG(" maximum failed cut " << totmax << " cut 8, position " << maximum->pos);
1000  continue;
1001  }
1002  } else if (maximum->pos > 4300.) {
1003  if (totmax < 8) {
1004  ATH_MSG_DEBUG(" maximum failed cut " << totmax << " cut 8, position " << maximum->pos);
1005  continue;
1006  }
1007  } else {
1008  if (totmax < 12) {
1009  ATH_MSG_DEBUG(" maximum failed cut " << totmax << " cut 12, position " << maximum->pos);
1010  continue;
1011  }
1012  }
1013  }
1014 
1015  ATH_MSG_DEBUG(" Overlap with Phi maximum: tgc " << ntgcOverlaps << " stgc " << nstgcOverlaps << " rpc " << nrpcOverlaps
1016  << " nphiTgc " << tgcClusters[stIndex].size() << " trigLay "
1017  << triggerLayers.size());
1018  if (stIndex == MuonStationIndex::EM && !tgcClusters[stIndex].empty() && ntgcOverlaps == 0) {
1019  ATH_MSG_VERBOSE(" No association in StationLayer " << MuonStationIndex::stName(stIndex) << " tgcs overlaps "
1020  << ntgcOverlaps << " on phi maximum "
1021  << tgcClusters[stIndex].size());
1022  continue;
1023  }
1024  if (stIndex == MuonStationIndex::EI && !tgcClusters[stIndex].empty() && ntgcOverlaps == 0) {
1025  ATH_MSG_VERBOSE(" No association in StationLayer " << MuonStationIndex::stName(stIndex) << " tgcs overlaps "
1026  << ntgcOverlaps << " on phi maximum "
1027  << tgcClusters[stIndex].size());
1028  continue;
1029  }
1030  if (stIndex == MuonStationIndex::EI && nstgcOverlaps == 0 && nstgcNoOverlaps != 0) {
1031  ATH_MSG_VERBOSE(" No association in StationLayer " << MuonStationIndex::stName(stIndex)
1032  << " stgcs without overlaps " << nstgcNoOverlaps);
1033  continue;
1034  }
1035  // require STGC confirmation
1036  if (m_requireTriggerConfirmationNSW && nmmHits > 0 && ntrigconfirm == 0) continue;
1037 
1038  associatedMaxima.insert(maximum);
1039  associatedMaximaVec.push_back(maximum);
1040 
1041  // check if there are matching maxima in neighbouring sectors
1042  if (pos != houghData.maxAssociationMap.end()) {
1043  associatedMaxima.insert(pos->second.begin(), pos->second.end());
1044  associatedMaximaVec.insert(associatedMaximaVec.end(), pos->second.begin(), pos->second.end());
1045  }
1046  }
1047  }
1048 
1049  if (associatedMaximaVec.empty()) continue;
1050  ATH_MSG_DEBUG(" processed phi maximum, associated eta maxima " << associatedMaximaVec.size());
1051  phiEtaAssociations[phiMaximum.get()] = std::move(associatedMaximaVec);
1052  }
1053 
1054  // finally idenitify all unassociated maxima and add them to the unassociated maxima list
1055  // now loop over eta maxima per layer
1056  for (unsigned int lay = 0; lay < MuonStationIndex::LayerIndexMax; ++lay) {
1058  unsigned int layerHash = MuonStationIndex::sectorLayerHash(region, layer);
1059 
1060  if (layer >= (int)unassEtaMaxima.size()) {
1061  ATH_MSG_WARNING(" size of unassEtaMaxima too small for region " << unassEtaMaxima.size() << " region "
1062  << MuonStationIndex::regionName(region));
1063  break;
1064  }
1065  MaximumVec& maxima = houghData.maxVec[layerHash];
1066 
1067  // loop over maxima per layer
1068  for (const auto& mit : maxima) {
1069  if (associatedMaxima.count(mit)) continue;
1070  unassEtaMaxima[layer].push_back(mit);
1071  ATH_MSG_DEBUG(" unassociated maximum in layer " << MuonStationIndex::layerName(layer) << " max-val " << mit->max);
1072  }
1073  }
1074  }
1075 
1077  MuonPatternCombinationCollection& patternCombis) const {
1078  ATH_MSG_DEBUG("Creating pattern combinations for eta patterns ");
1079 
1080  std::vector<MuonPatternChamberIntersect> chamberData;
1081 
1082  // bool isEndcap = maxima.size() == 5;
1083 
1084  // loop over layers
1085  for (const auto& max_sec : maxima) {
1086  // create vector for prds per chamber
1087  std::map<Identifier, std::set<const Trk::PrepRawData*>> prdsPerChamber;
1088 
1089  // loop over maxima per layer
1090  for (const auto& max : max_sec) {
1091  ATH_MSG_DEBUG(" new maximum " << max->max << " hits " << max->hits.size());
1092 
1093  // sanity check
1094  if (max->hits.empty()) {
1095  ATH_MSG_WARNING(" Maximum without hits ");
1096  continue;
1097  }
1098  ATH_MSG_DEBUG(" adding hits " << max->hits.size());
1099 
1100  // loop over hits in maximum and add them to the hit list
1101  for (const auto& hit : max->hits) {
1102  if (hit->tgc) {
1103  const Identifier chId = m_idHelperSvc->chamberId(hit->tgc->etaCluster.front()->identify());
1104  prdsPerChamber[chId].insert(hit->tgc->etaCluster.begin(), hit->tgc->etaCluster.end());
1105  } else if (hit->prd) {
1106  const Identifier chId = m_idHelperSvc->chamberId(hit->prd->identify());
1107  prdsPerChamber[chId].insert(hit->prd);
1108  }
1109  }
1110  }
1111 
1112  auto sortPrdIds = [](const Trk::PrepRawData* prd1, const Trk::PrepRawData* prd2) {
1113  return prd1->identify() < prd2->identify();
1114  };
1115  std::map<Identifier, std::set<const Trk::PrepRawData*>>::iterator chit = prdsPerChamber.begin();
1116  std::map<Identifier, std::set<const Trk::PrepRawData*>>::iterator chit_end = prdsPerChamber.end();
1117  for (; chit != chit_end; ++chit) {
1118  ATH_MSG_DEBUG("Adding chamber " << m_idHelperSvc->toStringChamber(chit->first) << " hits " << chit->second.size());
1119  std::vector<const Trk::PrepRawData*> prds;
1120  prds.insert(prds.end(), chit->second.begin(), chit->second.end());
1121  std::stable_sort(prds.begin(), prds.end(), sortPrdIds);
1122  const Trk::PrepRawData& prd = **prds.begin();
1123  Amg::Vector3D gpos = prd.detectorElement()->surface(prd.identify()).center();
1124  // create intersection and add it to combination
1125  ATH_MSG_DEBUG("Adding chamber with intersect phi direction " << gpos.phi() << " theta " << gpos.theta());
1126  MuonPatternChamberIntersect intersect(gpos, gpos.unit(), prds);
1127  chamberData.push_back(intersect);
1128  }
1129  }
1130  if (chamberData.empty()) return;
1131 
1132  MuonPatternCombination* combi = new MuonPatternCombination(nullptr, chamberData);
1133 
1134  ATH_MSG_DEBUG(" creating new unassociated " << m_printer->print(*combi));
1135  patternCombis.push_back(combi);
1136  }
1137 
1139  std::map<MuonHough::MuonPhiLayerHough::Maximum*, MuonLayerHoughTool::MaximumVec>& phiEtaAssociations,
1140  MuonPatternCombinationCollection& patternCombis) const {
1141  ATH_MSG_DEBUG("Creating pattern combinations from eta/phi combinations " << phiEtaAssociations.size());
1142 
1143  // loop over the phi maxima
1144  std::map<MuonHough::MuonPhiLayerHough::Maximum*, MaximumVec>::const_iterator pit = phiEtaAssociations.begin();
1145  std::map<MuonHough::MuonPhiLayerHough::Maximum*, MaximumVec>::const_iterator pit_end = phiEtaAssociations.end();
1146  for (; pit != pit_end; ++pit) {
1147  if (pit->second.empty()) continue;
1148 
1149  // collect phi hits per chamber
1150  std::map<Identifier, std::set<const Trk::PrepRawData*>> phiHitsPerChamber;
1151 
1152  // loop over hits
1153  for (const auto& hit : pit->first->hits) {
1154  if (hit->tgc) {
1155  const Identifier chId = m_idHelperSvc->chamberId(hit->tgc->phiCluster.front()->identify());
1156  phiHitsPerChamber[chId].insert(hit->tgc->phiCluster.begin(), hit->tgc->phiCluster.end());
1157  } else if (hit->prd) {
1158  const Identifier chId = m_idHelperSvc->chamberId(hit->prd->identify());
1159  phiHitsPerChamber[chId].insert(hit->prd);
1160  }
1161  }
1162 
1163  // create chamber intersections
1164  std::vector<MuonPatternChamberIntersect> chamberData;
1165  std::set<Identifier> addedPhiHits;
1166 
1167  // create vector for prds per chamber
1168  std::map<Identifier, std::set<const Trk::PrepRawData*>> prdsPerChamber;
1169 
1170  // store position and direction of the first maximum in the chamber layer
1171  std::map<MuonStationIndex::ChIndex, std::pair<Amg::Vector3D, Amg::Vector3D>> directionsPerChamberLayer;
1172 
1173  // loop over eta maxima
1174  for (const auto& max : pit->second) {
1175  ATH_MSG_DEBUG(" new maximum " << max->max << " hits " << max->hits.size());
1176 
1177  if (!max->hough) { ATH_MSG_WARNING("Maximum without associated Hough Transform"); }
1178 
1179  // sanity check
1180  if (max->hits.empty()) {
1181  ATH_MSG_WARNING(" Maximum without hits ");
1182  continue;
1183  }
1184  ATH_MSG_DEBUG(" adding hits " << max->hits.size());
1185 
1186  // loop over hits in maximum and add them to the hit list
1187  for (const auto& hit : max->hits) {
1188  Identifier chId;
1189  if (hit->tgc) {
1190  chId = m_idHelperSvc->chamberId(hit->tgc->etaCluster.front()->identify());
1191  prdsPerChamber[chId].insert(hit->tgc->etaCluster.begin(), hit->tgc->etaCluster.end());
1192  } else if (hit->prd) {
1193  chId = m_idHelperSvc->chamberId(hit->prd->identify());
1194  prdsPerChamber[chId].insert(hit->prd);
1195  } else {
1196  ATH_MSG_WARNING("Hit without associated PRDs");
1197  continue;
1198  }
1199  // the first time we have a maximun in this layer store the position and direction
1200  MuonStationIndex::ChIndex chIndex = m_idHelperSvc->chamberIndex(chId);
1201  if (!directionsPerChamberLayer.count(chIndex)) {
1202  // eta maximum has z(r) and theta parameters but these are local
1203  double maxpos = max->pos;
1204  double refPlane = 0.;
1205  bool isBarrel = !m_idHelperSvc->isEndcap(chId) || chIndex == MuonStationIndex::BEE;
1206  if (max->hough)
1207  refPlane = max->hough->m_descriptor.referencePosition;
1208  else if (hit->tgc)
1209  refPlane = hit->tgc->getEdge(TgcEdge::LowEtaLowPhi).z();
1210  else if (isBarrel)
1211  refPlane = hit->prd->detectorElement()->surface(hit->prd->identify()).center().perp();
1212  else
1213  refPlane = hit->prd->detectorElement()->surface(hit->prd->identify()).center().z();
1214 
1215  double r = isBarrel ? refPlane : maxpos;
1216  double z = isBarrel ? maxpos : refPlane;
1217  double theta = max->theta;
1218 
1219  // go to global
1220  double sign = 1.;
1221  if (isBarrel) {
1222  theta += M_PI_2;
1223  sign = -1.;
1224  }
1225 
1226  // phi maximum has one phi from position assume global Phi definition
1227  double phi = pit->first->pos; // phiCor(pit->first->pos,pit->first->sector,false);
1228 
1229  CxxUtils::sincos scphi(phi);
1230  double sinphi = scphi.sn;
1231  double cosphi = scphi.cs;
1232 
1233  CxxUtils::sincos sctheta(theta);
1234  double sintheta = sctheta.sn;
1235  double costheta = sctheta.cs;
1236 
1237  std::pair<Amg::Vector3D, Amg::Vector3D>& posDir = directionsPerChamberLayer[chIndex];
1238  posDir.first = Amg::Vector3D(r * cosphi, r * sinphi, z);
1239  posDir.second = Amg::Vector3D(sign * cosphi * costheta, sign * sinphi * costheta, sintheta);
1241  << " setting position: perp " << posDir.first.perp() << " z " << posDir.first.z() << " phi pos "
1242  << posDir.first.phi() << " direction phi " << posDir.second.phi() << " theta pos "
1243  << posDir.first.theta() << " direction theta " << posDir.second.theta() << " ref perp " << r << " z "
1244  << z << " phi " << phi << " theta " << theta);
1245  if (posDir.first.dot(posDir.second) < 0.) {
1246  ATH_MSG_WARNING(" direction not pointing to IP " << posDir.first.unit().dot(posDir.second));
1247  }
1248  }
1249 
1250  std::map<Identifier, std::set<const Trk::PrepRawData*>>::iterator pos = phiHitsPerChamber.find(chId);
1251  if (pos != phiHitsPerChamber.end()) {
1252  std::pair<std::set<Identifier>::iterator, bool> ipos = addedPhiHits.insert(chId);
1253  if (ipos.second) { prdsPerChamber[chId].insert(pos->second.begin(), pos->second.end()); }
1254  }
1255  }
1256  }
1257 
1258  auto sortPrdIds = [](const Trk::PrepRawData* prd1, const Trk::PrepRawData* prd2) {
1259  return prd1->identify() < prd2->identify();
1260  };
1261  std::map<Identifier, std::set<const Trk::PrepRawData*>>::iterator chit = prdsPerChamber.begin();
1262  std::map<Identifier, std::set<const Trk::PrepRawData*>>::iterator chit_end = prdsPerChamber.end();
1263  for (; chit != chit_end; ++chit) {
1264  ATH_MSG_DEBUG("Adding chamber " << m_idHelperSvc->toStringChamber(chit->first) << " hits " << chit->second.size());
1265  std::vector<const Trk::PrepRawData*> prds;
1266  prds.insert(prds.end(), chit->second.begin(), chit->second.end());
1267  std::stable_sort(prds.begin(), prds.end(), sortPrdIds);
1268  const Trk::PrepRawData& prd = **prds.begin();
1269 
1270  MuonStationIndex::ChIndex chIndex = m_idHelperSvc->chamberIndex(prd.identify());
1271  std::map<MuonStationIndex::ChIndex, std::pair<Amg::Vector3D, Amg::Vector3D>>::const_iterator pos =
1272  directionsPerChamberLayer.find(chIndex);
1275  if (pos != directionsPerChamberLayer.end()) {
1276  gpos = pos->second.first;
1277  gdir = pos->second.second;
1278  } else {
1279  ATH_MSG_WARNING("No global position and direction found, calculating from surface");
1280  gpos = prd.detectorElement()->surface(prd.identify()).center();
1281  gdir = -1 * gpos.unit();
1282  }
1283 
1284  ATH_MSG_DEBUG("Creating intersection " << MuonStationIndex::chName(chIndex) << " setting position: perp " << gpos.perp()
1285  << " z " << gpos.z() << " phi pos " << gpos.phi() << " direction phi " << gdir.phi()
1286  << " theta pos " << gpos.theta() << " theta " << gdir.theta() << " hits "
1287  << prds.size());
1288 
1289  // create intersection and add it to combination
1290  MuonPatternChamberIntersect intersect(gpos, gdir, prds);
1291  chamberData.push_back(intersect);
1292 
1293  }
1294  if (chamberData.empty()) continue;
1295  if (addedPhiHits.empty()) {
1296  ATH_MSG_DEBUG("No phi hits selected, skipping combi ");
1297  continue;
1298  }
1299  MuonPatternCombination* combi = new MuonPatternCombination(nullptr, chamberData);
1300  ATH_MSG_DEBUG("adding pattern combination with chambers " << chamberData.size() << " phi layers " << addedPhiHits.size()
1301  << std::endl
1302  << m_printer->print(*combi));
1303  patternCombis.push_back(combi);
1304  }
1305  }
1306 
1309  MuonLayerHoughTool::MaximumVec& maxima) const {
1310  if (hits.empty()) return false;
1311 
1312  if (hough.m_descriptor.chIndex < 0 || hough.m_descriptor.chIndex >= Muon::MuonStationIndex::ChIndexMax) {
1313  Identifier id = hits.front()->tgc ? hits.front()->tgc->etaCluster.front()->identify() : hits.front()->prd->identify();
1314  ATH_MSG_WARNING("Bad ChIndex " << m_idHelperSvc->toString(id) << " " << hough.m_descriptor.chIndex);
1315  return false;
1316  }
1317 
1318  // populate hough transform with hits
1319  std::stable_sort(hits.begin(), hits.end(), MuonHough::SortHitsPerLayer());
1320  if (m_debugHough) hough.setDebug(true);
1321  hough.fillLayer2(hits);
1322 
1323  Identifier id_hit = hits.front()->tgc ? hits.front()->tgc->etaCluster.front()->identify() : hits.front()->prd->identify();
1324  MuonHough::MuonLayerHoughSelector selectorLoose;
1326 
1327  if (m_idHelperSvc->issTgc(id_hit) || m_idHelperSvc->isMM(id_hit)) {
1328  selectorLoose = MuonHough::MuonLayerHoughSelector({std::make_pair(0, 3.9)});
1329  selector = MuonHough::MuonLayerHoughSelector({std::make_pair(0, 7.9)});
1330  } else {
1331  selectorLoose = m_selectorsLoose[hough.m_descriptor.chIndex];
1332  selector = m_selectors[hough.m_descriptor.chIndex];
1333  }
1334 
1335  // Muon::MuonStationIndex::StIndex stIndex = Muon::MuonStationIndex::toStationIndex(hough.m_descriptor.chIndex);
1336  unsigned int nmaxima = 0;
1337  while (nmaxima < 5) {
1339  if (hough.findMaximum(maximum, selectorLoose)) {
1340  hough.associateHitsToMaximum(maximum, hits);
1341  ATH_MSG_DEBUG("findMaxima: Found Eta Maximum "
1342  << nmaxima << " " << maximum.max << " trigConfirmed " << maximum.triggerConfirmed << " pos " << maximum.pos
1343  << " theta " << maximum.theta << " binPos " << maximum.binpos << " binRange " << maximum.binposmin << " -- "
1344  << maximum.binposmax << " binTheta " << maximum.bintheta << " nHits " << maximum.hits.size());
1345 
1346  int nmdt = 0;
1347  int nmm = 0;
1348  int nstgc = 0;
1349 
1350  const unsigned int nHitsInMaximum = maximum.hits.size();
1351  for (unsigned int i = 0; i < nHitsInMaximum; ++i) {
1352  MuonHough::Hit& hit = *(maximum.hits[i]);
1353  Identifier id = hit.tgc ? hit.tgc->etaCluster.front()->identify() : hit.prd->identify();
1354  int nhits = hit.tgc ? hit.tgc->etaCluster.size() : 1;
1355 
1356  nmdt += m_idHelperSvc->isMdt(id);
1357  nstgc += m_idHelperSvc->issTgc(id);
1358  nmm += m_idHelperSvc->isMM(id);
1359 
1360  ATH_MSG_VERBOSE("findMaxima: hit " << hit.layer << " " << m_idHelperSvc->toString(id) << " hits " << nhits);
1361  }
1362 
1363  // only store maxima that have MDT hits
1364  if (nmdt > 0 || (nmm + nstgc) > 0) {
1365  maxima.emplace_back(std::make_unique<MuonHough::MuonLayerHough::Maximum>(maximum));
1366  // add to seed list if
1367  if (maximum.max > selector.getCutValue(maximum.pos)) seedMaxima.push_back(maxima.back());
1368  ++nmaxima;
1369  }
1370  hough.fillLayer2(maximum.hits, true);
1371  } else {
1372  if (nmaxima > 0) { ATH_MSG_VERBOSE("findMaxima: No more maxima found " << nmaxima); }
1373  // ?!? if nmaximo == 0 here the function should return false, I think
1374  break;
1375  }
1376  }
1377  return true;
1378  }
1379 
1381  MuonLayerHoughTool::PhiMaximumVec& maxima, int sector) const {
1382  if (hits.empty()) return false;
1383 
1384  std::stable_sort(hits.begin(), hits.end(), MuonHough::SortHitsPerLayer());
1385  if (m_debugHough) hough.setDebug(true);
1386  hough.fillLayer2(hits);
1387 
1388  unsigned int nmaxima = 0;
1389  while (nmaxima < 5) {
1391  if (hough.findMaximum(maximum, 1.9)) {
1392  hough.associateHitsToMaximum(maximum, hits);
1393 
1394  ATH_MSG_DEBUG("findMaxima(Phi): Found Phi maximum " << nmaxima << " height " << maximum.max << " pos " << maximum.pos
1395  << " bin pos " << maximum.binpos << " binRange " << maximum.binposmin
1396  << " -- " << maximum.binposmax << " nHits " << maximum.hits.size());
1397 
1398  const unsigned int nHitsInMaximum = maximum.hits.size();
1399  for (unsigned int i = 0; i < nHitsInMaximum; ++i) {
1400  MuonHough::PhiHit& hit = *(maximum.hits[i]);
1401  Identifier id = hit.tgc ? hit.tgc->phiCluster.front()->identify() : hit.prd->identify();
1402 
1403  int nhits = hit.tgc ? hit.tgc->phiCluster.size() : 1;
1404  ATH_MSG_VERBOSE("findMaxima(Phi) phiHit " << m_idHelperSvc->toString(id) << " hits " << nhits);
1405  }
1406 
1407  maximum.sector = sector; // very fragile passing on of sector
1408 
1409  // check if the maximum is already filled, if so, don't add it again
1410  bool maximum_matched = false;
1411  for (auto pit = maxima.begin(); pit != maxima.end(); ++pit) {
1412  // reference to phi maximum
1413  MuonHough::MuonPhiLayerHough::Maximum& pmaximum = **pit;
1414  if (pmaximum.sector == maximum.sector && pmaximum.max == maximum.max && pmaximum.pos == maximum.pos &&
1415  pmaximum.hits.size() == maximum.hits.size() && pmaximum.binpos == maximum.binpos &&
1416  pmaximum.binposmin == maximum.binposmin && pmaximum.binposmax == maximum.binposmax) {
1417  ATH_MSG_DEBUG("extendSeed: sector has already been added! Skip. ");
1418  bool maximum_hitmatched = true; // check if there is a hit that is not the same
1419  for (unsigned int k = 0; k < maximum.hits.size(); ++k) {
1420  if (maximum.hits[k] != pmaximum.hits[k]) { // directly compare pointer address
1421  maximum_hitmatched = false;
1422  break;
1423  }
1424  }
1425  if (maximum_hitmatched) {
1426  maximum_matched = true;
1427  break;
1428  }
1429  }
1430  }
1431  // remove the hits from hough
1432  hough.fillLayer2(maximum.hits, true);
1433  if (maximum_matched) {
1434  //++nmaxima;
1435  continue;
1436  } else {
1437  maxima.push_back(std::make_shared<MuonHough::MuonPhiLayerHough::Maximum>(maximum));
1438  ++nmaxima;
1439  }
1440  } else {
1441  if (nmaxima > 0) { ATH_MSG_VERBOSE("findMaxima(Phi): No more maxima found " << nmaxima); }
1442  // ?!? same here, the function should return false if nothing was found, right?
1443  break;
1444  }
1445  }
1446  hough.reset();
1447  return true;
1448  }
1449 
1450  void MuonLayerHoughTool::fillHitsPerSector(const EventContext& ctx, State& state, const int sector,
1451  const CollectionsPerSector& collectionsPerSector, const MdtPrepDataContainer* mdtCont,
1452  const CscPrepDataContainer* /*cscCont*/, const TgcPrepDataContainer* tgcCont,
1453  const RpcPrepDataContainer* rpcCont, const sTgcPrepDataContainer* stgcCont,
1454  const MMPrepDataContainer* mmCont) const {
1455  MuonLayerHoughTool::HoughDataPerSector& houghData = state.houghDataPerSectorVec->vec[sector - 1];
1456  houghData.sector = sector;
1457  // loop over all possible station layers in the sector
1458  for (unsigned int tech = 0; tech < m_ntechnologies; ++tech) {
1459  for (unsigned int layerHash = 0; layerHash < MuonStationIndex::sectorLayerHashMax(); ++layerHash) {
1460  const HashVec& hashes = collectionsPerSector.technologyRegionHashVecs[tech][layerHash];
1461  if (hashes.empty()) continue;
1462  auto regionLayer = MuonStationIndex::decomposeSectorLayerHash(layerHash);
1463 
1464  for (const IdentifierHash& id_hash : hashes) {
1465  // !?! else if made by Felix
1466  if (mdtCont && !mdtCont->empty() && tech == MuonStationIndex::MDT) {
1467  const MdtPrepDataCollection* pos = mdtCont->indexFindPtr(id_hash);
1468  if (pos) fill(ctx, state.truthHits, *pos, houghData.hitVec[layerHash]);
1469  } else if (rpcCont && !rpcCont->empty() && tech == MuonStationIndex::RPC) {
1470  const RpcPrepDataCollection* pos = rpcCont->indexFindPtr(id_hash);
1471  if (pos) fill(ctx, state.truthHits, *pos, houghData.hitVec[layerHash], houghData.phiHitVec[regionLayer.first]);
1472  } else if (tgcCont && !tgcCont->empty() && tech == MuonStationIndex::TGC) {
1473  const TgcPrepDataCollection* pos = tgcCont->indexFindPtr(id_hash);
1474  if (pos)
1475  fill(ctx, state.truthHits, state.houghDataPerSectorVec->tgcClusteringObjs, *pos, houghData.hitVec[layerHash],
1476  houghData.phiHitVec[regionLayer.first], collectionsPerSector.sector);
1477  } else if (stgcCont && !stgcCont->empty() && tech == MuonStationIndex::STGC) {
1478  const sTgcPrepDataCollection* pos = stgcCont->indexFindPtr(id_hash);
1479  if (pos)
1480  fill(ctx, state.truthHits, *pos, houghData.hitVec[layerHash], houghData.phiHitVec[regionLayer.first],
1481  collectionsPerSector.sector);
1482  } else if (mmCont && !mmCont->empty() && tech == MuonStationIndex::MM) {
1483  const MMPrepDataCollection* pos = mmCont->indexFindPtr(id_hash);
1484  if (pos) fill(ctx, state.truthHits, *pos, houghData.hitVec[layerHash]);
1485  }
1486  }
1487  }
1488  }
1489  }
1490 
1491  void MuonLayerHoughTool::matchTruth(std::set<Identifier>& truthHits, const PRD_MultiTruthCollection& truthCol, const Identifier& id,
1492  MuonHough::HitDebugInfo& debug) const {
1493  typedef PRD_MultiTruthCollection::const_iterator iprdt;
1494  std::pair<iprdt, iprdt> range = truthCol.equal_range(id);
1495  // Loop over particles contributing to this cluster
1496  for (iprdt i = range.first; i != range.second; ++i) {
1497  if (!i->second.isValid()) {
1498  ATH_MSG_WARNING("Unexpected invalid HepMcParticleLink in PRD_MultiTruthCollection");
1499  } else {
1500  const HepMcParticleLink& link = i->second;
1501  if (link.cptr() && abs(link.cptr()->pdg_id()) == 13) {
1502  debug.barcode = HepMC::barcode(link); // FIXME barcode-based - requires MuonHough::HitDebugInfo to be migrated to uniqueID
1503  debug.pdgId = link.cptr()->pdg_id();
1504  truthHits.insert(id);
1505  }
1506  }
1507  }
1508  }
1509 
1510  void MuonLayerHoughTool::fill(const EventContext& ctx, std::set<Identifier>& truthHits, const MdtPrepDataCollection& mdts,
1512  if (mdts.empty()) return;
1513  auto truthCollections = m_truthNames.makeHandles(ctx);
1514  Identifier chid = mdts.identify();
1515  MuonStationIndex::DetectorRegionIndex region = m_idHelperSvc->regionIndex(chid);
1516  MuonStationIndex::LayerIndex layer = m_idHelperSvc->layerIndex(chid);
1517  int sector = m_idHelperSvc->sector(chid);
1518  unsigned int technology = m_idHelperSvc->technologyIndex(chid);
1519  bool barrelLike = (region == MuonStationIndex::Barrel || layer == MuonStationIndex::BarrelExtended);
1520  unsigned int nmdts(mdts.size()), nmdtsBad{0};
1521  for (const MdtPrepData* prd : mdts) {
1522  if (prd->adc() < 50 || prd->status() != Muon::MdtStatusDriftTime) {
1523  ++nmdtsBad;
1524  continue;
1525  }
1526  const Identifier id = prd->identify();
1527  float r = rCor(*prd);
1528  float x = barrelLike ? r : prd->globalPosition().z();
1529  float y = barrelLike ? prd->globalPosition().z() : r;
1530  int sublayer = sublay(id);
1531 
1532  float ymin = y - prd->localPosition()[Trk::locR];
1533  float ymax = y + prd->localPosition()[Trk::locR];
1534  MuonHough::HitDebugInfo* debug = new MuonHough::HitDebugInfo(technology, sector, region, layer, sublayer);
1535  debug->time = prd->tdc();
1536  debug->r = prd->localPosition()[Trk::locR];
1537 
1538  std::map<unsigned int, unsigned int>::const_iterator pos = m_techToTruthNameIdx.find(technology);
1539  if (pos != m_techToTruthNameIdx.end()) { matchTruth(truthHits, *truthCollections[pos->second], id, *debug); }
1540  MuonHough::Hit* hit = new MuonHough::Hit(sublayer, x, ymin, ymax, 1., debug, prd);
1541  hits.emplace_back(hit);
1542  }
1543 
1544  ATH_MSG_DEBUG("fillMDT: Filling " << m_idHelperSvc->toStringChamber(chid) << ": loc s" << sector << " "
1546  << " -> hits: " << nmdts << " bad " << nmdtsBad << " isSmallChamber "
1547  << m_idHelperSvc->isSmallChamber(chid));
1548  }
1549 
1550  void MuonLayerHoughTool::fill(const EventContext& ctx, std::set<Identifier>& truthHits, const CscPrepDataCollection& cscs, HitVec& hits,
1551  PhiHitVec& phiHits) const {
1553  return;
1554  auto truthCollections = m_truthNames.makeHandles(ctx);
1555  Identifier chid = cscs.identify();
1556  unsigned int technology = m_idHelperSvc->technologyIndex(chid);
1557  MuonStationIndex::LayerIndex layer = m_idHelperSvc->layerIndex(chid);
1558  MuonStationIndex::DetectorRegionIndex region = m_idHelperSvc->regionIndex(chid);
1559  int sector = m_idHelperSvc->sector(chid);
1560  unsigned int neta{0}, nphi{0};
1561  for (const CscPrepData* prd : cscs) {
1562  const bool meas_phi = m_idHelperSvc->rpcIdHelper().measuresPhi(prd->identify());
1563  nphi += meas_phi;
1564  neta += !meas_phi;
1565  }
1566  ATH_MSG_DEBUG("fillCscs: Filling " << m_idHelperSvc->toStringChamber(chid) << ": loc s" << sector << " "
1568  << " -> eta hits " << neta << " phi hits " << nphi);
1569  for (const CscPrepData* prd : cscs) {
1570  const Identifier id = prd->identify();
1571  int sublayer = sublay(id);
1572  MuonHough::HitDebugInfo* debug = new MuonHough::HitDebugInfo(technology, sector, region, layer, sublayer);
1573  debug->isEtaPhi = (neta && nphi);
1574  debug->trigConfirm = 1;
1575  debug->time = prd->time();
1576  std::map<unsigned int, unsigned int>::const_iterator pos = m_techToTruthNameIdx.find(technology);
1577  if (pos != m_techToTruthNameIdx.end()) { matchTruth(truthHits, *truthCollections[pos->second], id, *debug); }
1578  float weight = (neta && nphi) ? 2 : 1;
1579  if (m_idHelperSvc->rpcIdHelper().measuresPhi(id)) {
1580  const float r = rCor(*prd);
1581  const float phi = prd->globalPosition().phi();
1582  const double phi1 = phi; // phiCor(phi,sector);
1583  debug->r = -99999;
1584  MuonHough::PhiHit* hit = new MuonHough::PhiHit(sublayer, r, phi1, phi1, weight, debug, prd);
1585  phiHits.emplace_back(hit);
1586  } else {
1587  const float x = rCor(*prd);
1588  const float y = prd->globalPosition().z();
1589  const float stripCor = 0.5 * prd->detectorElement()->StripWidth(false);
1590  const float ymin = y - stripCor;
1591  const float ymax = y + stripCor;
1592  debug->r = stripCor;
1593  MuonHough::Hit* hit = new MuonHough::Hit(sublayer, x, ymin, ymax, weight, debug, prd);
1594  hits.emplace_back(hit);
1595  }
1596  }
1597  }
1598  void MuonLayerHoughTool::fill(const EventContext& ctx, std::set<Identifier>& truthHits, const RpcPrepDataCollection& rpcs,
1600  if (rpcs.empty()) return;
1601  auto truthCollections = m_truthNames.makeHandles(ctx);
1602  Identifier chid = rpcs.identify();
1603  unsigned int technology = m_idHelperSvc->technologyIndex(chid);
1604  MuonStationIndex::LayerIndex layer = m_idHelperSvc->layerIndex(chid);
1605  MuonStationIndex::DetectorRegionIndex region = m_idHelperSvc->regionIndex(chid);
1606  int sector = m_idHelperSvc->sector(chid);
1607  // check whether there are eta and phi hits
1608  unsigned int neta{0}, nphi{0};
1609  for (const RpcPrepData* prd : rpcs) {
1610  const bool meas_phi = m_idHelperSvc->rpcIdHelper().measuresPhi(prd->identify());
1611  nphi += meas_phi;
1612  neta += !meas_phi;
1613  }
1614  ATH_MSG_DEBUG("fillRPC: Filling " << m_idHelperSvc->toStringChamber(chid) << ": loc s" << sector << " "
1616  << " -> eta hits " << neta << " phi hits " << nphi);
1617 
1618  for (const RpcPrepData* prd : rpcs) {
1619  const Identifier id = prd->identify();
1620  int sublayer = sublay(id);
1621  MuonHough::HitDebugInfo* debug = new MuonHough::HitDebugInfo(technology, sector, region, layer, sublayer);
1622  debug->isEtaPhi = (neta && nphi);
1623  debug->trigConfirm = 1;
1624  debug->time = prd->time();
1625  std::map<unsigned int, unsigned int>::const_iterator pos = m_techToTruthNameIdx.find(technology);
1626  if (pos != m_techToTruthNameIdx.end()) { matchTruth(truthHits, *truthCollections[pos->second], id, *debug); }
1627  float weight = (neta && nphi) ? 2 : 1;
1628  if (m_idHelperSvc->rpcIdHelper().measuresPhi(id)) {
1629  const float r = rCor(*prd);
1630  const float phi = prd->globalPosition().phi();
1631  const double phi1 = phi; // phiCor(phi,sector);
1632  debug->r = -99999;
1633  MuonHough::PhiHit* hit = new MuonHough::PhiHit(sublayer, r, phi1, phi1, weight, debug, prd);
1634  phiHits.emplace_back(hit);
1635  } else {
1636  const float x = rCor(*prd);
1637  const float y = prd->globalPosition().z();
1638  const float stripCor = 0.5 * prd->detectorElement()->StripWidth(false);
1639  const float ymin = y - stripCor;
1640  const float ymax = y + stripCor;
1641  debug->r = stripCor;
1642  MuonHough::Hit* hit = new MuonHough::Hit(sublayer, x, ymin, ymax, weight, debug, prd);
1643  hits.emplace_back(hit);
1644  }
1645  }
1646  }
1647 
1648  void MuonLayerHoughTool::fill(const EventContext& ctx, std::set<Identifier>& truthHits, const MMPrepDataCollection& mms,
1650  if (mms.empty()) return;
1651  auto truthCollections = m_truthNames.makeHandles(ctx);
1652  Identifier chid = mms.identify();
1653  MuonStationIndex::DetectorRegionIndex region = m_idHelperSvc->regionIndex(chid);
1654  MuonStationIndex::LayerIndex layer = m_idHelperSvc->layerIndex(chid);
1655  int sector = m_idHelperSvc->sector(chid);
1656  unsigned int technology = m_idHelperSvc->technologyIndex(chid);
1657  ATH_MSG_DEBUG("fillMM: Filling " << m_idHelperSvc->toStringChamber(chid) << ": loc s" << sector << " "
1658  << MuonStationIndex::regionName(region) << " " << MuonStationIndex::layerName(layer) << " -> hits "
1659  << mms.size());
1660 
1661  std::array<double,8> multiplicity{};
1662  for (const MMPrepData* prd : mms) {
1663  const Identifier id = prd->identify();
1664  int sublayer = sublay(id) % 10;
1665  multiplicity[sublayer]++;
1666  }
1667 
1668  if( msgLvl(MSG::DEBUG) ){
1669  for (int i = 0; i<8 ; i++) if(multiplicity[i]>0) ATH_MSG_DEBUG(" sublayer " << i << " hits " << multiplicity[i]);
1670  }
1671 
1672  for (const MMPrepData* prd : mms) {
1673  const Identifier id = prd->identify();
1674  float x = prd->globalPosition().z();
1675  float y = rCor(*prd);
1676  int sublayer = sublay(id) % 10;
1677  float stripCor = prd->detectorElement()->getDesign(id)->inputPitch;
1678  float ymin = y - stripCor;
1679  float ymax = y + stripCor;
1680 
1681  //Downweight noise channels
1682  const double weight = 1. / std::max(1., multiplicity[sublayer]);
1683 
1684  MuonHough::HitDebugInfo* debug = new MuonHough::HitDebugInfo(technology, sector, region, layer, sublayer);
1685  debug->r = stripCor;
1686  std::map<unsigned int, unsigned int>::const_iterator pos = m_techToTruthNameIdx.find(technology);
1687  if (pos != m_techToTruthNameIdx.end()) { matchTruth(truthHits, *truthCollections[pos->second], id, *debug); }
1688  std::unique_ptr<MuonHough::Hit> hit = std::make_unique<MuonHough::Hit>(sublayer, x, ymin, ymax, weight, debug, prd);
1689  hits.emplace_back(std::move(hit));
1690  }
1691  }
1692 
1693  void MuonLayerHoughTool::fill(const EventContext& ctx, std::set<Identifier>& truthHits, const sTgcPrepDataCollection& stgcs,
1694  MuonLayerHoughTool::HitVec& hits, MuonLayerHoughTool::PhiHitVec& phiHits, int selectedSector) const {
1695  if (stgcs.empty()) return;
1696  auto truthCollections = m_truthNames.makeHandles(ctx);
1697  Identifier chid = stgcs.identify();
1698  MuonStationIndex::DetectorRegionIndex region = m_idHelperSvc->regionIndex(chid);
1699  MuonStationIndex::LayerIndex layer = m_idHelperSvc->layerIndex(chid);
1700  int sector = m_idHelperSvc->sector(chid);
1701  bool isNeighbouringSector = sector != selectedSector;
1702  unsigned int technology = m_idHelperSvc->technologyIndex(chid);
1703  ATH_MSG_DEBUG("fillsTGC: Filling " << m_idHelperSvc->toStringChamber(chid) << ": loc s" << sector << " "
1705  << " -> hits: " << stgcs.size());
1706 
1707  for (const sTgcPrepData* prd : stgcs) {
1708  const Identifier id = prd->identify();
1709  int channelType = m_idHelperSvc->stgcIdHelper().channelType(id);
1710 
1711  // only pick up phi hits in neighbouring sectors
1712  if (isNeighbouringSector && channelType == 1) continue;
1713  int sublayer = sublay(id);
1714 
1715  std::unique_ptr<MuonHough::HitDebugInfo> debug =
1716  std::make_unique<MuonHough::HitDebugInfo>(technology, sector, region, layer, sublayer);
1717  debug->isEtaPhi = 1;
1718  debug->trigConfirm = true;
1719 
1720  std::map<unsigned int, unsigned int>::const_iterator pos = m_techToTruthNameIdx.find(technology);
1721  if (pos != m_techToTruthNameIdx.end()) { matchTruth(truthHits, *truthCollections[pos->second], id, *debug); }
1722  if (m_idHelperSvc->stgcIdHelper().channelType(id) == 1) {
1723  // eta strips
1724  float x = prd->globalPosition().z();
1725  float y = rCor(*prd);
1726  float stripCor = 1.5; // get from det el
1727  const MuonGM::MuonChannelDesign* design = prd->detectorElement()->getDesign(id);
1728  if (design) {
1729  double stripWidth = design->inputWidth;
1730  double stripLength = design->channelLength(m_idHelperSvc->stgcIdHelper().channel(id));
1731  if (m_debugHough) ATH_MSG_DEBUG(" eta strip width " << stripWidth << " stripLength " << stripLength);
1732  stripCor = 0.5 * stripWidth;
1733  }
1734  debug->r = stripCor;
1735  float ymin = y - stripCor;
1736  float ymax = y + stripCor;
1737  MuonHough::Hit* hit = new MuonHough::Hit(sublayer, x, ymin, ymax, 1., debug.release(), prd);
1738  hits.emplace_back(hit);
1739  } else {
1740  double chWidth = 0;
1742  if (m_idHelperSvc->stgcIdHelper().channelType(id) == 0) {
1743  const MuonGM::MuonPadDesign* design = prd->detectorElement()->getPadDesign(id);
1744  if (!design) {
1745  ATH_MSG_WARNING("No design found for " << m_idHelperSvc->toString(id));
1746  continue;
1747  }
1748  // get the pad width from the detector design
1749  chWidth = 0.5 * design->channelWidth(prd->localPosition(), true);
1750  ATH_MSG_DEBUG(" Pad chWidth " << chWidth << " phi global " << prd->globalPosition().phi());
1751  } else if (m_idHelperSvc->stgcIdHelper().channelType(id) == 2) {
1752  const MuonGM::MuonChannelDesign* design = prd->detectorElement()->getDesign(id);
1753  if (!design) {
1754  ATH_MSG_WARNING("No design found for " << m_idHelperSvc->toString(id));
1755  continue;
1756  }
1757  chWidth = 0.5 * design->channelWidth();
1758  ATH_MSG_DEBUG(" Wire Gang chWidth " << chWidth << " phi global " << prd->globalPosition().phi());
1759  }
1760 
1761  Amg::Vector2D lp1(prd->localPosition().x() + chWidth, prd->localPosition().y());
1762  Amg::Vector3D gp1;
1763  prd->detectorElement()->surface(id).localToGlobal(lp1, gp1, gp1);
1764 
1765  lp1[0] = prd->localPosition().x() - chWidth;
1766  Amg::Vector3D gp2;
1767  prd->detectorElement()->surface(id).localToGlobal(lp1, gp2, gp2);
1768 
1769  double phi1 = gp1.phi();
1770  double phi2 = gp2.phi();
1771  double phi1c = phi1; // phiCor(phi1,selectedSector);
1772  double phi2c = phi2; // phiCor(phi2,selectedSector);
1773  double phi_check = std::abs(xAOD::P4Helpers::deltaPhi(phi1c, phi2c));
1774  if (phi_check > 0.3) {
1775  ATH_MSG_WARNING("bad local phi: in " << phi1 << ", " << phi2 << " sector phi "
1776  << m_sectorMapping.sectorPhi(selectedSector) << " phicor " << phi1c << ", "
1777  << phi2c);
1778  }
1779  if (isNeighbouringSector &&
1780  !(m_sectorMapping.insideSector(selectedSector, phi1) || m_sectorMapping.insideSector(selectedSector, phi2))) {
1781  ATH_MSG_DEBUG("Dropping phi hit in neighbouring sector " << m_idHelperSvc->toString(id) << " phi min "
1782  << std::min(phi1c, phi2c) << " max " << std::max(phi1c, phi2c)
1783  << " global phi: in " << phi1 << ", " << phi2 << " sector phi "
1784  << m_sectorMapping.sectorPhi(selectedSector));
1785  continue;
1786  }
1787  float r = rCor(*prd);
1788  float phiMin = std::min(phi1c, phi2c);
1789  float phiMax = std::max(phi1c, phi2c);
1790  ATH_MSG_VERBOSE("Phi hit " << m_idHelperSvc->toString(id) << " r " << r << " phi min " << phiMin << " phi max "
1791  << phiMax << " bc " << debug->barcode << " chw " << chWidth << " trigC " // FIXME barcode-based - requires MuonHough::HitDebugInfo to be migrated to uniqueID
1792  << debug->trigConfirm << " g phi " << phi1 << " " << phi2);
1793  MuonHough::PhiHit* phiHit =
1794  new MuonHough::PhiHit(sublayer, r, phiMin, phiMax, 1, debug.release(), prd);
1795  phiHits.emplace_back(phiHit);
1796  }
1797  }
1798  }
1799 
1800  void MuonLayerHoughTool::fill(const EventContext& ctx, std::set<Identifier>& truthHits,
1801  std::vector<std::unique_ptr<TgcHitClusteringObj>>& tgcClusteringObjs, const TgcPrepDataCollection& tgcs,
1802  MuonLayerHoughTool::HitVec& hits, MuonLayerHoughTool::PhiHitVec& phiHits, int sector) const {
1803  if (tgcs.empty()) return;
1804  tgcClusteringObjs.push_back(std::make_unique<TgcHitClusteringObj>(&m_idHelperSvc->tgcIdHelper()));
1805  TgcHitClusteringObj& clustering = *tgcClusteringObjs.back();
1806  std::vector<const TgcPrepData*> prds;
1807  prds.insert(prds.begin(), tgcs.begin(), tgcs.end());
1808  clustering.cluster(prds);
1809  clustering.buildClusters3D();
1810 
1811  Identifier chid = tgcs.identify();
1812  MuonStationIndex::DetectorRegionIndex region = m_idHelperSvc->regionIndex(chid);
1813  MuonStationIndex::LayerIndex layer = m_idHelperSvc->layerIndex(chid);
1814 
1815  if (clustering.clusters3D.empty()) {
1816  ATH_MSG_DEBUG("TgcHitClusteringObj, no 3D clusters! ");
1817  if (msgLvl(MSG::DEBUG)) {
1818  for (const TgcPrepData* prd : tgcs) { ATH_MSG_DEBUG(" " << m_idHelperSvc->toString(prd->identify())); }
1819  }
1820  return;
1821  }
1822  if (clustering.bestEtaCluster().empty()) {
1823  ATH_MSG_DEBUG("TgcHitClusteringObj, no eta cluster selected! ");
1824  if (msgLvl(MSG::DEBUG)) {
1825  for (const TgcPrepData* prd : prds) { ATH_MSG_DEBUG(" " << m_idHelperSvc->toString(prd->identify())); }
1826  }
1827  return;
1828  }
1829  auto truthCollections = m_truthNames.makeHandles(ctx);
1830  std::vector<int> sectors;
1831  getSectors(clustering.clusters3D.front(), sectors);
1832  unsigned int technology = m_idHelperSvc->technologyIndex(chid);
1833  for (unsigned int si = 0; si < sectors.size(); ++si) {
1834  if (sectors[si] != sector) continue;
1835 
1836  for (const TgcClusterObj3D& cl : clustering.clusters3D) {
1837  const Identifier id = cl.etaCluster.front()->identify();
1838 
1839  double x = cl.getEdge(TgcEdge::LowEtaLowPhi).z();
1840  double y11 = rCor(cl, TgcEdge::LowEtaLowPhi, sector);
1841  double y12 = rCor(cl, TgcEdge::LowEtaHighPhi, sector);
1842  double y21 = rCor(cl, TgcEdge::LowEtaLowPhi, sector);
1843  double y22 = rCor(cl, TgcEdge::HighEtaHighPhi, sector);
1844  double phi11 = cl.getEdge(TgcEdge::LowEtaLowPhi).phi();
1845  double phi12 = cl.getEdge(TgcEdge::LowEtaHighPhi).phi();
1846  double phi21 = cl.getEdge(TgcEdge::LowEtaLowPhi).phi();
1847  double phi22 = cl.getEdge(TgcEdge::HighEtaHighPhi).phi();
1848  double ymin = std::min(std::min(y11, y12), std::min(y21, y22));
1849  double ymax = std::max(std::max(y11, y12), std::max(y21, y22));
1850  double phimin = std::min(std::min(phi11, phi12), std::min(phi21, phi22));
1851  double phimax = std::max(std::max(phi11, phi12), std::max(phi21, phi22));
1852  double phi1 = phimin; // phiCor(phimin,sector);
1853  double phi2 = phimax; // phiCor(phimax,sector);
1854  int sublayer = sublay(id, x);
1855  ATH_MSG_VERBOSE("Cluster "<<m_idHelperSvc->toString(id)<<" x: "<<x<<", y11: "<<y11
1856  <<", y12: "<<y12<<", y21: "<<y21<<", y22: "<<y22<<", phi11: "<<phi11<<", "
1857  <<"phi12: "<<phi12<<", phi21: "<<phi21<<", phi22: "<<phi22<<" ymin: "<<ymin<<", ymax: "<<ymax
1858  <<", phimin: "<<phimin<<", phimax: "<<phimax);
1859 
1860  MuonHough::HitDebugInfo* debug = new MuonHough::HitDebugInfo(technology, sector, region, layer, sublayer);
1861  debug->clusterSize = cl.etaCluster.size();
1862  debug->clusterLayers = 2;
1863  debug->isEtaPhi = true;
1864  debug->time = cl.etaCluster.front()->getBcBitMap();
1865  std::map<unsigned int, unsigned int>::const_iterator pos = m_techToTruthNameIdx.find(technology);
1866  if (pos != m_techToTruthNameIdx.end()) { matchTruth(truthHits, *truthCollections[pos->second], id, *debug); }
1867 
1869  phiDebug->clusterSize = cl.phiCluster.size();
1870  phiDebug->clusterLayers = 1;
1871  phiDebug->isEtaPhi = true;
1872 
1873  std::unique_ptr<MuonHough::Hit> hit = std::make_unique<MuonHough::Hit>(sublayer, x, ymin, ymax, 2, debug, nullptr, &cl);
1874  std::unique_ptr<MuonHough::PhiHit> phiHit =
1875  std::make_unique<MuonHough::PhiHit>(sublayer, y11, phi1, phi2, 2, phiDebug, nullptr, &cl);
1876  hits.emplace_back(std::move(hit));
1877  phiHits.emplace_back(std::move(phiHit));
1878  }
1879  }
1880  ATH_MSG_DEBUG("fillTGC: Filling " << m_idHelperSvc->toStringChamber(chid) << ": loc s" << sector << " "
1882  << " -> etaHits: " << hits.size() << " phiHits: " << phiHits.size()
1883  << " sectors: " << sectors.size());
1884  }
1885 
1887  insertHash(m_idHelperSvc->sector(id), hash, id);
1888  }
1889 
1890  void MuonLayerHoughTool::insertHash(int sector, const IdentifierHash& hash, const Identifier& id) const{
1891  MuonStationIndex::TechnologyIndex techIndex = m_idHelperSvc->technologyIndex(id);
1892  int sectorLayerHash = MuonStationIndex::sectorLayerHash(m_idHelperSvc->regionIndex(id), m_idHelperSvc->layerIndex(id));
1893  m_collectionsPerSector[sector - 1].technologyRegionHashVecs[techIndex][sectorLayerHash].push_back(hash);
1894  }
1895 
1896  // all chambers are mapped onto a layer and sector map
1897  void MuonLayerHoughTool::initializeSectorMapping(const EventContext& ctx) const{
1898  if (m_sectorSetup) return;
1899  std::lock_guard kuchen(m_mutex);
1900  // cppcheck-suppress identicalConditionAfterEarlyExit; false positive
1901  if (m_sectorSetup) return;
1903  m_collectionsPerSector.resize(MuonStationIndex::numberOfSectors());
1904  // set sector numbers
1905  unsigned int nsectorHashMax = MuonStationIndex::sectorLayerHashMax();
1906  for (unsigned int i = 0; i < m_collectionsPerSector.size(); ++i) {
1907  m_collectionsPerSector[i].sector = i + 1;
1908  m_collectionsPerSector[i].technologyRegionHashVecs.resize(m_ntechnologies);
1909  for (auto it = m_collectionsPerSector[i].technologyRegionHashVecs.begin();
1910  it != m_collectionsPerSector[i].technologyRegionHashVecs.end(); ++it) {
1911  it->resize(nsectorHashMax);
1912  }
1913  }
1914  ATH_MSG_DEBUG("Initializing hashes: number of sectors " << MuonStationIndex::numberOfSectors() << " technologies "
1915  << m_ntechnologies << " sectorLayers "
1917  // loop over all available MDT collection identifiers and order them per sector
1918 
1919  auto loadHashes = [this] (const MuonIdHelper& idHelper){
1920  auto it = idHelper.module_begin();
1921  const auto it_end = idHelper.module_end();
1922  for (; it != it_end; ++it) {
1924  idHelper.get_module_hash(*it, hash);
1925  insertHash(hash, *it);
1926  }
1927  };
1928 
1929  if (m_idHelperSvc->hasMDT()) {
1930  loadHashes(m_idHelperSvc->mdtIdHelper());
1931  }
1932  if (m_idHelperSvc->hasRPC()) {
1933  loadHashes(m_idHelperSvc->rpcIdHelper());
1934  }
1935  if (m_idHelperSvc->hasCSC()) {
1936  loadHashes(m_idHelperSvc->cscIdHelper());
1937  }
1938  // loop over all available MM collection identifiers and order them per sector
1939  if (m_idHelperSvc->hasMM()) {
1940  auto it = m_idHelperSvc->mmIdHelper().detectorElement_begin();
1941  const auto it_end = m_idHelperSvc->mmIdHelper().detectorElement_end();
1942  for (; it != it_end; ++it) {
1944  m_idHelperSvc->mmIdHelper().get_module_hash(*it, hash);
1945  insertHash(hash, *it);
1946  }
1947  }
1948  // loop over all available STGC collection identifiers and order them per sector
1949  if (m_idHelperSvc->hasSTGC()) {
1950  auto it = m_idHelperSvc->stgcIdHelper().detectorElement_begin();
1951  const auto it_end = m_idHelperSvc->stgcIdHelper().detectorElement_end();
1952  for (; it != it_end; ++it) {
1954  m_idHelperSvc->stgcIdHelper().get_module_hash(*it, hash);
1955  int sector = m_idHelperSvc->sector(*it);
1956  insertHash(sector, hash, *it);
1957  int sectorU = sector != 1 ? sector - 1 : 16;
1958  int sectorD = sector != 16 ? sector + 1 : 1;
1959  insertHash(sectorU, hash, *it);
1960  insertHash(sectorD, hash, *it);
1961  }
1962  }
1963 
1964  if (m_idHelperSvc->hasTGC()) {
1965  // loop over all available TGC collection identifiers and order them per sector
1966  auto it = m_idHelperSvc->tgcIdHelper().module_begin();
1967  const auto it_end = m_idHelperSvc->tgcIdHelper().module_end();
1968  for (; it != it_end; ++it) {
1969  const MuonGM::TgcReadoutElement* detEl = detMgr->getTgcReadoutElement(*it);
1971  m_idHelperSvc->tgcIdHelper().get_module_hash(*it, hash);
1972  int nstrips = detEl->nStrips(1);
1973  const Amg::Vector3D p1 = detEl->channelPos(1, 1, 1);
1974  const Amg::Vector3D p2 = detEl->channelPos(1, 1, nstrips);
1975  std::vector<int> sectors1{}, sectors2{};
1976  getSectors(p1, sectors1);
1977  getSectors(p2, sectors2);
1978  std::unordered_set<int> added{};
1979  for (const int sector : sectors1) {
1980  insertHash(sector, hash, *it);
1981  added.insert(sector);
1982  }
1983  for (const int sector: sectors2) {
1984  if (added.insert(sector).second){
1985  insertHash(sector, hash, *it);
1986  }
1987  }
1988  }
1989  }
1990 
1991 
1992  ATH_MSG_DEBUG(" Printing collections per sector, number of technologies " << m_ntechnologies);
1993  for (int sector = 1; sector <= 16; ++sector) {
1995  ATH_MSG_DEBUG(" sector " << sector);
1996  TechnologyRegionHashVec& vec = m_collectionsPerSector[sector - 1].technologyRegionHashVecs;
1997  for (unsigned int hash = 0; hash < nsectorHashMax; ++hash) {
1998  std::pair<MuonStationIndex::DetectorRegionIndex, MuonStationIndex::LayerIndex> regionLayer =
2000 
2001  if (regionLayer.first != currentRegion) ATH_MSG_DEBUG(" " << MuonStationIndex::regionName(regionLayer.first));
2002  bool first = true;
2003  currentRegion = regionLayer.first;
2004  for (unsigned int tech = 0; tech < m_ntechnologies; ++tech) {
2005  std::stable_sort(vec[tech][hash].begin(), vec[tech][hash].end());
2006  if (!vec[tech][hash].empty()) {
2007  if (msgLvl(MSG::DEBUG)) {
2008  if (first) {
2009  ATH_MSG_DEBUG(" " << std::setw(7) << MuonStationIndex::layerName(regionLayer.second));
2010  first = false;
2011  }
2012  ATH_MSG_DEBUG(" " << std::setw(4)
2014  << " " << std::setw(4) << vec[tech][hash].size());
2015  }
2016  }
2017  }
2018  }
2019  }
2020  m_sectorSetup = true;
2021  }
2022 
2023  void MuonLayerHoughTool::printTruthSummary(std::set<Identifier>& truth, std::set<Identifier>& found) const {
2024  if (truth.size() == found.size()) {
2025  ATH_MSG_DEBUG(" All hits found: truth " << truth.size() << " found " << found.size());
2026  } else {
2027  ATH_MSG_DEBUG(" Some truth hits not found: truth " << truth.size() << " found " << found.size());
2028  std::vector<Identifier> result(truth.size() - found.size());
2030  std::set_difference(truth.begin(), truth.end(), found.begin(), found.end(), result.begin());
2031  result.resize(pos - result.begin());
2032  for (std::vector<Identifier>::iterator it = result.begin(); it != result.end(); ++it) {
2033  ATH_MSG_DEBUG(" " << m_idHelperSvc->toString(*it));
2034  }
2035  }
2036  }
2037 } // namespace Muon
python.root_lsr_rank.hashes
hashes
Definition: root_lsr_rank.py:34
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
Muon::MuonStationIndex::BIS
@ BIS
Definition: MuonStationIndex.h:17
Muon::MuonStationIndex::chName
static const std::string & chName(ChIndex index)
convert ChIndex into a string
Definition: MuonStationIndex.cxx:157
beamspotman.r
def r
Definition: beamspotman.py:676
MuonGM::MuonPadDesign
Parameters defining the design of the readout sTGC pads.
Definition: MuonPadDesign.h:40
Muon::MuonLayerHoughTool::associateMaximaToPhiMaxima
void associateMaximaToPhiMaxima(MuonStationIndex::DetectorRegionIndex region, HoughDataPerSector &houghData, std::map< MuonHough::MuonPhiLayerHough::Maximum *, MaximumVec > &phiEtaAssociations, std::vector< MaximumVec > &unassEtaMaxima) const
Definition: MuonLayerHoughTool.cxx:885
Muon::MuonStationIndex::toStationIndex
static StIndex toStationIndex(ChIndex index)
convert ChIndex into StIndex
Definition: MuonStationIndex.cxx:43
Muon::MuonPrepDataContainer
Template for Muon PRD containers (which are basically collections of MuonPrepDataCollections).
Definition: MuonPrepDataContainer.h:42
Muon::MuonStationIndex::LayerIndexMax
@ LayerIndexMax
BEE.
Definition: MuonStationIndex.h:43
ymin
double ymin
Definition: listroot.cxx:63
MuonHough::PhiHitVec
std::vector< std::shared_ptr< MuonHough::PhiHit > > PhiHitVec
Definition: MuonPhiLayerHough.h:20
MuonHough::MuonPhiLayerHough::Maximum::pos
float pos
Definition: MuonPhiLayerHough.h:27
Muon::MMPrepData
Class to represent MM measurements.
Definition: MMPrepData.h:22
GenEvent.h
Muon::HoughDataPerSec::nlayersWithMaxima
std::vector< int > nlayersWithMaxima
Definition: HoughDataPerSec.h:53
MuonPatternChamberIntersect.h
TRTCalib_Extractor.hits
hits
Definition: TRTCalib_Extractor.py:35
get_generator_info.result
result
Definition: get_generator_info.py:21
python.SystemOfUnits.m2
int m2
Definition: SystemOfUnits.py:92
Muon::TgcHitClusteringObj::cluster
bool cluster(const HitList &col)
Muon::MuonStationIndex::BarrelExtended
@ BarrelExtended
EE.
Definition: MuonStationIndex.h:42
Muon::MuonStationIndex::EndcapA
@ EndcapA
Definition: MuonStationIndex.h:49
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
Muon::HoughDataPerSec::phiHitVec
RegionPhiHitVec phiHitVec
Definition: HoughDataPerSec.h:50
Muon::MuonLayerHoughTool::m_printer
PublicToolHandle< MuonEDMPrinterTool > m_printer
Definition: MuonLayerHoughTool.h:195
Muon::HoughDataPerSec::phiMaxVec
RegionPhiMaximumVec phiMaxVec
Definition: HoughDataPerSec.h:52
Muon::MuonLayerHoughTool::m_muonManagerKey
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_muonManagerKey
Definition: MuonLayerHoughTool.h:191
Muon::MuonLayerHoughTool::m_selectorsLoose
std::vector< MuonHough::MuonLayerHoughSelector > m_selectorsLoose
Definition: MuonLayerHoughTool.h:198
Muon::MuonStationIndex::EEL
@ EEL
Definition: MuonStationIndex.h:18
Muon::MuonLayerHoughTool::m_extrapolationDistance
Gaudi::Property< float > m_extrapolationDistance
Definition: MuonLayerHoughTool.h:208
sTgcReadoutElement.h
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
index
Definition: index.py:1
Muon::MuonLayerHoughTool::Road::neighbouringRegion
MuonStationIndex::DetectorRegionIndex neighbouringRegion
Definition: MuonLayerHoughTool.h:77
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
Muon::MuonSectorMapping::getSectors
void getSectors(double phi, std::vector< int > &sectors) const
returns the main sector plus neighboring if the phi position is in an overlap region
Definition: MuonSectorMapping.h:97
PRD_MultiTruthCollection
A PRD is mapped onto all contributing particles.
Definition: PRD_MultiTruthCollection.h:24
MuonHough::MuonPhiLayerHough::Maximum::hough
const MuonPhiLayerHough * hough
Definition: MuonPhiLayerHough.h:37
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
Muon::MuonStationIndex::BML
@ BML
Definition: MuonStationIndex.h:17
TruthParticleContainer.h
Muon::MuonLayerHoughTool::rCor
double rCor(const Amg::Vector3D &pos, const Identifier &id) const
Definition: MuonLayerHoughTool.h:234
MuonHough::HitDebugInfo
struct containing additional debug information on the hits that is not needed for the actual alg but ...
Definition: MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:26
MuonGM::MuonChannelDesign::inputWidth
double inputWidth
Definition: MuonChannelDesign.h:36
MuonHough::MuonPhiLayerHough::Maximum::binposmax
int binposmax
Definition: MuonPhiLayerHough.h:31
Muon::MuonStationIndex::sectorLayerHashMax
static unsigned int sectorLayerHashMax()
maximum create a hash out of region and layer
Definition: MuonStationIndex.cxx:231
Muon::MuonStationIndex::LayerIndex
LayerIndex
enum to classify the different layers in the muon spectrometer
Definition: MuonStationIndex.h:38
TRTCalib_cfilter.p1
p1
Definition: TRTCalib_cfilter.py:130
Muon::MuonStationIndex::sectorLayerHash
static unsigned int sectorLayerHash(DetectorRegionIndex detectorRegionIndex, LayerIndex layerIndex)
create a hash out of region and layer
Definition: MuonStationIndex.cxx:226
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
skel.it
it
Definition: skel.GENtoEVGEN.py:396
Muon::MuonLayerHoughTool::PhiHitVec
HoughDataPerSec::PhiHitVec PhiHitVec
Definition: MuonLayerHoughTool.h:61
M_PI
#define M_PI
Definition: ActiveFraction.h:11
Muon::MuonLayerHoughTool::Road::seed
std::shared_ptr< MuonHough::MuonLayerHough::Maximum > seed
Definition: MuonLayerHoughTool.h:79
sincos.h
Helper to simultaneously calculate sin and cos of the same angle.
MuonHough::HitDebugInfo::clusterLayers
int clusterLayers
cluster size
Definition: MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:45
AthCommonMsg< AlgTool >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
Muon::MuonLayerHoughTool::initialize
virtual StatusCode initialize() override
Definition: MuonLayerHoughTool.cxx:27
MuonHough::MuonLayerHough
Definition: MuonLayerHough.h:59
Muon::MuonLayerHoughTool::extendSeed
void extendSeed(MuonHough::MuonDetectorHough &detectorHoughTransforms, Road &road, HoughDataPerSector &sectorData) const
Definition: MuonLayerHoughTool.cxx:530
xAOD::P4Helpers::deltaPhi
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition: xAODP4Helpers.h:69
MuonHough::MuonLayerHoughSelector
Definition: MuonLayerHoughSelector.h:12
MuonHough::MuonPhiLayerHough::fillLayer2
void fillLayer2(const PhiHitVec &hits, bool substract=false) const
Definition: MuonPhiLayerHough.cxx:29
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
MuonHough::MuonLayerHough::Maximum::binpos
int binpos
Definition: MuonLayerHough.h:75
Muon::MuonStationIndex::BOS
@ BOS
Definition: MuonStationIndex.h:17
Muon::MuonLayerHoughTool::State::foundTruthHits
std::set< Identifier > foundTruthHits
Definition: MuonLayerHoughTool.h:129
Trk::locR
@ locR
Definition: ParamDefs.h:44
MuonHough::HitDebugInfo::clusterSize
int clusterSize
index of reconstructed muon
Definition: MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:44
Muon::MuonLayerHoughTool::findMaxima
bool findMaxima(MaximumVec &seedMaxima, MuonHough::MuonLayerHough &hough, HitVec &hits, MaximumVec &maxima) const
Definition: MuonLayerHoughTool.cxx:1307
MuonHough::Hit::layer
int layer
Definition: MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:77
Muon::MuonLayerHoughTool::HitVec
HoughDataPerSec::HitVec HitVec
Definition: MuonLayerHoughTool.h:59
Muon::MuonStationIndex::BMS
@ BMS
Definition: MuonStationIndex.h:17
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Trk::Surface::center
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Muon
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
Definition: TrackSystemController.h:45
read_hist_ntuple.h1
h1
Definition: read_hist_ntuple.py:21
MuonHough::Hit
struct containing all hit information needed for the Hough transform
Definition: MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:60
Muon::MuonStationIndex::MM
@ MM
Definition: MuonStationIndex.h:56
x
#define x
intersection
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
Definition: compareFlatTrees.cxx:25
empty
bool empty(TH1 *h)
Definition: computils.cxx:295
Muon::MuonStationIndex::EIS
@ EIS
Definition: MuonStationIndex.h:18
Muon::MuonLayerHoughTool::m_doParabolicExtrapolation
Gaudi::Property< bool > m_doParabolicExtrapolation
Definition: MuonLayerHoughTool.h:206
Muon::TgcHitClusteringObj::buildClusters3D
bool buildClusters3D()
Definition: TgcHitClustering.cxx:65
Muon::MdtStatusDriftTime
@ MdtStatusDriftTime
The tube produced a vaild measurement.
Definition: MdtDriftCircleStatus.h:34
MuonHough::MuonPhiLayerHough::associateHitsToMaximum
void associateHitsToMaximum(Maximum &maximum, const PhiHitVec &hits) const
Definition: MuonPhiLayerHough.cxx:246
std::stable_sort
void stable_sort(std::reverse_iterator< DataModel_detail::iterator< DVL > > beg, std::reverse_iterator< DataModel_detail::iterator< DVL > > end, Compare comp)
Specialization of stable_sort for DataVector/List.
Definition: DVL_algorithms.h:711
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
ReadCondHandle.h
MuonHough::MuonPhiLayerHough::Maximum::binposmin
int binposmin
Definition: MuonPhiLayerHough.h:30
Muon::MuonLayerHoughTool::Road::maximumSet
std::set< std::shared_ptr< MuonHough::MuonLayerHough::Maximum > > maximumSet
Definition: MuonLayerHoughTool.h:87
Muon::MuonLayerHoughTool::m_ntechnologies
unsigned int m_ntechnologies
Definition: MuonLayerHoughTool.h:210
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
MuonGM::TgcReadoutElement::channelPos
Amg::Vector3D channelPos(const Identifier &id) const
Returns the position of the active channel (wireGang or strip)
MuonSegmentContainer.h
Muon::MuonStationIndex::EOS
@ EOS
Definition: MuonStationIndex.h:18
Muon::MuonSectorMapping::insideSector
bool insideSector(int sector, double phi) const
checks whether the phi position is consistent with sector
Definition: MuonSectorMapping.h:74
Muon::MuonStationIndex::numberOfSectors
static unsigned int numberOfSectors()
return total number of sectors
Definition: MuonStationIndex.h:106
Muon::MuonLayerHoughTool::Road::add
void add(std::shared_ptr< MuonHough::MuonLayerHough::Maximum > max)
Definition: MuonLayerHoughTool.h:80
IdentifiableContainerMT::empty
bool empty() const
return true if container is empty
Definition: IdentifiableContainerMT.h:244
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:189
MuonLayerHoughTool.h
Muon::MuonLayerHoughTool::analyse
std::pair< std::unique_ptr< MuonPatternCombinationCollection >, std::unique_ptr< HoughDataPerSectorVec > > analyse(State &state) const
Definition: MuonLayerHoughTool.cxx:203
Muon::TgcClusterObj3D::Edge::HighEtaHighPhi
@ HighEtaHighPhi
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
Muon::TgcClusterObj3D::Edge::LowEtaLowPhi
@ LowEtaLowPhi
TRTCalib_cfilter.p2
p2
Definition: TRTCalib_cfilter.py:131
MuonHough::MuonLayerHough::Maximum::binposmin
int binposmin
Definition: MuonLayerHough.h:76
Muon::TgcHitClusteringObj::bestEtaCluster
const HitList & bestEtaCluster() const
Definition: TgcHitClustering.cxx:12
MuonHough::MuonLayerHough::Maximum
struct representing the maximum in the hough space
Definition: MuonLayerHough.h:64
Muon::SortHoughDataPerSector
Definition: MuonLayerHoughTool.h:220
Muon::MuonLayerHoughTool::State::seedMaxima
MaximumVec seedMaxima
Definition: MuonLayerHoughTool.h:126
Muon::MuonStationIndex::decomposeSectorLayerHash
static std::pair< DetectorRegionIndex, LayerIndex > decomposeSectorLayerHash(unsigned int hash)
decompose the hash into Region and Layer
Definition: MuonStationIndex.cxx:237
MuonHough::MuonPhiLayerHough
Definition: MuonPhiLayerHough.h:22
Muon::MuonLayerHoughTool::MaximumVec
HoughDataPerSec::MaximumVec MaximumVec
Definition: MuonLayerHoughTool.h:63
Muon::MuonStationIndex::regionName
static const std::string & regionName(DetectorRegionIndex index)
convert DetectorRegionIndex into a string
Definition: MuonStationIndex.cxx:176
MuonHough::MuonLayerHough::Maximum::theta
float theta
Definition: MuonLayerHough.h:69
MuonIdHelper
Definition: MuonIdHelper.h:80
Muon::HoughDataPerSec::associatedToOtherSector
std::set< MuonHough::MuonLayerHough::Maximum * > associatedToOtherSector
Definition: HoughDataPerSec.h:59
python.changerun.m1
m1
Definition: changerun.py:32
Muon::MuonLayerHoughTool::m_techToTruthNameIdx
std::map< unsigned int, unsigned int > m_techToTruthNameIdx
Definition: MuonLayerHoughTool.h:211
MuonHough::MuonLayerHough::Maximum::max
float max
Definition: MuonLayerHough.h:67
MuonHough::PhiHit::tgc
const Muon::TgcClusterObj3D * tgc
Definition: MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:127
CxxUtils::sincos::cs
double cs
Definition: sincos.h:94
lumiFormat.i
int i
Definition: lumiFormat.py:85
z
#define z
Muon::RpcPrepData
Class to represent RPC measurements.
Definition: RpcPrepData.h:35
Muon::MuonPatternChamberIntersect
This class holds information needed for the Moore and MoMu pattern recognition for a muon chamber.
Definition: MuonPatternChamberIntersect.h:38
python.FPGATrackSimAnalysisConfig.hough
hough
Definition: FPGATrackSimAnalysisConfig.py:483
Muon::CscPrepData
Class representing clusters from the CSC.
Definition: CscPrepData.h:39
Muon::MuonStationIndex::STGC
@ STGC
Definition: MuonStationIndex.h:56
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
MuonHough::MuonPhiLayerHough::Maximum
Definition: MuonPhiLayerHough.h:23
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Muon::MuonStationIndex::EI
@ EI
Definition: MuonStationIndex.h:26
HepMC::barcode
int barcode(const T *p)
Definition: Barcode.h:16
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
Muon::MuonStationIndex::Barrel
@ Barrel
Definition: MuonStationIndex.h:49
Muon::MuonLayerHoughTool::Road::maxima
MaximumVec maxima
Definition: MuonLayerHoughTool.h:85
MuonHough::MuonLayerHough::Maximum::triggerConfirmed
int triggerConfirmed
Definition: MuonLayerHough.h:80
Muon::MuonLayerHoughTool::m_requireTriggerConfirmationNSW
Gaudi::Property< bool > m_requireTriggerConfirmationNSW
Definition: MuonLayerHoughTool.h:203
Muon::TgcClusterObj3D::phiCluster
HitList phiCluster
Definition: TgcHitClustering.h:27
MuonHough::MuonPhiLayerHough::Maximum::hits
PhiHitVec hits
Definition: MuonPhiLayerHough.h:35
Muon::MuonLayerHoughTool::initializeSectorMapping
void initializeSectorMapping(const EventContext &ctx) const
Definition: MuonLayerHoughTool.cxx:1897
MuonPatternCombination.h
Muon::MuonPrepDataCollection::identify
virtual Identifier identify() const override final
Muon::MuonLayerHoughTool::insertHash
void insertHash(const IdentifierHash &hash, const Identifier &id) const
Definition: MuonLayerHoughTool.cxx:1886
Muon::MuonStationIndex::DetectorRegionUnknown
@ DetectorRegionUnknown
Definition: MuonStationIndex.h:48
MuonGM::TgcReadoutElement
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/TgcReadoutElement.h:42
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
test_pyathena.parent
parent
Definition: test_pyathena.py:15
sign
int sign(int a)
Definition: TRT_StrawNeighbourSvc.h:107
Trk::TrkDetElementBase::surface
virtual const Surface & surface() const =0
Return surface associated with this detector element.
Muon::MuonLayerHoughTool::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MuonLayerHoughTool.h:194
Muon::MuonLayerHoughTool::CollectionsPerSector
Definition: MuonLayerHoughTool.h:53
Muon::MuonSectorMapping::sectorPhi
double sectorPhi(int sector) const
returns the centeral phi position of a sector in radians
Definition: MuonSectorMapping.h:81
Muon::MuonLayerHoughTool::createPatternCombinations
void createPatternCombinations(std::vector< MaximumVec > &maxima, MuonPatternCombinationCollection &patternCombis) const
Muon::MuonLayerHoughTool::PhiMaximumVec
HoughDataPerSec::PhiMaximumVec PhiMaximumVec
Definition: MuonLayerHoughTool.h:64
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Muon::MuonLayerHoughTool::mergePhiMaxima
void mergePhiMaxima(Road &road) const
Definition: MuonLayerHoughTool.cxx:446
MuonHough::HitDebugInfo::isEtaPhi
bool isEtaPhi
number of layers in the cluster
Definition: MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:46
Muon::MuonStationIndex::layerName
static const std::string & layerName(LayerIndex index)
convert LayerIndex into a string
Definition: MuonStationIndex.cxx:192
Muon::HoughDataPerSectorVec::vec
std::vector< HoughDataPerSec > vec
Definition: HoughDataPerSec.h:66
MuonHough::MuonDetectorHough::phiHough
MuonPhiLayerHough & phiHough(DetRegIdx region)
access phi transform
Definition: MuonRegionHough.h:69
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
Muon::MuonStationIndex::toLayerIndex
static LayerIndex toLayerIndex(ChIndex index)
convert ChIndex into LayerIndex
Definition: MuonStationIndex.cxx:56
MuonGM::TgcReadoutElement::nStrips
int nStrips(int gasGap) const
Returns the number of strips in a given gas gap.
Muon::MuonPrepDataCollection
Template to hold collections of MuonPrepRawData objects.
Definition: MuonPrepDataCollection.h:46
DataVector< Muon::MuonSegmentCombination >
Muon::MuonLayerHoughTool::Road::mergedPhiMaxima
std::vector< MuonHough::MuonPhiLayerHough::Maximum > mergedPhiMaxima
Definition: MuonLayerHoughTool.h:89
MuonGM::MuonPadDesign::channelWidth
double channelWidth(const Amg::Vector2D &pos, bool measPhi, bool preciseMeas=false) const
calculate local channel width
Definition: MuonPadDesign.h:142
Muon::MuonLayerHoughTool::MuonLayerHoughTool
MuonLayerHoughTool(const std::string &type, const std::string &name, const IInterface *parent)
Default constructor.
Definition: MuonLayerHoughTool.cxx:22
MuonHough::MuonPhiLayerHough::Maximum::max
float max
Definition: MuonPhiLayerHough.h:26
Muon::MuonStationIndex::EES
@ EES
Definition: MuonStationIndex.h:18
Muon::MuonStationIndex::DetectorRegionIndex
DetectorRegionIndex
enum to classify the different layers in the muon spectrometer
Definition: MuonStationIndex.h:47
Trk::PrepRawData
Definition: PrepRawData.h:62
MuonHough::MuonPhiLayerHough::Maximum::sector
int sector
Definition: MuonPhiLayerHough.h:33
Trk::PrepRawData::identify
Identifier identify() const
return the identifier
Muon::MuonLayerHoughTool::State::truthHits
std::set< Identifier > truthHits
Definition: MuonLayerHoughTool.h:128
Muon::TgcClusterObj3D::Edge::LowEtaHighPhi
@ LowEtaHighPhi
Muon::MuonLayerHoughTool::State
Definition: MuonLayerHoughTool.h:124
MuonHough::MuonPhiLayerHough::Maximum::binpos
int binpos
Definition: MuonPhiLayerHough.h:29
MuonHough::PhiHit::prd
const Trk::PrepRawData * prd
access to assiciated hit, either the prd or the tgc pointer is set in athena
Definition: MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:126
MuonPadDesign.h
Muon::MuonLayerHoughTool::Road
Definition: MuonLayerHoughTool.h:73
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
debug
const bool debug
Definition: MakeUncertaintyPlots.cxx:53
Muon::MuonLayerHoughTool::associateMaximaInNeighbouringSectors
void associateMaximaInNeighbouringSectors(HoughDataPerSector &houghData, std::vector< HoughDataPerSector > &houghDataPerSectorVec) const
Definition: MuonLayerHoughTool.cxx:810
Trk::PrepRawData::localPosition
const Amg::Vector2D & localPosition() const
return the local position reference
MuonHough::MuonLayerHough::Maximum::bintheta
int bintheta
Definition: MuonLayerHough.h:79
Muon::MuonLayerHoughTool::sublay
int sublay(const Identifier &id, float z=0) const
Definition: MuonLayerHoughTool.h:247
MuonHough::MuonLayerHough::Maximum::pos
float pos
Definition: MuonLayerHough.h:68
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
MuonHough::MuonDetectorHough
class managing all Hough transforms in the detector
Definition: MuonRegionHough.h:64
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
Muon::MuonLayerHoughTool::RegionMaximumVec
HoughDataPerSec::RegionMaximumVec RegionMaximumVec
Definition: MuonLayerHoughTool.h:66
Muon::MdtPrepData
Class to represent measurements from the Monitored Drift Tubes.
Definition: MdtPrepData.h:33
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Muon::MuonLayerHoughTool::associatePhiMaxima
void associatePhiMaxima(Road &road, PhiMaximumVec &phiMaxima) const
Definition: MuonLayerHoughTool.cxx:682
Muon::TgcClusterObj3D
Definition: TgcHitClustering.h:19
query_example.col
col
Definition: query_example.py:7
Muon::HoughDataPerSec::nphilayersWithMaxima
std::vector< int > nphilayersWithMaxima
Definition: HoughDataPerSec.h:54
MuonDetectorManager.h
Muon::MuonStationIndex::DetectorRegionIndexMax
@ DetectorRegionIndexMax
Definition: MuonStationIndex.h:50
Muon::MuonLayerHoughTool::printTruthSummary
void printTruthSummary(std::set< Identifier > &truth, std::set< Identifier > &found) const
Definition: MuonLayerHoughTool.cxx:2023
Muon::HoughDataPerSec
Definition: HoughDataPerSec.h:20
Muon::MuonLayerHoughTool::matchTruth
void matchTruth(std::set< Identifier > &truthHits, const PRD_MultiTruthCollection &truthCol, const Identifier &id, MuonHough::HitDebugInfo &debug) const
Definition: MuonLayerHoughTool.cxx:1491
Muon::MuonLayerHoughTool::HashVec
std::vector< IdentifierHash > HashVec
Definition: MuonLayerHoughTool.h:49
Muon::MuonLayerHoughTool::find
virtual std::pair< std::unique_ptr< MuonPatternCombinationCollection >, std::unique_ptr< HoughDataPerSectorVec > > find(const MdtPrepDataContainer *mdtCont, const CscPrepDataContainer *cscCols, const TgcPrepDataContainer *tgcCont, const RpcPrepDataContainer *rpcCont, const sTgcPrepDataContainer *stgcCont, const MMPrepDataContainer *mmCont, const EventContext &ctx) const override
Definition: MuonLayerHoughTool.cxx:180
Muon::MuonLayerHoughTool::getSectors
void getSectors(const Amg::Vector3D &pos, std::vector< int > &sectors) const
Definition: MuonLayerHoughTool.h:230
Muon::MuonLayerHoughTool::Road::phiMaxima
PhiMaximumVec phiMaxima
Definition: MuonLayerHoughTool.h:86
MuonHough::MuonLayerHough::Maximum::hits
HitVec hits
Definition: MuonLayerHough.h:81
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
CxxUtils::sincos::sn
double sn
Definition: sincos.h:91
Muon::MuonStationIndex::ChIndexMax
@ ChIndexMax
Definition: MuonStationIndex.h:19
MuonGM::MuonChannelDesign::channelLength
double channelLength(int channel) const
STRIPS ONLY: calculate channel length for a given strip number.
Definition: MuonChannelDesign.h:391
Muon::MuonLayerHoughTool::m_addSectors
Gaudi::Property< bool > m_addSectors
Definition: MuonLayerHoughTool.h:209
MuonChannelDesign.h
Muon::MuonLayerHoughTool::fill
void fill(const EventContext &ctx, std::set< Identifier > &truthHits, const MdtPrepDataCollection &mdts, HitVec &hits) const
Definition: MuonLayerHoughTool.cxx:1510
Muon::MuonStationIndex::EML
@ EML
Definition: MuonStationIndex.h:18
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
Muon::MuonLayerHoughTool::m_useSeeds
Gaudi::Property< bool > m_useSeeds
Definition: MuonLayerHoughTool.h:189
IdentifiableContainerMT::indexFindPtr
virtual const T * indexFindPtr(IdentifierHash hashId) const override final
return pointer on the found entry or null if out of range using hashed index - fast version,...
Definition: IdentifiableContainerMT.h:289
Muon::MuonLayerHoughTool::fillHitsPerSector
void fillHitsPerSector(const EventContext &ctx, State &state, const int sector, const CollectionsPerSector &hashes, const MdtPrepDataContainer *mdtCont, const CscPrepDataContainer *cscCont, const TgcPrepDataContainer *tgcCont, const RpcPrepDataContainer *rpcCont, const sTgcPrepDataContainer *stgcCont, const MMPrepDataContainer *mmCont) const
Definition: MuonLayerHoughTool.cxx:1450
MuonGM::MuonChannelDesign
Definition: MuonChannelDesign.h:24
Muon::MuonStationIndex::MDT
@ MDT
Definition: MuonStationIndex.h:56
Muon::TgcHitClusteringObj
Definition: TgcHitClustering.h:47
MuonHough::Hit::tgc
const Muon::TgcClusterObj3D * tgc
Definition: MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:89
Muon::MuonLayerHoughTool::m_truthNames
SG::ReadHandleKeyArray< PRD_MultiTruthCollection > m_truthNames
Definition: MuonLayerHoughTool.h:200
python.selector.AtlRunQuerySelectorLhcOlc.selector
selector
Definition: AtlRunQuerySelectorLhcOlc.py:611
y
#define y
Muon::HoughDataPerSec::maxAssociationMap
MaximumAssociationMap maxAssociationMap
Definition: HoughDataPerSec.h:57
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
Muon::MuonLayerHoughTool::TechnologyRegionHashVec
std::vector< RegionHashVec > TechnologyRegionHashVec
Definition: MuonLayerHoughTool.h:51
Amg::intersect
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
Definition: GeoPrimitivesHelpers.h:347
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Muon::MuonStationIndex::BIL
@ BIL
Definition: MuonStationIndex.h:17
Muon::MuonStationIndex::EndcapC
@ EndcapC
Definition: MuonStationIndex.h:49
Muon::MuonStationIndex::BEE
@ BEE
Definition: MuonStationIndex.h:17
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
Muon::MuonLayerHoughTool::CollectionsPerSector::technologyRegionHashVecs
TechnologyRegionHashVec technologyRegionHashVecs
Definition: MuonLayerHoughTool.h:55
DeMoScan.first
bool first
Definition: DeMoScan.py:536
DEBUG
#define DEBUG
Definition: page_access.h:11
Muon::MuonStationIndex::TGC
@ TGC
Definition: MuonStationIndex.h:56
Muon::HoughDataPerSec::nmaxHitsInRegion
std::vector< int > nmaxHitsInRegion
Definition: HoughDataPerSec.h:55
Muon::TgcPrepData
Class to represent TGC measurements.
Definition: TgcPrepData.h:32
Muon::MuonStationIndex::RPC
@ RPC
Definition: MuonStationIndex.h:56
python.LArCondContChannels.isBarrel
isBarrel
Definition: LArCondContChannels.py:659
CxxUtils::sincos
Helper to simultaneously calculate sin and cos of the same angle.
Definition: sincos.h:76
Muon::MuonStationIndex::ChIndex
ChIndex
enum to classify the different chamber layers in the muon spectrometer
Definition: MuonStationIndex.h:15
Muon::MuonLayerHoughTool::buildRoads
void buildRoads(MaximumVec &seedMaxima, MuonHough::MuonDetectorHough &detectorHoughTransforms, std::unique_ptr< HoughDataPerSectorVec > &houghDataPerSectorVec, std::vector< Road > &roads) const
Definition: MuonLayerHoughTool.cxx:331
Muon::HoughDataPerSec::sector
int sector
Definition: HoughDataPerSec.h:48
MuonHough::Hit::prd
const Trk::PrepRawData * prd
access to assiciated hit, either the prd or the tgc pointer is set in athena
Definition: MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:88
Muon::MuonLayerHoughTool::CollectionsPerSector::sector
int sector
Definition: MuonLayerHoughTool.h:54
Muon::MuonStationIndex::stName
static const std::string & stName(StIndex index)
convert StIndex into a string
Definition: MuonStationIndex.cxx:141
Muon::MuonLayerHoughTool::m_sectorMapping
MuonSectorMapping m_sectorMapping
Definition: MuonLayerHoughTool.h:213
MuonHough::extrapolate
float extrapolate(const MuonLayerHough::Maximum &ref, const MuonLayerHough::Maximum &ex, bool doparabolic=false)
Definition: MuonLayerHough.cxx:521
Muon::MuonStationIndex::StIndex
StIndex
enum to classify the different station layers in the muon spectrometer
Definition: MuonStationIndex.h:23
Muon::MuonSectorMapping::transformRToNeighboringSector
double transformRToNeighboringSector(double r, int sectorHit, int sectorTarget) const
transform a radial position from one sector frame into another
Definition: MuonSectorMapping.h:152
Muon::MuonLayerHoughTool::m_debugHough
Gaudi::Property< bool > m_debugHough
Definition: MuonLayerHoughTool.h:205
Muon::HoughDataPerSec::nphimaxHitsInRegion
std::vector< int > nphimaxHitsInRegion
Definition: HoughDataPerSec.h:56
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
MuonHough::MuonPhiLayerHough::setDebug
void setDebug(bool d)
Definition: MuonPhiLayerHough.h:44
AthAlgTool
Definition: AthAlgTool.h:26
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
Muon::MuonStationIndex::EMS
@ EMS
Definition: MuonStationIndex.h:18
Muon::MuonPatternCombination
The MuonPatternCombination class provides the means to store the output of the initial global pattern...
Definition: MuonPatternCombination.h:29
TruthParticle.h
Muon::MuonStationIndex::EOL
@ EOL
Definition: MuonStationIndex.h:18
MuonHough::MuonLayerHough::Maximum::binposmax
int binposmax
Definition: MuonLayerHough.h:77
set_intersection
Set * set_intersection(Set *set1, Set *set2)
Perform an intersection of two sets.
MuonGM::MuonChannelDesign::channelWidth
double channelWidth() const
calculate local channel width
Definition: MuonChannelDesign.h:399
MuonHough::SortHitsPerLayer
struct to sort the hits
Definition: MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:180
Muon::MuonStationIndex::TechnologyIndex
TechnologyIndex
enum to classify the different layers in the muon spectrometer
Definition: MuonStationIndex.h:54
Muon::sTgcPrepData
Class to represent sTgc measurements.
Definition: sTgcPrepData.h:20
Muon::MuonStationIndex::BOL
@ BOL
Definition: MuonStationIndex.h:17
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
Muon::MuonLayerHoughTool::Road::neighbouringSector
int neighbouringSector
Definition: MuonLayerHoughTool.h:78
Muon::HoughDataPerSec::hitVec
RegionHitVec hitVec
Definition: HoughDataPerSec.h:49
MuonHough::PhiHit
struct containing all hit information needed for the Hough transform
Definition: MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:99
Muon::TgcHitClusteringObj::clusters3D
std::vector< TgcClusterObj3D > clusters3D
Definition: TgcHitClustering.h:69
DataVector::empty
bool empty() const noexcept
Returns true if the collection is empty.
Trk::Surface::localToGlobal
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const =0
Specified by each surface type: LocalToGlobal method without dynamic memory allocation.
Muon::MuonStationIndex::EM
@ EM
Definition: MuonStationIndex.h:26
MuonHough::MuonPhiLayerHough::findMaximum
bool findMaximum(Maximum &maximum, float maxval) const
Definition: MuonPhiLayerHough.cxx:190
Muon::TgcClusterObj3D::etaCluster
HitList etaCluster
Definition: TgcHitClustering.h:26
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
Muon::MuonLayerHoughTool::m_selectors
std::vector< MuonHough::MuonLayerHoughSelector > m_selectors
Definition: MuonLayerHoughTool.h:197
fitman.k
k
Definition: fitman.py:528
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
Muon::MuonLayerHoughTool::State::houghDataPerSectorVec
std::unique_ptr< HoughDataPerSectorVec > houghDataPerSectorVec
Definition: MuonLayerHoughTool.h:127
ymax
double ymax
Definition: listroot.cxx:64
Trk::PrepRawData::detectorElement
virtual const TrkDetElementBase * detectorElement() const =0
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
Muon::MuonStationIndex::EIL
@ EIL
Definition: MuonStationIndex.h:18
Muon::HoughDataPerSec::maxVec
RegionMaximumVec maxVec
Definition: HoughDataPerSec.h:51
Identifier
Definition: IdentifierFieldParser.cxx:14
Muon::MuonLayerHoughTool::State::outputTruthHits
std::set< Identifier > outputTruthHits
Definition: MuonLayerHoughTool.h:130
Muon::MuonStationIndex::technologyName
static const std::string & technologyName(TechnologyIndex index)
convert LayerIndex into a string
Definition: MuonStationIndex.cxx:209