ATLAS Offline Software
Loading...
Searching...
No Matches
MuonHoughPatternFinderTool.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 <map>
8#include <memory>
9#include <set>
10
12#include "GaudiKernel/ConcurrencyFlags.h"
20#include "MuonSegment/MuonSegmentCombination.h" // for csc's
21#include "TFile.h"
22#include "TH1F.h"
26#include "TrkSurfaces/Surface.h"
28using namespace TrkDriftCircleMath;
29
30namespace Muon {
32 struct SegmentData {
34 unsigned int index{0};
35 const Muon::MdtPrepData* prd{nullptr};
36 inline Identifier id() const { return prd->identify(); };
37 inline double radius() const { return prd->localPosition()[0]; }
38 inline double errradius() const { return Amg::error(prd->localCovariance(), 0); }
39 double weights{1.};
40 double prob{1.}; // artificial probability that hit belongs to true muon
41
42 bool onsegment{false}; // non-zero if on segment, int indicates how many hits in same
43 // layer are on segment (used in weighting)
44 double psi{0.};
45
46 double weighted_trigger{0.};
47 bool tr_confirmation{false};
48
49 int layer_number{0}; // layer_number ranges from 0..5/7
50 };
51
52 MuonHoughPatternFinderTool::MuonHoughPatternFinderTool(const std::string& t, const std::string& n, const IInterface* p) :
53 AthAlgTool(t, n, p) {
54 declareInterface<IMuonHoughPatternFinderTool>(this);
55 }
58 if (m_use_histos) {
59 if (Gaudi::Concurrency::ConcurrencyFlags::numThreads() > 1) {
60 ATH_MSG_FATAL("Filling histograms not supported in MT jobs.");
61 return StatusCode::FAILURE;
62 }
63
64 m_h = std::make_unique<Hists>();
65 m_h->m_file = std::make_unique<TFile>("Hough_histos.root", "RECREATE");
66 m_h->m_weighthistogram = std::make_unique<TH1F>("weighthisto", "weighthisto", 100, -0.5, 2);
67 m_h->m_weighthistogrammdt = std::make_unique<TH1F>("weighthistomdt", "weighthistomdt", 100, -0.3, 2.2);
68 m_h->m_weighthistogramrpc = std::make_unique<TH1F>("weighthistorpc", "weighthistorpc", 100, -0.3, 2.2);
69 m_h->m_weighthistogramcsc = std::make_unique<TH1F>("weighthistocsc", "weighthistocsc", 100, -0.3, 2.2);
70 m_h->m_weighthistogramtgc = std::make_unique<TH1F>("weighthistotgc", "weighthistotgc", 100, -0.3, 2.2);
71 m_h->m_weighthistogramstgc = std::make_unique<TH1F>("weighthistostgc", "weighthistostgc", 100, -0.3, 2.2);
72 m_h->m_weighthistogrammm = std::make_unique<TH1F>("weighthistomm", "weighthistomm", 100, -0.3, 2.2);
73 }
74
75 ATH_MSG_VERBOSE("MuonHoughPatternFinderTool::Initializing");
77 ATH_MSG_VERBOSE("found Service MuonCombinePatternTool " << m_muonCombinePatternTool);
78
80 ATH_MSG_VERBOSE("found Service muonHoughPatternTool: " << m_muonHoughPatternTool);
81
82 ATH_CHECK(m_idHelperSvc.retrieve());
83
84 const RpcIdHelper& rpcHelper{m_idHelperSvc->rpcIdHelper()};
85 const MdtIdHelper& mdtIdHelper{m_idHelperSvc->mdtIdHelper()};
86 m_RpcToMdtOuterStDict[rpcHelper.stationNameIndex("BOL")] = mdtIdHelper.stationNameIndex("BOS");
87 m_RpcToMdtOuterStDict[rpcHelper.stationNameIndex("BOS")] = mdtIdHelper.stationNameIndex("BOL");
88 m_RpcToMdtOuterStDict[rpcHelper.stationNameIndex("BMS")] = mdtIdHelper.stationNameIndex("BML");
89 m_RpcToMdtOuterStDict[rpcHelper.stationNameIndex("BML")] = mdtIdHelper.stationNameIndex("BMS");
90
91 m_RpcToMdtInnerStDict[rpcHelper.stationNameIndex("BMS")] = mdtIdHelper.stationNameIndex("BIS");
92 m_RpcToMdtInnerStDict[rpcHelper.stationNameIndex("BML")] = mdtIdHelper.stationNameIndex("BIL");
93
94 ATH_CHECK(m_printer.retrieve());
95
96 if (m_hit_reweights) { ATH_MSG_DEBUG("Hit Reweighting " << m_hit_reweights); }
97
101
102 ATH_MSG_VERBOSE("End of Initializing");
103 return StatusCode::SUCCESS;
104 }
105
106 template <class T> std::vector<const MuonPrepDataCollection<T>*> MuonHoughPatternFinderTool::stdVec(const MuonPrepDataContainerT<T>* cont) const {
107 if (!cont) return {};
108 std::vector<const MuonPrepDataCollection<T>*> vec;
109 vec.reserve(cont->size());
110 std::transform(cont->begin(), cont->end(), std::back_inserter(vec),
111 [](const MuonPrepDataCollection<T>* ptr){return ptr;});
112 return vec;
113 }
115 const MdtPrepDataContainer* mdtCont, const CscPrepDataContainer* cscCont, const TgcPrepDataContainer* tgcCont,
116 const RpcPrepDataContainer* rpcCont, const sTgcPrepDataContainer* stgcCont, const MMPrepDataContainer* mmCont,
117 const EventContext& ctx) const {
118 return find(ctx, stdVec(mdtCont), stdVec(cscCont), stdVec(tgcCont),
119 stdVec(rpcCont), stdVec(stgcCont), stdVec(mmCont), nullptr);
120 }
121 MuonPatternHoughPair MuonHoughPatternFinderTool::find(const std::vector<const MdtPrepDataCollection*>& mdtCols,
122 const std::vector<const CscPrepDataCollection*>& cscCols,
123 const std::vector<const TgcPrepDataCollection*>& tgcCols,
124 const std::vector<const RpcPrepDataCollection*>& rpcCols,
125 const MuonSegmentCombinationCollection* cscSegmentCombis, const EventContext& ctx) const {
126 return find(ctx, mdtCols, cscCols, tgcCols, rpcCols, {}, {}, cscSegmentCombis);
127 }
129 const std::vector<const MdtPrepDataCollection*>& mdtCols,
130 const std::vector<const CscPrepDataCollection*>& cscCols,
131 const std::vector<const TgcPrepDataCollection*>& tgcCols,
132 const std::vector<const RpcPrepDataCollection*>& rpcCols,
133 const std::vector<const sTgcPrepDataCollection*>& stgcCols,
134 const std::vector<const MMPrepDataCollection*>& mmCols,
135 const MuonSegmentCombinationCollection* cscSegmentCombis) const{
138 std::map<int, std::vector<std::pair<int, int>>> rpcmdtstationmap;
141 std::map<int, std::vector<std::pair<int, int>>> tgcmdtstationmap;
142
146 EtaPhiHitAssocMap phietahitassociation{};
147
148 // read event_data:
149 std::unique_ptr<MuonHoughHitContainer> hitcontainer{
150 getAllHits(mdtCols, tgcCols, rpcCols, cscSegmentCombis, rpcmdtstationmap, tgcmdtstationmap, phietahitassociation)};
151
152 if (m_use_csc && !cscSegmentCombis) {
153 addCollections(cscCols, *hitcontainer, phietahitassociation);
154 }
155 if (m_use_mm) {
156 addCollections(mmCols, *hitcontainer, phietahitassociation);
157 }
158 if (m_use_stgc) {
159 addCollections(stgcCols, *hitcontainer, phietahitassociation);
160 }
161 // analyse data
162 std::unique_ptr<MuonPatternCombinationCollection> patCombiCol = analyse(ctx, *hitcontainer,
163 phietahitassociation);
164
165
166 // ensure we always output a collection
167 if (!patCombiCol) {
168 ATH_MSG_DEBUG(" NO pattern combinations found, creating empty collection ");
169 patCombiCol = std::make_unique<MuonPatternCombinationCollection>();
170 }
171
172 if (m_summary || msgLvl(MSG::DEBUG)) {
173 ATH_MSG_INFO(" summarizing Combined pattern combination output: " <<std::endl << m_printer->print(*patCombiCol));
174 }
175
176 ATH_MSG_VERBOSE("execute(end) ");
177 // return result
178 return {std::move(patCombiCol), nullptr};
179 }
180
182 if (m_use_histos) {
183 auto save_histo = [this](std::unique_ptr<TH1>& h_ptr) {
184 if (!h_ptr) return;
185 m_h->m_file->WriteObject(h_ptr.get(), h_ptr->GetName());
186 h_ptr.reset();
187 };
188 save_histo(m_h->m_weighthistogram);
189 save_histo(m_h->m_weighthistogrammdt);
190 save_histo(m_h->m_weighthistogramrpc);
191 save_histo(m_h->m_weighthistogramcsc);
192 save_histo(m_h->m_weighthistogramtgc);
193 save_histo(m_h->m_weighthistogramstgc);
194 save_histo(m_h->m_weighthistogrammm);
195
196 }
197 ATH_MSG_VERBOSE("finalize()");
198
199 return StatusCode::SUCCESS;
200 }
201
202 std::unique_ptr<MuonPatternCombinationCollection> MuonHoughPatternFinderTool::analyse(const EventContext& ctx,
203 const MuonHoughHitContainer& hitcontainer,
204 const EtaPhiHitAssocMap& phietahitassociation) const {
205 ATH_MSG_DEBUG("size of event: " << hitcontainer.size());
206
207 if (msgLvl(MSG::VERBOSE)) {
208 std::stringstream sstr{};
209 for (size_t h = 0; h < hitcontainer.size() ; ++h){
210 const auto& houghHit = hitcontainer.getHit(h);
211 sstr<<m_printer->print(*houghHit->getPrd())<<" weight: "<<houghHit->getWeight()<<std::endl;
212 }
213 ATH_MSG_VERBOSE("Dump Hough container "<<std::endl<<sstr.str());
214 }
215
216
218 MuonHoughPatternContainerShip houghpattern = m_muonHoughPatternTool->emptyHoughPattern();
219 // pass through hitcontainer (better still: preprawdata and only after make
220 // internal hitcontainer)
221
222 m_muonHoughPatternTool->makePatterns(hitcontainer, houghpattern);
223
224 std::unique_ptr<MuonPrdPatternCollection> phipatterns{m_muonHoughPatternTool->getPhiMuonPatterns(houghpattern)};
225 std::unique_ptr<MuonPrdPatternCollection> etapatterns{m_muonHoughPatternTool->getEtaMuonPatterns(houghpattern)};
226
227 if (m_summary || msgLvl(MSG::DEBUG)) {
228 if (phipatterns->empty())
229 ATH_MSG_INFO(" summarizing input: Phi pattern combination empty");
230 else
231 ATH_MSG_INFO(" summarizing Phi pattern combination input: " << std::endl << m_printer->print(*phipatterns));
232 if (etapatterns->empty())
233 ATH_MSG_INFO(" summarizing input: Eta pattern combination empty");
234 else
235 ATH_MSG_INFO(" summarizing Eta pattern combination input: " << std::endl << m_printer->print(*etapatterns));
236 }
237
238 ATH_MSG_DEBUG("writePatterns");
239 ATH_MSG_DEBUG("size: phi: " << phipatterns->size() << " eta: " << etapatterns->size());
240
241 std::unique_ptr<MuonPrdPatternCollection> combinedpatterns;
242 std::unique_ptr<MuonPatternCombinationCollection> patterncombinations{};
243
244 // make + write muonpatterncombinations
245 if (!etapatterns->empty()) {
246 combinedpatterns = m_muonCombinePatternTool->combineEtaPhiPatterns(*phipatterns, *etapatterns, phietahitassociation);
247 }
248
249 if (combinedpatterns) {
250 patterncombinations = m_muonCombinePatternTool->makePatternCombinations(*combinedpatterns);
251 } else {
252 ATH_MSG_DEBUG("No combined patterns, creating dummy.");
253 combinedpatterns = std::make_unique<MuonPrdPatternCollection>();
254 }
255
256 record(phipatterns, m_CosmicPhiPatternsKey, ctx);
257 record(etapatterns, m_CosmicEtaPatternsKey, ctx);
258 record(combinedpatterns, m_COMBINED_PATTERNSKey, ctx);
259
260 return patterncombinations;
261 }
262
263 std::unique_ptr<MuonHoughHitContainer> MuonHoughPatternFinderTool::getAllHits(
264 const std::vector<const MdtPrepDataCollection*>& mdtCols,
265 const std::vector<const TgcPrepDataCollection*>& tgcCols, const std::vector<const RpcPrepDataCollection*>& rpcCols,
266 const MuonSegmentCombinationCollection* cscSegmentCombis, std::map<int, std::vector<std::pair<int, int>>>& rpcmdtstationmap,
267 std::map<int, std::vector<std::pair<int, int>>>& tgcmdtstationmap,
268 EtaPhiHitAssocMap& phietahitassociation) const {
269 ATH_MSG_VERBOSE("getAllHits()");
270
271 std::unique_ptr<MuonHoughHitContainer> hitcontainer = std::make_unique<MuonHoughHitContainer>();
272 // reserve space for 5000 hits (arbitrary), this should gain some cpu/memory
273 // for background, but will lose for lower occupancy. If anyone knows a way to
274 // predict the number of muon hits, I'd like to hear it.
275 hitcontainer->reserve(5000);
276
277 if (cscSegmentCombis && m_use_csc) {
278 std::set<Identifier> csc_set; // set to make sure every csc hit is only
279 // passed to hitcontainer once
280 std::pair<std::set<Identifier>::iterator, bool> csc_pair;
281 std::map<int, int> nHitsPerLayer; // map that connect layer number (1000*eta +
282 // 100*phi + 10*chamberlayer+ 2*wirelayer +
283 // eta/phi)
284
285 std::vector<const Muon::CscClusterOnTrack*> csc_rots; // csc rots
286
287 std::vector<int> layer_ids; // if 0 then prd already added
288
289 csc_rots.reserve(400); // again arbitrary, atm (May 2008), the max number of
290 // csc segments is 50 (times 8 hits = 400)
291 layer_ids.reserve(400);
292
293 // two loops needed as number of hits per layer needs to be known
294 for (const Muon::MuonSegmentCombination* msc : *cscSegmentCombis) {
295 ATH_MSG_VERBOSE("CSC combo segments loop, segmentcombo " << msc);
296 for (unsigned int ss = 0; ss < msc->numberOfStations(); ++ss) {
297 for (const std::unique_ptr<MuonSegment>& ms : *msc->stationSegments(ss)) {
298 if (!ms) {
299 ATH_MSG_DEBUG("Segment has been already skimmed");
300 continue;
301 }
302 ATH_MSG_VERBOSE("CSC segments loop, segment: " << ms.get());
303 PrepDataSet phi_set;
304 std::vector<const Trk::PrepRawData*> eta_vector;
305
306 int nRoTs = ms->numberOfContainedROTs();
307 for (int i = 0; i < nRoTs; ++i) {
308 const Muon::CscClusterOnTrack* cscOnSeg = dynamic_cast<const Muon::CscClusterOnTrack*>(ms->rioOnTrack(i));
309 if (!cscOnSeg) {
310 ATH_MSG_INFO("Dynamic cast to CscClusterOnTrack failed!");
311 continue;
312 }
313 csc_rots.push_back(cscOnSeg);
314 Identifier id = cscOnSeg->identify();
315 bool channel_type = m_idHelperSvc->cscIdHelper().measuresPhi(id);
316 csc_pair = csc_set.insert(id);
317 if (!csc_pair.second) {
318 ATH_MSG_DEBUG(" CSC hit was already added, weight set to 0");
319 layer_ids.push_back(0);
320 } else {
321 const int layer_id = 1000 * m_idHelperSvc->cscIdHelper().stationEta(id) +
322 100 * m_idHelperSvc->cscIdHelper().stationPhi(id) +
323 10 * m_idHelperSvc->cscIdHelper().chamberLayer(id) +
324 2 * m_idHelperSvc->cscIdHelper().wireLayer(id) + channel_type;
325 ATH_MSG_DEBUG("csc layer_id: " << layer_id);
326 ++nHitsPerLayer[layer_id];
327 layer_ids.push_back(layer_id);
328 }
329
330 if (channel_type) { // phi hit
331 if (!phi_set.insert(cscOnSeg->prepRawData()).second) { ATH_MSG_INFO(" CSC phi hit was already added"); }
332 } else { // eta hit
333 eta_vector.push_back(cscOnSeg->prepRawData());
334 }
335 } // rots
336 // add hit association from segment to map:
337 if (!phi_set.empty()) {
338 ATH_MSG_VERBOSE("Number of Phi Csc hits in segment: " << phi_set.size());
339 for (const Trk::PrepRawData* prd : eta_vector) { phietahitassociation.insert(std::make_pair(prd, phi_set)); }
340 }
341 }
342 }
343 }
344
345 for (unsigned int i = 0; i < csc_rots.size(); i++) {
346 const Muon::CscPrepData* prd = csc_rots[i]->prepRawData();
347
348 const Amg::Vector3D& globalpos = csc_rots[i]->globalPosition();
349 bool channel_type = m_idHelperSvc->cscIdHelper().measuresPhi(csc_rots[i]->identify());
350
351 double weight = 0.;
352 if (layer_ids[i] != 0) { // not yet added
353 double number_of_hits = (double)nHitsPerLayer[layer_ids[i]];
354 weight = m_weight_csc_on_segment / (0.75 * std::sqrt(number_of_hits) + 0.25 * number_of_hits);
355 }
356
357 ATH_MSG_DEBUG(m_printer->print(*prd) << " weight " << weight);
358 std::shared_ptr<MuonHoughHit> hit = std::make_shared<MuonHoughHit>(globalpos, channel_type, MuonHough::CSC, 1., weight, prd);
359
360 hitcontainer->addHit(hit);
361 if (m_use_histos) {
362 Hists& h = getHists();
363 h.m_weighthistogram->Fill(weight);
364 h.m_weighthistogramcsc->Fill(weight);
365 }
366 }
367 } // use_csc_segments
368 // taken and modified from
369 // DetectorDescription/GeoModel/HitDisplay/src/HitDisplaySystem.cxx
370
371 if (m_use_rpc) {
372 for (const RpcPrepDataCollection* rpc_coll : rpcCols) {
373 addRpcCollection(rpc_coll, *hitcontainer, rpcmdtstationmap, phietahitassociation);
374 }
375 }
376
377 if (m_use_tgc) {
378 for (const TgcPrepDataCollection* tgc_coll : tgcCols) {
379 addTgcCollection(tgc_coll, *hitcontainer, tgcmdtstationmap, phietahitassociation);
380 }
381 }
382
383 if (m_use_mdt) {
384 for (const MdtPrepDataCollection* prep_coll : mdtCols) {
385 addMdtCollection(prep_coll, *hitcontainer, rpcmdtstationmap, tgcmdtstationmap);
386 }
387 }
388
389
390
391 if (msgLevel(MSG::VERBOSE)) {
392 ATH_MSG_VERBOSE("MuonHoughPatternFinderTool::getAllHits() saving " << hitcontainer->size() << " converted hits");
393 for (unsigned int i = 0; i < hitcontainer->size(); i++) {
394 ATH_MSG_VERBOSE(" hit " << hitcontainer->getHit(i)->getWhichDetector() << " (" << hitcontainer->getHit(i)->getHitx() << ","
395 << hitcontainer->getHit(i)->getHity() << "," << hitcontainer->getHit(i)->getHitz() << ") "
396 << " weight: " << hitcontainer->getHit(i)->getWeight()
397 << " measures phi: " << hitcontainer->getHit(i)->getMeasuresPhi());
398 }
399 }
400
401 ATH_MSG_VERBOSE("MuonHoughPatternFinderTool::getAllHits() saving " << phietahitassociation.size() << "associated hits ");
402 return hitcontainer;
403
404 } // getAllHits
405
406 void MuonHoughPatternFinderTool::record(std::unique_ptr<MuonPrdPatternCollection>& patCol,
407 const SG::WriteHandleKey<MuonPrdPatternCollection>& key, const EventContext& ctx) const {
408 if (!patCol) {
409 ATH_MSG_WARNING("Zero pointer, could not save patterns!!! ");
410 return;
411 }
412
413 // check whether we are writing patterns to storegate, if not delete pattern
414 if (!m_recordAllOutput) {
415 ATH_MSG_DEBUG("Deleted patterns: " << patCol->size() << " at " << key.key());
416 // since patCol Datavector, it owns (by defaults its elements)
417
418 } else {
420 StatusCode sc = handle.record(std::move(patCol));
421 if (sc.isFailure()) {
422 ATH_MSG_WARNING("Could not save patterns at " << key.key());
423 } else {
424 ATH_MSG_DEBUG("Saved patterns: " << patCol->size() << " at " << key.key());
425 }
426 }
427 }
429 const RpcPrepDataCollection* rpc_coll, MuonHoughHitContainer& hitcontainer,
430 std::map<int, std::vector<std::pair<int, int>>>& rpcmdtstationmap,
431 EtaPhiHitAssocMap& phietahitassociation) const {
432 std::set<int> layers; // different layer definition between the two!!
433
434 int size_begin = hitcontainer.size();
435 addCollection(*rpc_coll, hitcontainer, phietahitassociation);
436 int size_end = hitcontainer.size();
437
438 updateRpcMdtStationMap((*rpc_coll->begin())->identify(), size_begin, size_end, rpcmdtstationmap);
439 }
440
442 const Muon::TgcPrepDataCollection* tgc_coll, MuonHoughHitContainer& hitcontainer,
443 std::map<int, std::vector<std::pair<int, int>>>& tgcmdtstationmap,
444 EtaPhiHitAssocMap& phietahitassociation) const {
445
446 int size_begin = hitcontainer.size();
447 addCollection(*tgc_coll, hitcontainer, phietahitassociation);
448 int size_end = hitcontainer.size();
449 updateTgcMdtStationMap((*tgc_coll->begin())->identify(), size_begin, size_end, tgcmdtstationmap);
450 }
451
453 std::map<int, std::vector<std::pair<int, int>>>& rpcmdtstationmap,
454 std::map<int, std::vector<std::pair<int, int>>>& tgcmdtstationmap) const {
455 const unsigned int size = mdt_coll->size();
456 if (!size) return;
457 const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
458
459 auto new_mdt_hit = [](const Muon::MdtPrepData* mdt_hit, double prob, double weight) {
460 return std::make_shared<MuonHoughHit>(mdt_hit->globalPosition(), false /*measures_phi*/, MuonHough::MDT, prob, weight, mdt_hit); // getPrd
461 };
462 if (m_showerskip) {
463 const Muon::MdtPrepData* mdt = (*mdt_coll->begin());
464 const MuonGM::MdtReadoutElement* detEl = mdt->detectorElement();
465 unsigned int channels = 2 * detEl->getNLayers() * detEl->getNtubesperlayer(); // Factor 2 for number of multilayers, should
466 // be changed when only 1 detector element per
467 // chamber (the chambers with only 1
468 // multilayer have a twice less severe cut
469 // (for convenience))
470 double occupancy = (double)size / (double)channels;
471
472 ATH_MSG_DEBUG(" size: " << size << " channels: " << channels << " occupancy: " << occupancy);
473
474 // if more than m_showerskipperc (default 30%) of all hits in the chamber is
475 // hit then all weights to 0 only done for large chambers (more than 50
476 // hits)
477 if (occupancy > m_showerskipperc && size > 50) {
478 ATH_MSG_DEBUG("Chamber skipped! Too high occupancy (>" << m_showerskipperc << "%): " << occupancy
479 << " association to pattern still possible");
480
481 for (const MdtPrepData* mdt_hit : *mdt_coll) {
482 if (m_mdt_tdc_cut && mdt_hit->status() != Muon::MdtStatusDriftTime) continue;
483 if ((m_mdt_adc_cut && (mdt_hit->adc() > m_mdt_adc_min)) || !m_mdt_adc_cut) {
484 ATH_MSG_DEBUG(m_printer->print(*mdt_hit));
485 hitcontainer.addHit(new_mdt_hit(mdt_hit, 0., 0.));
486 }
487 }
488 return;
489 }
490 }
491
492 std::map<int, int> nHitsPerLayer;
493 std::map<int, int> number_of_hots_per_layer; // number of trigger confirmed or hits on segment
494 // within layer (key)
495
496 std::vector<SegmentData> collected_data{};
497 collected_data.reserve(size);
498
499 std::vector<double> tubecount(idHelper.tubeMax() + 2);
500
501
502
503 for (const Muon::MdtPrepData* mdt : *mdt_coll) // first
504 {
505
506 if (m_mdt_tdc_cut && mdt->status() != Muon::MdtStatusDriftTime) {
507 ATH_MSG_VERBOSE("Skip Mdt hit "<<m_printer->print(*mdt)<<" due to out of time tdc");
508 continue;
509 }
510 if (m_mdt_adc_cut && (mdt->adc() <= m_mdt_adc_min)) {
511 ATH_MSG_VERBOSE("Skip Mdt hit "<<m_printer->print(*mdt)<< "due to too low adc:"<<mdt->adc()<<". Required "<<m_mdt_adc_min);
512 continue;
513 }
514 SegmentData prd_data{};
515 prd_data.index = collected_data.size();
516 prd_data.prd = mdt;
517
518 const int tube = idHelper.tube(prd_data.id());
519 const int multi_layer = idHelper.multilayer(prd_data.id());
520 const int tube_layer = idHelper.tubeLayer(prd_data.id());
521
522 prd_data.layer_number =
523 (multi_layer - 1) * idHelper.tubeLayerMax() + (tube_layer - 1); // layer_number ranges from 0..5/7
524
525 tubecount[tube] += 1.;
526 tubecount[tube - 1] += 0.5;
527 tubecount[tube + 1] += 0.5;
528
529 ATH_MSG_VERBOSE(" layer_number: " << prd_data.layer_number << " multi_layer: " << multi_layer
530 << " tube_layer: " << tube_layer);
531 collected_data.push_back(std::move(prd_data));
532 }
533
534 const unsigned int prdsize = collected_data.size();
535
536 if (!prdsize) return;
537
538 if (!m_hit_reweights) {
539 for (const SegmentData& mdt_hit : collected_data) {
540 ATH_MSG_DEBUG(m_printer->print(*mdt_hit.prd));
541 hitcontainer.addHit(new_mdt_hit(mdt_hit.prd, 1., 1.));
542 }
543 return;
544 }
545
546 double tubem = *(std::max_element(tubecount.begin(), tubecount.end()));
547
548 // allweights 0
549 if (tubem < 2.01) {
550 ATH_MSG_VERBOSE(" TOO SMALL tubem : " << tubem);
551 for (const SegmentData& mdt_hit : collected_data) {
552 ATH_MSG_DEBUG(m_printer->print(*mdt_hit.prd) << " weight " << 0 << " adc: " << mdt_hit.prd->adc());
553 hitcontainer.addHit(new_mdt_hit(mdt_hit.prd, 0., 0.));
554 if (m_use_histos) {
555 Hists& h = getHists();
556 h.m_weighthistogram->Fill(0);
557 h.m_weighthistogrammdt->Fill(0);
558 }
559
560 } // collection
561 return;
562 }
563
564 // fast segment search:
565
566 for (SegmentData& mdt_hit : collected_data) {
567 const int tube = idHelper.tube(mdt_hit.id());
568 if (tubecount[tube] > 1) ++nHitsPerLayer[mdt_hit.layer_number];
569
570 // KILL 1 hit cases
571 if (tubecount[tube] <= 1.) mdt_hit.prob = 0.;
572 } // end hit loop i
573
574 int ml1{0}, ml2{0};
575 for (const auto& map_it : nHitsPerLayer) {
576 const bool count_1 = map_it.first >= idHelper.tubeLayerMax();
577 ml1 += count_1;
578 ml2 += !count_1;
579 }
580
581 // allweights = 0
582 if (ml1 + ml2 < 2.01) {
583 ATH_MSG_VERBOSE(" TOO SMALL ml1 + ml2 : " << ml1 << " ml2 " << ml2);
584 for (const SegmentData& mdt_hit : collected_data) {
585 ATH_MSG_DEBUG(m_printer->print(*mdt_hit.prd) << " weight " << 0);
586 hitcontainer.addHit(new_mdt_hit(mdt_hit.prd, 0., 0.));
587 if (m_use_histos) {
588 Hists& h = getHists();
589 h.m_weighthistogram->Fill(0);
590 h.m_weighthistogrammdt->Fill(0);
591 }
592 } // collection
593 return;
594 }
595
596 DCVec dcs;
597 dcs.reserve(prdsize);
598 const MdtIdHelper& mdtHelper = m_idHelperSvc->mdtIdHelper();
599 for (const SegmentData& mdt_hit : collected_data) {
600 if (mdt_hit.prob < 0.01) continue;
601
602 // create new DriftCircircleMath::DriftCircle::DriftState
603 const Amg::Vector3D& globalpos = mdt_hit.prd->globalPosition();
604
605 const Identifier hitId = mdt_hit.id();
606 TrkDriftCircleMath::MdtId mdtid(mdtHelper.isBarrel(hitId),
607 mdtHelper.multilayer(hitId) - 1,
608 mdtHelper.tubeLayer(hitId) - 1,
609 mdtHelper.tube(hitId) - 1);
610 TrkDriftCircleMath::DriftCircle dc(TrkDriftCircleMath::LocVec2D(globalpos.perp(), globalpos.z()),
611 mdt_hit.radius(),
612 mdt_hit.errradius(),
614 mdtid,
615 nullptr,
616 mdt_hit.index);
617 dcs.emplace_back(std::move(dc));
618 }
619
620 bool seg_found = true;
621 while (seg_found) {
622 std::vector<int> sel(dcs.size());
623 double angleDif = 0.;
624
625 fastSegmentFinder(dcs, ml1, ml2, angleDif, sel);
626
627 if (ml1 + ml2 >= 2.1) {
628 int removed_hits = 0; // keeps track of number of removed hits
629 for (unsigned int i = 0; i < sel.size(); ++i) {
630 if (sel[i] != 0) {
631 unsigned int j = dcs[i - removed_hits].index(); // index of position in prd vec
632 SegmentData& mdt_hit = collected_data[j];
633 mdt_hit.onsegment = 1;
634 mdt_hit.psi = angleDif;
635 ++number_of_hots_per_layer[mdt_hit.layer_number];
636
637 // remove hit from dcs container for next iteration!!
638 dcs.erase(dcs.begin() + i - removed_hits);
639 ++removed_hits;
640 }
641 }
642 } else {
643 seg_found = false;
644 }
645 }
646
647 // trigger confirmation checks:
648
649 int stationcode = stationCode(collected_data[0].id());
650 const bool barrel = idHelper.isBarrel(collected_data[0].id());
651 // rpc:
652
653 std::map<int, std::vector<std::pair<int, int>>>::const_iterator stationmap_it = rpcmdtstationmap.find(stationcode);
654
655 if (stationmap_it != rpcmdtstationmap.end()) {
656 const std::vector<std::pair<int, int>>& stationhits = (*stationmap_it).second;
657
658 // stationloop
659 for (unsigned int i = 0; i < stationhits.size(); i++) {
660 // rpc hit loop
661 for (int j = stationhits[i].first; j < stationhits[i].second; j++) {
662 const std::shared_ptr<MuonHoughHit> rpchit = hitcontainer.getHit(j);
663 if (rpchit->getWeight() < 0.01) continue;
664 const Amg::Vector3D& rpcPos = rpchit->getPosition();
665 const double rpc_radius = rpcPos.perp();
666 const double rpc_rz_ratio = rpc_radius / rpcPos.z();
667 const double rpc_inv_rz_ratio = 1. / rpc_rz_ratio;
668
669 for (SegmentData& mdt_hit : collected_data) {
670 // Mdt hit loop
671 double dis = 0.;
672 const Amg::Vector3D& globalpos = mdt_hit.prd->globalPosition();
673 if (barrel) {
674 dis = globalpos.z() - globalpos.perp() * rpc_inv_rz_ratio;
675 } else { // can that happen?
676 dis = globalpos.perp() - rpc_rz_ratio * globalpos.z();
677 }
678
680
681 if (std::abs(dis) < 250.) {
682 double wnew = 1.5 + (250. - std::abs(dis)) / 251.;
683 mdt_hit.weighted_trigger = std::max(mdt_hit.weighted_trigger, wnew);
684 }
685 }
686 }
687 }
688 }
689
690 // tgc:
691
692 stationmap_it = tgcmdtstationmap.find(stationcode);
693
694 if (stationmap_it != tgcmdtstationmap.end()) {
695 const std::vector<std::pair<int, int>>& stationhits = (*stationmap_it).second;
696
697 // stationloop
698 for (unsigned int i = 0; i < stationhits.size(); i++) {
699 // tgc hit loop
700 for (int j = stationhits[i].first; j < stationhits[i].second; j++) {
701 const std::shared_ptr<MuonHoughHit> tgchit = hitcontainer.getHit(j);
702 if (!tgchit || tgchit->getWeight() < 0.01) continue;
703 const Amg::Vector3D& tgcPos = tgchit->getPosition();
704 const double tgc_rz_ratio = tgcPos.perp() / tgcPos.z();
705
706 for (SegmentData& mdt_hit : collected_data) {
707 // Mdt hit loop
708 if (mdt_hit.weighted_trigger < 0.1) mdt_hit.weighted_trigger = 3.;
709 const Amg::Vector3D& globalpos = mdt_hit.prd->globalPosition();
710 double dis = globalpos.perp() - tgc_rz_ratio * globalpos.z(); // only endcap extrapolation
711 if (std::abs(dis) < 250.) {
712 double wnew = 3.5 + (250. - std::abs(dis)) / 251.;
713 mdt_hit.weighted_trigger = std::max(mdt_hit.weighted_trigger, wnew);
714 }
715 }
716 }
717 }
718 }
719
720 // define trigger confirmation:
721
722 for (SegmentData& mdt_hit : collected_data) {
723 // for MDTs require trigger chamber confirmation
724 // or segment with selected hits
725
726 mdt_hit.tr_confirmation = (mdt_hit.weighted_trigger > 1.5 && mdt_hit.weighted_trigger < 2.55) ||
727 (mdt_hit.weighted_trigger > 3.5 && mdt_hit.weighted_trigger < 4.55);
728
729 // add confirmed hits to hots layer count:
730 if (mdt_hit.tr_confirmation && !mdt_hit.onsegment) { // else already added
731 ++number_of_hots_per_layer[mdt_hit.layer_number];
732 }
733 }
734
735 // calculate final weights:
736
737 for (SegmentData& mdt_hit : collected_data) {
738 if (mdt_hit.prob < 0.01) {
739 mdt_hit.weights = 0;
740 continue;
741 } // throw away hits that are not significant
742
743 // correct for several number of hits in layer:
744 std::map<int, int>::const_iterator map_it = nHitsPerLayer.find(mdt_hit.layer_number);
745 if (map_it != nHitsPerLayer.end()) {
746 int layerhits = (*map_it).second;
747 double layer_weight = 1. / (0.25 * layerhits + 0.75 * std::sqrt(layerhits));
748
749 if (!mdt_hit.tr_confirmation && !mdt_hit.onsegment) {
750 // downweighting for non-confirmed hits:
751 mdt_hit.prob = std::max(0., mdt_hit.prob - 0.2);
752 // correct for several number of hits in layer:
753 mdt_hit.weights = mdt_hit.prob * layer_weight;
754 }
755
756 else {
757 // Correct probabilities for hits on segment or confirmed by RPC/TGC
758 double rej = 1. / (1. - layer_weight + 0.10);
759 double rej0 = 1.; // irrevelant value
760
761 if (mdt_hit.onsegment && mdt_hit.tr_confirmation) {
762 rej0 = 30;
763 } else if (mdt_hit.onsegment) {
764 rej0 = 1.75 / (mdt_hit.psi + 0.05);
765 } // 1.75 = 5*0.35
766 else if (mdt_hit.tr_confirmation) {
767 rej0 = 8;
768 }
769
770 double rej_total = rej * rej0;
771 mdt_hit.prob = rej_total / (1. + rej_total);
772
773 // correct for several number of confirmed hits in layer:
774 map_it = number_of_hots_per_layer.find(mdt_hit.layer_number);
775 if (map_it != number_of_hots_per_layer.end()) {
776 int layerhits_conf = (*map_it).second;
777 mdt_hit.weights = mdt_hit.prob / (0.25 * layerhits_conf + 0.75 * std::sqrt(layerhits_conf));
778 } else {
779 ATH_MSG_INFO("Entry not in map! This should not happen");
780 mdt_hit.weights = mdt_hit.prob;
781 }
782 }
783 } else {
784 ATH_MSG_INFO("Entry not in map! This should not happen");
785 mdt_hit.weights = mdt_hit.prob;
786 }
787
789
790 ATH_MSG_DEBUG(m_printer->print(*mdt_hit.prd)
791 << " trigger weight " << mdt_hit.weighted_trigger << " on segment " << mdt_hit.onsegment << " psi " << mdt_hit.psi
792 << " prob " << mdt_hit.prob << " weight " << mdt_hit.weights);
793 hitcontainer.addHit(new_mdt_hit(mdt_hit.prd, mdt_hit.prob, mdt_hit.weights));
794 if (m_use_histos) {
795 Hists& h = getHists();
796 h.m_weighthistogram->Fill(mdt_hit.weights);
797 h.m_weighthistogrammdt->Fill(mdt_hit.weights);
798 }
799
800 } // collection
801 }
802 template <class CollContainer> void MuonHoughPatternFinderTool::addCollections(const std::vector<const CollContainer*>& colls,
803 MuonHoughHitContainer& hitcontainer,
804 EtaPhiHitAssocMap& phietahitassociation) const {
805 for (const auto* cont_ptr : colls) addCollection(*cont_ptr, hitcontainer, phietahitassociation);
806 }
807 template <class CollContainer> void MuonHoughPatternFinderTool::addCollection(const CollContainer& cont,
808 MuonHoughHitContainer& hitcontainer,
809 EtaPhiHitAssocMap& phietahitassociation) const{
810 if (cont.empty()) return;
811 std::map<Identifier, unsigned> nHitsPerLayer{};
812 hitcontainer.reserve(cont.size() + hitcontainer.size());
814 unsigned channel_max{0};
815
816 if constexpr (std::is_same<CollContainer, CscPrepDataCollection>::value) {
817 channel_max = m_idHelperSvc->cscIdHelper().stripMax();
818 } else if constexpr (std::is_same<CollContainer, TgcPrepDataCollection>::value) {
819 channel_max = m_idHelperSvc->tgcIdHelper().channelMax();
820 } else if constexpr (std::is_same<CollContainer, RpcPrepDataCollection>::value) {
821 channel_max = m_idHelperSvc->rpcIdHelper().stripMax();
822 } else if constexpr(std::is_same<CollContainer, sTgcPrepDataCollection>::value) {
825 channel_max = m_idHelperSvc->stgcIdHelper().channelMax(cont.front()->identify()) * 3;
826 } else if constexpr(std::is_same<CollContainer, MMPrepDataCollection>::value) {
827 channel_max = m_idHelperSvc->mmIdHelper().channelMax(cont.front()->identify());
828 }
829
830 auto layer_channel = [this](const Identifier& id) {
831 if constexpr (std::is_same<CollContainer, CscPrepDataCollection>::value) {
832 return m_idHelperSvc->cscIdHelper().channel(id);
833 } else if constexpr(std::is_same<CollContainer, TgcPrepDataCollection>::value) {
834 return m_idHelperSvc->tgcIdHelper().channel(id);
835 } else if constexpr(std::is_same<CollContainer, RpcPrepDataCollection>::value) {
836 return m_idHelperSvc->rpcIdHelper().channel(id);
837 } else if constexpr(std::is_same<CollContainer, sTgcPrepDataCollection>::value) {
838 return m_idHelperSvc->stgcIdHelper().channel(id);
839 } else if constexpr(std::is_same<CollContainer, MMPrepDataCollection>::value) {
840 return m_idHelperSvc->mmIdHelper().channel(id);
841 }
842 return 1;
843 };
844
845 std::set<int> layers{};
846
847 auto layer_number = [this, &layers]( const Identifier& id ) -> int{
848 if constexpr (std::is_same<CollContainer,RpcPrepDataCollection>::value) {
849 const int n_gasGaps = m_idHelperSvc->rpcIdHelper().gasGapMax(id);
850 const int n_doubR = m_idHelperSvc->rpcIdHelper().doubletRMax(id);
851 return n_gasGaps* (m_idHelperSvc->rpcIdHelper().doubletR(id) - 1) +
852 (m_idHelperSvc->rpcIdHelper().gasGap(id) -1) + n_doubR*n_gasGaps*m_idHelperSvc->measuresPhi(id);
853 } else if constexpr(std::is_same<CollContainer,TgcPrepDataCollection>::value) {
854 const int n_gasGaps = m_idHelperSvc->tgcIdHelper().gasGapMax(id);
855 return (m_idHelperSvc->tgcIdHelper().gasGap(id) - 1) + n_gasGaps * m_idHelperSvc->measuresPhi(id);
856 } else if constexpr(std::is_same<CollContainer,CscPrepDataCollection>::value) {
857 const int n_layer = m_idHelperSvc->cscIdHelper().chamberLayerMax(id);
858 const int n_chlay = m_idHelperSvc->cscIdHelper().wireLayerMax(id);
859 return n_layer*(m_idHelperSvc->cscIdHelper().wireLayer(id) -1) +
860 (m_idHelperSvc->cscIdHelper().chamberLayer(id) -1) + n_layer*n_chlay * m_idHelperSvc->measuresPhi(id);
861 } else if constexpr(std::is_same<CollContainer,sTgcPrepDataCollection>::value) {
862 const int n_lay = m_idHelperSvc->stgcIdHelper().gasGapMax(id);
863 const int n_chtype = m_idHelperSvc->stgcIdHelper().channelTypeMax(id);
864 return n_chtype*n_lay*(m_idHelperSvc->stgcIdHelper().multilayer(id) - 1) +
865 n_lay*(m_idHelperSvc->stgcIdHelper().channelType(id) -1) +
866 (m_idHelperSvc->stgcIdHelper().gasGap(id) -1);
867 } else if constexpr(std::is_same<CollContainer,MMPrepDataCollection>::value) {
868 const int n_lay = m_idHelperSvc->mmIdHelper().gasGapMax(id);
869 return n_lay*(m_idHelperSvc->mmIdHelper().multilayer(id) - 1) +
870 (m_idHelperSvc->mmIdHelper().gasGap(id) -1);
871 }
872 ATH_MSG_VERBOSE("Layer numbers not implemented for "<<m_idHelperSvc->toString(id));
873 return static_cast<int>(layers.size());
874 };
875
876
877 std::vector<float> channelWeights;
878
880 if (!m_hit_reweights) {
881 channelWeights.assign(2*channel_max + 2, 2.);
882 } else {
883 channelWeights.assign(2*channel_max + 2, 0);
884 for (const auto* prd : cont) {
885 const bool measures_phi = m_idHelperSvc->measuresPhi(prd->identify());
886 layers.insert(layer_number(prd->identify()));
888 if constexpr (std::is_same<CollContainer, sTgcPrepDataCollection>::value ||
889 std::is_same<CollContainer, MMPrepDataCollection>::value) {
890 for (uint16_t ch : prd->stripNumbers()) {
891 const int channel = ch + measures_phi * channel_max;
892 channelWeights.at(channel -1) += 0.55;
893 channelWeights.at(channel) += 1.;
894 channelWeights.at(channel + 1) +=0.55;
895 }
896 } else {
898 const int channel = layer_channel(prd->identify()) + measures_phi * channel_max;
899 channelWeights[channel -1] += 0.55;
900 channelWeights[channel] += 1.;
901 channelWeights[channel + 1] +=0.55;
902 }
903 }
904 }
905
906 std::map<Identifier, PrepDataSet> gasgapphimap{};
907 for (const auto* prd : cont) {
908 const bool measures_phi = m_idHelperSvc->measuresPhi(prd->identify());
909 const int channel = layer_channel(prd->identify()) + measures_phi * channel_max;
911 nHitsPerLayer[m_idHelperSvc->layerId(prd->identify())] += layers.size() > 1 && (channelWeights[channel] > 1.);
912
913 if (!measures_phi) continue;
914 gasgapphimap[m_idHelperSvc->gasGapId(prd->identify())].insert(prd);
915 }
916
918 if constexpr(std::is_same<CollContainer, TgcPrepDataCollection>::value) {
919 det_tech = MuonHough::TGC;
920 } else if constexpr(std::is_same<CollContainer, RpcPrepDataCollection>::value) {
921 det_tech = MuonHough::RPC;
922 }
924 for (const auto* prd : cont) {
925 double weight = 1.;
926 if (m_hit_reweights) {
927 double number_of_hits = nHitsPerLayer[m_idHelperSvc->layerId(prd->identify())];
928 weight = number_of_hits ? 1. / (0.25 * std::sqrt(number_of_hits) + 0.75 * number_of_hits) : 0.;
929 if( layers.size() == 2) weight /= 2.;
930 }
931
932 const Identifier id = prd->identify();
933 const bool measuresPhi = m_idHelperSvc->measuresPhi(id);
934
935 std::shared_ptr<MuonHoughHit> hit = std::make_shared<MuonHoughHit>(prd->globalPosition(),
936 measuresPhi, det_tech, (weight > 0.), weight, prd);
937
938 hitcontainer.addHit(hit);
939 ATH_MSG_DEBUG(m_printer->print(*prd) << " weight " << weight);
940 if (m_use_histos) {
941 Hists& h = getHists();
942 h.m_weighthistogram->Fill(weight);
943 if constexpr (std::is_same<CollContainer, CscPrepDataCollection>::value) {
944 h.m_weighthistogramcsc->Fill(weight);
945 } else if constexpr(std::is_same<CollContainer, TgcPrepDataCollection>::value) {
946 h.m_weighthistogramtgc->Fill(weight);
947 } else if constexpr(std::is_same<CollContainer, RpcPrepDataCollection>::value) {
948 h.m_weighthistogramrpc->Fill(weight);
949 } else if constexpr(std::is_same<CollContainer, sTgcPrepDataCollection>::value) {
950 h.m_weighthistogramstgc->Fill(weight);
951 } else if constexpr(std::is_same<CollContainer, MMPrepDataCollection>::value) {
952 h.m_weighthistogrammm->Fill(weight);
953 }
954 }
955 if (!measuresPhi) {
956 const PrepDataSet& phi_prds = gasgapphimap[m_idHelperSvc->gasGapId(prd->identify())];
957 if (!phi_prds.empty()) phietahitassociation.insert(std::make_pair(prd, phi_prds));
958 }
959 }
960 }
961 void MuonHoughPatternFinderTool::updateRpcMdtStationMap(const Identifier rpcid, const int hit_begin, const int hit_end,
962 std::map<int, std::vector<std::pair<int, int>>>& rpcmdtstationmap) const {
963 // input is a RPC identifier, begin container and end container
964 // rpcmdtstationmap is updated
965 //
966 // called once per rpc collection/station
967
968 ATH_MSG_VERBOSE("updateRpcMdtStationMap" << m_idHelperSvc->toString(rpcid));
969 if (!m_idHelperSvc->isRpc(rpcid)) return;
970 std::map<int, std::vector<std::pair<int, int>>>::iterator it;
971 int stationcode = stationCode(rpcid);
972
973 // store station code
974
975 addToStationMap(rpcmdtstationmap, it, stationcode, hit_begin, hit_end);
976
977 int idphi = m_idHelperSvc->rpcIdHelper().stationPhi(rpcid);
978 int ideta = m_idHelperSvc->rpcIdHelper().stationEta(rpcid);
979
980 int idphi1 = idphi - 1;
981 if (idphi1 == 0) idphi1 = 8;
982 int idphi2 = idphi + 1;
983 if (idphi2 > 8) idphi2 = 1;
984
985 std::map<int, int>::const_iterator station_itr = m_RpcToMdtOuterStDict.find(m_idHelperSvc->rpcIdHelper().stationName(rpcid));
986 if (station_itr == m_RpcToMdtOuterStDict.end()) return;
987
988 // store Neighbouring station codes
989 int stationNameMDT = station_itr->second;
990
991 stationcode = stationCode(stationNameMDT, idphi1, ideta);
992 addToStationMap(rpcmdtstationmap, it, stationcode, hit_begin, hit_end);
993
994 stationcode = stationCode(stationNameMDT, idphi2, ideta);
995 addToStationMap(rpcmdtstationmap, it, stationcode, hit_begin, hit_end);
996
997 // Also look into Inner station
998
999 // std::map<int, int> m_RpcToMdtInnerStDict{};
1000 station_itr = m_RpcToMdtInnerStDict.find(m_idHelperSvc->rpcIdHelper().stationName(rpcid));
1001 if (station_itr == m_RpcToMdtInnerStDict.end()) return;
1002 stationNameMDT = station_itr->second;
1003 stationcode = stationCode(stationNameMDT, idphi, ideta);
1004 addToStationMap(rpcmdtstationmap, it, stationcode, hit_begin, hit_end);
1005 }
1006
1007 void MuonHoughPatternFinderTool::updateTgcMdtStationMap(const Identifier tgcid, int hit_begin, int hit_end,
1008 std::map<int, std::vector<std::pair<int, int>>>& tgcmdtstationmap) const {
1009 // input is a TGC identifier, begin container and end container
1010 // tgcmdtstationmap is updated
1011 //
1012 // called once per tgc collection/station
1013 std::string st = m_idHelperSvc->tgcIdHelper().stationNameString(m_idHelperSvc->tgcIdHelper().stationName(tgcid));
1014 if (st[0] != 'T') return;
1015
1016 constexpr std::array<int, 5> T31{2, 3, 3, 4, 4};
1017 constexpr std::array<int, 5> T32{3, 4, 4, 5, 5};
1018 constexpr std::array<int, 5> T11{2, 3, 4, 4, 4};
1019 constexpr std::array<int, 5> T12{3, 4, 5, 5, 5};
1020
1021 std::map<int, std::vector<std::pair<int, int>>>::iterator it;
1022
1023 // Determine station phi in MDT
1024
1025 int modphiTGC = 48;
1026 if (st[2] == 'F') modphiTGC = 24;
1027 if (st[1] == '4') modphiTGC = 24;
1028
1029 int idphi = m_idHelperSvc->tgcIdHelper().stationPhi(tgcid);
1030 int ideta = m_idHelperSvc->tgcIdHelper().stationEta(tgcid);
1031 int index = abs(ideta) - 1;
1032 int idphi1MDT = 1 + int(8. * (idphi + 1) / modphiTGC);
1033 int idphi2MDT = 1 + int(8. * (idphi - 1) / modphiTGC);
1034 if (idphi1MDT > 8) idphi1MDT = 1;
1035 if (idphi2MDT > 8) idphi2MDT = 1;
1036
1037 int sign = 1;
1038 if (ideta < 0) sign = -1;
1039
1040 // Determine two station etas in MDT
1041
1042 int ideta1MDT = 0;
1043 int ideta2MDT = 0;
1044 if (st[2] == 'F') {
1045 ideta1MDT = sign * 1;
1046 ideta2MDT = sign * 2;
1047 }
1048 if (st[2] == 'E') {
1049 if (st[1] == '4') {
1050 // T4
1051 ideta1MDT = sign * 4;
1052 ideta2MDT = sign * 5;
1053 } else if (st[1] == '3') {
1054 // T3
1055 ideta1MDT = sign * T31[index];
1056 ideta2MDT = sign * T32[index];
1057 } else {
1058 // T1 or T2
1059 ideta1MDT = sign * T11[index];
1060 ideta2MDT = sign * T12[index];
1061 }
1062 }
1063 std::string station1 = "EML";
1064 std::string station2 = "EMS";
1065 if (st[1] == '4') {
1066 station1 = "EIL";
1067 station2 = "EIS";
1068 }
1069 const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
1070 int stationNameMDT1 = idHelper.stationNameIndex(station1);
1071 int stationNameMDT2 = idHelper.stationNameIndex(station2);
1072
1073 // store station Inner and Middle codes
1074
1075 int stationcode = stationCode(stationNameMDT1, idphi1MDT, ideta1MDT);
1076 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1077 stationcode = stationCode(stationNameMDT2, idphi1MDT, ideta1MDT);
1078 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1079 if (ideta1MDT != ideta2MDT) {
1080 stationcode = stationCode(stationNameMDT1, idphi1MDT, ideta2MDT);
1081 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1082 stationcode = stationCode(stationNameMDT2, idphi1MDT, ideta2MDT);
1083 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1084 }
1085 if (idphi1MDT != idphi2MDT) {
1086 stationcode = stationCode(stationNameMDT1, idphi2MDT, ideta1MDT);
1087 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1088 stationcode = stationCode(stationNameMDT2, idphi2MDT, ideta1MDT);
1089 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1090 if (ideta1MDT != ideta2MDT) {
1091 stationcode = stationCode(stationNameMDT1, idphi2MDT, ideta2MDT);
1092 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1093 stationcode = stationCode(stationNameMDT2, idphi2MDT, ideta2MDT);
1094 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1095 }
1096 }
1097 // Store corresponding Outer stations
1098
1099 if (station1 == "EMS") { station1 = "EOS"; }
1100 if (station2 == "EML") {
1101 station2 = "EOL";
1102 } else
1103 return;
1104
1105 stationNameMDT1 = idHelper.stationNameIndex(station1);
1106 stationNameMDT2 = idHelper.stationNameIndex(station2);
1107
1108 stationcode = stationCode(stationNameMDT1, idphi1MDT, ideta1MDT);
1109 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1110 stationcode = stationCode(stationNameMDT2, idphi1MDT, ideta1MDT);
1111 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1112 if (ideta1MDT != ideta2MDT) {
1113 stationcode = stationCode(stationNameMDT1, idphi1MDT, ideta2MDT);
1114 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1115 stationcode = stationCode(stationNameMDT2, idphi1MDT, ideta2MDT);
1116 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1117 }
1118 if (idphi1MDT != idphi2MDT) {
1119 stationcode = stationCode(stationNameMDT1, idphi2MDT, ideta1MDT);
1120 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1121 stationcode = stationCode(stationNameMDT2, idphi2MDT, ideta1MDT);
1122 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1123
1124 if (ideta1MDT != ideta2MDT) {
1125 stationcode = stationCode(stationNameMDT1, idphi2MDT, ideta2MDT);
1126 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1127 stationcode = stationCode(stationNameMDT2, idphi2MDT, ideta2MDT);
1128 addToStationMap(tgcmdtstationmap, it, stationcode, hit_begin, hit_end);
1129 }
1130 }
1131 }
1132
1134 return stationCode(m_idHelperSvc->stationName(id), m_idHelperSvc->stationPhi(id),
1135 m_idHelperSvc->stationEta(id));
1136 }
1137
1138 int MuonHoughPatternFinderTool::stationCode(int stationname, int phi, int eta) {
1139 return 10000000 * stationname + 100000 * phi + 1000 * (eta + 10);
1140 }
1141
1142 void MuonHoughPatternFinderTool::addToStationMap(std::map<int, std::vector<std::pair<int, int>>>& stationmap,
1143 std::map<int, std::vector<std::pair<int, int>>>::iterator& it, int& stationcode,
1144 const int& hit_begin, const int& hit_end) {
1145 it = stationmap.find(stationcode);
1146 if (it == stationmap.end()) {
1147 std::vector<std::pair<int, int>> dummyvec;
1148 dummyvec.emplace_back(hit_begin, hit_end);
1149 stationmap[stationcode] = dummyvec;
1150 } else {
1151 (*it).second.emplace_back(hit_begin, hit_end);
1152 }
1153 }
1154
1155 void MuonHoughPatternFinderTool::fastSegmentFinder(TrkDriftCircleMath::DCVec& dcs, int& nl1, int& nl2, double& angleDif,
1156 std::vector<int>& sel) const {
1157 //
1158 // Input: vector of driftcircles per chamber
1159 // Output: nl1 = segment hits in multilayer 1 and nl2 = segment hits in
1160 // multilayer 2
1161 // : sel(1:dcs.size) = 0 NOT selected = 1 on segment
1162 //
1163 // Method: constructs the tangent lines to all driftcircle combinations and
1164 // counts hits in a road of 1.5 mm
1165 // segment = combination with most hits
1166 // uses TrkDriftCircleMath software
1167 //
1168
1169 // Layers with more than 10 hits are skipped as seed, if all layers have more
1170 // than 10 hits, no fits are tried
1171
1172 nl1 = 0;
1173 nl2 = 0;
1174 angleDif = -1.;
1175 if (dcs.empty()) return;
1176
1177 DCCit it_end = dcs.end();
1178 DCCit it1 = dcs.begin();
1179 std::map<int, DCVec> layerHits; // map between layer and driftcircles
1180 std::map<int, int> dcsId; // map between 'idnumber' and position
1181
1182 std::map<int, DCVec>::iterator map_it;
1183 int nhits = 0;
1184 for (; it1 != it_end; ++it1, nhits++) {
1185 sel[nhits] = 0;
1186 int isort = MdtIdHelper::maxNTubesPerLayer * (4 * (it1->id().ml()) + it1->id().lay()) + it1->id().tube();
1187 dcsId[isort] = nhits;
1188 int ilay = 4 * (it1->id().ml()) + it1->id().lay();
1189 ATH_MSG_VERBOSE(" ilay " << ilay << " isort " << isort);
1190
1191 map_it = layerHits.find(ilay);
1192 if (map_it != layerHits.end()) {
1193 (*map_it).second.push_back(*it1);
1194 } else {
1195 DCVec dcl;
1196 dcl.reserve(dcs.size());
1197 dcl.push_back(*it1);
1198 layerHits[ilay] = dcl;
1199 }
1200 }
1201
1202 unsigned int nHits = 0; // is maximalized
1203 unsigned int nHitsLine = 0;
1204 unsigned int nPassedTubes = 0;
1205 double roadWidth = 1.5;
1208 bool stop = false;
1209 for (int i = 0; i < 8; i++) {
1210 if (layerHits.count(i) != 1) continue;
1211 DCVec& dci = layerHits[i];
1212 if (dci.size() > 10) continue;
1213 DCCit iti = dci.begin();
1214 DCCit iti_end = dci.end();
1215 for (; iti != iti_end; ++iti) {
1216 // One seed selected
1217 float tubeRadius = 14.6;
1218 if ((*iti).rot()) { // if no access to rot, can't do anything here
1219 tubeRadius = (*iti).rot()->detectorElement()->innerTubeRadius();
1220 }
1221 for (int j = 7; j > i; j--) {
1222 if (layerHits.count(j) != 1) continue;
1223 DCVec& dcj = layerHits[j];
1224 if (dcj.size() > 10) continue;
1225 DCCit itj = dcj.begin();
1226 DCCit itj_end = dcj.end();
1227 for (; itj != itj_end; ++itj) {
1228 // Second seed selected
1229 double hitx = (*itj).x();
1230 double hity = (*itj).y();
1231 double norm = std::hypot(hitx, hity);
1232 double cphi = hitx / norm;
1233 double sphi = hity / norm;
1235 for (TrkDriftCircleMath::TangentToCircles::LineVec::const_iterator lit = lines.begin(); lit != lines.end(); ++lit) {
1236 double coshit = std::cos((*lit).phi());
1237 double sinhit = std::sin((*lit).phi());
1238 const double cospsi = std::min(std::max(-1.,coshit * cphi + sinhit * sphi), 1.);
1239 double psi = std::acos(cospsi);
1240 if (psi > 0.3) continue;
1241 matchWithLine.set(*lit, roadWidth, TrkDriftCircleMath::MatchDCWithLine::Road, tubeRadius);
1242 const TrkDriftCircleMath::DCOnTrackVec& hitsOnLine = matchWithLine.match(dcs);
1243 unsigned int matchedHits = matchWithLine.hitsOnTrack();
1244 ATH_MSG_VERBOSE(" Summary nHits " << matchedHits << " nl1 " << matchWithLine.hitsMl1() << " nl2 "
1245 << matchWithLine.hitsMl2());
1246 if (matchedHits > nHits || (matchedHits == nHits && psi < angleDif)) {
1247 int dnl = std::abs(static_cast<int>(matchWithLine.hitsMl1()) - static_cast<int>(matchWithLine.hitsMl2()));
1248 ATH_MSG_DEBUG(" matchWithLine.hitsOnTrack() > nHits old " << nHits << " new: " << matchedHits);
1249 ATH_MSG_DEBUG(" dnl " << dnl << " old dnl " << std::abs(nl1 - nl2));
1250 ATH_MSG_DEBUG(" hit cos phi " << cphi << " line " << coshit << " sin phi " << sphi << " line " << sinhit
1251 << " psi " << psi);
1252
1253 // update of variables:
1254 nHits = matchedHits;
1255 nl1 = matchWithLine.hitsMl1();
1256 nl2 = matchWithLine.hitsMl2();
1257 nHitsLine = hitsOnLine.size();
1258 nPassedTubes = matchWithLine.passedTubes();
1259 hitsOnLineSel = hitsOnLine;
1260 angleDif = psi;
1261 }
1262
1263 ATH_MSG_VERBOSE(" Select nHits " << nHits << " nl1 " << nl1 << " nl2 " << nl2);
1264 if (nHits >= dcs.size()) stop = true;
1265 } // end lines
1266 if (stop) break;
1267 } // end itj
1268 if (stop) break;
1269 } // end j
1270 if (stop) break;
1271 } // end iti
1272 if (stop) break;
1273 } // end i
1274
1275 ATH_MSG_DEBUG(" Fast segment finder Max Layers hit " << dcs.size() << " nHitsLine - nHits " << nHitsLine - nl1 - nl2
1276 << " passed Tubes -nHits " << nPassedTubes - nl1 - nl2 << " nl1 " << nl1
1277 << " nl2 " << nl2 << " angleDif " << angleDif);
1278
1279 TrkDriftCircleMath::DCOnTrackIt itt = hitsOnLineSel.begin();
1280 TrkDriftCircleMath::DCOnTrackIt itt_end = hitsOnLineSel.end();
1281 int i = 0;
1282 for (; itt != itt_end; ++itt, i++) {
1283 int isort = MdtIdHelper::maxNTubesPerLayer * (4 * (itt->id().ml()) + itt->id().lay()) + itt->id().tube();
1284 if (dcsId.count(isort) == 1) {
1285 int dcsIndex = dcsId[isort];
1286 sel[dcsIndex] = 1;
1287
1288 ATH_MSG_DEBUG(" Selected Hit index " << dcsIndex << " MultiLayer " << itt->id().ml() << " layer " << itt->id().lay()
1289 << " tube " << itt->id().tube());
1290 } else {
1291 ATH_MSG_WARNING(" ALARM fastSegmentFinder hit NOT found " << i << " isort " << isort);
1292 }
1293 }
1294 }
1295
1297 // We earlier checked that no more than one thread is being used.
1298 Hists* h ATLAS_THREAD_SAFE = m_h.get();
1299 return *h;
1300 }
1301
1302} // namespace Muon
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::vector< size_t > vec
static Double_t ss
static Double_t sc
std::vector< MuonHoughPatternContainer > MuonHoughPatternContainerShip
DataVector< Muon::MuonSegmentCombination > MuonSegmentCombinationCollection
This typedef represents a collection of MuonSegmentCombination objects.
static const uint32_t nHits
int sign(int a)
#define ATLAS_THREAD_SAFE
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
bool msgLvl(const MSG::Level lvl) const
const_iterator begin() const noexcept
size_type size() const noexcept
const_iterator end() const
return const_iterator for end of container
size_t size() const
Duplicate of fullSize for backwards compatability.
const_iterator begin() const
return const_iterator for first entry
int multilayer(const Identifier &id) const
Access to components of the ID.
int tube(const Identifier &id) const
static int tubeLayerMax()
int tubeLayer(const Identifier &id) const
static constexpr int maxNTubesPerLayer
The maxNTubesPerLayer represents the absolute maximum of tubes which are built into a single multilay...
Definition MdtIdHelper.h:68
int tubeMax() const
int getNLayers() const
Returns the number of tube layers inside the multilayer.
int getNtubesperlayer() const
Returns the number of tubes in each tube layer.
unsigned int size() const
returns size of hitcontainer
std::shared_ptr< MuonHoughHit > getHit(int hitno) const
returns Hit at position hitno
void reserve(int size)
allocates memory for hitvector
void addHit(const std::shared_ptr< MuonHoughHit > &hit)
add hit to container
int stationNameIndex(const std::string &name) const
bool isBarrel(const Identifier &id) const
Class to represent the calibrated clusters created from CSC strips.
virtual const CscPrepData * prepRawData() const override final
Returns the CscPrepData - is a CscPrepData in this scope.
Class representing clusters from the CSC.
Definition CscPrepData.h:39
Class to represent measurements from the Monitored Drift Tubes.
Definition MdtPrepData.h:33
int adc() const
Returns the ADC (typically range is 0 to 250)
virtual const MuonGM::MdtReadoutElement * detectorElement() const override
Returns the detector element corresponding to this PRD.
MdtDriftCircleStatus status() const
Returns the status of the measurement.
virtual const Amg::Vector3D & globalPosition() const
Returns the global position of the CENTER of the drift tube (i.e.
void fastSegmentFinder(TrkDriftCircleMath::DCVec &dcs, int &nl1, int &nl2, double &angleDif, std::vector< int > &sel) const
finds best segment for given driftcircle vector (nl1/2 = number of dc's in ml 1 and 2,...
IMuonCombinePatternTool::PrepDataSet PrepDataSet
void addTgcCollection(const Muon::TgcPrepDataCollection *, MuonHoughHitContainer &hitcontainer, std::map< int, std::vector< std::pair< int, int > > > &tgcmdtstationmap, EtaPhiHitAssocMap &phietahitassociation) const
convert and add tgc preprawdata collection (1 chamber)
std::map< int, int > m_RpcToMdtOuterStDict
Dictionary to translate from the RPC to the MDT station names.
Gaudi::Property< bool > m_use_rpc
use rpc preprawdata (true)
void updateTgcMdtStationMap(const Identifier tgcid, int hit_begin, int hit_end, std::map< int, std::vector< std::pair< int, int > > > &tgcmdtstationmap) const
update station map for tgc chamber, with id of chamber, and size of hits in tgc chamber
std::unique_ptr< MuonHoughHitContainer > getAllHits(const std::vector< const MdtPrepDataCollection * > &mdtCols, const std::vector< const TgcPrepDataCollection * > &tgcCols, const std::vector< const RpcPrepDataCollection * > &rpcCols, const MuonSegmentCombinationCollection *cscSegmentCombis, std::map< int, std::vector< std::pair< int, int > > > &rpcmdtstationmap, std::map< int, std::vector< std::pair< int, int > > > &tgcmdtstationmap, EtaPhiHitAssocMap &phietahitassociation) const
retrieves all hits and converts them into internal EDM
void addMdtCollection(const MdtPrepDataCollection *mdt_coll, MuonHoughHitContainer &hitcontainer, std::map< int, std::vector< std::pair< int, int > > > &rpcmdtstationmap, std::map< int, std::vector< std::pair< int, int > > > &tgcmdtstationmap) const
convert and add mdt preprawdata collection (1 chamber)
virtual StatusCode initialize() override
initialize
Gaudi::Property< bool > m_use_mdt
use mdt preprawdata (true)
Gaudi::Property< bool > m_showerskip
reduce cpu for showers (true)
int stationCode(const Identifier &id) const
calculates an unique stationcode integer (own convention)
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
void addRpcCollection(const RpcPrepDataCollection *rpc_coll, MuonHoughHitContainer &hitcontainer, std::map< int, std::vector< std::pair< int, int > > > &rpcmdtstationmap, EtaPhiHitAssocMap &phietahitassociation) const
convert and add rpc preprawdata collection (1 chamber)
void updateRpcMdtStationMap(const Identifier rpcid, int hit_begin, int hit_end, std::map< int, std::vector< std::pair< int, int > > > &rpcmdtstationmap) const
update station map for rpc chamber, with id of chamber, and size of hits in rpc chamber
MuonPatternHoughPair find(const std::vector< const MdtPrepDataCollection * > &mdtCols, const std::vector< const CscPrepDataCollection * > &cscCols, const std::vector< const TgcPrepDataCollection * > &tgcCols, const std::vector< const RpcPrepDataCollection * > &rpcCols, const MuonSegmentCombinationCollection *cscSegmentCombis, const EventContext &ctx) const override
find patterns for a give set of MuonPrepData collections + optionally CSC segment combinations
Gaudi::Property< int > m_mdt_adc_min
value of adc cut (50)
Gaudi::Property< bool > m_mdt_adc_cut
use adc cut (true)
virtual ~MuonHoughPatternFinderTool()
destructor
Gaudi::Property< bool > m_use_tgc
use tgc preprawdata (true)
Gaudi::Property< bool > m_use_csc
use csc preprawdata (true)
std::pair< std::unique_ptr< MuonPatternCombinationCollection >, std::unique_ptr< Muon::HoughDataPerSectorVec > > MuonPatternHoughPair
Gaudi::Property< double > m_showerskipperc
percentage of occupancy to skip MDT chamber (0.3)
Gaudi::Property< bool > m_hit_reweights
reweight hits (true)
Gaudi::Property< bool > m_use_histos
flag to output a root file to study the weights of hits
ToolHandle< Muon::IMuonCombinePatternTool > m_muonCombinePatternTool
Pointer to concrete tool.
MuonHoughPatternFinderTool(const std::string &, const std::string &, const IInterface *)
constructor
std::vector< const MuonPrepDataCollection< T > * > stdVec(const MuonPrepDataContainerT< T > *cont) const
Gaudi::Property< bool > m_recordAllOutput
flag to write out intermediate patterns
IMuonCombinePatternTool::EtaPhiHitAssocMap EtaPhiHitAssocMap
Gaudi::Property< bool > m_mdt_tdc_cut
use tdc cut (false)
PublicToolHandle< Muon::MuonEDMPrinterTool > m_printer
static void addToStationMap(std::map< int, std::vector< std::pair< int, int > > > &stationmap, std::map< int, std::vector< std::pair< int, int > > >::iterator &it, int &stationcode, const int &hit_begin, const int &hit_end)
double m_weight_csc_on_segment
use weight for csc segments
void addCollection(const CollContainer &cont, MuonHoughHitContainer &hitcontainer, EtaPhiHitAssocMap &phietahitassociation) const
Inserts the Prds into the Hough container & fills the eta phi association map.
SG::WriteHandleKey< MuonPrdPatternCollection > m_COMBINED_PATTERNSKey
void record(std::unique_ptr< MuonPrdPatternCollection > &patCol, const SG::WriteHandleKey< MuonPrdPatternCollection > &key, const EventContext &ctx) const
record patterncollection to storegate or deletes collection when m_recordAllOutput is false
std::unique_ptr< MuonPatternCombinationCollection > analyse(const EventContext &ctx, const MuonHoughHitContainer &hitcontainer, const EtaPhiHitAssocMap &phietahitassociation) const
analyse hits
SG::WriteHandleKey< MuonPrdPatternCollection > m_CosmicEtaPatternsKey
virtual StatusCode finalize() override
finalize
SG::WriteHandleKey< MuonPrdPatternCollection > m_CosmicPhiPatternsKey
void addCollections(const std::vector< const CollContainer * > &colls, MuonHoughHitContainer &hitcontainer, EtaPhiHitAssocMap &phietahitassociation) const
ToolHandle< IMuonHoughPatternTool > m_muonHoughPatternTool
Pointer to concrete tool.
Gaudi::Property< bool > m_summary
flag to print out a summary of what comes in and what comes out
Template to hold collections of MuonPrepRawData objects.
Class to hold a set of MuonSegments belonging together.
Property holding a SG store/key/clid from which a WriteHandle is made.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
This class represents a drift time measurement.
Definition DriftCircle.h:22
@ InTime
drift time too small to be compatible with drift spectrum
Definition DriftCircle.h:27
Implementation of 2 dimensional vector class.
Definition LocVec2D.h:16
const DCOnTrackVec & match(const DCVec &dcs)
void set(const Line &l, double deltaCut, MatchStrategy strategy, double tubeRadius)
static LineVec tangentLines(const DriftCircle &dc1, const DriftCircle &dc2)
Identifier identify() const
return the identifier -extends MeasurementBase
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
Eigen::Matrix< double, 3, 1 > Vector3D
DetectorTechnology
enum to identify the muondetectortechnology
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
MuonPrepDataCollection< TgcPrepData > TgcPrepDataCollection
MuonPrepDataContainerT< RpcPrepData > RpcPrepDataContainer
MuonPrepDataContainer< MuonPrepDataCollection< PrdType > > MuonPrepDataContainerT
MuonPrepDataContainerT< TgcPrepData > TgcPrepDataContainer
MuonPrepDataContainerT< MdtPrepData > MdtPrepDataContainer
MuonPrepDataContainerT< sTgcPrepData > sTgcPrepDataContainer
@ MdtStatusDriftTime
The tube produced a vaild measurement.
MuonPrepDataContainerT< MMPrepData > MMPrepDataContainer
MuonPrepDataCollection< MdtPrepData > MdtPrepDataCollection
MuonHoughPatternFinderTool::MuonPatternHoughPair MuonPatternHoughPair
MuonPrepDataContainerT< CscPrepData > CscPrepDataContainer
MuonPrepDataCollection< RpcPrepData > RpcPrepDataCollection
Function object to check whether two Segments are sub/super sets or different.
DCVec::const_iterator DCCit
std::vector< DriftCircle > DCVec
DCOnTrackVec::iterator DCOnTrackIt
Definition DCOnTrack.h:60
std::vector< DCOnTrack > DCOnTrackVec
Definition DCOnTrack.h:59
Definition index.py:1
pointer to the CSC segment combination collection
const Muon::MdtPrepData * prd
double radius() const
Identifier of the PRD.