ATLAS Offline Software
Loading...
Searching...
No Matches
FPGATrackSimMatrixGenAlgo.cxx
Go to the documentation of this file.
1// Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
9
10
11#include "GaudiKernel/MsgStream.h"
12#include "GaudiKernel/ITHistSvc.h"
20
21#include "TH1.h"
22#include "TH2.h"
23#include "TStyle.h"
24
25#include <cassert>
26#include <sstream>
27#include <iostream>
28#include <fstream>
29#include <cmath>
30#include <utility>
31
32
34// Constructors
36
37FPGATrackSimMatrixGenAlgo::FPGATrackSimMatrixGenAlgo(const std::string& name, ISvcLocator* pSvcLocator) :
38 AthAlgorithm(name, pSvcLocator)
39{
40}
41
42
43
45// Initialize
47
49{
50 ATH_MSG_DEBUG("initialize()");
51
52 // set the slicing variables from inputs
53 m_sliceMax.qOverPt = m_temp_c_max;
58
59 m_sliceMin.qOverPt = m_temp_c_min;
64
65 m_nBins.qOverPt = m_temp_c_slices;
70
71 // Retrieve handles
72 ATH_CHECK(m_tHistSvc.retrieve());
74 ATH_CHECK(m_hitInputTool.retrieve());
75 ATH_CHECK(m_hitMapTool.retrieve());
76 ATH_CHECK(m_EvtSel.retrieve());
77 ATH_CHECK(m_roadFinderTool.retrieve());
80 ATH_CHECK(m_trackExtensionTool.retrieve(EnableTool{m_doHoughConstants && m_doSecondStage}));
81 ATH_CHECK(m_trackFitterTool_1st.retrieve(EnableTool{m_doHoughConstants && m_doSecondStage}));
82 ATH_CHECK(m_overlapRemovalTool.retrieve(EnableTool{m_doHoughConstants && m_doSecondStage}));
83
84
85
87 if (m_ideal_geom == 0) {
88 ATH_MSG_INFO("Hough constants method needs idealized geometry > 0, aborting.");
89 return StatusCode::FAILURE;
90 }
91 m_nRegions = m_FPGATrackSimMapping->RegionMap_1st()->getNRegions();
92 m_pmap_2nd = m_FPGATrackSimMapping->PlaneMap_2nd(0);
93 m_pmap_1st = m_FPGATrackSimMapping->PlaneMap_1st(0);
94 // Get detector configurations
95 m_nLayers_1st = m_FPGATrackSimMapping->PlaneMap_1st(0)->getNLogiLayers();
96 m_nDim_1st = m_FPGATrackSimMapping->PlaneMap_1st(0)->getNCoords();
97 m_nLayers_2nd = m_FPGATrackSimMapping->PlaneMap_2nd(0)->getNLogiLayers();
98 m_nDim_2nd = m_FPGATrackSimMapping->PlaneMap_2nd(0)->getNCoords();
99 }
100 else {
101 // Get detector configurations
102 m_nLayers_1st = m_FPGATrackSimMapping->PlaneMap_2nd(0)->getNLogiLayers();
103 m_nRegions = m_FPGATrackSimMapping->RegionMap_2nd()->getNRegions();
104 m_nDim_1st = m_FPGATrackSimMapping->PlaneMap_2nd(0)->getNCoords();
105 }
106
107 m_sector_cum.resize(m_nRegions);
108
109 // Retrieve slice information
110 m_sliceMin = m_EvtSel->getMin();
111 m_sliceMax = m_EvtSel->getMax();
112
113 // Check q/pt binning information
114 if (m_qOverPtBins.size() == 0) {
115 ATH_MSG_ERROR("q/pt bin information not set in matrix element job options!");
116 return StatusCode::FAILURE;
117 }
118
119
120 // Histograms
122
124
125 return StatusCode::SUCCESS;
126}
127
128
130{
131 // Training tracks
132 for (unsigned i = 0; i < FPGATrackSimTrackPars::NPARS; i++) {
133 std::string name = "h_trainingTrack_" + FPGATrackSimTrackPars::parName(i);
134 std::string title = FPGATrackSimTrackPars::parName(i) + " of tracks passing pt/barcode check";
135
136 m_h_trainingTrack[i] = new TH1I(name.c_str(), title.c_str(), 100, m_sliceMin[i], m_sliceMax[i]);
137 ATH_CHECK(m_tHistSvc->regHist("/TRIGFPGATrackSimMATRIXOUT/" + name, m_h_trainingTrack[i]));
138 }
139
140 // Sector pars
141 for (unsigned i = 0; i < FPGATrackSimTrackPars::NPARS; i++) {
142
143 std::string name = "h_sectorPars_" + FPGATrackSimTrackPars::parName(i);
144 std::string title = "Average " + FPGATrackSimTrackPars::parName(i) + " in sector";
145
146 m_h_sectorPars[i] = new TH1I(name.c_str(), title.c_str(), 100, m_sliceMin[i], m_sliceMax[i]);
147 ATH_CHECK(m_tHistSvc->regHist("/TRIGFPGATrackSimMATRIXOUT/" + name, m_h_sectorPars[i]));
148 }
149
150 // Select hit failure
151 for (unsigned i = 0; i < FPGATrackSimTrackPars::NPARS; i++) {
152
153 std::string name = "h_SHfailure_" + FPGATrackSimTrackPars::parName(i);
154 std::string title = FPGATrackSimTrackPars::parName(i) + " of tracks failing in selectHit()";
155
156 m_h_SHfailure[i] = new TH1I(name.c_str(), title.c_str(), 100, m_sliceMin[i], m_sliceMax[i]);
157 ATH_CHECK(m_tHistSvc->regHist("/TRIGFPGATrackSimMATRIXOUT/" + name, m_h_SHfailure[i]));
158 }
159
160 // 3 hits in layer
161 for (unsigned i = 0; i < FPGATrackSimTrackPars::NPARS; i++) {
162
163 std::string name = "h_3hitsInLayer_" + FPGATrackSimTrackPars::parName(i);
164 std::string title = FPGATrackSimTrackPars::parName(i) + " of tracks containing 3+ hits in a single layer";
165
166 m_h_3hitsInLayer[i] = new TH1I(name.c_str(), title.c_str(), 100, m_sliceMin[i], m_sliceMax[i]);
167 ATH_CHECK(m_tHistSvc->regHist("/TRIGFPGATrackSimMATRIXOUT/" + name, m_h_3hitsInLayer[i]));
168 }
169
170 // Not enough hits
171 for (unsigned i = 0; i < FPGATrackSimTrackPars::NPARS; i++) {
172 std::string name = "h_notEnoughHits_" + FPGATrackSimTrackPars::parName(i);
173 std::string title = FPGATrackSimTrackPars::parName(i) + " of tracks failing because it didn't have enough hits";
174
175 m_h_notEnoughHits[i] = new TH1I(name.c_str(), title.c_str(), 100, m_sliceMin[i], m_sliceMax[i]);
176 ATH_CHECK(m_tHistSvc->regHist("/TRIGFPGATrackSimMATRIXOUT/" + name, m_h_notEnoughHits[i]));
177 }
178
179 m_h_trackQoP_okHits = new TH1I("h_trackQoP_okHits", "half inverse pt of tracks passing hit check",
180 m_nBins.qOverPt, m_sliceMin.qOverPt, m_sliceMax.qOverPt);
181 m_h_trackQoP_okRegion = new TH1I("h_trackQoP_okRegion", "half inverse pt of tracks passing region check",
182 m_nBins.qOverPt, m_sliceMin.qOverPt, m_sliceMax.qOverPt);
183 m_h_nHit = new TH1I("h_nHit", "number of hits in sector", 100, 0, 100);
184
185 ATH_CHECK(m_tHistSvc->regHist("/TRIGFPGATrackSimMATRIXOUT/h_trackQoP_okHits", m_h_trackQoP_okHits));
186 ATH_CHECK(m_tHistSvc->regHist("/TRIGFPGATrackSimMATRIXOUT/h_trackQoP_okRegion", m_h_trackQoP_okRegion));
187 ATH_CHECK(m_tHistSvc->regHist("/TRIGFPGATrackSimMATRIXOUT/h_nHit",m_h_nHit));
188
189 return StatusCode::SUCCESS;
190}
191
193{
194 FPGATrackSimTrackPars pars = track.getPars();
195 for (unsigned i = 0; i < FPGATrackSimTrackPars::NPARS; i++)
196 hists[i]->Fill(pars[i]);
197}
198
200// Execute
202
203
205{
206 ATH_MSG_DEBUG("execute()");
207 m_eventHeader->clearHits();
208 m_eventHeader->reset();
209 // Get hits and training tracks from this event
210 ATH_CHECK(m_hitInputTool->readData(m_eventHeader, Gaudi::Hive::currentContext()));
211
212 std::vector<FPGATrackSimHit> hits = getLogicalHits();
213
214 std::vector<FPGATrackSimTruthTrack> truth_tracks = m_eventHeader->optional().getTruthTracks();
215 std::vector<FPGATrackSimTruthTrack> tracks = filterTrainingTracks(truth_tracks);
216 m_nTracks += truth_tracks.size();
217 if (tracks.empty()) {
218 ATH_MSG_DEBUG("Empty training tracks");
219 return StatusCode::SUCCESS;
220 }
221 // Prepare a map of the hits according the barcode
222 std::map<int, std::vector<FPGATrackSimHit>> barcode_hits = makeBarcodeMap(hits, tracks);
223 // For each training track, find the sector it belongs to and accumulate the
224 // hit coordinates and track parameters.
225 for (FPGATrackSimTruthTrack const & track : tracks) {
226
227 int nSlices = m_FPGATrackSimMapping->SubRegionMap()->getNRegions();
228
229 // Get list of hits associated to the current truth track
230 std::vector<FPGATrackSimHit> & sector_hits = barcode_hits[track.getBarcode()];
231
232 const FPGATrackSimPlaneMap *t_pmap = nullptr;
233
234 // Get the hits that will form the actual sector
235
236 for (int iSlice = 0; iSlice<nSlices; iSlice++){
237 t_pmap = m_FPGATrackSimMapping->PlaneMap_2nd(iSlice);
238
239 for (auto & iHit : sector_hits) {
240 t_pmap->map(iHit);
241 }
242
243 /* For now, don't do this. If we need regionalized/binned fit constants it needs to come from the road.
244 std::vector<FPGATrackSimHit> sector_hits;
245 bool success = filterSectorHits(track_hits, sector_hits, track, true, iSlice);
246 if (!success) continue; // Skip this track if it has bad hits (not complete, etc.)
247 */
248
249 m_h_trackQoP_okHits->Fill(track.getQOverPt());
250
251 // Get the region of this sector
252 // TODO: do we need this the pattern recognition should deal with it.
253 int region = 0; //sgetRegion(sector_hits, false);
254 //if (region < 0 || region >= m_nRegions) continue;
255 m_h_trackQoP_okRegion->Fill(track.getQOverPt());
256
257 //For the Hough constants, find the Hough roads
258 std::vector<FPGATrackSimRoad> houghRoads;
260
261 std::vector<std::shared_ptr<const FPGATrackSimHit>> phits;
262
263 ATH_MSG_DEBUG("Starting from some number of sector hits = " << sector_hits.size());
264 for (const FPGATrackSimHit& hit : sector_hits) if (hit.isMapped() && hit.isReal()) phits.emplace_back(std::make_shared<const FPGATrackSimHit>(hit));
265 ATH_MSG_DEBUG("Passing nhits = " << phits.size() << " to road finder");
266 StatusCode sc = m_roadFinderTool->getRoads(phits, houghRoads, truth_tracks);
267 if (sc.isFailure()) ATH_MSG_WARNING("Hough Transform -> getRoads() failed");
268
269 ATH_MSG_DEBUG("We found " << houghRoads.size() << " roads");
270
271 // We now want to just form the accumulator for any valid combination of hits
272 // In first stage mode we'll make the track fitter just generate combinations
273 std::vector<FPGATrackSimTrack> tracks_1st;
274 if (m_doSecondStage) {
275 ATH_CHECK(m_trackFitterTool_1st->getTracks(houghRoads, tracks_1st, m_EvtSel->getMin(), m_EvtSel->getMax()));
276 ATH_CHECK(m_overlapRemovalTool->runOverlapRemoval(tracks_1st));
277 } else {
278 roadsToTrack(houghRoads, tracks_1st, m_pmap_1st);
279 ATH_MSG_DEBUG("We found " << tracks_1st.size() << " combinations");
280 }
281 for (const auto& track_comb : tracks_1st) {
282 auto & track_hits_ptrs = track_comb.getFPGATrackSimHitPtrs();
283
284 if (m_doSecondStage) { // if doing 2nd stage, we want to get tracks from the road and then do tracking and overlap removal
285
286 // Prepare the accumulator struct
287 std::vector<module_t> modules(m_nLayers_2nd);
289 std::vector<std::shared_ptr<const FPGATrackSimHit>> phits_2nd;
290
291 // Pass all hits-- it's not possible to only select second stage hits here...
292 for (const auto& hit : sector_hits) {
293 phits_2nd.push_back(std::make_shared<const FPGATrackSimHit>(hit));
294 }
295
296 // Use the track extension tool to actually produce a new set of roads.
297 std::vector<FPGATrackSimRoad> roads_2nd;
298 ATH_CHECK(m_trackExtensionTool->extendTracks(phits_2nd, tracks_1st, roads_2nd));
299
300 // Now produce "track" candidates and loop over them.
301 std::vector<FPGATrackSimTrack> tracks_2nd;
302 roadsToTrack(roads_2nd, tracks_2nd, m_pmap_2nd);
303 for (const FPGATrackSimTrack& track_2nd : tracks_2nd) {
304 auto & track_hits_2nd_ptrs = track_2nd.getFPGATrackSimHitPtrs();
305 std::vector<module_t> modules(m_nLayers_2nd);
307 acc.pars.qOverPt = track_2nd.getHoughY();
308 acc.pars.phi = track_2nd.getHoughX();
309
310 std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> modules_acc = {modules, acc};
311 std::vector<std::shared_ptr<const FPGATrackSimHit>> phits;
312 ATH_CHECK(makeAccumulator(track_hits_2nd_ptrs, track, modules_acc));
313
314 // Add the track to the accumulate map
315 accumulate(m_sector_cum[region], modules_acc.first, modules_acc.second);
316
318 ATH_CHECK(fillAccumulatorByDropping(track_hits_2nd_ptrs, false, acc.pars.phi, acc.pars.qOverPt, modules, m_sector_cum[region], track, iSlice));
319
321 }
322 }
323 else {
324 // For each track combination (from a Hough road)
325 double y = track_comb.getHoughY();
326 double x = track_comb.getHoughX();
327 // Prepare the accumulator struct
328 std::vector<module_t> modules(m_nLayers_1st);
330 acc.pars.qOverPt = y;
331 acc.pars.phi = x;
332 std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> modules_acc = {modules, acc};
333 ATH_CHECK(makeAccumulator(track_hits_ptrs, track, modules_acc));
334
335 // Add the track to the accumulate map
336 accumulate(m_sector_cum[region], modules_acc.first, modules_acc.second);
337
339 ATH_CHECK(fillAccumulatorByDropping(track_hits_ptrs, true, acc.pars.phi, acc.pars.qOverPt, modules, m_sector_cum[region], track, iSlice));
340
342 }
343 }
344 }
345 else{
346 // Convert sector_hits to non-owning shared_ptr vector for the non-Hough-constants path
347 std::vector<std::shared_ptr<const FPGATrackSimHit>> sector_hits_ptrs;
348 sector_hits_ptrs.reserve(sector_hits.size());
349 // Single control block representing "the lifetime of sector_hits" (non-owning)
350 auto owner = std::shared_ptr<const std::vector<FPGATrackSimHit>>(
351 &sector_hits,
352 [](const std::vector<FPGATrackSimHit>*) {} // no-op deleter
353 );
354
355 for (const auto& hit : sector_hits) {
356 // Aliasing ctor: shares owner's control block, but points to this element
357 sector_hits_ptrs.emplace_back(owner, &hit);
358 }
359
360 // Prepare the accumulator struct
361 std::vector<module_t> modules(m_nLayers_1st);
363 std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> modules_acc = {modules, acc};
364 ATH_CHECK(makeAccumulator(sector_hits_ptrs, track, modules_acc));
365
366 // Add the track to the accumulate map
367 accumulate(m_sector_cum[region], modules_acc.first, modules_acc.second);
368
370 ATH_CHECK(fillAccumulatorByDropping(sector_hits_ptrs, true, acc.pars.phi, acc.pars.qOverPt, modules, m_sector_cum[region], track, iSlice));
371
373 }
374 }
375 }
376
377 return StatusCode::SUCCESS;
378}
379
380
381// Converts raw hits from header into logical hits, and filters those in FPGATrackSim layers
382// Could replace this with the RawToLogical tool (but probably won't)
383std::vector<FPGATrackSimHit> FPGATrackSimMatrixGenAlgo::getLogicalHits()
384{
385 std::vector<FPGATrackSimHit> hits;
386 //Setup the logical header...
388 //Map the hits to the logical header...
389 unsigned stage = 0;
390 if (m_doHoughConstants) stage = 1; // For now Hough constants only works on 1st stage
391 else stage = 2;
392 StatusCode sc = m_hitMapTool->convert(stage, *m_eventHeader, logicalHeader);
393 if (sc.isFailure()) ATH_MSG_ERROR("Hit mapping failed");
394
395 // Since the clustering tool modifies the logical towers-- refactored this
396 // to only access the output hits from the towers.
397 if (m_doClustering) {
398 std::vector<FPGATrackSimCluster> clustered_hits;
399 sc = m_clusteringTool->DoClustering(logicalHeader, clustered_hits);
400 if (sc.isFailure()) ATH_MSG_ERROR("Clustering failed");
401 }
402 // Optionally do spacepoints (as well).
403 if (m_doSpacePoints) {
404 std::vector<FPGATrackSimCluster> spacepoints;
405 sc = m_spacePointsTool->DoSpacePoints(logicalHeader, spacepoints);
406 if (sc.isFailure()) ATH_MSG_ERROR("Spacepoints failed");
407 }
408
409 // It should now be safe to pull the towers, regardless.
410 std::vector<FPGATrackSimTowerInputHeader> towers = logicalHeader.towers();
411 for (auto &tower : towers) {
412 std::vector<FPGATrackSimHit> const & towerHits = tower.hits();
413 for (FPGATrackSimHit const & hit : towerHits) {
414 hits.push_back(hit);
415 }
416 }
417 return hits;
418}
419
420
421// Filters tracks based on m_PT_THRESHOLD and m_TRAING_PDG and D0_THRESHOLD
422std::vector<FPGATrackSimTruthTrack> FPGATrackSimMatrixGenAlgo::filterTrainingTracks(std::vector<FPGATrackSimTruthTrack> const & truth_tracks) const
423{
424 std::vector<FPGATrackSimTruthTrack> training_tracks;
425
426 for (FPGATrackSimTruthTrack const & track : truth_tracks) {
427 if (HepMC::generations(&track) >= 1 || std::abs(track.getPDGCode()) != m_TRAIN_PDG) continue;
428 if (std::abs(track.getD0()) > m_D0_THRESHOLD) continue;
429
430 // Actually use the event selection service here to kill anything outside the region.
431 if (!(m_EvtSel->passMatching(track))) continue;
432
433 double pt = TMath::Sqrt(track.getPX()*track.getPX() + track.getPY()*track.getPY());
434 double pt_GeV = pt / 1000;
435
436 // Add the track to the list of good tracks
437 if (pt_GeV > m_PT_THRESHOLD) training_tracks.push_back(track);
438
439 // Debug
440 if (msgLvl(MSG::DEBUG)) {
441 double c = track.getQ() /(2 * pt);
442 double eta = TMath::ASinH(track.getPZ() / pt);
443 double phi = TMath::ATan2(track.getPY(), track.getPX());
444 ATH_MSG_DEBUG("pt_GeV = "<< pt_GeV
445 << " c = " << c
446 << " eta = " << eta
447 << " phi = " << phi
448 << " pdgcode = " << track.getPDGCode());
449 }
451 }
452
453 return training_tracks;
454}
455
456
457// Sorts 'hits' by barcodes appearing in 'tracks', drops the rest.
458std::map<int, std::vector<FPGATrackSimHit>> FPGATrackSimMatrixGenAlgo::makeBarcodeMap(std::vector<FPGATrackSimHit> const & hits, std::vector<FPGATrackSimTruthTrack> const & tracks) const
459{
460 std::map<int, std::vector<FPGATrackSimHit>> map;
461
462 // Ready the barcodes
463 for (const FPGATrackSimTruthTrack & track : tracks)
464 map[track.getBarcode()] = std::vector<FPGATrackSimHit>();
465
466 // Add the hits
467 for (const FPGATrackSimHit & hit : hits) {
468 // Get the predominant barcode for the current hit
469 int barcode = hit.getTruth().best_barcode();
470
471 // Add hit to the list; skip the hits if not associated to a good truth tracks
472 auto it = map.find(barcode);
473 if (it != map.end()) (*it).second.push_back(hit);
474 }
475
476 return map;
477}
478
479
480// Given two hits in the same layer, selects the better hit to use for sector
481// generation based on multiple criteria.
482//
483// Returns:
484// 0 - Failure, this track should be discarded
485// 1 - Keep old hit
486// 2 - Use new hit
487//
488// NB: sector overlap is a perfectly reasonable situation with forward disks
489// eta and phi will differ in general in this case
490// Take the lower-z hit preferentially (right thing to do? d0/pT tradeoff)
491// But something fishy is going on if we've got two hits on the same disk.
493{
494 if (old_hit.isReal() && !new_hit.isReal()) return selectHit_returnCode::SH_KEEP_OLD;
495 if (!old_hit.isReal() && new_hit.isReal()) return selectHit_returnCode::SH_KEEP_NEW;
496 if (!old_hit.isReal() && !new_hit.isReal()) return selectHit_returnCode::SH_FAILURE;
497 if ((new_hit.getSection() == old_hit.getSection()) && (new_hit.getLayer() == old_hit.getLayer())
498 && (new_hit.getEtaModule() == old_hit.getEtaModule()) && (new_hit.getPhiModule() == old_hit.getPhiModule())) {
499 ATH_MSG_DEBUG("Two hits on same module");
501 }
502 // Always prefer spacepoints, regardless of all other considerations.
503 // This is necessary in part due to spacepoint duplication.
504 if (old_hit.getHitType() == HitType::spacepoint && new_hit.getHitType() != HitType::spacepoint) {
506 } else if (old_hit.getHitType() != HitType::spacepoint && new_hit.getHitType() == HitType::spacepoint) {
508 }
509 int new_section = new_hit.getSection();
510 int old_section = old_hit.getSection();
511
512 if (old_section == new_section) {
513 if (old_hit.getEtaModule() == new_hit.getEtaModule()) {
514 int rmax = 0;
515 if (m_doHoughConstants && is1ststage) {
516 int phi_max = m_FPGATrackSimMapping->SubRegionMap()->getRegionBoundaries(subregion, new_hit.getLayer(), new_section).phi_max;
517 int phi_min = m_FPGATrackSimMapping->SubRegionMap()->getRegionBoundaries(subregion, new_hit.getLayer(), new_section).phi_min;
518 rmax = phi_max - phi_min;
519
520 }
521 else {
522 int phi_max = m_FPGATrackSimMapping->SubRegionMap_2nd()->getRegionBoundaries(subregion, new_hit.getLayer(), new_section).phi_max;
523 int phi_min = m_FPGATrackSimMapping->SubRegionMap_2nd()->getRegionBoundaries(subregion, new_hit.getLayer(), new_section).phi_min;
524 rmax = phi_max - phi_min;
525 }
526
527 int phi_diff = old_hit.getPhiModule() - new_hit.getPhiModule();
528
529 if (phi_diff == 1 || phi_diff == -rmax) return selectHit_returnCode::SH_KEEP_OLD;
530 else if (phi_diff == -1 || phi_diff == rmax) return selectHit_returnCode::SH_KEEP_NEW;
531 else {
532 ATH_MSG_DEBUG("Hits are too far away in phi");
534 }
535 }
536 else { // Different eta is no good
537 ATH_MSG_DEBUG("Hits are in different eta");
539 }
540 }
541 else { // sections are different
542 int layer = old_hit.getLayer();
543 bool old_isEC = 0;
544 bool new_isEC = 0;
545 int old_disk = 0;
546 int new_disk = 0;
547 if (m_doHoughConstants && is1ststage) {
548 old_isEC = m_FPGATrackSimMapping->PlaneMap_1st(subregion)->isEC(layer, old_section);
549 new_isEC = m_FPGATrackSimMapping->PlaneMap_1st(subregion)->isEC(layer, new_section);
550 old_disk = m_FPGATrackSimMapping->PlaneMap_1st(subregion)->getLayerInfo(layer, old_section).physDisk;
551 new_disk = m_FPGATrackSimMapping->PlaneMap_1st(subregion)->getLayerInfo(layer, new_section).physDisk;
552 }
553 else {
554 old_isEC = m_FPGATrackSimMapping->PlaneMap_2nd(subregion)->isEC(layer, old_section);
555 new_isEC = m_FPGATrackSimMapping->PlaneMap_2nd(subregion)->isEC(layer, new_section);
556 old_disk = m_FPGATrackSimMapping->PlaneMap_2nd(subregion)->getLayerInfo(layer, old_section).physDisk;
557 new_disk = m_FPGATrackSimMapping->PlaneMap_2nd(subregion)->getLayerInfo(layer, new_section).physDisk;
558 }
559 // If one is barrel and one endcap, it's definitely OK, take the barrel hit
560 if (old_isEC != new_isEC) {
561
562 if (old_isEC) return selectHit_returnCode::SH_KEEP_NEW;
564 }
565 // Two endcap hits : same disk: discard
566 else if (old_disk == new_disk) {
567
568 ATH_MSG_DEBUG("Two modules hit in same physical disk " << old_disk);
570 }
571 // Two endcap hits on same side: different disks: take the lower-z
572 else {
573 ATH_MSG_DEBUG("Keeping the lower-z of the two disks (" << old_disk << ", " << new_disk << ") hit");
574 if (old_disk > new_disk) return selectHit_returnCode::SH_KEEP_NEW;
576 }
577 }
578}
579
580
581// A sector is created from hits in all layers. Sometimes there will be extraneous hits
582// that need to be filtered. This functions returns true on success, and by reference
583// the filtered hit list with size m_nLayers_1st.
584//
585// See selectHit() for details on which hit is chosen when there's more than 1 per layer.
586bool FPGATrackSimMatrixGenAlgo::filterSectorHits(std::vector<FPGATrackSimHit> const & all_hits, std::vector<FPGATrackSimHit> & sector_hits,
587 FPGATrackSimTruthTrack const & t, bool is1ststage, int subregion) const
588{
589 FPGATrackSimHit nohit;
591 int nLayers = (is1ststage ? m_nLayers_1st : m_nLayers_2nd);
592 const FPGATrackSimRegionMap *rmap = (is1ststage ? m_FPGATrackSimMapping->SubRegionMap() : m_FPGATrackSimMapping->SubRegionMap_2nd());
593 sector_hits.resize(nLayers, nohit);
594 std::vector<int> layer_count(nLayers); // count number of hits seen in each layer
595
596 for (FPGATrackSimHit const & hit : all_hits) {
597 if (!hit.isReal() || !hit.isMapped()) continue;
598
599 // Sanity check. make sure the hit is actually in the first stage?
600 // If the hit falls within the boundaries of ANY subregion in the first stage, it's 1st stage.
601 if (rmap->getRegions(hit).size() == 0) {
602 continue;
603 }
604 int layer = hit.getLayer();
605 if (layer_count[layer] == 0){
606 layer_count[layer]++;
607 sector_hits[layer] = hit;
608 }
609 else if (layer_count[layer] == 1) {
610 layer_count[layer]++;
611 // Already found a hit in this layer, so pick which hit to use
612 selectHit_returnCode selected_hit = selectHit(sector_hits[layer], hit, is1ststage, subregion);
613
614 if (selected_hit == selectHit_returnCode::SH_FAILURE) {
616 return false;
617 }
618 else if (selected_hit == selectHit_returnCode::SH_KEEP_NEW) sector_hits[layer] = hit;
619 }
620 else {
621 ATH_MSG_DEBUG("Too many hits on a plane, exiting filterHitsSec");
623 return false;
624 }
625 }
626 // Count number of wildcards, spacepoints, and pixel hits.
627 int nwc = 0;
628 int num_sp = 0;
629 int num_pixel = 0;
630
631 // Check we have the right number of hits.
632 for (int i = 0; i < nLayers; ++i)
633 {
634 if (layer_count[i] == 0)
635 {
636 ATH_MSG_DEBUG("Layer " << i << " has no hits");
637 nwc++;
638 }
639
640 // Now that we've decided which hit to use-- check their type.
641 if (sector_hits[i].getHitType() == HitType::spacepoint) {
642 num_sp += 1;
643 }
644 if (sector_hits[i].isPixel()) {
645 num_pixel += 1;
646 }
647 }
648 ATH_MSG_DEBUG("Found " << nwc << " wildcards compared to maximum: " << m_MaxWC);
649 // Divide by 2 due to spacepoint duplication.
650 num_sp /= 2;
651 ATH_MSG_DEBUG("Found " << num_sp << " spacepoints after removing duplicates.");
652 // Require we don't have too many wildcards.
653 if (nwc > m_MaxWC)
654 {
656 return false;
657 }
658 // Require that we have a certain number of "2D" hits (i.e. pixels and spacepoints)
659 // The effect of this is that we can ensure we have 4/5 2D hits but 7/9 hits total.
660 // NOTE Again, uncomment logic below for second stage running.
661 num_sp += num_pixel;
662 int minSpacePlusPixel = /*m_isSecondStage ? m_minSpacePlusPixel2 :*/ m_minSpacePlusPixel;
663 if (num_sp < minSpacePlusPixel) {
664 ATH_MSG_DEBUG("Not enough pixel hits + spacepoints (" << num_sp << " < " << minSpacePlusPixel << ")");
666 return false;
667 }
668 return true;
669}
670
671
672// Returns the lowest index region that contains all hits in 'hits'
673int FPGATrackSimMatrixGenAlgo::getRegion(std::vector<FPGATrackSimHit> const & hits, bool is1ststage) const
674{
675 // Start with a bitmask, all true, and set a region to false if any mismatch is found
676 std::vector<bool> region_mask(m_nRegions, true);
677
678 for (FPGATrackSimHit const & hit : hits) {
679 if (hit.isReal()) { // don't worry about hits that are WCs
680 for (int region = 0; region < m_nRegions; region++) {
681 if (m_doHoughConstants && is1ststage) {
682 if (!m_FPGATrackSimMapping->RegionMap_1st()->isInRegion(region, hit))
683 region_mask[region] = false;
684 }
685 else {
686 if (!m_FPGATrackSimMapping->RegionMap_2nd()->isInRegion(region, hit))
687 region_mask[region] = false;
688 }
689 }
690 }
691 }
692
693 // For now just give preference to lowest region index for simplicity
694 for (int region = 0; region < m_nRegions; region++) {
695 if (region_mask[region])
696 return region;
697 }
698
699 return -1;
700}
701
702// Fill accumulators by dropping one hit
703StatusCode FPGATrackSimMatrixGenAlgo::fillAccumulatorByDropping(std::vector<std::shared_ptr<const FPGATrackSimHit>> const &sector_hits, bool is1ststage, double x, double y, std::vector<module_t> &modules, AccumulateMap &map, FPGATrackSimTruthTrack const & track, int subregion) const
704{
705
706 int nLayers = (is1ststage ? m_nLayers_1st : m_nLayers_2nd);
707 int nDim = (is1ststage ? m_nDim_1st : m_nDim_2nd);
708
709 int nwc = 0;
710 for (auto module : modules) {
711 if (module == -1) nwc++;
712 }
713 // Don't do this unless we miss at most one hit!
714 if (nwc < m_MaxWC) {
715 for (int layer = 0; layer < nLayers; layer++) {
716 // Create a modified pointer vector with a wildcard in this layer
717 std::vector<std::shared_ptr<const FPGATrackSimHit>> modified_hits = sector_hits;
718
719 // Create a new wildcard hit, and put it here.
720 ATH_MSG_DEBUG("Attempting to make wildcard in layer " << layer << ", is1ststage = " << is1ststage);
721 auto wcHit = std::make_shared<FPGATrackSimHit>();
722 wcHit->setHitType(HitType::wildcard);
723 wcHit->setLayer(layer);
724 if (is1ststage) wcHit->setDetType(m_FPGATrackSimMapping->PlaneMap_1st(subregion)->getDetType(layer));
725 else wcHit->setDetType(m_FPGATrackSimMapping->PlaneMap_2nd(subregion)->getDetType(layer));
726
727 modified_hits[layer] = std::move(wcHit);
728
729 // If this is a spacepoint, we must also convert the other hit.
730 std::shared_ptr<const FPGATrackSimHit> originalHit;
731 unsigned other_layer = 0;
732 if (sector_hits[layer] && sector_hits[layer]->getHitType() == HitType::spacepoint) {
733 other_layer = (sector_hits[layer]->getPhysLayer() % 2 == 0) ? layer + 1 : layer - 1;
734 originalHit = std::make_shared<FPGATrackSimHit>(sector_hits[other_layer]->getOriginalHit());
735 modified_hits[other_layer] = std::move(originalHit);
736 }
737
738 FPGATrackSimMatrixAccumulator new_acc(nLayers, nDim);
739 new_acc.pars.qOverPt = y;
740 new_acc.pars.phi = x;
741 std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> new_modules_acc = {modules, new_acc};
742
743 auto sc = makeAccumulator(modified_hits, track, new_modules_acc);
744 if (sc != StatusCode::SUCCESS){
745 ATH_MSG_ERROR("FPGATrackSimMatrixGenAlgo::fillAccumulatorByDropping; makeAccumulator failed");
746 return StatusCode::FAILURE;
747 }
748 accumulate(map, new_modules_acc.first, new_modules_acc.second);
749 }
750 }
751 return StatusCode::SUCCESS;
752}
753
754// Given a track and corresponding hits, returns the sector (list of modules) and the accumulation
755// struct.
756StatusCode FPGATrackSimMatrixGenAlgo::makeAccumulator(std::vector<std::shared_ptr<const FPGATrackSimHit>> const & sector_hits, FPGATrackSimTruthTrack const & track, std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> & accumulator) const
757{
758
759
761 int nLayers = (m_doSecondStage ? m_nLayers_2nd : m_nLayers_1st);
762 int nDim = (m_doSecondStage ? m_nDim_2nd : m_nDim_1st);
763 std::vector<module_t> modules(nLayers);
764 FPGATrackSimMatrixAccumulator acc(nLayers, nDim);
765
766 //find the bin!
767 // NOTE: this only implements q/pt binning, not the subregion / eta pattern-based constants for now.
768 int sectorbin = 0;
769 double qoverpt = track.getQ() / track.getPt();
770
771 // for 2nd stage we only use one q/pt bin
772 if (m_absQOverPtBinning || m_doSecondStage) qoverpt = abs(qoverpt);
773 if (!m_doSecondStage) {
774 for (unsigned bin = 0; bin < m_qOverPtBins.size()-1; bin++) {
776 if (qoverpt < m_qOverPtBins[bin+1]) break;
777 }
778 }
779
780 // Create sector definitions (list of modules)
781 std::string module_printout = "";
782 for (int i = 0; i < nLayers; i++)
783 {
784 if (sector_hits[i] && sector_hits[i]->isReal()) {
785 if (m_single) modules[i] = sector_hits[i]->getIdentifierHash();
786 else {
787 modules[i] = sectorbin;
788 // Modify sectorbin by a "type" field, which for now means: 0 = not spacepoint, 1 = spacepoint.
789 // This will fail if we have more than 99 q/pt bins!
790 if (sector_hits[i]->getHitType() == HitType::spacepoint) {
792 }
793 module_printout += std::to_string(modules[i]) + ", ";
794 }
795 }
796 else {
797 modules[i] = -1; // WC
798 }
799 }
800
801 ATH_MSG_DEBUG("Generating track in sectorbin = " << sectorbin << " with modules: " << module_printout);
802
803
804 if (m_single) {
805 const int ToKeep[13] = {2200,2564,2861,3831,5368,14169,14173,20442,20446,29625,29629,42176,42180};
806 bool keepThis = true;
807 for (int i = 0; i < 13; i++) {
808 if (modules[i] != ToKeep[i] && modules[i] != -1) {
809 keepThis = false;
810 }
811 }
812
813 if (!keepThis) {
814 for (int i = 0; i < 13; i++) modules[i] = -1;
815 }
816 else {
817 for (int i = 0; i < 13; i++) {
818 }
819 }
820 }
821
822
823 // Hough Constants parameters
824 double y = accumulator.second.pars.qOverPt;
825 double x = accumulator.second.pars.phi;
826
827 // Vectorize (flatten) coordinates
828 std::vector<float> coords;
829
830 for (int i = 0; i < nLayers; ++i) {
831
832 if (sector_hits[i] && sector_hits[i]->isReal()) {
833 double target_r = (m_doSecondStage ? m_FPGATrackSimMapping->RegionMap_2nd()->getAvgRadius(0, i) : m_FPGATrackSimMapping->RegionMap_1st()->getAvgRadius(0, i));
834 // If this is a spacepoint the target R should be the average of the two layers.
835 // TODO, get this to be loaded in from a mean radii file into the mapping infrastructure.
836 if (sector_hits[i]->getHitType() == HitType::spacepoint) {
837 int other_layer = (sector_hits[i]->getSide() == 0) ? i + 1 : i - 1;
838 target_r = (m_doSecondStage ?
839 (target_r + m_FPGATrackSimMapping->RegionMap_2nd()->getAvgRadius(0, other_layer))/2. :
840 (target_r + m_FPGATrackSimMapping->RegionMap_1st()->getAvgRadius(0, other_layer))/2.);
841 }
842
843 std::vector<float> coords_tmp;
844 if ( m_ideal_geom > 1 ) {
845 coords_tmp = computeIdealCoords(*sector_hits[i], x, y, target_r, m_doDeltaPhiConsts, TrackCorrType::Second);
846 }
847 else {
848 coords_tmp = computeIdealCoords(*sector_hits[i], x, y, target_r, m_doDeltaPhiConsts, TrackCorrType::None);
849 }
850
851 // Create phi for any hits that are not spacepoints, as well as "inner" spacepoints.
852 // but not outer spacepoints. this avoids duplicate coordinates.
853 if (sector_hits[i]->getHitType() != HitType::spacepoint || sector_hits[i]->getSide() == 0) {
854 // get idealized gPhi
855 coords.push_back(coords_tmp[1]);
856 }
857
858 // Create a z coordinate for the "outer" layer of the spacepoint and for 2D pixel hits.
859 // This means that a spacepoint will write out (phi, eta) pairs, but (0, phi) or (phi, 0) if it's missing.
860 if (sector_hits[i]->getDim() == 2 || (sector_hits[i]->getHitType() == HitType::spacepoint && (sector_hits[i]->getPhysLayer() % 2) == 1)) {
861 // get idealized z
862 coords.push_back(coords_tmp[0]);
863 }
864 }
865 else {
866 if (pmap->getDim(i) == 2) {
867 coords.push_back(0);
868 }
869 coords.push_back(0);
870 }
871 }
872
873 assert(coords.size() == (size_t)nDim);
874 acc.hit_coords = coords;
875 acc.hit_coordsG = coords;
876
877 // Get the track parameters
878 acc.pars = track.getPars();
880 acc.pars.qOverPt = (y / 1000.0) - track.getQOverPt(); // fit for delta q/pT
881 acc.pars.phi = x - track.getPhi(); // fit for delta phi_0
882 }
883
885 for (unsigned i = 0; i < FPGATrackSimTrackPars::NPARS; i++)
886 bins[i] = (acc.pars[i] - m_sliceMin[i]) * m_nBins[i] / (m_sliceMax[i] - m_sliceMin[i]);
887 acc.track_bins.push_back(bins);
888
889 // Force phi to be in [0, 2pi] (post binning)
890 if (!m_doDeltaPhiConsts) {
891 while (acc.pars.phi < 0) acc.pars.phi += 2*M_PI;
892 while (acc.pars.phi > 2*M_PI) acc.pars.phi -= 2*M_PI;
893 }
894
895 // Calculate the pre-multiplied elements
896 for (int i = 0; i < nDim; i++)
897 {
898 acc.hit_x_QoP[i] = coords[i] * acc.pars.qOverPt;
899 acc.hit_xG_HIP[i] = coords[i] * acc.pars.qOverPt;
900 acc.hit_x_d0[i] = coords[i] * acc.pars.d0;
901 acc.hit_x_z0[i] = coords[i] * acc.pars.z0;
902 acc.hit_x_eta[i] = coords[i] * acc.pars.eta;
903 acc.hit_xG_eta[i] = coords[i] * acc.pars.eta;
904 acc.hit_x_phi[i] = coords[i] * acc.pars.phi;
905
906 for (int j = i; j < nDim; j++)
907 acc.covariance[i * nDim + j] = coords[i] * coords[j];
908
909 for (int j = i; j < nDim; j++)
910 acc.covarianceG[i * nDim + j] = coords[i] * coords[j];
911 }
912
913 accumulator = {modules, acc};
914 return StatusCode::SUCCESS;
915}
916
917
918
920// Finalize
922
923
925{
926 ATH_MSG_DEBUG("finalize()");
927 ATH_MSG_INFO("Tracks used: " << m_nTracksUsed << "/" << m_nTracks);
928 int nLayers = (m_doSecondStage ? m_nLayers_2nd : m_nLayers_1st);
929 int nDim = (m_doSecondStage ? m_nDim_2nd : m_nDim_1st);
930
931 for (int region = 0; region < m_nRegions; region++) {
932 // Create the tree
933 std::stringstream name;
934 std::stringstream title;
935 name << "am" << region;
936 title << "Ambank " << region << " parameters";
937 TTree* tree = new TTree(name.str().c_str(), title.str().c_str());
938 ATH_CHECK(m_tHistSvc->regTree(Form("/TRIGFPGATrackSimMATRIXOUT/%s",tree->GetName()), tree));
939
940 // Fill the tree
941 ::fillTree(m_sector_cum[region], tree, nLayers, nDim);
942 // Monitoring
943 ATH_MSG_INFO("Sectors found in region " << region << ": " << m_sector_cum[region].size());
944 for (auto & sector_info : m_sector_cum[region]) {
945 double coverage = sector_info.second.track_bins.size();
946 m_h_nHit->Fill(coverage);
947 for (unsigned i = 0; i < FPGATrackSimTrackPars::NPARS; i++)
948 m_h_sectorPars[i]->Fill(sector_info.second.pars[i] / coverage);
949 }
950 }
951
953 ATH_CHECK(m_tHistSvc->finalize());
954 return StatusCode::SUCCESS;
955}
956
957
959{
960 TTree* sliceTree = new TTree("slice", "Region slice boundaries"); // slice
961
962 sliceTree->Branch("c_max", &m_sliceMax.qOverPt);
963 sliceTree->Branch("d0_max", &m_sliceMax.d0);
964 sliceTree->Branch("phi_max", &m_sliceMax.phi);
965 sliceTree->Branch("z0_max", &m_sliceMax.z0);
966 sliceTree->Branch("eta_max", &m_sliceMax.eta);
967
968 sliceTree->Branch("c_min", &m_sliceMin.qOverPt);
969 sliceTree->Branch("d0_min", &m_sliceMin.d0);
970 sliceTree->Branch("phi_min", &m_sliceMin.phi);
971 sliceTree->Branch("z0_min", &m_sliceMin.z0);
972 sliceTree->Branch("eta_min", &m_sliceMin.eta);
973
974 sliceTree->Branch("c_slices", &m_nBins.qOverPt);
975 sliceTree->Branch("d0_slices", &m_nBins.d0);
976 sliceTree->Branch("phi_slices", &m_nBins.phi);
977 sliceTree->Branch("z0_slices", &m_nBins.z0);
978 sliceTree->Branch("eta_slices", &m_nBins.eta);
979
980 StatusCode sc = m_tHistSvc->regTree("/TRIGFPGATrackSimMATRIXOUT/slice",sliceTree);
981 if (sc.isFailure()) ATH_MSG_ERROR("tHist failed");
982
983 sliceTree->Fill();
984}
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::vector< float > computeIdealCoords(const FPGATrackSimHit &hit, const double hough_x, const double hough_y, const double target_r, const bool doDeltaGPhis, const TrackCorrType trackCorrType)
void roadsToTrack(std::vector< FPGATrackSimRoad > &roads, std::vector< FPGATrackSimTrack > &track_cands, const FPGATrackSimPlaneMap *pmap)
bool accumulate(AccumulateMap &map, std::vector< module_t > const &modules, FPGATrackSimMatrixAccumulator const &acc)
Accumulates an accumulator (e.g.
Helper struct for accumulating sector information for matrix generation.
std::unordered_map< std::vector< module_t >, FPGATrackSimMatrixAccumulator, container_hash< std::vector< module_t > > > AccumulateMap
void fillTrackPars(TH1I *const hists[FPGATrackSimTrackPars::NPARS], FPGATrackSimTruthTrack const &track)
Algorithm to generate matrix files, to be used for sector and constant generation.
void fillTree(AccumulateMap &map, TTree *tree, int nLayers, int nCoords)
Writes the contents of an AccumulateMap into the supplied tree (one entry per sector).
Stores slice definitions for FPGATrackSim regions.
bool hit(const std::valarray< int > &ids, int pdgId)
static Double_t sc
static const std::vector< std::string > bins
#define y
#define x
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
bool msgLvl(const MSG::Level lvl) const
void setHitType(HitType type)
int getEtaModule(bool old=false) const
unsigned getPhiModule() const
bool isReal() const
unsigned getSection() const
HitType getHitType() const
const std::vector< FPGATrackSimTowerInputHeader > & towers() const
ToolHandle< FPGATrackSimRawToLogicalHitsTool > m_hitMapTool
std::map< int, std::vector< FPGATrackSimHit > > makeBarcodeMap(std::vector< FPGATrackSimHit > const &hits, std::vector< FPGATrackSimTruthTrack > const &tracks) const
Gaudi::Property< float > m_temp_c_max
FPGATrackSimMatrixGenAlgo(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< bool > m_doDeltaPhiConsts
Gaudi::Property< float > m_temp_d0_max
const FPGATrackSimPlaneMap * m_pmap_2nd
std::vector< FPGATrackSimTruthTrack > filterTrainingTracks(std::vector< FPGATrackSimTruthTrack > const &truth_tracks) const
Gaudi::Property< std::vector< double > > m_qOverPtBins
Gaudi::Property< float > m_temp_phi_max
Gaudi::Property< int > m_temp_z0_slices
Gaudi::Property< float > m_PT_THRESHOLD
Gaudi::Property< int > m_temp_d0_slices
Gaudi::Property< int > m_temp_eta_slices
TH1I * m_h_trainingTrack[FPGATrackSimTrackPars::NPARS]
Gaudi::Property< int > m_temp_phi_slices
ToolHandle< FPGATrackSimRoadUnionTool > m_roadFinderTool
Gaudi::Property< float > m_temp_c_min
Gaudi::Property< float > m_temp_z0_max
Gaudi::Property< float > m_temp_eta_min
Gaudi::Property< float > m_D0_THRESHOLD
StatusCode makeAccumulator(std::vector< std::shared_ptr< const FPGATrackSimHit > > const &sector_hits, FPGATrackSimTruthTrack const &track, std::pair< std::vector< module_t >, FPGATrackSimMatrixAccumulator > &accumulator) const
Gaudi::Property< bool > m_doSpacePoints
Gaudi::Property< bool > m_absQOverPtBinning
Gaudi::Property< float > m_temp_phi_min
Gaudi::Property< float > m_temp_z0_min
ToolHandle< FPGATrackSimClusteringToolI > m_clusteringTool
ToolHandle< FPGATrackSimOverlapRemovalTool > m_overlapRemovalTool
StatusCode fillAccumulatorByDropping(std::vector< std::shared_ptr< const FPGATrackSimHit > > const &sector_hits, bool is1ststage, double x, double y, std::vector< module_t > &modules, AccumulateMap &map, FPGATrackSimTruthTrack const &track, int subregion) const
Gaudi::Property< bool > m_doClustering
TH1I * m_h_notEnoughHits[FPGATrackSimTrackPars::NPARS]
Gaudi::Property< int > m_minSpacePlusPixel
const FPGATrackSimPlaneMap * m_pmap_1st
TH1I * m_h_sectorPars[FPGATrackSimTrackPars::NPARS]
std::vector< FPGATrackSimHit > getLogicalHits()
TH1I * m_h_3hitsInLayer[FPGATrackSimTrackPars::NPARS]
FPGATrackSimEventInputHeader * m_eventHeader
ToolHandle< FPGATrackSimTrackFitterTool > m_trackFitterTool_1st
ServiceHandle< ITHistSvc > m_tHistSvc
selectHit_returnCode selectHit(FPGATrackSimHit const &old_hit, FPGATrackSimHit const &new_hit, bool is1ststage, int subregion) const
std::vector< AccumulateMap > m_sector_cum
Gaudi::Property< float > m_temp_d0_min
Gaudi::Property< bool > m_dropHitsAndFill
Gaudi::Property< int > m_temp_c_slices
ToolHandle< IFPGATrackSimTrackExtensionTool > m_trackExtensionTool
ServiceHandle< IFPGATrackSimMappingSvc > m_FPGATrackSimMapping
Gaudi::Property< bool > m_doHoughConstants
ServiceHandle< IFPGATrackSimEventSelectionSvc > m_EvtSel
int getRegion(std::vector< FPGATrackSimHit > const &hits, bool is1ststage) const
bool filterSectorHits(std::vector< FPGATrackSimHit > const &all_hits, std::vector< FPGATrackSimHit > &sector_hits, FPGATrackSimTruthTrack const &t, bool is1ststage, int subregion) const
Gaudi::Property< float > m_temp_eta_max
TH1I * m_h_SHfailure[FPGATrackSimTrackPars::NPARS]
ToolHandle< FPGATrackSimSpacePointsToolI > m_spacePointsTool
Gaudi::Property< bool > m_doSecondStage
ToolHandle< IFPGATrackSimInputTool > m_hitInputTool
uint32_t getDim(size_t logiLayer) const
void map(FPGATrackSimHit &hit) const
static std::string parName(unsigned i)
STL class.
int generations(const T &p)
Method to return how many interactions a particle has undergone during simulation (TODO migrate to be...
constexpr int QPT_SECTOR_OFFSET
constexpr int SPACEPOINT_SECTOR_OFFSET
TChain * tree