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<std::shared_ptr<const 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 std::vector<FPGATrackSimHit> track_hits = track_comb.getFPGATrackSimHits();
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<std::shared_ptr<const FPGATrackSimRoad>> roads_2nd;
298 std::vector<std::shared_ptr<const FPGATrackSimTrack>> ptracks_1st;
299 ptracks_1st.reserve(tracks_1st.size());
300 for (const auto& track : tracks_1st) {
301 ptracks_1st.push_back(std::make_shared<const FPGATrackSimTrack>(track));
302 }
303 ATH_CHECK(m_trackExtensionTool->extendTracks(phits_2nd, ptracks_1st, roads_2nd));
304
305 // Now produce "track" candidates and loop over them.
306 std::vector<FPGATrackSimTrack> tracks_2nd;
307 roadsToTrack(roads_2nd, tracks_2nd, m_pmap_2nd);
308 for (const FPGATrackSimTrack& track_2nd : tracks_2nd) {
309 std::vector<FPGATrackSimHit> track_hits_2nd = track_2nd.getFPGATrackSimHits();
310 std::vector<module_t> modules(m_nLayers_2nd);
312 acc.pars.qOverPt = track_2nd.getHoughY();
313 acc.pars.phi = track_2nd.getHoughX();
314
315 std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> modules_acc = {modules, acc};
316 std::vector<std::shared_ptr<const FPGATrackSimHit>> phits;
317 ATH_CHECK(makeAccumulator(track_hits_2nd, track, modules_acc));
318
319 // Add the track to the accumulate map
320 accumulate(m_sector_cum[region], modules_acc.first, modules_acc.second);
321
323 ATH_CHECK(fillAccumulatorByDropping(track_hits_2nd, false, acc.pars.phi, acc.pars.qOverPt, modules, m_sector_cum[region], track, iSlice));
324
326 }
327 }
328 else {
329 // For each track combination (from a Hough road)
330 double y = track_comb.getHoughY();
331 double x = track_comb.getHoughX();
332 // Prepare the accumulator struct
333 std::vector<module_t> modules(m_nLayers_1st);
335 acc.pars.qOverPt = y;
336 acc.pars.phi = x;
337 std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> modules_acc = {modules, acc};
338 ATH_CHECK(makeAccumulator(track_hits, track, modules_acc));
339
340 // Add the track to the accumulate map
341 accumulate(m_sector_cum[region], modules_acc.first, modules_acc.second);
342
344 ATH_CHECK(fillAccumulatorByDropping(track_hits, true, acc.pars.phi, acc.pars.qOverPt, modules, m_sector_cum[region], track, iSlice));
345
347 }
348 }
349 }
350 else{
351 // Prepare the accumulator struct
352 std::vector<module_t> modules(m_nLayers_1st);
354 std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> modules_acc = {modules, acc};
355 ATH_CHECK(makeAccumulator(sector_hits, track, modules_acc));
356
357 // Add the track to the accumulate map
358 accumulate(m_sector_cum[region], modules_acc.first, modules_acc.second);
359
361 ATH_CHECK(fillAccumulatorByDropping(sector_hits, true, acc.pars.phi, acc.pars.qOverPt, modules, m_sector_cum[region], track, iSlice));
362
364 }
365 }
366 }
367
368 return StatusCode::SUCCESS;
369}
370
371
372// Converts raw hits from header into logical hits, and filters those in FPGATrackSim layers
373// Could replace this with the RawToLogical tool (but probably won't)
374std::vector<FPGATrackSimHit> FPGATrackSimMatrixGenAlgo::getLogicalHits()
375{
376 std::vector<FPGATrackSimHit> hits;
377 //Setup the logical header...
379 //Map the hits to the logical header...
380 unsigned stage = 0;
381 if (m_doHoughConstants) stage = 1; // For now Hough constants only works on 1st stage
382 else stage = 2;
383 StatusCode sc = m_hitMapTool->convert(stage, *m_eventHeader, logicalHeader);
384 if (sc.isFailure()) ATH_MSG_ERROR("Hit mapping failed");
385
386 // Since the clustering tool modifies the logical towers-- refactored this
387 // to only access the output hits from the towers.
388 if (m_doClustering) {
389 std::vector<FPGATrackSimCluster> clustered_hits;
390 sc = m_clusteringTool->DoClustering(logicalHeader, clustered_hits);
391 if (sc.isFailure()) ATH_MSG_ERROR("Clustering failed");
392 }
393 // Optionally do spacepoints (as well).
394 if (m_doSpacePoints) {
395 std::vector<FPGATrackSimCluster> spacepoints;
396 sc = m_spacePointsTool->DoSpacePoints(logicalHeader, spacepoints);
397 if (sc.isFailure()) ATH_MSG_ERROR("Spacepoints failed");
398 }
399
400 // It should now be safe to pull the towers, regardless.
401 std::vector<FPGATrackSimTowerInputHeader> towers = logicalHeader.towers();
402 for (auto &tower : towers) {
403 std::vector<FPGATrackSimHit> const & towerHits = tower.hits();
404 for (FPGATrackSimHit const & hit : towerHits) {
405 hits.push_back(hit);
406 }
407 }
408 return hits;
409}
410
411
412// Filters tracks based on m_PT_THRESHOLD and m_TRAING_PDG and D0_THRESHOLD
413std::vector<FPGATrackSimTruthTrack> FPGATrackSimMatrixGenAlgo::filterTrainingTracks(std::vector<FPGATrackSimTruthTrack> const & truth_tracks) const
414{
415 std::vector<FPGATrackSimTruthTrack> training_tracks;
416
417 for (FPGATrackSimTruthTrack const & track : truth_tracks) {
418 if (HepMC::generations(&track) >= 1 || std::abs(track.getPDGCode()) != m_TRAIN_PDG) continue;
419 if (std::abs(track.getD0()) > m_D0_THRESHOLD) continue;
420
421 // Actually use the event selection service here to kill anything outside the region.
422 if (!(m_EvtSel->passMatching(track))) continue;
423
424 double pt = TMath::Sqrt(track.getPX()*track.getPX() + track.getPY()*track.getPY());
425 double pt_GeV = pt / 1000;
426
427 // Add the track to the list of good tracks
428 if (pt_GeV > m_PT_THRESHOLD) training_tracks.push_back(track);
429
430 // Debug
431 if (msgLvl(MSG::DEBUG)) {
432 double c = track.getQ() /(2 * pt);
433 double eta = TMath::ASinH(track.getPZ() / pt);
434 double phi = TMath::ATan2(track.getPY(), track.getPX());
435 ATH_MSG_DEBUG("pt_GeV = "<< pt_GeV
436 << " c = " << c
437 << " eta = " << eta
438 << " phi = " << phi
439 << " pdgcode = " << track.getPDGCode());
440 }
442 }
443
444 return training_tracks;
445}
446
447
448// Sorts 'hits' by barcodes appearing in 'tracks', drops the rest.
449std::map<int, std::vector<FPGATrackSimHit>> FPGATrackSimMatrixGenAlgo::makeBarcodeMap(std::vector<FPGATrackSimHit> const & hits, std::vector<FPGATrackSimTruthTrack> const & tracks) const
450{
451 std::map<int, std::vector<FPGATrackSimHit>> map;
452
453 // Ready the barcodes
454 for (const FPGATrackSimTruthTrack & track : tracks)
455 map[track.getBarcode()] = std::vector<FPGATrackSimHit>();
456
457 // Add the hits
458 for (const FPGATrackSimHit & hit : hits) {
459 // Get the predominant barcode for the current hit
460 int barcode = hit.getTruth().best_barcode();
461
462 // Add hit to the list; skip the hits if not associated to a good truth tracks
463 auto it = map.find(barcode);
464 if (it != map.end()) (*it).second.push_back(hit);
465 }
466
467 return map;
468}
469
470
471// Given two hits in the same layer, selects the better hit to use for sector
472// generation based on multiple criteria.
473//
474// Returns:
475// 0 - Failure, this track should be discarded
476// 1 - Keep old hit
477// 2 - Use new hit
478//
479// NB: sector overlap is a perfectly reasonable situation with forward disks
480// eta and phi will differ in general in this case
481// Take the lower-z hit preferentially (right thing to do? d0/pT tradeoff)
482// But something fishy is going on if we've got two hits on the same disk.
484{
485 if (old_hit.isReal() && !new_hit.isReal()) return selectHit_returnCode::SH_KEEP_OLD;
486 if (!old_hit.isReal() && new_hit.isReal()) return selectHit_returnCode::SH_KEEP_NEW;
487 if (!old_hit.isReal() && !new_hit.isReal()) return selectHit_returnCode::SH_FAILURE;
488 if ((new_hit.getSection() == old_hit.getSection()) && (new_hit.getLayer() == old_hit.getLayer())
489 && (new_hit.getEtaModule() == old_hit.getEtaModule()) && (new_hit.getPhiModule() == old_hit.getPhiModule())) {
490 ATH_MSG_DEBUG("Two hits on same module");
492 }
493 // Always prefer spacepoints, regardless of all other considerations.
494 // This is necessary in part due to spacepoint duplication.
495 if (old_hit.getHitType() == HitType::spacepoint && new_hit.getHitType() != HitType::spacepoint) {
497 } else if (old_hit.getHitType() != HitType::spacepoint && new_hit.getHitType() == HitType::spacepoint) {
499 }
500 int new_section = new_hit.getSection();
501 int old_section = old_hit.getSection();
502
503 if (old_section == new_section) {
504 if (old_hit.getEtaModule() == new_hit.getEtaModule()) {
505 int rmax = 0;
506 if (m_doHoughConstants && is1ststage) {
507 int phi_max = m_FPGATrackSimMapping->SubRegionMap()->getRegionBoundaries(subregion, new_hit.getLayer(), new_section).phi_max;
508 int phi_min = m_FPGATrackSimMapping->SubRegionMap()->getRegionBoundaries(subregion, new_hit.getLayer(), new_section).phi_min;
509 rmax = phi_max - phi_min;
510
511 }
512 else {
513 int phi_max = m_FPGATrackSimMapping->SubRegionMap_2nd()->getRegionBoundaries(subregion, new_hit.getLayer(), new_section).phi_max;
514 int phi_min = m_FPGATrackSimMapping->SubRegionMap_2nd()->getRegionBoundaries(subregion, new_hit.getLayer(), new_section).phi_min;
515 rmax = phi_max - phi_min;
516 }
517
518 int phi_diff = old_hit.getPhiModule() - new_hit.getPhiModule();
519
520 if (phi_diff == 1 || phi_diff == -rmax) return selectHit_returnCode::SH_KEEP_OLD;
521 else if (phi_diff == -1 || phi_diff == rmax) return selectHit_returnCode::SH_KEEP_NEW;
522 else {
523 ATH_MSG_DEBUG("Hits are too far away in phi");
525 }
526 }
527 else { // Different eta is no good
528 ATH_MSG_DEBUG("Hits are in different eta");
530 }
531 }
532 else { // sections are different
533 int layer = old_hit.getLayer();
534 bool old_isEC = 0;
535 bool new_isEC = 0;
536 int old_disk = 0;
537 int new_disk = 0;
538 if (m_doHoughConstants && is1ststage) {
539 old_isEC = m_FPGATrackSimMapping->PlaneMap_1st(subregion)->isEC(layer, old_section);
540 new_isEC = m_FPGATrackSimMapping->PlaneMap_1st(subregion)->isEC(layer, new_section);
541 old_disk = m_FPGATrackSimMapping->PlaneMap_1st(subregion)->getLayerInfo(layer, old_section).physDisk;
542 new_disk = m_FPGATrackSimMapping->PlaneMap_1st(subregion)->getLayerInfo(layer, new_section).physDisk;
543 }
544 else {
545 old_isEC = m_FPGATrackSimMapping->PlaneMap_2nd(subregion)->isEC(layer, old_section);
546 new_isEC = m_FPGATrackSimMapping->PlaneMap_2nd(subregion)->isEC(layer, new_section);
547 old_disk = m_FPGATrackSimMapping->PlaneMap_2nd(subregion)->getLayerInfo(layer, old_section).physDisk;
548 new_disk = m_FPGATrackSimMapping->PlaneMap_2nd(subregion)->getLayerInfo(layer, new_section).physDisk;
549 }
550 // If one is barrel and one endcap, it's definitely OK, take the barrel hit
551 if (old_isEC != new_isEC) {
552
553 if (old_isEC) return selectHit_returnCode::SH_KEEP_NEW;
555 }
556 // Two endcap hits : same disk: discard
557 else if (old_disk == new_disk) {
558
559 ATH_MSG_DEBUG("Two modules hit in same physical disk " << old_disk);
561 }
562 // Two endcap hits on same side: different disks: take the lower-z
563 else {
564 ATH_MSG_DEBUG("Keeping the lower-z of the two disks (" << old_disk << ", " << new_disk << ") hit");
565 if (old_disk > new_disk) return selectHit_returnCode::SH_KEEP_NEW;
567 }
568 }
569}
570
571
572// A sector is created from hits in all layers. Sometimes there will be extraneous hits
573// that need to be filtered. This functions returns true on success, and by reference
574// the filtered hit list with size m_nLayers_1st.
575//
576// See selectHit() for details on which hit is chosen when there's more than 1 per layer.
577bool FPGATrackSimMatrixGenAlgo::filterSectorHits(std::vector<FPGATrackSimHit> const & all_hits, std::vector<FPGATrackSimHit> & sector_hits,
578 FPGATrackSimTruthTrack const & t, bool is1ststage, int subregion) const
579{
580 FPGATrackSimHit nohit;
582 int nLayers = (is1ststage ? m_nLayers_1st : m_nLayers_2nd);
583 const FPGATrackSimRegionMap *rmap = (is1ststage ? m_FPGATrackSimMapping->SubRegionMap() : m_FPGATrackSimMapping->SubRegionMap_2nd());
584 sector_hits.resize(nLayers, nohit);
585 std::vector<int> layer_count(nLayers); // count number of hits seen in each layer
586
587 for (FPGATrackSimHit const & hit : all_hits) {
588 if (!hit.isReal() || !hit.isMapped()) continue;
589
590 // Sanity check. make sure the hit is actually in the first stage?
591 // If the hit falls within the boundaries of ANY subregion in the first stage, it's 1st stage.
592 if (rmap->getRegions(hit).size() == 0) {
593 continue;
594 }
595 int layer = hit.getLayer();
596 if (layer_count[layer] == 0){
597 layer_count[layer]++;
598 sector_hits[layer] = hit;
599 }
600 else if (layer_count[layer] == 1) {
601 layer_count[layer]++;
602 // Already found a hit in this layer, so pick which hit to use
603 selectHit_returnCode selected_hit = selectHit(sector_hits[layer], hit, is1ststage, subregion);
604
605 if (selected_hit == selectHit_returnCode::SH_FAILURE) {
607 return false;
608 }
609 else if (selected_hit == selectHit_returnCode::SH_KEEP_NEW) sector_hits[layer] = hit;
610 }
611 else {
612 ATH_MSG_DEBUG("Too many hits on a plane, exiting filterHitsSec");
614 return false;
615 }
616 }
617 // Count number of wildcards, spacepoints, and pixel hits.
618 int nwc = 0;
619 int num_sp = 0;
620 int num_pixel = 0;
621
622 // Check we have the right number of hits.
623 for (int i = 0; i < nLayers; ++i)
624 {
625 if (layer_count[i] == 0)
626 {
627 ATH_MSG_DEBUG("Layer " << i << " has no hits");
628 nwc++;
629 }
630
631 // Now that we've decided which hit to use-- check their type.
632 if (sector_hits[i].getHitType() == HitType::spacepoint) {
633 num_sp += 1;
634 }
635 if (sector_hits[i].isPixel()) {
636 num_pixel += 1;
637 }
638 }
639 ATH_MSG_DEBUG("Found " << nwc << " wildcards compared to maximum: " << m_MaxWC);
640 // Divide by 2 due to spacepoint duplication.
641 num_sp /= 2;
642 ATH_MSG_DEBUG("Found " << num_sp << " spacepoints after removing duplicates.");
643 // Require we don't have too many wildcards.
644 if (nwc > m_MaxWC)
645 {
647 return false;
648 }
649 // Require that we have a certain number of "2D" hits (i.e. pixels and spacepoints)
650 // The effect of this is that we can ensure we have 4/5 2D hits but 7/9 hits total.
651 // NOTE Again, uncomment logic below for second stage running.
652 num_sp += num_pixel;
653 int minSpacePlusPixel = /*m_isSecondStage ? m_minSpacePlusPixel2 :*/ m_minSpacePlusPixel;
654 if (num_sp < minSpacePlusPixel) {
655 ATH_MSG_DEBUG("Not enough pixel hits + spacepoints (" << num_sp << " < " << minSpacePlusPixel << ")");
657 return false;
658 }
659 return true;
660}
661
662
663// Returns the lowest index region that contains all hits in 'hits'
664int FPGATrackSimMatrixGenAlgo::getRegion(std::vector<FPGATrackSimHit> const & hits, bool is1ststage) const
665{
666 // Start with a bitmask, all true, and set a region to false if any mismatch is found
667 std::vector<bool> region_mask(m_nRegions, true);
668
669 for (FPGATrackSimHit const & hit : hits) {
670 if (hit.isReal()) { // don't worry about hits that are WCs
671 for (int region = 0; region < m_nRegions; region++) {
672 if (m_doHoughConstants && is1ststage) {
673 if (!m_FPGATrackSimMapping->RegionMap_1st()->isInRegion(region, hit))
674 region_mask[region] = false;
675 }
676 else {
677 if (!m_FPGATrackSimMapping->RegionMap_2nd()->isInRegion(region, hit))
678 region_mask[region] = false;
679 }
680 }
681 }
682 }
683
684 // For now just give preference to lowest region index for simplicity
685 for (int region = 0; region < m_nRegions; region++) {
686 if (region_mask[region])
687 return region;
688 }
689
690 return -1;
691}
692
693// Fill accumulators by dropping one hit
694StatusCode FPGATrackSimMatrixGenAlgo::fillAccumulatorByDropping(std::vector<FPGATrackSimHit> &sector_hits, bool is1ststage, double x, double y, std::vector<module_t> &modules, AccumulateMap &map, FPGATrackSimTruthTrack const & track, int subregion) const
695{
696
697 int nLayers = (is1ststage ? m_nLayers_1st : m_nLayers_2nd);
698 int nDim = (is1ststage ? m_nDim_1st : m_nDim_2nd);
699
700 int nwc = 0;
701 for (auto module : modules) {
702 if (module == -1) nwc++;
703 }
704 // Don't do this unless we miss at most one hit!
705 if (nwc < m_MaxWC) {
706 for (int layer = 0; layer < nLayers; layer++) {
707 // Back up the current hit in this layer.
708 FPGATrackSimHit backup_hit = sector_hits[layer];
709
710 // Create a new wildcard hit, and put it here.
711 ATH_MSG_DEBUG("Attempting to make wildcard in layer " << layer << ", is1ststage = " << is1ststage);
712 FPGATrackSimHit *wcHit = new FPGATrackSimHit();
714 wcHit->setLayer(layer);
715 if (is1ststage) wcHit->setDetType(m_FPGATrackSimMapping->PlaneMap_1st(subregion)->getDetType(layer));
716 else wcHit->setDetType(m_FPGATrackSimMapping->PlaneMap_2nd(subregion)->getDetType(layer));
717
718 sector_hits[layer] = *wcHit;
719
720 // If this is a spacepoint, we must also convert the other hit.
721 FPGATrackSimHit other_backup = backup_hit;
722 unsigned other_layer = 0;
723 if (backup_hit.getHitType() == HitType::spacepoint) {
724 other_layer = (backup_hit.getPhysLayer() % 2 == 0) ? layer + 1 : layer - 1;
725 other_backup = sector_hits[other_layer];
726 sector_hits[other_layer] = other_backup.getOriginalHit();
727 }
728
729 FPGATrackSimMatrixAccumulator new_acc(nLayers, nDim);
730 new_acc.pars.qOverPt = y;
731 new_acc.pars.phi = x;
732 std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> new_modules_acc = {modules, new_acc};
733
734 auto sc = makeAccumulator(sector_hits, track, new_modules_acc);
735 if (sc != StatusCode::SUCCESS){
736 delete wcHit;
737 ATH_MSG_ERROR("FPGATrackSimMatrixGenAlgo::fillAccumulatorByDropping; makeAccumulator failed");
738 return StatusCode::FAILURE;
739 }
740 accumulate(map, new_modules_acc.first, new_modules_acc.second);
741
742 // Restore the hit. May not be necessary to clean up wcHit here.
743 sector_hits[layer] = backup_hit;
744 delete wcHit;
745
746 // Restore the other layer, if this is a spacepoint.
747 if (backup_hit.getHitType() == HitType::spacepoint) {
748 sector_hits[other_layer] = other_backup;
749 }
750 }
751 }
752 return StatusCode::SUCCESS;
753}
754
755// Given a track and corresponding hits, returns the sector (list of modules) and the accumulation
756// struct.
757StatusCode FPGATrackSimMatrixGenAlgo::makeAccumulator(std::vector<FPGATrackSimHit> const & sector_hits, FPGATrackSimTruthTrack const & track, std::pair<std::vector<module_t>, FPGATrackSimMatrixAccumulator> & accumulator) const
758{
759
760
762 int nLayers = (m_doSecondStage ? m_nLayers_2nd : m_nLayers_1st);
763 int nDim = (m_doSecondStage ? m_nDim_2nd : m_nDim_1st);
764 std::vector<module_t> modules(nLayers);
765 FPGATrackSimMatrixAccumulator acc(nLayers, nDim);
766
767 //find the bin!
768 // NOTE: this only implements q/pt binning, not the subregion / eta pattern-based constants for now.
769 int sectorbin = 0;
770 double qoverpt = track.getQ() / track.getPt();
771
772 // for 2nd stage we only use one q/pt bin
773 if (m_absQOverPtBinning || m_doSecondStage) qoverpt = abs(qoverpt);
774 if (!m_doSecondStage) {
775 for (unsigned bin = 0; bin < m_qOverPtBins.size()-1; bin++) {
777 if (qoverpt < m_qOverPtBins[bin+1]) break;
778 }
779 }
780
781 // Create sector definitions (list of modules)
782 std::string module_printout = "";
783 for (int i = 0; i < nLayers; i++)
784 {
785 if (sector_hits[i].isReal()) {
786 if (m_single) modules[i] = sector_hits[i].getIdentifierHash();
787 else {
788 modules[i] = sectorbin;
789 // Modify sectorbin by a "type" field, which for now means: 0 = not spacepoint, 1 = spacepoint.
790 // This will fail if we have more than 99 q/pt bins!
791 if (sector_hits[i].getHitType() == HitType::spacepoint) {
793 }
794 module_printout += std::to_string(modules[i]) + ", ";
795 }
796 }
797 else {
798 modules[i] = -1; // WC
799 }
800 }
801
802 ATH_MSG_DEBUG("Generating track in sectorbin = " << sectorbin << " with modules: " << module_printout);
803
804
805 if (m_single) {
806 const int ToKeep[13] = {2200,2564,2861,3831,5368,14169,14173,20442,20446,29625,29629,42176,42180};
807 bool keepThis = true;
808 for (int i = 0; i < 13; i++) {
809 if (modules[i] != ToKeep[i] && modules[i] != -1) {
810 keepThis = false;
811 }
812 }
813
814 if (!keepThis) {
815 for (int i = 0; i < 13; i++) modules[i] = -1;
816 }
817 else {
818 for (int i = 0; i < 13; i++) {
819 }
820 }
821 }
822
823
824 // Hough Constants parameters
825 double y = accumulator.second.pars.qOverPt;
826 double x = accumulator.second.pars.phi;
827
828 // Vectorize (flatten) coordinates
829 std::vector<float> coords;
830
831 for (int i = 0; i < nLayers; ++i) {
832
833 if (sector_hits[i].isReal()) {
834 double target_r = (m_doSecondStage ? m_FPGATrackSimMapping->RegionMap_2nd()->getAvgRadius(0, i) : m_FPGATrackSimMapping->RegionMap_1st()->getAvgRadius(0, i));
835 // If this is a spacepoint the target R should be the average of the two layers.
836 // TODO, get this to be loaded in from a mean radii file into the mapping infrastructure.
837 if (sector_hits[i].getHitType() == HitType::spacepoint) {
838 int other_layer = (sector_hits[i].getSide() == 0) ? i + 1 : i - 1;
839 target_r = (m_doSecondStage ?
840 (target_r + m_FPGATrackSimMapping->RegionMap_2nd()->getAvgRadius(0, other_layer))/2. :
841 (target_r + m_FPGATrackSimMapping->RegionMap_1st()->getAvgRadius(0, other_layer))/2.);
842 }
843
844 std::vector<float> coords_tmp;
845 if ( m_ideal_geom > 1 ) {
846 coords_tmp = computeIdealCoords(sector_hits[i], x, y, target_r, m_doDeltaPhiConsts, TrackCorrType::Second);
847 }
848 else {
849 coords_tmp = computeIdealCoords(sector_hits[i], x, y, target_r, m_doDeltaPhiConsts, TrackCorrType::None);
850 }
851
852 // Create phi for any hits that are not spacepoints, as well as "inner" spacepoints.
853 // but not outer spacepoints. this avoids duplicate coordinates.
854 if (sector_hits[i].getHitType() != HitType::spacepoint || sector_hits[i].getSide() == 0) {
855 // get idealized gPhi
856 coords.push_back(coords_tmp[1]);
857 }
858
859 // Create a z coordinate for the "outer" layer of the spacepoint and for 2D pixel hits.
860 // This means that a spacepoint will write out (phi, eta) pairs, but (0, phi) or (phi, 0) if it's missing.
861 if (sector_hits[i].getDim() == 2 || (sector_hits[i].getHitType() == HitType::spacepoint && (sector_hits[i].getPhysLayer() % 2) == 1)) {
862 // get idealized z
863 coords.push_back(coords_tmp[0]);
864 }
865 }
866 else {
867 if (pmap->getDim(i) == 2) {
868 coords.push_back(0);
869 }
870 coords.push_back(0);
871 }
872 }
873
874 assert(coords.size() == (size_t)nDim);
875 acc.hit_coords = coords;
876 acc.hit_coordsG = coords;
877
878 // Get the track parameters
879 acc.pars = track.getPars();
881 acc.pars.qOverPt = (y / 1000.0) - track.getQOverPt(); // fit for delta q/pT
882 acc.pars.phi = x - track.getPhi(); // fit for delta phi_0
883 }
884
886 for (unsigned i = 0; i < FPGATrackSimTrackPars::NPARS; i++)
887 bins[i] = (acc.pars[i] - m_sliceMin[i]) * m_nBins[i] / (m_sliceMax[i] - m_sliceMin[i]);
888 acc.track_bins.push_back(bins);
889
890 // Force phi to be in [0, 2pi] (post binning)
891 if (!m_doDeltaPhiConsts) {
892 while (acc.pars.phi < 0) acc.pars.phi += 2*M_PI;
893 while (acc.pars.phi > 2*M_PI) acc.pars.phi -= 2*M_PI;
894 }
895
896 // Calculate the pre-multiplied elements
897 for (int i = 0; i < nDim; i++)
898 {
899 acc.hit_x_QoP[i] = coords[i] * acc.pars.qOverPt;
900 acc.hit_xG_HIP[i] = coords[i] * acc.pars.qOverPt;
901 acc.hit_x_d0[i] = coords[i] * acc.pars.d0;
902 acc.hit_x_z0[i] = coords[i] * acc.pars.z0;
903 acc.hit_x_eta[i] = coords[i] * acc.pars.eta;
904 acc.hit_xG_eta[i] = coords[i] * acc.pars.eta;
905 acc.hit_x_phi[i] = coords[i] * acc.pars.phi;
906
907 for (int j = i; j < nDim; j++)
908 acc.covariance[i * nDim + j] = coords[i] * coords[j];
909
910 for (int j = i; j < nDim; j++)
911 acc.covarianceG[i * nDim + j] = coords[i] * coords[j];
912 }
913
914 accumulator = {modules, acc};
915 return StatusCode::SUCCESS;
916}
917
918
919
921// Finalize
923
924
926{
927 ATH_MSG_DEBUG("finalize()");
928 ATH_MSG_INFO("Tracks used: " << m_nTracksUsed << "/" << m_nTracks);
929 int nLayers = (m_doSecondStage ? m_nLayers_2nd : m_nLayers_1st);
930 int nDim = (m_doSecondStage ? m_nDim_2nd : m_nDim_1st);
931
932 for (int region = 0; region < m_nRegions; region++) {
933 // Create the tree
934 std::stringstream name;
935 std::stringstream title;
936 name << "am" << region;
937 title << "Ambank " << region << " parameters";
938 TTree* tree = new TTree(name.str().c_str(), title.str().c_str());
939 ATH_CHECK(m_tHistSvc->regTree(Form("/TRIGFPGATrackSimMATRIXOUT/%s",tree->GetName()), tree));
940
941 // Fill the tree
942 ::fillTree(m_sector_cum[region], tree, nLayers, nDim);
943 // Monitoring
944 ATH_MSG_INFO("Sectors found in region " << region << ": " << m_sector_cum[region].size());
945 for (auto & sector_info : m_sector_cum[region]) {
946 double coverage = sector_info.second.track_bins.size();
947 m_h_nHit->Fill(coverage);
948 for (unsigned i = 0; i < FPGATrackSimTrackPars::NPARS; i++)
949 m_h_sectorPars[i]->Fill(sector_info.second.pars[i] / coverage);
950 }
951 }
952
954 ATH_CHECK(m_tHistSvc->finalize());
955 return StatusCode::SUCCESS;
956}
957
958
960{
961 TTree* sliceTree = new TTree("slice", "Region slice boundaries"); // slice
962
963 sliceTree->Branch("c_max", &m_sliceMax.qOverPt);
964 sliceTree->Branch("d0_max", &m_sliceMax.d0);
965 sliceTree->Branch("phi_max", &m_sliceMax.phi);
966 sliceTree->Branch("z0_max", &m_sliceMax.z0);
967 sliceTree->Branch("eta_max", &m_sliceMax.eta);
968
969 sliceTree->Branch("c_min", &m_sliceMin.qOverPt);
970 sliceTree->Branch("d0_min", &m_sliceMin.d0);
971 sliceTree->Branch("phi_min", &m_sliceMin.phi);
972 sliceTree->Branch("z0_min", &m_sliceMin.z0);
973 sliceTree->Branch("eta_min", &m_sliceMin.eta);
974
975 sliceTree->Branch("c_slices", &m_nBins.qOverPt);
976 sliceTree->Branch("d0_slices", &m_nBins.d0);
977 sliceTree->Branch("phi_slices", &m_nBins.phi);
978 sliceTree->Branch("z0_slices", &m_nBins.z0);
979 sliceTree->Branch("eta_slices", &m_nBins.eta);
980
981 StatusCode sc = m_tHistSvc->regTree("/TRIGFPGATrackSimMATRIXOUT/slice",sliceTree);
982 if (sc.isFailure()) ATH_MSG_ERROR("tHist failed");
983
984 sliceTree->Fill();
985}
#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< std::shared_ptr< const 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.
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 setLayer(unsigned v)
void setHitType(HitType type)
int getEtaModule(bool old=false) const
unsigned getPhiModule() const
unsigned getPhysLayer(bool old=false) const
bool isReal() const
const FPGATrackSimHit getOriginalHit() const
unsigned getSection() const
HitType getHitType() const
void setDetType(SiliconTech detType)
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
Gaudi::Property< bool > m_doSpacePoints
Gaudi::Property< bool > m_absQOverPtBinning
Gaudi::Property< float > m_temp_phi_min
Gaudi::Property< float > m_temp_z0_min
StatusCode makeAccumulator(std::vector< FPGATrackSimHit > const &sector_hits, FPGATrackSimTruthTrack const &track, std::pair< std::vector< module_t >, FPGATrackSimMatrixAccumulator > &accumulator) const
ToolHandle< FPGATrackSimClusteringToolI > m_clusteringTool
ToolHandle< FPGATrackSimOverlapRemovalTool > m_overlapRemovalTool
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
StatusCode fillAccumulatorByDropping(std::vector< FPGATrackSimHit > &sector_hits, bool is1ststage, double x, double y, std::vector< module_t > &modules, AccumulateMap &map, FPGATrackSimTruthTrack const &track, int subregion) const
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