ATLAS Offline Software
Loading...
Searching...
No Matches
TrigFastTrackFinder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// TrigFastTrackFinder.cxx
7// -------------------------------
8// ATLAS Collaboration
9//
10// package created 16/04/2013 by Dmitry Emeliyanov (see ChangeLog for more details)
11//
13
14
15
16#include "TrigFastTrackFinder.h"
17
28
29//
32#include "TrkTrack/Track.h"
33
35#include "TrkTrack/Track.h"
36
37#include "CxxUtils/phihelper.h"
38
40
42
44
45//for UTT
48
49#include <cmath>
50#include <iostream>
51#include <algorithm>
52#include <memory>
53
54TrigFastTrackFinder::TrigFastTrackFinder(const std::string& name, ISvcLocator* pSvcLocator) :
55
56 AthReentrantAlgorithm(name, pSvcLocator),
57 m_trackMaker("InDet::SiTrackMaker_xk/InDetTrigSiTrackMaker"),
58 m_trigInDetTrackFitter("TrigInDetTrackFitter"),
59 m_trigZFinder("TrigZFinder/TrigZFinder", this ),
60 m_trackSummaryTool("Trk::ITrackSummaryTool/ITrackSummaryTool"),
61 m_disTrkFitter("Trk::GlobalChi2Fitter/InDetTrackFitter"),
62 m_useBeamSpot(true),
63 m_doZFinder(false),
64 m_doZFinderOnly(false),
66 m_nfreeCut(5),
70 m_pixelId(0),
71 m_sctId(0),
72 m_idHelper(0),
75 m_useGPU(false),
76 m_LRTmode(false),
77 m_LRTD0Min(0.0),
78 m_LRTHardMinPt(0.0),
80 m_dodEdxTrk(false),
82 m_ITkMode(false),
83 m_standaloneMode(false)
84{
85
87 declareProperty( "MinHits", m_minHits = 5,"Minimum number of hits needed to perform tracking" );
88
89 //** Zfinder mode
90 declareProperty( "doZFinder", m_doZFinder = true,"Use fast ZFinder to find z of primary vertices");
91 declareProperty( "doZFinderOnly", m_doZFinderOnly = false,"stop processing after ZFinder - no tracking performed");
92 declareProperty( "VertexSeededMode", m_vertexSeededMode = false); //** NOT USED Obsolete? ATR-24242
93 declareProperty( "doFastZVertexSeeding", m_doFastZVseeding = true,"Use ZFinder vertex information to filter seeds");
94 declareProperty( "zVertexResolution", m_tcs.m_zvError = 10.0," Half-width (mm) in z of z region used to filter seeds when doFastZVertexSeeding enabled" );
95 declareProperty( "zVertexResolutionEndcap", m_tcs.m_zvErrorEndcap = -1," Half-width (mm) in z of region used to filter seeds when doFastZVertexSeeding enabled, for endcap pixels; set to zVertexResolution value later if left negative" );
96 declareProperty( "StoreZFinderVertices", m_storeZFinderVertices = false ); //** NOT USED - to be implemented ATR-24242
97
98
100 declareProperty("useNewLayerNumberScheme", m_useNewLayerNumberScheme = false,"Use LayerNumberTool for layer numbers");
101
103 declareProperty("Doublet_FilterRZ", m_tcs.m_doubletFilterRZ = true,"Enable check that doublet is consistent with the RoI in the RZ plane");
104 declareProperty("DoubletDR_Max", m_tcs.m_doublet_dR_Max = 270.0,"Maximum Radial distance between spacepoints forming Doublets");
105 declareProperty("SeedRadBinWidth", m_tcs.m_seedRadBinWidth = 2.0);
106
108 declareProperty("Triplet_D0Max", m_tcs.m_tripletD0Max = 4.0,"Maximum d0 for triplet");
109 declareProperty("Triplet_D0_PPS_Max", m_tcs.m_tripletD0_PPS_Max = 1.7,"Maximin d0 for PPS doublets");
110 declareProperty("Triplet_nMaxPhiSlice", m_tcs.m_nMaxPhiSlice = 53,"Number of phi-slices used for seeding");
111 declareProperty("Triplet_MaxBufferLength", m_tcs.m_maxTripletBufferLength = 3,"Maximum number of triplets sharing a common middle spacepoint");
112 declareProperty("TripletDoPSS", m_tcs.m_tripletDoPSS = false,"Allow PSS Triplet seeds");
113 declareProperty("TripletDoPPS", m_tcs.m_tripletDoPPS = true,"Allow PPS triplet seeds");
114 declareProperty("TripletDoConfirm", m_tcs.m_tripletDoConfirm = false,"Enable triplet confirmation");
115 declareProperty("DoubletDR_Max_Confirm", m_tcs.m_doublet_dR_Max_Confirm = 150.0,"doublet max DR when TripletDoConfirm enabled");
116 declareProperty("TripletMaxCurvatureDiff", m_tcs.m_curv_delta = 0.001,"Maximum curvature difference allowed in seed confirmation");//for the triplet confirmation
117 declareProperty("Triplet_DtCut", m_tcs.m_tripletDtCut = 10.0);//i.e. 10*sigma_MS
118 declareProperty("pTmin", m_pTmin = 1000.0,"Triplet pT threshold is pTmin*Triplet_MinPtFrac" );
119 declareProperty("Triplet_MinPtFrac", m_tripletMinPtFrac = 0.3,"Triplet pT threshold is pTmin*Triplet_MinPtFrac");
120 declareProperty("doSeedRedundancyCheck", m_checkSeedRedundancy = false,"skip Triplets already used in a track");
121
123 declareProperty("UseTrigSeedML", m_tcs.m_useTrigSeedML = 0,"set ML-based seed selection mode (0 disables)" );
124 declareProperty("TrigSeedML_LUT", m_trigseedML_LUT = "trigseed_ml_pixel_barrel_kde.lut","LUT used by ML-based seed selection");
125 declareProperty("maxEC_Pixel_cluster_length", m_tcs.m_maxEC_len = 1.5,"Maximum Endcap Pixel cluster length for ML-based seed selection" );
126
127
128 //* Clone removal (removal of tracks sharing too many hits */
129
130 declareProperty( "FreeClustersCut" ,m_nfreeCut,"Minimum number of unshared clusters");
131
132 //** Cuts applied to final tracks after Fit
133 declareProperty("TrackInitialD0Max", m_initialD0Max = 10.0,"Maximum d0 of track");
134 declareProperty("TrackZ0Max", m_Z0Max = 300.0,"Maximum z0 of track");
135
136
137 /* Monitoring */
138 declareProperty( "doResMon", m_doResMonitoring = true,"enable unbiased residual monitoring");
139 declareProperty( "UseBeamSpot", m_useBeamSpot = true,"Monitor d0 with respect to beamspot");
140
141 //* Collection Names */
142 declareProperty("TracksName",
143 m_outputTracksKey = std::string("TrigFastTrackFinder_Tracks"),
144 "TrackCollection name");
145
146 declareProperty("inputTracksName",
147 m_inputTracksKey = std::string(""),
148 "TrackCollection name");
149
150 declareProperty("RoIs", m_roiCollectionKey = std::string("OutputRoIs"), "RoIs to read in");
151
152 //* Tools */
153 declareProperty( "initialTrackMaker", m_trackMaker);
154 declareProperty( "trigInDetTrackFitter", m_trigInDetTrackFitter );
155 declareProperty( "trigZFinder", m_trigZFinder );
156 declareProperty("TrackSummaryTool", m_trackSummaryTool);
157
158 // Accleration
159 declareProperty("useGPU", m_useGPU = false,"Use GPU acceleration");
160
161 // Large Radius Tracking
162 declareProperty("LRT_Mode", m_LRTmode,"Enable Large Radius Tracking mode" );
163 declareProperty("LRT_D0Min", m_LRTD0Min=0.0,"Minimum d0 for tracks to be saved in LRT Mode" );
164 declareProperty("LRT_HardMinPt", m_LRTHardMinPt=0.0,"Minimum pT for tracks to be saved in LRT Mode");
165
166 // UTT
167 declareProperty("dodEdxTrk", m_dodEdxTrk = false);
168 declareProperty("doDisappearingTrk", m_doDisappearingTrk = false);
169 declareProperty("DisTrackFitter", m_disTrkFitter );
170
171 // Phase II
172 declareProperty("ITkMode", m_ITkMode = false);
173 declareProperty("StandaloneMode", m_standaloneMode = false);
174
175}
176
177//--------------------------------------------------------------------------
178
180
181//-----------------------------------------------------------------------
182
184
186 ATH_CHECK(m_outputTracksKey.initialize() );
187
188 // optional input tracks collection if present the clusters on previously found tracks are not used to form seeds
189 if (m_LRTmode) {
190 ATH_CHECK(m_inputTracksKey.initialize( !m_inputTracksKey.key().empty() ) );
191 }
192 // optional PRD to track association map
193 ATH_CHECK(m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty() ));
194
195
196 ATH_CHECK(m_beamSpotKey.initialize());
197
198 ATH_MSG_DEBUG(" TrigFastTrackFinder : MinHits set to " << m_minHits);
199
200 ATH_CHECK(m_numberingTool.retrieve());
201
202 if(!m_ITkMode) {
203 ATH_CHECK(m_spacePointTool.retrieve());
204 }
205 else {
206 m_spacePointTool.disable();
207 }
208
209 ATH_CHECK(m_trackMaker.retrieve());
210
212
213 if (m_doZFinder) {
214 ATH_CHECK(m_trigZFinder.retrieve());
215 // If m_tcs.m_zvErrorEndcap has negative default value, it was not set by user,
216 // so set it to the same value as m_tcs.m_zvError
217 if (m_tcs.m_zvErrorEndcap < 0) m_tcs.m_zvErrorEndcap = m_tcs.m_zvError;
218 } else {
219 m_trigZFinder.disable();
220 }
221
222 ATH_CHECK(m_trackSummaryTool.retrieve());
223
224 //Get ID helper
225 ATH_CHECK(detStore()->retrieve(m_idHelper, "AtlasID"));
226
227 ATH_CHECK(detStore()->retrieve(m_pixelId, "PixelID"));
228
229 ATH_CHECK(detStore()->retrieve(m_sctId, "SCT_ID"));
230
231 // monitoring
232 if ( !m_monTool.empty() ) {
233 ATH_CHECK(m_monTool.retrieve() );
234 }
235 else {
236 ATH_MSG_INFO("Monitoring tool is empty");
237 }
238
239 ATH_MSG_DEBUG(" doResMon " << m_doResMonitoring);
240
241 if(m_useGPU) {//for GPU acceleration
242 ATH_CHECK(m_accelSvc.retrieve());
243 ATH_CHECK(m_accelTool.retrieve());
244 }
245
246 ATH_MSG_INFO("Use GPU acceleration : "<<std::boolalpha<<m_useGPU);
247
248 if (m_LRTmode) {
249 ATH_MSG_INFO(" FTF configures in Large Radius Tracking Mode");
250 // set TrigTrackSeedGenerator to LRTmode
251 m_tcs.m_LRTmode=m_LRTmode;
252
253 }
254
255 if(m_tcs.m_useTrigSeedML > 0) {
256 //LUT params
257 int lut_w = 30;
258 int lut_h = 45;
259 float lut_range[4] = {0.0,3.0,0.0,9.0};
260 TrigSeedML_LUT L(1,lut_w,lut_h,lut_range);
261 //read data from LUT file
262 std::string lut_fileName = PathResolver::find_file(m_trigseedML_LUT, "DATAPATH");
263 if (lut_fileName.empty()) {
264 ATH_MSG_ERROR("Cannot find TrigSeedML LUT file " << lut_fileName);
265 return StatusCode::FAILURE;
266 }
267 else {
268 ATH_MSG_INFO(lut_fileName);
269 std::ifstream ifs(lut_fileName.c_str());
270 int row, col0, col1;
271 while(!ifs.eof()) {
272 ifs >> row >> col0 >> col1;
273 if(ifs.eof()) break;
274 for(int c=col0;c<=col1;c++) L.setBin(row, c);
275 }
276 ifs.close();
277 ATH_MSG_INFO("TrigSeedML LUT initialized from file " << m_trigseedML_LUT);
278 m_tcs.m_vLUT.push_back(L);
279 }
280 }
281 if (m_ITkMode) {
282 ATH_CHECK(m_seedingTool.retrieve());
283 } else {
284 m_seedingTool.disable();
285 }
286
287 // UTT tools
288 if( m_doDisappearingTrk ) {
289 ATH_CHECK(m_extrapolator.retrieve());
290 ATH_MSG_DEBUG("Retrieved tool " << m_extrapolator);
291
292 ATH_CHECK(m_disTrkFitter.retrieve());
293 ATH_MSG_DEBUG("Retrieved tool " << m_disTrkFitter);
294 } else {
295 m_extrapolator.disable();
296 m_disTrkFitter.disable();
297 }
298
299 // UTT read/write handles
300 ATH_CHECK( m_dEdxTrkKey.initialize(m_dodEdxTrk) );
301 ATH_CHECK( m_dEdxHitKey.initialize(m_dodEdxTrk) );
303
304 //
305 ATH_MSG_DEBUG("FTF : " << name() );
306 ATH_MSG_DEBUG(" m_tcs.m_doubletFilterRZ : " << m_tcs.m_doubletFilterRZ );
307 ATH_MSG_DEBUG(" m_tcs.m_doublet_dR_Max : " << m_tcs.m_doublet_dR_Max );
308 ATH_MSG_DEBUG(" m_tcs.m_doublet_dR_Max_Confirm : " << m_tcs.m_doublet_dR_Max_Confirm );
309 ATH_MSG_DEBUG(" m_tcs.m_seedRadBinWidth : " << m_tcs.m_seedRadBinWidth );
310 ATH_MSG_DEBUG(" m_tcs.m_tripletD0Max : " << m_tcs.m_tripletD0Max );
311 ATH_MSG_DEBUG(" m_tcs.m_tripletD0_PPS_Max : " << m_tcs.m_tripletD0_PPS_Max );
312 ATH_MSG_DEBUG(" m_tcs.m_nMaxPhiSlice : " << m_tcs.m_nMaxPhiSlice );
313 ATH_MSG_DEBUG(" m_tcs.m_maxTripletBufferLength : " << m_tcs.m_maxTripletBufferLength );
314 ATH_MSG_DEBUG(" m_tcs.m_tripletDoPSS : " << m_tcs.m_tripletDoPSS );
315 ATH_MSG_DEBUG(" m_tcs.m_tripletDoPPS : " << m_tcs.m_tripletDoPPS );
316 ATH_MSG_DEBUG(" m_tcs.m_tripletDoConfirm : " << m_tcs.m_tripletDoConfirm );
317 ATH_MSG_DEBUG(" m_tcs.m_curv_delta : " << m_tcs.m_curv_delta );
318 ATH_MSG_DEBUG(" m_tcs.m_tripletDtCut : " << m_tcs.m_tripletDtCut );
319 ATH_MSG_DEBUG(" m_tcs.m_useTrigSeedML : " << m_tcs.m_useTrigSeedML );
320 ATH_MSG_DEBUG(" m_trigseedML_LUT : " << m_trigseedML_LUT );
321 ATH_MSG_DEBUG(" m_tcs.m_maxEC_len : " << m_tcs.m_maxEC_len );
322 ATH_MSG_DEBUG(" m_vertexSeededMode : " << m_vertexSeededMode );
323 ATH_MSG_DEBUG(" m_doZFinder : " << m_doZFinder );
324 ATH_MSG_DEBUG(" m_doZFinderOnly : " << m_doZFinderOnly );
325 ATH_MSG_DEBUG(" m_doFastZVseeding : " << m_doFastZVseeding );
326 ATH_MSG_DEBUG(" m_tcs.m_zvError : " << m_tcs.m_zvError );
327 ATH_MSG_DEBUG(" m_tcs.m_zvErrorEndcap : " << m_tcs.m_zvErrorEndcap );
328 ATH_MSG_DEBUG(" m_storeZFinderVertices : " << m_storeZFinderVertices );
329 ATH_MSG_DEBUG(" m_tripletMinPtFrac : " << m_tripletMinPtFrac );
330 ATH_MSG_DEBUG(" m_pTmin : " << m_pTmin );
331 ATH_MSG_DEBUG(" m_initialD0Max : " << m_initialD0Max );
332 ATH_MSG_DEBUG(" m_Z0Max : " << m_Z0Max );
333 ATH_MSG_DEBUG(" m_checkSeedRedundancy : " << m_checkSeedRedundancy );
334 ATH_MSG_DEBUG(" m_minHits : " << m_minHits );
335 ATH_MSG_DEBUG(" " );
336 ATH_MSG_DEBUG(" m_useBeamSpot : " << m_useBeamSpot );
337 ATH_MSG_DEBUG(" m_nfreeCut : " << m_nfreeCut );
338 ATH_MSG_DEBUG(" m_spacePointTool : " << m_spacePointTool );
339 ATH_MSG_DEBUG(" m_numberingTool : " << m_numberingTool );
340 ATH_MSG_DEBUG(" m_trackMaker : " << m_trackMaker );
341 ATH_MSG_DEBUG(" m_trigInDetTrackFitter : " << m_trigInDetTrackFitter );
342 ATH_MSG_DEBUG(" m_trigZFinder : " << m_trigZFinder );
343 ATH_MSG_DEBUG(" m_trackSummaryTool : " << m_trackSummaryTool );
344 ATH_MSG_DEBUG(" m_doResMonitoring : " << m_doResMonitoring );
345 ATH_MSG_DEBUG(" m_doCloneRemoval : " << m_doCloneRemoval );
346 ATH_MSG_DEBUG(" m_useNewLayerNumberScheme : " << m_useNewLayerNumberScheme );
347 ATH_MSG_DEBUG(" m_useGPU : " << m_useGPU );
348 ATH_MSG_DEBUG(" m_LRTmode : " << m_LRTmode );
349 ATH_MSG_DEBUG(" m_dodEdxTrk : " << m_dodEdxTrk );
350 ATH_MSG_DEBUG(" m_ITkMode : " << m_ITkMode );
351 ATH_MSG_DEBUG(" m_useTracklets : " << m_useTracklets );
352
353 ATH_MSG_DEBUG(" Initialized successfully");
354
355
356 return StatusCode::SUCCESS;
357}
358
359
360//-------------------------------------------------------------------------
361
363{
364 //getting magic numbers from the layer numbering tool
365
366 m_tcs.m_maxBarrelPix = m_numberingTool->offsetBarrelSCT();
367 m_tcs.m_minEndcapPix = m_numberingTool->offsetEndcapPixels();
368 m_tcs.m_maxEndcapPix = m_numberingTool->offsetEndcapSCT();
369 m_tcs.m_maxSiliconLayer = m_numberingTool->maxSiliconLayerNum();
370 m_tcs.m_layerGeometry.clear();
371
373 const std::vector<TrigInDetSiLayer>* pVL = m_numberingTool->layerGeometry();
374 std::copy(pVL->begin(),pVL->end(),std::back_inserter(m_tcs.m_layerGeometry));
375 }
376
377 m_tcs.m_tripletPtMin = m_tripletMinPtFrac*m_pTmin;
378
379 return StatusCode::SUCCESS;
380}
381
382
383StatusCode TrigFastTrackFinder::execute(const EventContext& ctx) const {
384
386
387 outputTracks = std::make_unique<TrackCollection>();
388
389 const TrackCollection* inputTracks = nullptr;
390 if (m_LRTmode) {
391 if (!m_inputTracksKey.key().empty()){
393 ATH_CHECK(inputTrackHandle.isValid());
394 inputTracks = inputTrackHandle.ptr();
395 }
396 }
398
399 //RoI preparation/update
400
401 if (m_standaloneMode) {
402 //the default fullscan TrigRoiDescriptor settings for beamspot width (z-range) are incorrect
403 const TrigRoiDescriptor internalRoI = TrigRoiDescriptor(0, -4.5, 4.5, 0, -M_PI, M_PI, 0, -150.0, 150.0);
404
405 ATH_CHECK(findTracks(trackEventData, internalRoI, inputTracks, *outputTracks, ctx));
406
407 } else {
409
410 ATH_CHECK(roiCollection.isValid());
411
412 if ( roiCollection->size()>1 ) ATH_MSG_WARNING( "More than one Roi in the collection: " << m_roiCollectionKey << ", this is not supported - use a composite Roi: Using the first Roi ONLY" );
413
414 if ( roiCollection->size()==0) {
415 ATH_MSG_ERROR("No Roi found for " << m_roiCollectionKey.key() );
416 return StatusCode::FAILURE;
417 }
418
419 TrigRoiDescriptor internalRoI = **roiCollection->begin();
420
421 ATH_CHECK(findTracks(trackEventData, internalRoI, inputTracks, *outputTracks, ctx));
422 }
423
425
428
429 return StatusCode::SUCCESS;
430}
431
432
433
435 const TrigRoiDescriptor& roi,
436 const TrackCollection* inputTracks,
437 TrackCollection& outputTracks,
438 const EventContext& ctx) const {
439 ATH_MSG_DEBUG( "Input RoI " << roi );
440
441 auto mnt_roi_nTracks = Monitored::Scalar<int>("roi_nTracks", 0);
442 std::vector<int> vec_seedSize;
443 auto mnt_seedSize = Monitored::Collection("trk_seedSize", vec_seedSize);
444 auto mnt_roi_nSPs = Monitored::Scalar<int>("roi_nSPs", 0);
445 auto mnt_roi_nSPsPIX = Monitored::Scalar<int>("roi_nSPsPIX", 0);
446 auto mnt_roi_nSPsSCT = Monitored::Scalar<int>("roi_nSPsSCT", 0);
447 auto monSP = Monitored::Group(m_monTool, mnt_roi_nSPsPIX, mnt_roi_nSPsSCT, mnt_seedSize);
448
449 auto mnt_timer_Total = Monitored::Timer<std::chrono::milliseconds>("TIME_Total");
450 auto mnt_timer_SpacePointConversion = Monitored::Timer<std::chrono::milliseconds>("TIME_SpacePointConversion");
451 auto mnt_timer_PatternReco = Monitored::Timer<std::chrono::milliseconds>("TIME_PattReco");
452 auto mnt_timer_TripletMaking = Monitored::Timer<std::chrono::milliseconds>("TIME_Triplets");
453 auto mnt_timer_CombTracking = Monitored::Timer<std::chrono::milliseconds>("TIME_CmbTrack");
454 auto mnt_timer_TrackFitter = Monitored::Timer<std::chrono::milliseconds>("TIME_TrackFitter");
455 auto mnt_timer_dEdxTrk = Monitored::Timer<std::chrono::milliseconds>("TIME_dEdxTrk");
456 auto mnt_timer_disTrkZVertex = Monitored::Timer<std::chrono::milliseconds>("TIME_disTrkZVertex");
457 auto mnt_timer_disTrk = Monitored::Timer<std::chrono::milliseconds>("TIME_disappearingTrack");
458 auto monTime = Monitored::Group(m_monTool, mnt_roi_nTracks, mnt_roi_nSPs, mnt_timer_Total, mnt_timer_SpacePointConversion,
459 mnt_timer_PatternReco, mnt_timer_TripletMaking, mnt_timer_CombTracking, mnt_timer_TrackFitter,
460 mnt_timer_dEdxTrk, mnt_timer_disTrkZVertex, mnt_timer_disTrk);
461
462 auto mnt_roi_lastStageExecuted = Monitored::Scalar<int>("roi_lastStageExecuted", 0);
463 auto monDataError = Monitored::Group(m_monTool, mnt_roi_lastStageExecuted);
464
465 mnt_timer_Total.start();
466 mnt_timer_SpacePointConversion.start();
467
468
469 mnt_roi_lastStageExecuted = 1;
470
471 std::vector<TrigSiSpacePointBase> convertedSpacePoints;
472
473 convertedSpacePoints.reserve(5000);
474
475 std::map<Identifier, std::vector<long int> > siClusterMap;
476
477 if (!m_ITkMode) {
478
479 if (m_LRTmode) {
480 // In LRT mode read the input track collection and enter the clusters on track into the cluster map so these are not used for seeding
481 if (!m_inputTracksKey.key().empty()) {
482 ATH_MSG_DEBUG("LRT Mode: Got input track collection with "<<inputTracks->size()<< "tracks");
483 long int trackIndex=0;
484 for (auto t:*inputTracks) {
485 updateClusterMap(trackIndex++, t, siClusterMap);
486 }
487 }
488 ATH_CHECK(m_spacePointTool->getSpacePoints(roi, convertedSpacePoints, mnt_roi_nSPsPIX, mnt_roi_nSPsSCT, ctx, &siClusterMap));
489 }
490 else {
491 ATH_CHECK(m_spacePointTool->getSpacePoints(roi, convertedSpacePoints, mnt_roi_nSPsPIX, mnt_roi_nSPsSCT, ctx));
492 }
493
494 }
495
496 mnt_timer_SpacePointConversion.stop();
497 mnt_roi_nSPs = mnt_roi_nSPsPIX + mnt_roi_nSPsSCT;
498
499 if (!m_ITkMode) {
500
501 if( mnt_roi_nSPs >= m_minHits ) {
502 ATH_MSG_DEBUG("REGTEST / Found " << mnt_roi_nSPs << " space points.");
503 ATH_MSG_DEBUG("REGTEST / Found " << mnt_roi_nSPsPIX << " Pixel space points.");
504 ATH_MSG_DEBUG("REGTEST / Found " << mnt_roi_nSPsSCT << " SCT space points.");
505 ATH_MSG_DEBUG("REGTEST / converted space points size = " << convertedSpacePoints.size());
507 }
508 else {
509 ATH_MSG_DEBUG("No tracks found - too few hits in ROI to run " << mnt_roi_nSPs);
511 return StatusCode::SUCCESS;
512 }
513 }
514
515 mnt_roi_lastStageExecuted = 2;
516
518 std::unique_ptr<TrigRoiDescriptor> tmpRoi = std::make_unique<TrigRoiDescriptor>(roi);
519
520 auto vertices = std::make_unique<TrigVertexCollection>();
521 std::vector<float> vZv;
522
523 if (m_doZFinder) {
524 auto mnt_timer_ZFinder = Monitored::Timer<std::chrono::milliseconds>("TIME_ZFinder");
525 auto monTimeZFinder = Monitored::Group(m_monTool, mnt_timer_ZFinder);
526 mnt_timer_ZFinder.start();
527
529 tmpRoi = std::make_unique<TrigRoiDescriptor>(true);
530 tmpRoi->setComposite(true);
531
532 vertices = std::make_unique<TrigVertexCollection>(*m_trigZFinder->findZ( convertedSpacePoints, roi));
533
534 ATH_MSG_DEBUG("vertices->size(): " << vertices->size());
535
536
537 if ( m_doFastZVseeding ) {
538 vZv.reserve(vertices->size());
539 for (const auto vertex : *vertices) {
540 ATH_MSG_DEBUG("REGTEST / ZFinder vertex: " << *vertex);
541 float z = vertex->z();
542 float zMinus = z - 7.0;
543 float zPlus = z + 7.0;
544 TrigRoiDescriptor* newRoi = new TrigRoiDescriptor(roi.eta(), roi.etaMinus(), roi.etaPlus(),
545 roi.phi(), roi.phiMinus(), roi.phiPlus(), z, zMinus, zPlus);
546 tmpRoi->push_back(newRoi);
547 vZv.push_back(z);
548 }
549
550 ATH_MSG_DEBUG("REGTEST / tmpRoi: " << *tmpRoi);
551 }
552
553 mnt_timer_ZFinder.stop();
554
555 if ( m_doZFinderOnly ) {
561 return StatusCode::SUCCESS;
562 }
563 }
564
565
566 mnt_roi_lastStageExecuted = 3;
567
568 mnt_timer_PatternReco.start();
569
570 mnt_timer_TripletMaking.start();
571
572 std::vector<TrigInDetTriplet> triplets;
573
574 std::vector<TrigInDetTracklet> new_tracklets;
575
576 if(!m_useGPU) {
577
578 if (m_ITkMode) {
579
580 TrigInDetTrackSeedingResult seed_result = m_seedingTool->findSeeds(roi, new_tracklets, ctx);
581
582 mnt_roi_nSPsPIX = seed_result.m_nPixelSPs;
583 mnt_roi_nSPsSCT = seed_result.m_nStripSPs;
584 mnt_roi_nSPs = mnt_roi_nSPsPIX + mnt_roi_nSPsSCT;
585
586 if( mnt_roi_nSPs >= m_minHits ) {
587 ATH_MSG_DEBUG("REGTEST / Found " << mnt_roi_nSPs << " space points.");
588 ATH_MSG_DEBUG("REGTEST / Found " << mnt_roi_nSPsPIX << " Pixel space points.");
589 ATH_MSG_DEBUG("REGTEST / Found " << mnt_roi_nSPsSCT << " SCT space points.");
591 }
592 else {
593 ATH_MSG_DEBUG("No tracks found - too few hits in ROI to run " << mnt_roi_nSPs);
595 return StatusCode::SUCCESS;
596 }
597
598 } else {
600
601 seedGen.loadSpacePoints(convertedSpacePoints);
602
604 seedGen.createSeeds(tmpRoi.get(), vZv);
605 }
606 else {
607 seedGen.createSeeds(tmpRoi.get());
608 }
609
610 seedGen.getSeeds(triplets);
611 }
612 }
613 else {
614 //GPU offloading begins ...
615 ATH_CHECK(m_accelSvc->isReady()); // or remake it into afterfork incident
616 makeSeedsOnGPU(m_tcs, tmpRoi.get(), convertedSpacePoints, triplets);
617
618 //GPU offloading ends ...
619 }
620
621 unsigned int nTrackSeeds = m_useTracklets ? new_tracklets.size() : triplets.size();
622
623 ATH_MSG_DEBUG("number of triplets: " << nTrackSeeds);
624
625 mnt_timer_TripletMaking.stop();
626 mnt_roi_lastStageExecuted = 4;
627
628 mnt_timer_CombTracking.start();
629
630 // 8. Combinatorial tracking
631
632 std::vector<std::tuple<bool, double,Trk::Track*>> qualityTracks; //bool used for later filtering
633 qualityTracks.reserve(nTrackSeeds);
634
635 auto mnt_roi_nSeeds = Monitored::Scalar<int>("roi_nSeeds", 0);
636 auto monTrk_seed = Monitored::Group(m_monTool, mnt_roi_nSeeds);
637
638 long int trackIndex=0;
639
640 bool PIX = true;
641 bool SCT = true;
642
643 m_trackMaker->newTrigEvent(ctx, trackEventData, PIX, SCT);
645
646 std::vector<Trk::Track*> disFailTrks;
647 std::vector<Trk::Track*> disCombTrks;
648 std::vector<std::tuple<bool, double, Trk::Track*>> qualityDisFailTrks;
649 std::vector<std::tuple<bool, double, Trk::Track*>> qualityDisCombTrks;
650 int disTrk_n_disCombTrks=0;
651 int disTrk_n_disCombTrks_cleaning=0;
652 int disTrk_n_disFailTrks=0;
653 int disTrk_n_disFailTrks_cleaning=0;
654
655
656
657 for(unsigned int seedIdx=0;seedIdx!=nTrackSeeds;seedIdx++) {
658
659 std::vector<const Trk::SpacePoint*> spVec;
660
661 if( m_useTracklets && (!new_tracklets.empty())) { //create an n-SP seed
662 spVec = new_tracklets[seedIdx].seed();
663 }
664 else {
665
666 const TrigInDetTriplet &seed = triplets[seedIdx];
667 const Trk::SpacePoint* osp1 = seed.s1().offlineSpacePoint();
668 const Trk::SpacePoint* osp2 = seed.s2().offlineSpacePoint();
669 const Trk::SpacePoint* osp3 = seed.s3().offlineSpacePoint();
670
671 spVec = {osp1, osp2, osp3};//create a 3-SP seed
672 }
673
674 vec_seedSize.push_back(spVec.size());//monitoring seed length for GBTS seeding
675
677 //check if clusters do not belong to any track
678 std::vector<Identifier> clusterIds;
679 extractClusterIds(spVec.at(0), clusterIds);
680 extractClusterIds(spVec.at(1), clusterIds);
681 extractClusterIds(spVec.at(2), clusterIds);
682 if(usedByAnyTrack(clusterIds, siClusterMap)) {
683 continue;
684 }
685 }
686 ++mnt_roi_nSeeds;
687
688 std::list<Trk::Track*> tracks;
689 std::list<Trk::Track*> tracksFail;
690 std::list<Trk::Track*> tracksAll = m_trackMaker->getTracks(ctx, trackEventData, spVec);
691 auto resultCode = trackEventData.combinatorialData().resultCode();
693 tracks = tracksAll;
694 }
695 else {
696 tracksFail = tracksAll;
697 }
698
699 if( m_doDisappearingTrk ) {
700 ATH_MSG_VERBOSE("size of tracks=" << tracks.size() << ", tracksFail=" << tracksFail.size() << ": resultCode=" << resultCode);
701 const TrigInDetTriplet &seed = triplets[seedIdx];
702 for(std::list<Trk::Track*>::const_iterator t=tracks.begin(); t!=tracks.end(); ++t) {
703 if( ! (*t) ) continue;
704 m_trackSummaryTool->updateTrack(ctx, **t);
705 disTrk_n_disCombTrks++;
706 if( (*t)->perigeeParameters()!=0 && isCleaningPassDisTrack(seed, (*t), false) ) {
707 ATH_MSG_VERBOSE("... combTrk, cleaningPass");
708 disTrk_n_disCombTrks_cleaning++;
709 disCombTrks.push_back((*t));
710 qualityDisCombTrks.emplace_back(std::make_tuple(true, -disTrackQuality((*t)), (*t)));
711 }
712 }
713 for(std::list<Trk::Track*>::const_iterator t=tracksFail.begin(); t!=tracksFail.end(); ++t) {
714 if( ! (*t) ) continue;
715 m_trackSummaryTool->updateTrack(ctx, **t);
716 disTrk_n_disFailTrks++;
717 if( (*t)->perigeeParameters()!=0 && isCleaningPassDisTrack(seed, (*t), true) ) {
718 ATH_MSG_VERBOSE("... failTrk, cleaningPass");
719 disTrk_n_disFailTrks_cleaning++;
720 disFailTrks.push_back((*t));
721 qualityDisFailTrks.emplace_back(std::make_tuple(true, -disTrackQuality((*t)), (*t)));
722 }
723 else {
724 delete(*t); // delete failed trk but not disFailTrk candidate
725 }
726 }
727 }
728
729 for(std::list<Trk::Track*>::const_iterator t=tracks.begin(); t!=tracks.end(); ++t) {
730 if((*t)) {
731 float d0 = (*t)->perigeeParameters()==0 ? 10000.0 : (*t)->perigeeParameters()->parameters()[Trk::d0];
732 if (std::abs(d0) > m_initialD0Max) {
733 ATH_MSG_DEBUG("REGTEST / Reject track with d0 = " << d0 << " > " << m_initialD0Max);
734 qualityTracks.push_back(std::make_tuple(false,0,(*t)));//Flag track as bad, but keep in vector for later deletion
735 continue;
736 }
738 //update clusterMap
739 updateClusterMap(trackIndex++, (*t), siClusterMap);
740 }
741 if(m_doCloneRemoval) {
742 qualityTracks.push_back(std::make_tuple(true, -trackQuality((*t)), (*t)));
743 }
744 else {
745 qualityTracks.push_back(std::make_tuple(true, 0, (*t)));
746 }
747 }
748 }
749 ATH_MSG_VERBOSE("Found "<<tracks.size()<<" tracks using triplet");
750 }
751
752 if( m_doDisappearingTrk ) {
753 ATH_MSG_DEBUG("===> nr of disFailTrks=" << disTrk_n_disFailTrks << " -> cleaning pass=" << disTrk_n_disFailTrks_cleaning);
754 ATH_MSG_DEBUG("===> nr of disCombTrks=" << disTrk_n_disCombTrks << " -> cleaning pass=" << disTrk_n_disCombTrks_cleaning);
755 }
756
757 m_trackMaker->endEvent(trackEventData);
758
759 //clone removal
760 if(m_doCloneRemoval) {
761 filterSharedTracks(qualityTracks);
762 }
763
764 // filter shared hits
765 if( m_doDisappearingTrk ) {
766 filterSharedDisTracks(qualityDisFailTrks);
767 filterSharedDisTracks(qualityDisCombTrks);
768 }
769
770 TrackCollection initialTracks;
771 initialTracks.reserve(qualityTracks.size());
772
773 TrackCollection extraDisCombTracks;
774 // if( m_doDisappearingTrk ) extraDisCombTracks.reserve(qualityTracks.size());
775
776 unsigned int idx=0;
777 std::vector<unsigned int> indexDisCombTrk;
778 for(const auto& q : qualityTracks) {
779 bool needed_for_disCombTrk = false;
780 if( m_doDisappearingTrk ) {
781 Trk::Track* trk_q = std::get<2>(q);
782 for(const auto& qdis : qualityDisCombTrks ) {
783 if( std::get<2>(qdis) == trk_q ) {
784 needed_for_disCombTrk = std::get<0>(qdis);
785 break;
786 }
787 }
788 if( needed_for_disCombTrk) ATH_MSG_VERBOSE("idx=" << idx << " ===> neded for disCombTrk");
789 }
790 if (std::get<0>(q)==true) {
791 initialTracks.push_back(std::get<2>(q));
792 if( m_doDisappearingTrk && needed_for_disCombTrk ) indexDisCombTrk.push_back(idx);
793 }
794 else {
795 if( ! m_doDisappearingTrk ) {
796 delete std::get<2>(q);
797 }
798 else {
799 if( needed_for_disCombTrk ) {
800 ATH_MSG_VERBOSE("... adding to extraDisCombTracks");
801 extraDisCombTracks.push_back(std::get<2>(q));
802 }
803 else {
804 delete std::get<2>(q);
805 }
806 }
807 }
808 idx++;
809 }
810 qualityTracks.clear();
811
812 ATH_MSG_DEBUG("After clone removal "<<initialTracks.size()<<" tracks left");
813
814
815 mnt_timer_CombTracking.stop();
816 mnt_timer_PatternReco.stop();
817
818 mnt_roi_lastStageExecuted = 5;
819
820 mnt_timer_TrackFitter.start();
821
822 if( ! m_dodEdxTrk ) {
823
824 if(m_doTrackRefit) {
825 m_trigInDetTrackFitter->fit(initialTracks, outputTracks, ctx, m_particleHypothesis);
826 }
827 else {
828 outputTracks = std::move(initialTracks);
829 }
830 }
831 else {
832 TrackCollection outputTrackswTP;
833
834 m_trigInDetTrackFitter->fit(initialTracks, outputTracks, outputTrackswTP, ctx, m_particleHypothesis, true); // add TP to TSoS for dEdx
835
836 // large dEdx finding
837 mnt_timer_dEdxTrk.start();
838 for(auto t=outputTrackswTP.begin(); t!=outputTrackswTP.end();t++) { m_trackSummaryTool->updateTrack(ctx, **t); }
839 ATH_CHECK( finddEdxTrk(ctx,outputTrackswTP) );
840
841 }
842
843 if( m_dodEdxTrk ) mnt_timer_dEdxTrk.stop(); // to include timing to destroy TrackCollection object
844
845 if( outputTracks.empty() ) {
846 ATH_MSG_DEBUG("REGTEST / No tracks fitted");
847 }
848
849
850 bool do_recoverDisCombTrk = true;
851 if( m_doDisappearingTrk && (initialTracks.size()!=outputTracks.size()) ) {
852 ATH_MSG_DEBUG("part of initialTracks fails in fitting. do not try to recover DisCombTracks");
853 do_recoverDisCombTrk = false;
854 }
855
856 TrackCollection fittedExtraDisCombTracks;
857 fittedExtraDisCombTracks.reserve(extraDisCombTracks.size());
858 TrackCollection fittedDisCombTrks(SG::VIEW_ELEMENTS);
860 ATH_MSG_VERBOSE("nr of extraDisCombTracks=" << extraDisCombTracks.size());
861 if( extraDisCombTracks.size() > 0 ) {
862 ATH_MSG_VERBOSE("fitting extraDisCombTracks ...");
863 m_trigInDetTrackFitter->fit(extraDisCombTracks, fittedExtraDisCombTracks, ctx, m_particleHypothesis);
864 for (auto fittedTrack = fittedExtraDisCombTracks.begin(); fittedTrack!=fittedExtraDisCombTracks.end(); ++fittedTrack) {
865 (*fittedTrack)->info().setPatternRecognitionInfo(Trk::TrackInfo::FastTrackFinderSeed);
866 m_trackSummaryTool->updateTrack(ctx, **fittedTrack);
867 fittedDisCombTrks.push_back(*fittedTrack);
868 }
869 }
870 }
871
872 //check track parameters
873
874 for ( auto fittedTrack = outputTracks.begin(); fittedTrack!=outputTracks.end(); ) {
875 if ((*fittedTrack)->perigeeParameters()) {
876 float d0 = (*fittedTrack)->perigeeParameters()->parameters()[Trk::d0];
877 float z0 = (*fittedTrack)->perigeeParameters()->parameters()[Trk::z0];
878 if (std::abs(d0) > m_initialD0Max || std::abs(z0) > m_Z0Max) {
879 if(m_LRTmode){
880 ATH_MSG_DEBUG("REGTEST / Reject track after fit with d0 = " << d0 << " z0= " << z0
881 << " larger than limits (" << m_initialD0Max << ", " << m_Z0Max << ")");
882 }else{
883 ATH_MSG_WARNING("REGTEST / Reject track after fit with d0 = " << d0 << " z0= " << z0
884 << " larger than limits (" << m_initialD0Max << ", " << m_Z0Max << ")");
885 }
886 ATH_MSG_DEBUG(**fittedTrack);
887 fittedTrack = outputTracks.erase(fittedTrack);
888 continue;
889 }
890
891 if(m_LRTmode){
892 //reject tracks which have a d0 below a cut but only when an input track collection (from ftf) is also present
893 if(m_LRTD0Min>0.0){
894 if(std::abs(d0) < m_LRTD0Min && !m_inputTracksKey.key().empty()){
895 ATH_MSG_DEBUG("REGTEST / Reject track after fit for min d0 (" << d0 << " < " << m_LRTD0Min <<")");
896 fittedTrack = outputTracks.erase(fittedTrack);
897 continue;
898 }
899 }
900
901 //calculate pt
902 float trkPt = 0.0;
903 if(m_LRTHardMinPt > 0.0){
904 //avoid a floating poitn error
905 if(std::abs((*fittedTrack)->perigeeParameters()->parameters()[Trk::qOverP]) >= 1e-9){
906 trkPt = std::sin((*fittedTrack)->perigeeParameters()->parameters()[Trk::theta])/std::abs((*fittedTrack)->perigeeParameters()->parameters()[Trk::qOverP]);
907
908 if(trkPt < m_LRTHardMinPt){
909 ATH_MSG_DEBUG("REGTEST / Reject track after fit for min pt (" << trkPt << " < " << m_LRTHardMinPt <<")");
910 fittedTrack = outputTracks.erase(fittedTrack);
911 continue;
912 }
913 }
914 }
915 }
916 }
917 ++fittedTrack;
918 }
919
920 mnt_timer_TrackFitter.stop();
921
922 //make track summary
923
924 size_t counter(1);
925 idx = 0;
926
927 for ( auto fittedTrack = outputTracks.begin();fittedTrack!=outputTracks.end();++fittedTrack) {
928
929 (*fittedTrack)->info().setPatternRecognitionInfo(Trk::TrackInfo::FastTrackFinderSeed);
930 ATH_MSG_VERBOSE("Updating fitted track: " << counter);
931 ATH_MSG_VERBOSE(**fittedTrack);
932 m_trackSummaryTool->updateTrack(ctx, **fittedTrack);
933 ATH_MSG_VERBOSE("Updated track: " << counter);
934 ATH_MSG_VERBOSE(**fittedTrack);
935
936 if( m_doDisappearingTrk && do_recoverDisCombTrk ) {
937 if( std::find(indexDisCombTrk.begin(),indexDisCombTrk.end(),idx)!=indexDisCombTrk.end() ) {
938 ATH_MSG_VERBOSE("fittedTrack idx=" << idx << ": recovers also for DisCombTrack");
939 fittedDisCombTrks.push_back(*fittedTrack);
940 }
941 }
942
943 ++counter;
944 idx++;
945 }
946
947 if( outputTracks.empty() ) {
948 ATH_MSG_DEBUG("REGTEST / No tracks reconstructed");
949 }
950 mnt_roi_lastStageExecuted = 6;
951
952 mnt_roi_nTracks = outputTracks.size();
953
954 // z-vertex for UTT
955 std::vector<double> disTrk_v_xVtx;
956 std::vector<double> disTrk_v_yVtx;
957 std::vector<double> disTrk_v_zVtx;
958 if( m_doDisappearingTrk ) {
959 mnt_timer_disTrkZVertex.start();
960 recoVertexForDisTrack(ctx, outputTracks, disTrk_v_xVtx, disTrk_v_yVtx, disTrk_v_zVtx);
961 mnt_timer_disTrkZVertex.stop();
962 }
963
964 // disappearing track reco
965 if( m_doDisappearingTrk ) {
966 mnt_timer_disTrk.start();
967 ATH_CHECK( findDisTracks(ctx,outputTracks,qualityDisFailTrks,qualityDisCombTrks,fittedDisCombTrks,disTrk_v_xVtx,disTrk_v_yVtx,disTrk_v_zVtx) );
968 mnt_timer_disTrk.stop();
969 }
970 //monitor Z-vertexing
971
972 //monitor number of tracks
973 ATH_MSG_DEBUG("REGTEST / Found " << outputTracks.size() << " tracks");
974 if( !outputTracks.empty() )
976
978 fillMon(outputTracks, *vertices, roi, ctx);
979
980 mnt_roi_lastStageExecuted = 7;
981
982 mnt_timer_Total.stop();
983
984 return StatusCode::SUCCESS;
985}
986
988
990 m = Tr->trackStateOnSurfaces()->begin(),
991 me = Tr->trackStateOnSurfaces()->end ();
992
993 double quality = 0. ;
994 const double W = 17.;
995
996 for(; m!=me; ++m) {
997 const Trk::FitQualityOnSurface fq = (*m)->fitQualityOnSurface();
998 if(!fq) continue;
999
1000 double x2 = fq.chiSquared();
1001 double q;
1002 if(fq.numberDoF() == 2) q = (1.2*(W-x2*.5));
1003 else q = (W-x2 );
1004 if(q < 0.) q = 0.;
1005 quality+=q;
1006 }
1007 return quality;
1008}
1009
1010void TrigFastTrackFinder::filterSharedTracks(std::vector<std::tuple<bool, double,Trk::Track*>>& QT) const {
1011
1012 std::set<const Trk::PrepRawData*> clusters;
1013
1014 const Trk::PrepRawData* prd[100];
1015
1016 std::sort(QT.begin(), QT.end(),
1017 [](const std::tuple<bool, double, Trk::Track*>& lhs, const std::tuple<bool, double, Trk::Track*>& rhs) {
1018 return std::get<1>(lhs) < std::get<1>(rhs); } );
1019
1020 for (auto& q : QT) {
1022 m = std::get<2>(q)->measurementsOnTrack()->begin(),
1023 me = std::get<2>(q)->measurementsOnTrack()->end ();
1024
1025 int nf = 0, nc = 0;
1026 for(; m!=me; ++m ) {
1027
1028 const Trk::PrepRawData* pr = ((const Trk::RIO_OnTrack*)(*m))->prepRawData();
1029 if(pr) {
1030 ++nc;
1031 if(clusters.find(pr)==clusters.end()) {prd[nf++]=pr; if(nf==100) break;}
1032 }
1033 }
1034 if((nf >= m_nfreeCut) || (nf == nc) ) {
1035 for(int n=0; n!=nf; ++n) clusters.insert(prd[n]);
1036 }
1037 else {
1038 std::get<0>(q) = false;
1039 }
1040 }
1041}
1042
1043//---------------------------------------------------------------------------
1044
1046{
1047
1048 ATH_MSG_INFO("=========================================================");
1049 ATH_MSG_INFO("TrigFastTrackFinder::finalize() - TrigFastTrackFinder Statistics: ");
1050 ATH_MSG_INFO("RoI processed: " << m_countTotalRoI);
1051 ATH_MSG_INFO("RoI with enough SPs : " << m_countRoIwithEnoughHits);
1052 ATH_MSG_INFO("RoI with Track(s) : " << m_countRoIwithTracks);
1053 ATH_MSG_INFO("=========================================================");
1054
1055 return StatusCode::SUCCESS;
1056}
1057
1058void TrigFastTrackFinder::updateClusterMap(long int trackIdx, const Trk::Track* pTrack, std::map<Identifier, std::vector<long int> >& clusterMap) const {
1059 //loop over clusters
1060
1061 for(auto tMOT = pTrack->measurementsOnTrack()->begin(); tMOT != pTrack->measurementsOnTrack()->end(); ++tMOT) {
1062
1063 const InDet::SiClusterOnTrack* siCLOT = dynamic_cast<const InDet::SiClusterOnTrack*>(*tMOT);
1064 if (siCLOT==nullptr) continue;
1065 const InDet::SiCluster* siCL = dynamic_cast<const InDet::SiCluster*>(siCLOT->prepRawData());
1066 if (siCL==nullptr) continue;
1067
1068 if(m_ITkMode) {
1069 //skip non-pixel clusters because all seeds are PPP in ITK mode
1070 const InDet::PixelCluster* pixCL = dynamic_cast<const InDet::PixelCluster*>(siCL);
1071 if(pixCL==nullptr) continue;
1072 }
1073
1074 Identifier id = siCL->identify();
1075 clusterMap[id].push_back(trackIdx);
1076 }
1077}
1078
1079void TrigFastTrackFinder::extractClusterIds(const Trk::SpacePoint* pSP, std::vector<Identifier>& vIds) const {
1080 const InDet::SiCluster* pCL = dynamic_cast<const InDet::SiCluster*>(pSP->clusterList().first);
1081 if(pCL!=nullptr) vIds.push_back(pCL->identify());
1082 //check second cluster : SCT uv clusters only !
1083 pCL = dynamic_cast<const InDet::SiCluster*>(pSP->clusterList().second);
1084 if(pCL!=nullptr) vIds.push_back(pCL->identify());
1085}
1086
1087bool TrigFastTrackFinder::usedByAnyTrack(const std::vector<Identifier>& vIds, std::map<Identifier, std::vector<long int> >& clusterMap) const {
1088
1089 std::vector<long int> xSection;
1090 //initializing
1091 std::map<Identifier, std::vector<long int> >::iterator itm0 = clusterMap.find(*vIds.begin());
1092 if(itm0 == clusterMap.end()) return false;
1093 xSection.reserve((*itm0).second.size());
1094 std::copy((*itm0).second.begin(), (*itm0).second.end(), std::back_inserter(xSection));
1095 std::vector<Identifier>::const_iterator it = vIds.begin();++it;
1096 for(;it!=vIds.end();++it) {
1097 std::map<Identifier, std::vector<long int> >::iterator itm1 = clusterMap.find(*it);
1098 if(itm1 == clusterMap.end()) return false;
1099 std::vector<long int> tmp;
1100 std::set_intersection(xSection.begin(), xSection.end(), (*itm1).second.begin(),(*itm1).second.end(), std::back_inserter(tmp));
1101 if(tmp.empty()) return false;
1102 //update xSection
1103 xSection.clear();
1104 xSection.reserve(tmp.size());
1105 std::copy(tmp.begin(), tmp.end(), std::back_inserter(xSection));
1106 }
1107 return !xSection.empty();
1108}
1109
1111 const TrigRoiDescriptor& roi, const EventContext& ctx) const {
1112 float shift_x = 0;
1113 float shift_y = 0;
1114 if(m_useBeamSpot) {
1116 FTF::getBeamSpotShift(shift_x, shift_y, **beamSpotHandle);
1117 }
1118 auto mnt_roi_eta = Monitored::Scalar<float>("roi_eta", 0.0);
1119 auto mnt_roi_phi = Monitored::Scalar<float>("roi_phi", 0.0);
1120 auto mnt_roi_etaWidth = Monitored::Scalar<float>("roi_etaWidth", 0.0);
1121 auto mnt_roi_phiWidth = Monitored::Scalar<float>("roi_phiWidth", 0.0);
1122 auto mnt_roi_z = Monitored::Scalar<float>("roi_z", 0.0);
1123 auto mnt_roi_zWidth = Monitored::Scalar<float>("roi_zWidth", 0.0);
1124 auto monRoI = Monitored::Group(m_monTool, mnt_roi_eta, mnt_roi_phi, mnt_roi_etaWidth, mnt_roi_phiWidth, mnt_roi_z, mnt_roi_zWidth);
1125
1126 if (roi.composite()){
1127 for(unsigned int i=0; i<roi.size(); i++) {
1128 const IRoiDescriptor *subroi = roi.at(i);
1129 if (subroi){
1130 mnt_roi_eta = subroi->eta();
1131 mnt_roi_phi = subroi->phi();
1132 mnt_roi_etaWidth = subroi->etaPlus() - subroi->etaMinus();
1133 mnt_roi_phiWidth = CxxUtils::wrapToPi(subroi->phiPlus() - subroi->phiMinus());
1134 mnt_roi_z = subroi->zed();
1135 mnt_roi_zWidth = subroi->zedPlus() - subroi->zedMinus();
1136 monRoI.fill();
1137 }
1138 }
1139 }
1140 else {
1141 mnt_roi_eta = roi.eta();
1142 mnt_roi_phi = roi.phi();
1143 mnt_roi_etaWidth = roi.etaPlus() - roi.etaMinus();
1144 mnt_roi_phiWidth = CxxUtils::wrapToPi(roi.phiPlus() - roi.phiMinus());
1145 mnt_roi_z = roi.zed();
1146 mnt_roi_zWidth = roi.zedPlus() - roi.zedMinus();
1147 }
1148
1149 std::vector<float> mnt_trk_pt;
1150 std::vector<float> mnt_trk_a0;
1151 std::vector<float> mnt_trk_z0;
1152 std::vector<float> mnt_trk_phi0;
1153 std::vector<float> mnt_trk_eta;
1154 std::vector<float> mnt_trk_chi2dof;
1155 std::vector<float> mnt_trk_nSiHits;
1156 std::vector<float> mnt_trk_nPIXHits;
1157 std::vector<float> mnt_trk_nSCTHits;
1158 std::vector<float> mnt_trk_a0beam;
1159 std::vector<float> mnt_trk_z0beam;
1160 std::vector<float> mnt_trk_dPhi0;
1161 std::vector<float> mnt_trk_dEta;
1162
1163 auto mon_pt = Monitored::Collection("trk_pt", mnt_trk_pt);
1164 auto mon_a0 = Monitored::Collection("trk_a0", mnt_trk_a0);
1165 auto mon_z0 = Monitored::Collection("trk_z0", mnt_trk_z0);
1166 auto mon_phi0 = Monitored::Collection("trk_phi0", mnt_trk_phi0);
1167 auto mon_eta = Monitored::Collection("trk_eta", mnt_trk_eta);
1168 auto mon_chi2dof = Monitored::Collection("trk_chi2dof", mnt_trk_chi2dof);
1169 auto mon_nSiHits = Monitored::Collection("trk_nSiHits", mnt_trk_nSiHits);
1170 auto mon_nPIXHits = Monitored::Collection("trk_nPIXHits", mnt_trk_nPIXHits);
1171 auto mon_nSCTHits = Monitored::Collection("trk_nSCTHits", mnt_trk_nSCTHits);
1172 auto mon_a0beam = Monitored::Collection("trk_a0beam", mnt_trk_a0beam);
1173 auto mon_z0beam = Monitored::Collection("trk_z0beam", mnt_trk_z0beam);
1174 auto mon_dPhi0 = Monitored::Collection("trk_dPhi0", mnt_trk_dPhi0);
1175 auto mon_dEta = Monitored::Collection("trk_dEta", mnt_trk_dEta);
1176 auto monTrk = Monitored::Group(m_monTool, mon_pt, mon_a0, mon_z0, mon_phi0, mon_eta, mon_chi2dof,
1177 mon_nSiHits, mon_nPIXHits, mon_nSCTHits, mon_a0beam, mon_z0beam, mon_dPhi0, mon_dEta);
1178
1179 std::vector<float> mnt_roi_zVertices;
1180 auto mon_roi_nZvertices = Monitored::Scalar<int>("roi_nZvertices", 0);
1181 auto mon_roi_zVertices = Monitored::Collection("roi_zVertices", mnt_roi_zVertices);
1182 auto monVtx = Monitored::Group(m_monTool, mon_roi_nZvertices, mon_roi_zVertices);
1183 mon_roi_nZvertices = vertices.size();
1184 for (const auto vertex : vertices) {
1185 mnt_roi_zVertices.push_back(vertex->z());
1186 }
1187
1188 for (auto track : tracks) {
1189 const Trk::TrackParameters* trackPars = track->perigeeParameters();
1190 if(trackPars==nullptr) {
1191 continue;
1192 }
1193
1194 if(trackPars->covariance()==nullptr) {
1195 continue;
1196 }
1197
1198 float a0 = trackPars->parameters()[Trk::d0];
1199 float z0 = trackPars->parameters()[Trk::z0];
1200 float phi0 = trackPars->parameters()[Trk::phi0];
1201 float theta = trackPars->parameters()[Trk::theta];
1202 float eta = -log(tan(0.5*theta));
1203 mnt_trk_a0.push_back(a0);
1204 mnt_trk_z0.push_back(z0);
1205 mnt_trk_phi0.push_back(phi0);
1206 mnt_trk_a0beam.push_back(a0+shift_x*std::sin(phi0)-shift_y*std::cos(phi0));
1207 mnt_trk_z0beam.push_back(z0+(shift_x*std::cos(phi0)+shift_y*std::sin(phi0))/std::tan(theta));
1208 mnt_trk_eta.push_back(eta);
1209 for(unsigned int i=0; i<roi.size(); i++) {
1210 mnt_trk_dPhi0.push_back(CxxUtils::wrapToPi(phi0 - (roi.at(i))->phi()));
1211 mnt_trk_dEta.push_back(eta - (roi.at(i))->eta());
1212 }
1213
1214 float qOverP = trackPars->parameters()[Trk::qOverP];
1215 if (qOverP==0) {
1216 ATH_MSG_DEBUG("REGTEST / q/p == 0, adjusting to 1e-12");
1217 qOverP = 1e-12;
1218 }
1219 float pT=sin(theta)/qOverP;
1220
1221 const Trk::FitQuality* fq = track->fitQuality();
1222 float chi2 = 1e8;
1223 if (fq) {
1224 ATH_MSG_VERBOSE("Fitted chi2: " << fq->chiSquared());
1225 ATH_MSG_VERBOSE("Fitted ndof: " << fq->numberDoF());
1226 if(fq->numberDoF()!=0) {
1227 chi2 = fq->chiSquared()/fq->numberDoF();
1228 }
1229 }
1230 mnt_trk_pt.push_back(pT);
1231 mnt_trk_chi2dof.push_back(chi2);
1232
1233 int nPix=0, nSct=0;
1234
1235 for(auto tSOS = track->trackStateOnSurfaces()->begin();
1236 tSOS!=track->trackStateOnSurfaces()->end(); ++tSOS) {
1237 if ((*tSOS)->type(Trk::TrackStateOnSurface::Perigee) == false) {
1238 const Trk::FitQualityOnSurface fq = (*tSOS)->fitQualityOnSurface();
1239 if(!fq) continue;
1240 int nd = fq.numberDoF();
1241 if(nd==2) nPix++;
1242 if(nd==1) nSct++;
1243 }
1244 }
1245 mnt_trk_nPIXHits.push_back(nPix);
1246 mnt_trk_nSCTHits.push_back(nSct/2);
1247 mnt_trk_nSiHits.push_back(nPix + nSct/2);
1248
1249 ATH_MSG_DEBUG("REGTEST / track npix/nsct/phi0/pt/eta/d0/z0/chi2: " <<
1250 nPix << " / " <<
1251 nSct/2 << " / " <<
1252 phi0 << " / " <<
1253 pT << " / " <<
1254 eta << " / " <<
1255 a0 << " / " <<
1256 z0 << " / " <<
1257 chi2);
1258 // tighter selection for unbiased residuals
1259 bool goodTrack = std::fabs(pT)>1000. && (nPix + nSct/2) > 3 && nSct > 0;
1260 if (goodTrack && m_doResMonitoring) {
1261 runResidualMonitoring(*track, ctx);
1262 }
1263 }
1264}
1265
1266void TrigFastTrackFinder::runResidualMonitoring(const Trk::Track& track, const EventContext& ctx) const {
1267
1268 std::vector<float> mnt_layer_IBL;
1269 std::vector<float> mnt_layer_PixB;
1270 std::vector<float> mnt_layer_PixE;
1271 std::vector<float> mnt_layer_SCTB;
1272 std::vector<float> mnt_layer_SCTE;
1273 std::vector<float> mnt_hit_IBLPhiResidual;
1274 std::vector<float> mnt_hit_IBLEtaResidual;
1275 std::vector<float> mnt_hit_IBLPhiPull;
1276 std::vector<float> mnt_hit_IBLEtaPull;
1277 std::vector<float> mnt_hit_PIXBarrelPhiResidual;
1278 std::vector<float> mnt_hit_PIXBarrelEtaResidual;
1279 std::vector<float> mnt_hit_PIXBarrelPhiPull;
1280 std::vector<float> mnt_hit_PIXBarrelEtaPull;
1281 std::vector<float> mnt_hit_SCTBarrelResidual;
1282 std::vector<float> mnt_hit_SCTBarrelPull;
1283 std::vector<float> mnt_hit_PIXEndcapPhiResidual;
1284 std::vector<float> mnt_hit_PIXEndcapEtaResidual;
1285 std::vector<float> mnt_hit_PIXEndcapPhiPull;
1286 std::vector<float> mnt_hit_PIXEndcapEtaPull;
1287 std::vector<float> mnt_hit_SCTEndcapResidual;
1288 std::vector<float> mnt_hit_SCTEndcapPull;
1289 std::vector<float> mnt_hit_PIXBarrelL1PhiResidual;
1290 std::vector<float> mnt_hit_PIXBarrelL1EtaResidual;
1291 std::vector<float> mnt_hit_PIXBarrelL2PhiResidual;
1292 std::vector<float> mnt_hit_PIXBarrelL2EtaResidual;
1293 std::vector<float> mnt_hit_PIXBarrelL3PhiResidual;
1294 std::vector<float> mnt_hit_PIXBarrelL3EtaResidual;
1295 std::vector<float> mnt_hit_PIXEndcapL1PhiResidual;
1296 std::vector<float> mnt_hit_PIXEndcapL1EtaResidual;
1297 std::vector<float> mnt_hit_PIXEndcapL2PhiResidual;
1298 std::vector<float> mnt_hit_PIXEndcapL2EtaResidual;
1299 std::vector<float> mnt_hit_PIXEndcapL3PhiResidual;
1300 std::vector<float> mnt_hit_PIXEndcapL3EtaResidual;
1301 std::vector<float> mnt_hit_SCTBarrelL1PhiResidual;
1302 std::vector<float> mnt_hit_SCTBarrelL2PhiResidual;
1303 std::vector<float> mnt_hit_SCTBarrelL3PhiResidual;
1304 std::vector<float> mnt_hit_SCTBarrelL4PhiResidual;
1305 std::vector<float> mnt_hit_SCTEndcapL1PhiResidual;
1306 std::vector<float> mnt_hit_SCTEndcapL2PhiResidual;
1307 std::vector<float> mnt_hit_SCTEndcapL3PhiResidual;
1308 std::vector<float> mnt_hit_SCTEndcapL4PhiResidual;
1309 std::vector<float> mnt_hit_SCTEndcapL5PhiResidual;
1310 std::vector<float> mnt_hit_SCTEndcapL6PhiResidual;
1311 std::vector<float> mnt_hit_SCTEndcapL7PhiResidual;
1312 std::vector<float> mnt_hit_SCTEndcapL8PhiResidual;
1313 std::vector<float> mnt_hit_SCTEndcapL9PhiResidual;
1314 auto mon_layer_IBL = Monitored::Collection("layer_IBL", mnt_layer_IBL);
1315 auto mon_layer_PixB = Monitored::Collection("layer_PixB",mnt_layer_PixB);
1316 auto mon_layer_PixE = Monitored::Collection("layer_PixE",mnt_layer_PixE);
1317 auto mon_layer_SCTB = Monitored::Collection("layer_SCTB",mnt_layer_SCTB);
1318 auto mon_layer_SCTE = Monitored::Collection("layer_SCTE",mnt_layer_SCTE);
1319 auto mon_hit_IBLPhiResidual = Monitored::Collection("hit_IBLPhiResidual",mnt_hit_IBLPhiResidual);
1320 auto mon_hit_IBLEtaResidual = Monitored::Collection("hit_IBLEtaResidual",mnt_hit_IBLEtaResidual);
1321 auto mon_hit_IBLPhiPull = Monitored::Collection("hit_IBLPhiPull",mnt_hit_IBLPhiPull);
1322 auto mon_hit_IBLEtaPull = Monitored::Collection("hit_IBLEtaPull",mnt_hit_IBLEtaPull);
1323 auto mon_hit_PIXBarrelPhiResidual = Monitored::Collection("hit_PIXBarrelPhiResidual",mnt_hit_PIXBarrelPhiResidual);
1324 auto mon_hit_PIXBarrelEtaResidual = Monitored::Collection("hit_PIXBarrelEtaResidual",mnt_hit_PIXBarrelEtaResidual);
1325 auto mon_hit_PIXBarrelPhiPull = Monitored::Collection("hit_PIXBarrelPhiPull",mnt_hit_PIXBarrelPhiPull);
1326 auto mon_hit_PIXBarrelEtaPull = Monitored::Collection("hit_PIXBarrelEtaPull",mnt_hit_PIXBarrelEtaPull);
1327 auto mon_hit_SCTBarrelResidual = Monitored::Collection("hit_SCTBarrelResidual",mnt_hit_SCTBarrelResidual);
1328 auto mon_hit_SCTBarrelPull = Monitored::Collection("hit_SCTBarrelPull",mnt_hit_SCTBarrelPull);
1329 auto mon_hit_PIXEndcapPhiResidual = Monitored::Collection("hit_PIXEndcapPhiResidual",mnt_hit_PIXEndcapPhiResidual);
1330 auto mon_hit_PIXEndcapEtaResidual = Monitored::Collection("hit_PIXEndcapEtaResidual",mnt_hit_PIXEndcapEtaResidual);
1331 auto mon_hit_PIXEndcapPhiPull = Monitored::Collection("hit_PIXEndcapPhiPull",mnt_hit_PIXEndcapPhiPull);
1332 auto mon_hit_PIXEndcapEtaPull = Monitored::Collection("hit_PIXEndcapEtaPull",mnt_hit_PIXEndcapEtaPull);
1333 auto mon_hit_SCTEndcapResidual = Monitored::Collection("hit_SCTEndcapResidual",mnt_hit_SCTEndcapResidual);
1334 auto mon_hit_SCTEndcapPull = Monitored::Collection("hit_SCTEndcapPull",mnt_hit_SCTEndcapPull);
1335 auto mon_hit_PIXBarrelL1PhiResidual = Monitored::Collection("hit_PIXBarrelL1PhiResidual",mnt_hit_PIXBarrelL1PhiResidual);
1336 auto mon_hit_PIXBarrelL1EtaResidual = Monitored::Collection("hit_PIXBarrelL1EtaResidual",mnt_hit_PIXBarrelL1EtaResidual);
1337 auto mon_hit_PIXBarrelL2PhiResidual = Monitored::Collection("hit_PIXBarrelL2PhiResidual",mnt_hit_PIXBarrelL2PhiResidual);
1338 auto mon_hit_PIXBarrelL2EtaResidual = Monitored::Collection("hit_PIXBarrelL2EtaResidual",mnt_hit_PIXBarrelL2EtaResidual);
1339 auto mon_hit_PIXBarrelL3PhiResidual = Monitored::Collection("hit_PIXBarrelL3PhiResidual",mnt_hit_PIXBarrelL3PhiResidual);
1340 auto mon_hit_PIXBarrelL3EtaResidual = Monitored::Collection("hit_PIXBarrelL3EtaResidual",mnt_hit_PIXBarrelL3EtaResidual);
1341 auto mon_hit_PIXEndcapL1PhiResidual = Monitored::Collection("hit_PIXEndcapL1PhiResidual",mnt_hit_PIXEndcapL1PhiResidual);
1342 auto mon_hit_PIXEndcapL1EtaResidual = Monitored::Collection("hit_PIXEndcapL1EtaResidual",mnt_hit_PIXEndcapL1EtaResidual);
1343 auto mon_hit_PIXEndcapL2PhiResidual = Monitored::Collection("hit_PIXEndcapL2PhiResidual",mnt_hit_PIXEndcapL2PhiResidual);
1344 auto mon_hit_PIXEndcapL2EtaResidual = Monitored::Collection("hit_PIXEndcapL2EtaResidual",mnt_hit_PIXEndcapL2EtaResidual);
1345 auto mon_hit_PIXEndcapL3PhiResidual = Monitored::Collection("hit_PIXEndcapL3PhiResidual",mnt_hit_PIXEndcapL3PhiResidual);
1346 auto mon_hit_PIXEndcapL3EtaResidual = Monitored::Collection("hit_PIXEndcapL3EtaResidual",mnt_hit_PIXEndcapL3EtaResidual);
1347 auto mon_hit_SCTBarrelL1PhiResidual = Monitored::Collection("hit_SCTBarrelL1PhiResidual",mnt_hit_SCTBarrelL1PhiResidual);
1348 auto mon_hit_SCTBarrelL2PhiResidual = Monitored::Collection("hit_SCTBarrelL2PhiResidual",mnt_hit_SCTBarrelL2PhiResidual);
1349 auto mon_hit_SCTBarrelL3PhiResidual = Monitored::Collection("hit_SCTBarrelL3PhiResidual",mnt_hit_SCTBarrelL3PhiResidual);
1350 auto mon_hit_SCTBarrelL4PhiResidual = Monitored::Collection("hit_SCTBarrelL4PhiResidual",mnt_hit_SCTBarrelL4PhiResidual);
1351 auto mon_hit_SCTEndcapL1PhiResidual = Monitored::Collection("hit_SCTEndcapL1PhiResidual",mnt_hit_SCTEndcapL1PhiResidual);
1352 auto mon_hit_SCTEndcapL2PhiResidual = Monitored::Collection("hit_SCTEndcapL2PhiResidual",mnt_hit_SCTEndcapL2PhiResidual);
1353 auto mon_hit_SCTEndcapL3PhiResidual = Monitored::Collection("hit_SCTEndcapL3PhiResidual",mnt_hit_SCTEndcapL3PhiResidual);
1354 auto mon_hit_SCTEndcapL4PhiResidual = Monitored::Collection("hit_SCTEndcapL4PhiResidual",mnt_hit_SCTEndcapL4PhiResidual);
1355 auto mon_hit_SCTEndcapL5PhiResidual = Monitored::Collection("hit_SCTEndcapL5PhiResidual",mnt_hit_SCTEndcapL5PhiResidual);
1356 auto mon_hit_SCTEndcapL6PhiResidual = Monitored::Collection("hit_SCTEndcapL6PhiResidual",mnt_hit_SCTEndcapL6PhiResidual);
1357 auto mon_hit_SCTEndcapL7PhiResidual = Monitored::Collection("hit_SCTEndcapL7PhiResidual",mnt_hit_SCTEndcapL7PhiResidual);
1358 auto mon_hit_SCTEndcapL8PhiResidual = Monitored::Collection("hit_SCTEndcapL8PhiResidual",mnt_hit_SCTEndcapL8PhiResidual);
1359 auto mon_hit_SCTEndcapL9PhiResidual = Monitored::Collection("hit_SCTEndcapL9PhiResidual",mnt_hit_SCTEndcapL9PhiResidual);
1360
1361 auto monRes = Monitored::Group(m_monTool, mon_layer_IBL, mon_layer_PixB, mon_layer_PixE, mon_layer_SCTB, mon_layer_SCTE, mon_hit_IBLPhiResidual, mon_hit_IBLEtaResidual, mon_hit_IBLPhiPull, mon_hit_IBLEtaPull, mon_hit_PIXBarrelPhiResidual, mon_hit_PIXBarrelEtaResidual, mon_hit_PIXBarrelPhiPull, mon_hit_PIXBarrelEtaPull, mon_hit_SCTBarrelResidual, mon_hit_SCTBarrelPull, mon_hit_PIXEndcapPhiResidual, mon_hit_PIXEndcapEtaResidual, mon_hit_PIXEndcapPhiPull, mon_hit_PIXEndcapEtaPull, mon_hit_SCTEndcapResidual, mon_hit_SCTEndcapPull, mon_hit_PIXBarrelL1PhiResidual, mon_hit_PIXBarrelL1EtaResidual, mon_hit_PIXBarrelL2PhiResidual, mon_hit_PIXBarrelL2EtaResidual, mon_hit_PIXBarrelL3PhiResidual, mon_hit_PIXBarrelL3EtaResidual, mon_hit_PIXEndcapL1PhiResidual, mon_hit_PIXEndcapL1EtaResidual, mon_hit_PIXEndcapL2PhiResidual, mon_hit_PIXEndcapL2EtaResidual, mon_hit_PIXEndcapL3PhiResidual, mon_hit_PIXEndcapL3EtaResidual, mon_hit_SCTBarrelL1PhiResidual, mon_hit_SCTBarrelL2PhiResidual, mon_hit_SCTBarrelL3PhiResidual, mon_hit_SCTBarrelL4PhiResidual, mon_hit_SCTEndcapL1PhiResidual, mon_hit_SCTEndcapL2PhiResidual, mon_hit_SCTEndcapL3PhiResidual, mon_hit_SCTEndcapL4PhiResidual, mon_hit_SCTEndcapL5PhiResidual, mon_hit_SCTEndcapL6PhiResidual, mon_hit_SCTEndcapL7PhiResidual, mon_hit_SCTEndcapL8PhiResidual, mon_hit_SCTEndcapL9PhiResidual);
1362
1363 std::vector<TrigL2HitResidual> vResid;
1364 vResid.clear();
1365 StatusCode scRes = m_trigInDetTrackFitter->getUnbiasedResiduals(track,vResid, ctx);
1366 if(!scRes.isSuccess()) return;
1367 for(std::vector<TrigL2HitResidual>::iterator it=vResid.begin();it!=vResid.end();++it) {
1368 Identifier id = it->identify();
1369 int pixlayer= (m_pixelId->layer_disk(id) );
1370 int sctlayer= (m_sctId->layer_disk(id) );
1371
1372 switch(it->regionId()) {
1373 case Region::PixBarrel :
1374 mnt_layer_PixB.push_back(pixlayer);
1375 mnt_hit_PIXBarrelPhiResidual.push_back(it->phiResidual());
1376 mnt_hit_PIXBarrelPhiPull.push_back(it->phiPull());
1377 mnt_hit_PIXBarrelEtaResidual.push_back(it->etaResidual());
1378 mnt_hit_PIXBarrelEtaPull.push_back(it->etaPull());
1379 if (pixlayer == 1) {
1380 mnt_hit_PIXBarrelL1PhiResidual.push_back(it->phiResidual());
1381 mnt_hit_PIXBarrelL1EtaResidual.push_back(it->etaResidual());
1382 }
1383 if (pixlayer == 2) {
1384 mnt_hit_PIXBarrelL2PhiResidual.push_back(it->phiResidual());
1385 mnt_hit_PIXBarrelL2EtaResidual.push_back(it->etaResidual());
1386 }
1387 if (pixlayer == 3) {
1388 mnt_hit_PIXBarrelL3PhiResidual.push_back(it->phiResidual());
1389 mnt_hit_PIXBarrelL3EtaResidual.push_back(it->etaResidual());
1390 }
1391 break;
1392 case Region::PixEndcap :
1393 ATH_MSG_DEBUG("Pixel Endcap " );
1394 mnt_layer_PixE.push_back(pixlayer);
1395 mnt_hit_PIXEndcapPhiResidual.push_back(it->phiResidual());
1396 mnt_hit_PIXEndcapPhiPull.push_back(it->phiPull());
1397 mnt_hit_PIXEndcapEtaResidual.push_back(it->etaResidual());
1398 mnt_hit_PIXEndcapEtaPull.push_back(it->etaPull());
1399 if (pixlayer == 0) {
1400 mnt_hit_PIXEndcapL1PhiResidual.push_back(it->phiResidual());
1401 mnt_hit_PIXEndcapL1EtaResidual.push_back(it->etaResidual());
1402 }
1403 if (pixlayer == 1) {
1404 mnt_hit_PIXEndcapL2PhiResidual.push_back(it->phiResidual());
1405 mnt_hit_PIXEndcapL2EtaResidual.push_back(it->etaResidual());
1406 }
1407 if (pixlayer == 2) {
1408 mnt_hit_PIXEndcapL3PhiResidual.push_back(it->phiResidual());
1409 mnt_hit_PIXEndcapL3EtaResidual.push_back(it->etaResidual());
1410 }
1411 break;
1412 case Region::SctBarrel :
1413 mnt_layer_SCTB.push_back(sctlayer);
1414 mnt_hit_SCTBarrelResidual.push_back(it->phiResidual());
1415 mnt_hit_SCTBarrelPull.push_back(it->phiPull());
1416 if (sctlayer == 0) {
1417 mnt_hit_SCTBarrelL1PhiResidual.push_back(it->phiResidual());
1418 }
1419 if (sctlayer == 1) {
1420 mnt_hit_SCTBarrelL2PhiResidual.push_back(it->phiResidual());
1421 }
1422 if (sctlayer == 2) {
1423 mnt_hit_SCTBarrelL3PhiResidual.push_back(it->phiResidual());
1424 }
1425 if (sctlayer == 3) {
1426 mnt_hit_SCTBarrelL4PhiResidual.push_back(it->phiResidual());
1427 }
1428 break;
1429 case Region::SctEndcap :
1430 ATH_MSG_DEBUG("SCT Endcap" );
1431 mnt_layer_SCTE.push_back(sctlayer);
1432 mnt_hit_SCTEndcapResidual.push_back(it->phiResidual());
1433 mnt_hit_SCTEndcapPull.push_back(it->phiPull());
1434 if (sctlayer == 0) {
1435 mnt_hit_SCTEndcapL1PhiResidual.push_back(it->phiResidual());
1436 }
1437 if (sctlayer == 1) {
1438 mnt_hit_SCTEndcapL2PhiResidual.push_back(it->phiResidual());
1439 }
1440 if (sctlayer == 2) {
1441 mnt_hit_SCTEndcapL3PhiResidual.push_back(it->phiResidual());
1442 }
1443 if (sctlayer == 3) {
1444 mnt_hit_SCTEndcapL4PhiResidual.push_back(it->phiResidual());
1445 }
1446 if (sctlayer == 4) {
1447 mnt_hit_SCTEndcapL5PhiResidual.push_back(it->phiResidual());
1448 }
1449 if (sctlayer == 5) {
1450 mnt_hit_SCTEndcapL6PhiResidual.push_back(it->phiResidual());
1451 }
1452 if (sctlayer == 6) {
1453 mnt_hit_SCTEndcapL7PhiResidual.push_back(it->phiResidual());
1454 }
1455 if (sctlayer == 7) {
1456 mnt_hit_SCTEndcapL8PhiResidual.push_back(it->phiResidual());
1457 }
1458 if (sctlayer == 8) {
1459 mnt_hit_SCTEndcapL9PhiResidual.push_back(it->phiResidual());
1460 }
1461 break;
1462 case Region::IBL :
1463 mnt_layer_IBL.push_back(pixlayer);
1464 if (m_tcs.m_maxSiliconLayer==32) {
1465 mnt_hit_IBLPhiResidual.push_back(it->phiResidual());
1466 mnt_hit_IBLPhiPull.push_back(it->phiPull());
1467 mnt_hit_IBLEtaResidual.push_back(it->etaResidual());
1468 mnt_hit_IBLEtaPull.push_back(it->etaPull());
1469 }
1470 else {//No IBL, fill pixel histograms instead
1471 ATH_MSG_DEBUG("IBL wrong region" );
1472 mnt_hit_PIXBarrelPhiResidual.push_back(it->phiResidual());
1473 mnt_hit_PIXBarrelPhiPull.push_back(it->phiPull());
1474 mnt_hit_PIXBarrelEtaResidual.push_back(it->etaResidual());
1475 mnt_hit_PIXBarrelEtaPull.push_back(it->etaPull());
1476 }
1477 break;
1478 case Region::Undefined :
1479 ATH_MSG_DEBUG("Undefined ID region");
1480 break;
1481 }
1482 }
1483}
1484
1486::vector<TrigSiSpacePointBase>& vsp, std::vector<TrigInDetTriplet>& output) const {
1487
1488 output.clear();
1489
1490 TrigAccel::DATA_EXPORT_BUFFER* dataBuffer = new TrigAccel::DATA_EXPORT_BUFFER(5000);//i.e. 5KB
1491
1492 size_t actualSize = m_accelTool->exportSeedMakingJob(tcs, roi, vsp, *dataBuffer);
1493
1494 ATH_MSG_DEBUG("SeedMakingJob is ready, data size for transfer = " <<actualSize);
1495
1496 std::shared_ptr<TrigAccel::OffloadBuffer> pBuff = std::make_shared<TrigAccel::OffloadBuffer>(dataBuffer);
1497
1499
1500 if(pJob) {
1501 ATH_MSG_DEBUG("Work item created for task "<<TrigAccel::InDetJobControlCode::MAKE_SEEDS);
1502
1503 pJob->run();
1504
1505 std::shared_ptr<TrigAccel::OffloadBuffer> pOB = pJob->getOutput();
1506
1507 int nTriplets = m_accelTool->extractTripletsFromOutput(pOB,vsp, output);
1508
1509 ATH_MSG_DEBUG("Found "<<nTriplets<<" triplets on GPU");
1510 }
1511
1512 delete pJob;
1513 delete dataBuffer;
1514}
1515
1516StatusCode TrigFastTrackFinder::createEmptyUTTEDMs(const EventContext& ctx) const
1517{
1518 if( m_dodEdxTrk ) {
1520 ATH_CHECK( dEdxTrkHandle.record(std::make_unique<xAOD::TrigCompositeContainer>(), std::make_unique<xAOD::TrigCompositeAuxContainer>()) );
1521
1523 ATH_CHECK( dEdxHitHandle.record(std::make_unique<xAOD::TrigCompositeContainer>(), std::make_unique<xAOD::TrigCompositeAuxContainer>()) );
1524 }
1525 if( m_doDisappearingTrk ) {
1527 ATH_CHECK( disTrkCandHandle.record(std::make_unique<xAOD::TrigCompositeContainer>(), std::make_unique<xAOD::TrigCompositeAuxContainer>()) );
1528 }
1529 return StatusCode::SUCCESS;
1530}
1531
1532
1533int TrigFastTrackFinder::getSPLayer(int layer, float eta) const
1534{
1535 float abseta = std::fabs(eta);
1536
1537 // Pixel barrel or SCT barrel
1538 if( 0<=layer && layer <=7 ) {
1539 ATH_MSG_VERBOSE("layer=" << layer << ", eta=" << abseta);
1540 return layer;
1541 }
1542
1543 int base = 0;
1544
1545 //
1546 const float PixBR6limit = 1.29612;
1547 const float PixBR5limit = 1.45204;
1548 const float PixBR4limit = 1.64909;
1549 const float PixBR3limit = 1.90036;
1550 const float PixBR2limit = 2.2146;
1551
1552 // Pixel Endcap #1
1553 base = 8;
1554 if( layer==base || layer==(base+12) ) {
1555 ATH_MSG_VERBOSE("Pix EC1, eta=" << abseta);
1556 if( abseta > PixBR2limit ) return 2;
1557 return 3;
1558 }
1559
1560 // Pixel Endcap #2
1561 base = 9;
1562 if( layer==base || layer==(base+12) ) {
1563 ATH_MSG_VERBOSE("Pix EC2, eta=" << abseta);
1564 if( abseta > PixBR2limit ) return 2;
1565 return 3;
1566 }
1567
1568 // Pixel Endcap #3
1569 base = 10;
1570 if( layer==base || layer==(base+12) ) {
1571 ATH_MSG_VERBOSE("Pix EC3, eta=" << abseta);
1572 return 3;
1573 }
1574
1575 // SCT Endcap #1
1576 base = 11;
1577 if( layer==base || layer==(base+12) ) {
1578 ATH_MSG_VERBOSE("Sct EC1, eta=" << abseta);
1579 if( abseta < PixBR6limit ) return 7;
1580 else if( abseta < PixBR5limit ) return 6;
1581 return 5;
1582 }
1583
1584 // SCT Endcap #2
1585 base = 12;
1586 if( layer==base || layer==(base+12) ) {
1587 ATH_MSG_VERBOSE("Sct EC2, eta=" << abseta);
1588 if( abseta < PixBR5limit ) return 7;
1589 else if( abseta < PixBR4limit ) return 6;
1590 return 4;
1591 }
1592
1593 // SCT Endcap #3
1594 base = 13;
1595 if( layer==base || layer==(base+12) ) {
1596 ATH_MSG_VERBOSE("Sct EC3, eta=" << abseta);
1597 if( abseta < PixBR4limit ) return 7;
1598 return 5;
1599 }
1600
1601 // SCT Endcap #4
1602 base = 14;
1603 if( layer==base || layer==(base+12) ) {
1604 ATH_MSG_VERBOSE("Sct EC4, eta=" << abseta);
1605 if( abseta < PixBR4limit ) return 6;
1606 else if( abseta < PixBR3limit ) return 6;
1607 return 4;
1608 }
1609
1610 // SCT Endcap #5
1611 base = 15;
1612 if( layer==base || layer==(base+12) ) {
1613 ATH_MSG_VERBOSE("Sct EC5, eta=" << abseta);
1614 if( abseta < PixBR3limit ) return 7;
1615 return 5;
1616 }
1617
1618 // SCT Endcap #6
1619 base = 16;
1620 if( layer==base || layer==(base+12) ) {
1621 ATH_MSG_VERBOSE("Sct EC6, eta=" << abseta);
1622 if( abseta < PixBR3limit ) return 6;
1623 return 4;
1624 }
1625
1626 // SCT Endcap #7
1627 base = 17;
1628 if( layer==base || layer==(base+12) ) {
1629 ATH_MSG_VERBOSE("Sct EC7, eta=" << abseta);
1630 if( abseta < PixBR3limit ) return 7;
1631 return 5;
1632 }
1633
1634 // SCT Endcap #8
1635 base = 18;
1636 if( layer==base || layer==(base+12) ) {
1637 ATH_MSG_VERBOSE("Sct EC8, eta=" << abseta);
1638 if( abseta < PixBR3limit ) return 7;
1639 return 6;
1640 }
1641
1642 // SCT Endcap #9
1643 base = 19;
1644 if( layer==base || layer==(base+12) ) {
1645 ATH_MSG_VERBOSE("Sct EC9, eta=" << abseta);
1646 return 7;
1647 }
1648
1649 return 0;
1650}
1651
1652
1653StatusCode TrigFastTrackFinder::finddEdxTrk(const EventContext& ctx, const TrackCollection& outputTracks) const
1654{
1656 ATH_CHECK( dEdxTrkHandle.record(std::make_unique<xAOD::TrigCompositeContainer>(), std::make_unique<xAOD::TrigCompositeAuxContainer>()) );
1657 auto dEdxTrkContainer = dEdxTrkHandle.ptr();
1658 dEdxTrkContainer->reserve(outputTracks.size());
1659
1661 ATH_CHECK( dEdxHitHandle.record(std::make_unique<xAOD::TrigCompositeContainer>(), std::make_unique<xAOD::TrigCompositeAuxContainer>()) );
1662 auto dEdxHitContainer = dEdxHitHandle.ptr();
1663
1664 std::vector<float> mnt_dedx;
1665 std::vector<int> mnt_dedx_nusedhits;
1666 auto mon_dedx = Monitored::Collection("trk_dedx", mnt_dedx);
1667 auto mon_dedx_nusedhits = Monitored::Collection("trk_dedx_nusedhits", mnt_dedx_nusedhits);
1668 auto mondEdx = Monitored::Group(m_monTool, mon_dedx, mon_dedx_nusedhits);
1669
1670 int i_track=0;
1671
1672 ATH_MSG_VERBOSE("========== in finddEdxTrk ==========");
1673
1674
1675 static constexpr float TRKCUT_PTGEV_LOOSE = 3.0;
1676 static constexpr float TRKCUT_PTGEV_TIGHT = 10.0;
1677 static constexpr float TRKCUT_DEDX_LOOSE = 1.25;
1678 static constexpr float TRKCUT_DEDX_TIGHT = 1.55;
1679
1680 for (const auto track: outputTracks) {
1681
1682 float shift_x = 0; float shift_y = 0;
1683 if(m_useBeamSpot) {
1685 FTF::getBeamSpotShift(shift_x, shift_y, **beamSpotHandle);
1686 }
1687
1688 ATH_MSG_VERBOSE("+++++++ i_track: " << i_track << " +++++++");
1689 i_track++;
1690
1691 trackInfo theTrackInfo;
1692 bool igt = FTF::isGoodTrackUTT(track, theTrackInfo, shift_x, shift_y, TRKCUT_PTGEV_LOOSE);
1693 if (not igt) {continue;}
1694
1695 ATH_MSG_VERBOSE("calculate dEdx -->");
1696 int pixelhits=0; int n_usedhits=0;
1697 std::vector<float> v_pixhit_dedx; std::vector<float> v_pixhit_tot; std::vector<float> v_pixhit_trkchi2; std::vector<float> v_pixhit_trkndof;
1698 std::vector<int> v_pixhit_iblovfl; std::vector<int> v_pixhit_loc; std::vector<int> v_pixhit_layer;
1699 float dedx = dEdx(track,pixelhits,n_usedhits,v_pixhit_dedx,v_pixhit_tot,v_pixhit_trkchi2,v_pixhit_trkndof,
1700 v_pixhit_iblovfl,v_pixhit_loc,v_pixhit_layer);
1701 ATH_MSG_VERBOSE("--> dedx = " << dedx);
1702
1703 mnt_dedx.push_back(dedx);
1704 mnt_dedx_nusedhits.push_back(n_usedhits);
1705
1706 bool hpt = (theTrackInfo.ptGeV >= TRKCUT_PTGEV_TIGHT && dedx >= TRKCUT_DEDX_LOOSE);
1707 bool lpt = (theTrackInfo.ptGeV >= TRKCUT_PTGEV_LOOSE && dedx >= TRKCUT_DEDX_TIGHT);
1708 if( ! hpt && ! lpt ) continue;
1709
1711 dEdxTrkContainer->push_back(dEdxTrk);
1712 dEdxTrk->setDetail<int> ("dEdxTrk_id", i_track);
1713 dEdxTrk->setDetail<float>("dEdxTrk_pt", theTrackInfo.ptGeV*Gaudi::Units::GeV);
1714 dEdxTrk->setDetail<float>("dEdxTrk_eta", theTrackInfo.eta);
1715 dEdxTrk->setDetail<float>("dEdxTrk_phi", theTrackInfo.phi0);
1716 dEdxTrk->setDetail<float>("dEdxTrk_a0beam", theTrackInfo.a0beam);
1717 dEdxTrk->setDetail<float>("dEdxTrk_dedx", dedx);
1718 dEdxTrk->setDetail<int> ("dEdxTrk_dedx_n_usedhits", n_usedhits);
1719 dEdxTrk->setDetail<int> ("dEdxTrk_n_hits_innermost", theTrackInfo.n_hits_innermost);
1720 dEdxTrk->setDetail<int> ("dEdxTrk_n_hits_inner", theTrackInfo.n_hits_inner);
1721 dEdxTrk->setDetail<int> ("dEdxTrk_n_hits_pix", theTrackInfo.n_hits_pix);
1722 dEdxTrk->setDetail<int> ("dEdxTrk_n_hits_sct", theTrackInfo.n_hits_sct);
1723
1724 for(unsigned int i=0; i<v_pixhit_dedx.size(); i++) {
1726 dEdxHitContainer->push_back(dEdxHit);
1727 dEdxHit->setDetail<int> ("dEdxHit_trkid", i_track);
1728 dEdxHit->setDetail<float>("dEdxHit_dedx", v_pixhit_dedx[i]);
1729 dEdxHit->setDetail<float>("dEdxHit_tot", v_pixhit_tot[i]);
1730 dEdxHit->setDetail<float>("dEdxHit_trkchi2", v_pixhit_trkchi2[i]);
1731 dEdxHit->setDetail<float>("dEdxHit_trkndof", v_pixhit_trkndof[i]);
1732 dEdxHit->setDetail<int> ("dEdxHit_iblovfl", v_pixhit_iblovfl[i]);
1733 dEdxHit->setDetail<int> ("dEdxHit_loc", v_pixhit_loc[i]);
1734 dEdxHit->setDetail<int> ("dEdxHit_layer", v_pixhit_layer[i]);
1735 }
1736 }
1737 return StatusCode::SUCCESS;
1738}
1739
1740
1741
1742float TrigFastTrackFinder::dEdx(const Trk::Track* track, int& pixelhits, int& n_usedhits,
1743 std::vector<float>& v_pixhit_dedx, std::vector<float>& v_pixhit_tot,
1744 std::vector<float>& v_pixhit_trkchi2, std::vector<float>& v_pixhit_trkndof,
1745 std::vector<int>& v_pixhit_iblovfl, std::vector<int>& v_pixhit_loc, std::vector<int>& v_pixhit_layer) const
1746{
1747 const float Pixel_sensorthickness=.025; // 250 microns Pixel Planars
1748 const float IBL_3D_sensorthickness=.023; // 230 microns IBL 3D
1749 const float IBL_PLANAR_sensorthickness=.020; // 200 microns IBL Planars
1750
1751 const float energyPair = 3.68e-6; // Energy in MeV to create an electron-hole pair in silicon
1752 const float sidensity = 2.329; // silicon density in g cm^-3
1753
1754 float conversion_factor=energyPair/sidensity;
1755
1756 // Loop over pixel hits on track, and calculate dE/dx:
1757
1758 pixelhits = 0;
1759 n_usedhits = 0;
1760
1761 v_pixhit_dedx.clear();
1762 v_pixhit_tot.clear();
1763 v_pixhit_trkchi2.clear();
1764 v_pixhit_trkndof.clear();
1765 v_pixhit_iblovfl.clear();
1766 v_pixhit_loc.clear();
1767 v_pixhit_layer.clear();
1768
1769 const int PIXLOC_IBL_PL = 0;
1770 const int PIXLOC_IBL_3D = 1;
1771 const int PIXLOC_PIX_LY = 2;
1772 const int PIXLOC_PIX_EC = 3;
1773 const int PIXLOC_IBL_UNKNOWN = 4;
1774 const int PIXLOC_PIX_UNKNOWN = 5;
1775
1776 std::multimap<float,int> dEdxMap;
1777 float dEdxValue = 0;
1778
1779 // Check for track states:
1780 const Trk::TrackStates* recoTrackStates = track->trackStateOnSurfaces();
1781 if (recoTrackStates) {
1782
1783 Trk::TrackStates::const_iterator tsosIter = recoTrackStates->begin();
1784 Trk::TrackStates::const_iterator tsosIterEnd = recoTrackStates->end();
1785
1786 int i_tsos=0;
1787
1788 // Loop over track states on surfaces (i.e. generalized hits):
1789 for ( ; tsosIter != tsosIterEnd; ++tsosIter) {
1790
1791 ATH_MSG_VERBOSE("-------- TSoS: " << i_tsos++ << " --------");
1792
1793 const Trk::MeasurementBase *measurement = (*tsosIter)->measurementOnTrack();
1794 if ( measurement == nullptr ) {
1795 ATH_MSG_VERBOSE("no measurement on this TSoS, skip it");
1796 continue;
1797 }
1798 const Trk::TrackParameters* tp = (*tsosIter)->trackParameters();
1799 if( tp == nullptr ) {
1800 ATH_MSG_VERBOSE("no trackParameters() to this TSoS, skip it");
1801 continue;
1802 }
1803 const InDet::PixelClusterOnTrack *pixclus = dynamic_cast<const InDet::PixelClusterOnTrack*>(measurement);
1804 if ( pixclus == nullptr ) {
1805 ATH_MSG_VERBOSE("this TSoS is not Pixel, skip it");
1806 continue;
1807 }
1808 const InDet::PixelCluster* prd = pixclus->prepRawData();
1809 if( prd == nullptr ) {
1810 ATH_MSG_VERBOSE("no PrepRawData(), skip it");
1811 continue;
1812 }
1813
1814 float dotProd = tp->momentum().dot(tp->associatedSurface().normal());
1815 float cosalpha = std::abs(dotProd/tp->momentum().mag());
1816 ATH_MSG_VERBOSE("dotProd / cosalpha = " << dotProd << " / " << cosalpha);
1817 if (std::abs(cosalpha)<.16) continue;
1818
1819 const std::vector<int>& v_tots = prd->totList();
1820 float charge = prd->totalCharge();
1821 float tot = prd->totalToT();
1822 ATH_MSG_VERBOSE("charge / ToT = " << charge << " / " << tot);
1823 charge *= cosalpha; // path length correction
1824
1825 double locx = pixclus->localParameters()[Trk::locX];
1826 double locy = pixclus->localParameters()[Trk::locY];
1827 int bec = m_pixelId->barrel_ec(pixclus->identify());
1828 int layer = m_pixelId->layer_disk(pixclus->identify());
1829 int eta_module = m_pixelId->eta_module(pixclus->identify()); //check eta module to select thickness
1830
1831 float chi2 = 0.;
1832 float ndof = 0.;
1833 const Trk::FitQualityOnSurface fq = (*tsosIter)->fitQualityOnSurface();
1834 if(fq) {
1835 chi2 = fq.chiSquared();
1836 ndof = fq.doubleNumberDoF();
1837 }
1838
1839 int iblOverflow=0; // keep track if this is IBL overflow
1840 float thickness=0;
1841 int loc=-1;
1842
1843 if ( (bec==0) and (layer==0) ){ // IBL
1844 const float overflowIBLToT = 16; // m_overflowIBLToT = m_offlineCalibSvc->getIBLToToverflow();
1845 for (int pixToT : v_tots) {
1846 if (pixToT >= overflowIBLToT) {
1847 iblOverflow = 1; // overflow pixel hit -- flag cluster
1848 break; //no need to check other hits of this cluster
1849 }
1850 }
1851 if(iblOverflow==1) ATH_MSG_VERBOSE("IBL overflow");
1852
1853 if(((eta_module>=-10 && eta_module<=-7)||(eta_module>=6 && eta_module<=9)) && (std::abs(locy)<10. && (locx>-8.33 && locx <8.3)) ){ // IBL 3D
1854 thickness = IBL_3D_sensorthickness;
1855 loc = PIXLOC_IBL_3D;
1856 }
1857 else if((eta_module>=-6 && eta_module<=5) && (std::abs(locy)<20. &&( locx >-8.33 && locx <8.3 )) ){ // IBL planer
1858 thickness = IBL_PLANAR_sensorthickness;
1859 loc = PIXLOC_IBL_PL;
1860 }
1861 else {
1862 ATH_MSG_VERBOSE("unknown IBL module");
1863 loc = PIXLOC_IBL_UNKNOWN;
1864 }
1865 }
1866 else if(bec==0 && std::abs(locy)<30. && (( locx > -8.20 && locx < -0.60 ) || ( locx > 0.50 && locx < 8.10 ) ) ){ //PIXEL layer
1867 thickness = Pixel_sensorthickness;
1868 loc = PIXLOC_PIX_LY;
1869 }
1870 else if(std::abs(bec) == 2 && std::abs(locy)<30. && ( ( locx > -8.15 && locx < -0.55 ) || ( locx > 0.55 && locx < 8.15 ) ) ) { //PIXEL endcap
1871 thickness = Pixel_sensorthickness;
1872 loc = PIXLOC_PIX_EC;
1873 }
1874 else {
1875 ATH_MSG_VERBOSE("unknown Pixel module");
1876 loc = PIXLOC_IBL_UNKNOWN;
1877 }
1878
1879 dEdxValue = 0;
1880 if( loc != PIXLOC_IBL_UNKNOWN && loc != PIXLOC_PIX_UNKNOWN ) {
1881 dEdxValue = charge*conversion_factor/thickness;
1882 dEdxMap.insert(std::pair<float,int>(dEdxValue, iblOverflow));
1883 pixelhits++;
1884 }
1885 ATH_MSG_VERBOSE("dEdx=" << dEdxValue);
1886 v_pixhit_dedx.push_back(dEdxValue); v_pixhit_tot.push_back(tot);
1887 v_pixhit_trkchi2.push_back(chi2); v_pixhit_trkndof.push_back(ndof);
1888 v_pixhit_iblovfl.push_back(iblOverflow); v_pixhit_loc.push_back(loc); v_pixhit_layer.push_back(layer);
1889 }
1890 }
1891
1892 // Now calculate dEdx, multimap is already sorted in ascending order
1893 // float averageCharge=-1;
1894
1895 float averagedEdx=0.;
1896 int IBLOverflow=0;
1897
1898 int i_map=0;
1899
1900 for (std::pair<float,int> itdEdx : dEdxMap) {
1901 ATH_MSG_VERBOSE("++++++++ i_map: " << i_map++ << " ++++++++");
1902 if(itdEdx.second==0){
1903 ATH_MSG_VERBOSE("usedhits, dEdx=" << itdEdx.first);
1904 averagedEdx += itdEdx.first;
1905 n_usedhits++;
1906 }
1907 if(itdEdx.second > 0){
1908 ATH_MSG_VERBOSE("IBLOverflow");
1909 IBLOverflow++;
1910 }
1911 // break, skipping last or the two last elements depending on total measurements
1912 if (((int)pixelhits >= 5) and ((int)n_usedhits >= (int)pixelhits-2)) {
1913 ATH_MSG_VERBOSE("break, skipping last or two last elements");
1914 break;
1915 }
1916
1917 // break, IBL Overflow case pixelhits==3 and 4
1918 if((int)IBLOverflow>0 and ((int)pixelhits==3) and (int)n_usedhits==1) {
1919 ATH_MSG_VERBOSE("break, IBL overflow case, pixel hits=3");
1920 break;
1921 }
1922 if((int)IBLOverflow>0 and ((int)pixelhits==4) and (int)n_usedhits==2) {
1923 ATH_MSG_VERBOSE("break, IBL overflow case, pixel hits=4");
1924 break;
1925 }
1926
1927 if (((int)pixelhits > 1) and ((int)n_usedhits >=(int)pixelhits-1)) {
1928 ATH_MSG_VERBOSE("break, skipping last??");
1929 break;
1930 }
1931
1932 if((int)IBLOverflow>0 and (int)pixelhits==1){ // only IBL in overflow
1933 ATH_MSG_VERBOSE("break, only IBL in overflow");
1934 averagedEdx=itdEdx.first;
1935 break;
1936 }
1937 }
1938
1939 if (n_usedhits > 0 or (n_usedhits==0 and(int)IBLOverflow>0 and (int)pixelhits==1)) {
1940 if(n_usedhits > 0) averagedEdx = averagedEdx / n_usedhits;
1941 //if(n_usedhits == 0 and (int)IBLOverflow > 0 and (int)pixelhits == 1) averagedEdx = averagedEdx; //no-op
1942 ATH_MSG_DEBUG("=====> averaged dEdx = " << averagedEdx << " =====>");;
1943 ATH_MSG_DEBUG(" +++ Used hits: " << n_usedhits << ", IBL overflows: " << IBLOverflow );;
1944 ATH_MSG_DEBUG(" +++ Original number of measurements = " << pixelhits << " (map size = " << dEdxMap.size() << ") ");
1945 return averagedEdx;
1946 }
1947
1948 // -- false return
1949 ATH_MSG_DEBUG("dEdx not calculated, return 0");
1950 return 0.;
1951}
1952
1954{
1955 const float PT_CUT = 3.0;
1956 //
1957 const double FAIL_CHI2_OV_NDOF_CUT = 20.0;
1958 //
1959 const int COMB_N_HITS_IBL_OR_BL_CUT = 1;
1960 const int COMB_N_HITS_PIX_BR_CUT = 3;
1961 const double COMB_CHI2_OV_NDOF_PIX_BR_CUT = 3.0;
1962 const int COMB_N_GOOD_HITS_SCT_BR_CUT = 2;
1963 const int COMB_N_GOOD_DOUBLEHITS_SCT_BR_CUT = 0;
1964
1965 // sanity check
1966 if( trk==nullptr ) return false;
1967 if( trk->perigeeParameters()==nullptr ) return false;
1968 if( trk->fitQuality()==nullptr ) return false;
1969
1970 // if allpix/barrel
1971 if( !seed.s1().isPixel() || !seed.s2().isPixel() || !seed.s3().isPixel() ) return false;
1972 float s1_z = seed.s1().z();
1973 float s2_z = seed.s2().z();
1974 float s3_z = seed.s3().z();
1975 const float PIXEL_BARREL_Z = 410.0;
1976 if( std::abs(s1_z) > PIXEL_BARREL_Z || std::abs(s2_z) > PIXEL_BARREL_Z || std::abs(s3_z) > PIXEL_BARREL_Z ) return false;
1977 ATH_MSG_VERBOSE("FTF::isCleaningPassDisTrack> ... barrel cut passed");
1978
1979 // pt cut
1980 double theta = trk->perigeeParameters()->parameters()[Trk::theta];
1981 double qOverP = std::abs(trk->perigeeParameters()->parameters()[Trk::qOverP]);
1982 if ( qOverP < 1e-12 ) qOverP = 1e-12;
1983 double pt = sin(theta)/qOverP;
1984 if( pt/1000.0 < PT_CUT ) return false;
1985 ATH_MSG_VERBOSE("FTF::isCleaningPassDisTrack> ... pT cut passed");
1986
1987 // fail/comb dependent cuts
1988 if( isFail ) {
1989 double chi2 = trk->fitQuality()->chiSquared();
1990 double ndof = trk->fitQuality()->doubleNumberDoF();
1991 if( std::abs(ndof) < 1e-12 ) return false;
1992 if( chi2/ndof > FAIL_CHI2_OV_NDOF_CUT ) return false;
1993 ATH_MSG_VERBOSE("FTF::isCleaningPassDisTrack> ... (failTrk) Chi2 cut passed");
1994 }
1995 else {
1996
1997 const auto & barrelInfo = getTrkBarrelLayerInfo(trk);
1998
1999 int n_hits_iblbl = barrelInfo[0].nHits + barrelInfo[1].nHits;
2000 if( n_hits_iblbl < COMB_N_HITS_IBL_OR_BL_CUT ) return false;
2001
2002 // PIX cuts
2003 int n_hits_pixbr = 0;
2004 double chi2_pixbr = 0;
2005 int ndof_pixbr = 0;
2006 for(unsigned int ily=0; ily<=3; ily++) {
2007 n_hits_pixbr += barrelInfo[ily].nHits;
2008 chi2_pixbr += barrelInfo[ily].chiSq;
2009 ndof_pixbr += barrelInfo[ily].nDof;
2010 }
2011 if( n_hits_pixbr < COMB_N_HITS_PIX_BR_CUT ) return false;
2012 if( ndof_pixbr < 1 ) return false;
2013 double chi2_ov_ndof_pixbr = chi2_pixbr / ndof_pixbr;
2014 if( chi2_ov_ndof_pixbr > COMB_CHI2_OV_NDOF_PIX_BR_CUT ) return false;
2015 ATH_MSG_VERBOSE("FTF::isCleaningPassDisTrack> ... (combTrk) Pix cut passed");
2016
2017 // SCT cuts
2018 int n_hits_sctbr_good = 0;
2019 int n_doublehits_sctbr_good = 0;
2020 for(unsigned int ily=4; ily<=7; ily++) {
2021 n_hits_sctbr_good += barrelInfo[ily].nGood;
2022 if( barrelInfo[ily].nGood >= 2 ) n_doublehits_sctbr_good++;
2023 }
2024 if( n_hits_sctbr_good > COMB_N_GOOD_HITS_SCT_BR_CUT ) return false;
2025 if( n_doublehits_sctbr_good > COMB_N_GOOD_DOUBLEHITS_SCT_BR_CUT ) return false;
2026 ATH_MSG_VERBOSE("FTF::isCleaningPassDisTrack> ... (combTrk) SCT cut passed");
2027 }
2028
2029 // cut passed
2030 return true;
2031}
2032
2033std::array<TrigFastTrackFinder::OneLayerInfo_t, TrigFastTrackFinder::N_BARREL_LAYERS>
2035{
2036 static constexpr double CHI2_GOOD_CUT = 3.0;
2037 //nHits, chiSq, nDof, nGood in array
2038 std::array<TrigFastTrackFinder::OneLayerInfo_t, TrigFastTrackFinder::N_BARREL_LAYERS> result{};
2039 if (not t) return result;
2040
2041 const Trk::TrackStates* recoTrackStates = t->trackStateOnSurfaces();
2042 if (recoTrackStates) {
2043 Trk::TrackStates::const_iterator tsosIter = recoTrackStates->begin();
2044 Trk::TrackStates::const_iterator tsosIterEnd = recoTrackStates->end();
2045 for ( ; tsosIter != tsosIterEnd; ++tsosIter) {
2046 const Trk::FitQualityOnSurface fq = (*tsosIter)->fitQualityOnSurface();
2047 double x2 = 0;
2048 int ndof = 0;
2049 if(fq) {
2050 x2 = fq.chiSquared();
2051 ndof = fq.numberDoF();
2052 }
2053 bool chi2_good = (x2 <= CHI2_GOOD_CUT);
2054 const Trk::MeasurementBase *measurement = (*tsosIter)->measurementOnTrack();
2055 const InDet::PixelClusterOnTrack *pixclus = dynamic_cast<const InDet::PixelClusterOnTrack*>(measurement);
2056 if (pixclus!=nullptr) {
2057 int bec = m_pixelId->barrel_ec(pixclus->identify());
2058 int layer = m_pixelId->layer_disk(pixclus->identify());
2059 if ( bec==0 ) {
2060 if( layer < 0 || 3 < layer ) {
2061 ATH_MSG_WARNING("Pixel layer out of range, layer=" << layer);
2062 continue;
2063 }
2064 result[layer].nHits++;
2065 result[layer].chiSq += x2;
2066 result[layer].nDof += ndof;
2067 if(chi2_good) result[layer].nGood++;
2068 }
2069 }
2070 const InDet::SCT_ClusterOnTrack *sctclus = dynamic_cast<const InDet::SCT_ClusterOnTrack*>(measurement);
2071 if (sctclus!=nullptr) {
2072 int bec = m_sctId->barrel_ec(sctclus->identify());
2073 int layer = m_sctId->layer_disk(sctclus->identify());
2074 if ( bec==0 ) {
2075 if( layer < 0 || 3 < layer ) {
2076 ATH_MSG_WARNING("SCT layer out of range, layer=" << layer);
2077 continue;
2078 }
2079 layer += 4;
2080 result[layer].nHits++;
2081 result[layer].chiSq += x2;
2082 result[layer].nDof += ndof;
2083 if(chi2_good) result[layer].nGood++;
2084 }
2085 }
2086 }//end loop on TSoS
2087 }
2088 return result;
2089}
2090
2092{
2094 m = Tr->trackStateOnSurfaces()->begin(),
2095 me = Tr->trackStateOnSurfaces()->end ();
2096
2097 double quality_pixel = 0. ;
2098 double quality_sct = 0. ;
2099
2100 const double W = 17.;
2101
2102 for(; m!=me; ++m) {
2103 const Trk::FitQualityOnSurface fq = (*m)->fitQualityOnSurface();
2104 if(!fq) continue;
2105
2106 double x2 = fq.chiSquared();
2107 double q;
2108 if(fq.numberDoF() == 2) q = (1.2*(W-x2*.5));
2109 else q = (W-x2 );
2110 if(q < 0.) q = 0.;
2111
2112 const Trk::MeasurementBase *measurement = (*m)->measurementOnTrack();
2113 if (measurement) {
2114 const InDet::PixelClusterOnTrack *pixclus = dynamic_cast<const InDet::PixelClusterOnTrack*>(measurement);
2115 if( pixclus !=0 ) quality_pixel += q;
2116 else quality_sct += q;
2117 }
2118 }
2119
2120 //
2121 double quality = quality_pixel;
2122 quality -= quality_sct;
2123 if( quality < 0. ) quality = 0.;
2124
2125 return quality;
2126}
2127
2128void TrigFastTrackFinder::recoVertexForDisTrack(const EventContext& ctx, TrackCollection& tracks, std::vector<double>& v_xvtx, std::vector<double>& v_yvtx, std::vector<double>& v_zvtx) const
2129{
2130 v_xvtx.clear();
2131 v_yvtx.clear();
2132 v_zvtx.clear();
2133
2134 // beamspot and tilt
2136 Amg::Vector3D vertex = beamSpotHandle->beamPos();
2137 double xVTX = vertex.x();
2138 double yVTX = vertex.y();
2139 double tiltXZ = beamSpotHandle->beamTilt(0);
2140 double tiltYZ = beamSpotHandle->beamTilt(1);
2141
2142 // zvertex
2143 const double CLUSTCUT_DIST_SIGMA = 5.0;
2144 const double CLUSTCUT_DIST = 2.5;
2145 const double CLUSTCUT_SEED_PT = 3.0;
2146
2147 const int VTXCUT_N_TRACKS = 3;
2148 const int VTXCUT_ALGO = 1; // 0: highest pT track, 1: sumPt
2149
2150 std::vector<std::tuple<int,double,double,Trk::Track*>> QT;
2151 QT.reserve(tracks.size());
2152
2153 for (auto t=tracks.begin(); t!=tracks.end(); ++t) {
2154 if( ! isGoodForDisTrackVertex(*t, ctx) ) continue;
2155 // consider for vertex fitting (idx, sort, weight, Trk)
2156 double theta = (*t)->perigeeParameters()->parameters()[Trk::theta];
2157 double qOverP = std::abs((*t)->perigeeParameters()->parameters()[Trk::qOverP]);
2158 if ( qOverP < 1e-12 ) qOverP = 1e-12;
2159 double pt = sin(theta)/qOverP;
2160 pt /= 1000.0;
2161 QT.emplace_back(std::make_tuple(-1,pt,pt,(*t)));
2162 }
2163
2164 // sort
2165 std::sort(QT.begin(), QT.end(),
2166 [](const std::tuple<int,double,double,Trk::Track*>& lhs, const std::tuple<int,double,double,Trk::Track*>& rhs) {
2167 return std::get<1>(lhs) > std::get<1>(rhs); } );
2168
2169 // clustering
2170 std::vector<int> cluster_ntrk;
2171 std::vector<double> cluster_ptsum;
2172 std::vector<double> cluster_z;
2173 std::vector<double> cluster_wsum;
2174 std::vector<double> cluster_zerr;
2175 std::vector<double> cluster_w2sum;
2176
2177 for(unsigned int i=0; i<QT.size(); ++i) {
2178 Trk::Track* t = std::get<3>(QT[i]);
2179 double z = t->perigeeParameters()->parameters()[Trk::z0];
2180 double zerr = sqrt((*(t->perigeeParameters()->covariance()))(Trk::z0,Trk::z0));
2181 double w = std::get<2>(QT[i]);
2182 double pt = std::get<1>(QT[i]);
2183 if(i==0) {
2184 cluster_ntrk.push_back(1); cluster_ptsum.push_back(pt);
2185 cluster_z.push_back(w*z); cluster_wsum.push_back(w);
2186 cluster_zerr.push_back(w*zerr*w*zerr); cluster_w2sum.push_back(w*w);
2187 continue;
2188 }
2189 //
2190 const int IDX_INITIAL = 100;
2191 double dist_min = 100.0;
2192 int idx_min = IDX_INITIAL;
2193 for(unsigned j=0; j<cluster_z.size(); ++j) {
2194 double dist = std::abs(z - cluster_z[j]/cluster_wsum[j]);
2195 if( dist < dist_min ) {
2196 dist_min = dist;
2197 idx_min = j;
2198 }
2199 }
2200 int match_idx = IDX_INITIAL;
2201 if( idx_min != IDX_INITIAL ) {
2202 double c_zerr_min = std::sqrt(cluster_zerr[idx_min]/cluster_w2sum[idx_min]);
2203 double err = std::sqrt(zerr*zerr+c_zerr_min*c_zerr_min);
2204 if( std::abs(err) < 1e-12 ) err = 1e-12;
2205 double dist = dist_min / err;
2206 if( dist < CLUSTCUT_DIST_SIGMA && dist_min < CLUSTCUT_DIST ) { match_idx = idx_min; }
2207 }
2208 //
2209 if( match_idx == IDX_INITIAL ) {
2210 if( pt > CLUSTCUT_SEED_PT && dist_min > CLUSTCUT_DIST ) {
2211 cluster_ntrk.push_back(1); cluster_ptsum.push_back(pt);
2212 cluster_z.push_back(w*z); cluster_wsum.push_back(w);
2213 cluster_zerr.push_back(w*zerr*w*zerr); cluster_w2sum.push_back(w*w);
2214 }
2215 continue;
2216 }
2217 int new_n = cluster_ntrk[match_idx] + 1;
2218 double new_ptsum = cluster_ptsum[match_idx] + pt;
2219 double new_z = cluster_z[match_idx] + w*z;
2220 double new_wsum = cluster_wsum[match_idx] + w;
2221 double new_zerr = cluster_zerr[match_idx] + w*zerr*w*zerr;
2222 double new_w2sum = cluster_w2sum[match_idx] + w*w;
2223 cluster_ntrk[match_idx] = new_n;
2224 cluster_ptsum[match_idx] = new_ptsum;
2225 cluster_z[match_idx] = new_z;
2226 cluster_wsum[match_idx] = new_wsum;
2227 cluster_zerr[match_idx] = new_zerr;
2228 cluster_w2sum[match_idx] = new_w2sum;
2229 }
2230 QT.clear();
2231
2232 // determine zvtx (pt sort)
2233 std::vector<std::tuple<double,double,double,int>> zVtx;
2234 zVtx.reserve(tracks.size());
2235 for(unsigned int i=0; i<cluster_z.size(); i++) {
2236 if( cluster_ntrk[i] < VTXCUT_N_TRACKS ) continue;
2237 double z = cluster_z[i] / cluster_wsum[i];
2238 double zerr = std::sqrt(cluster_zerr[i] / cluster_w2sum[i]);
2239 zVtx.push_back(std::make_tuple(cluster_ptsum[i],z,zerr,cluster_ntrk[i]));
2240 }
2241 // ptsum sort
2242 if( VTXCUT_ALGO == 1 ) {
2243 std::sort(zVtx.begin(), zVtx.end(),
2244 [](const std::tuple<double,double,double,int>& lhs, const std::tuple<double,double,double,int>& rhs) {
2245 return std::get<0>(lhs) > std::get<0>(rhs); } );
2246 }
2247 ATH_MSG_VERBOSE("disTrkZVtertex> ===== looping zVtx size: " << zVtx.size());
2248 for(unsigned int i=0; i<zVtx.size(); i++) {
2249 double z = std::get<1>(zVtx[i]);
2250 double zerr = std::get<2>(zVtx[i]);
2251 double pt = std::get<0>(zVtx[i]);
2252 int n = std::get<3>(zVtx[i]);
2253 v_zvtx.push_back(z);
2254 v_xvtx.push_back(xVTX - tiltXZ*z); //correction for tilt
2255 v_yvtx.push_back(yVTX - tiltYZ*z); //correction for tilt
2256 ATH_MSG_VERBOSE("disTrkZVtertex> Vertex cand i=" << i << ": z = " << z << " +- " << zerr << ", sum n / pt = " << n << " / " << pt);
2257 }
2258
2259 // monitoring
2260 auto mnt_disTrk_nVtx = Monitored::Scalar<int> ("disTrk_nVtx", 0);
2261 auto mnt_disTrk_xVtx = Monitored::Scalar<float>("disTrk_xVtx", 0);
2262 auto mnt_disTrk_yVtx = Monitored::Scalar<float>("disTrk_yVtx", 0);
2263 auto mnt_disTrk_zVtx = Monitored::Scalar<float>("disTrk_zVtx", 0);
2264 auto monDisTrk = Monitored::Group(m_monTool, mnt_disTrk_nVtx, mnt_disTrk_xVtx, mnt_disTrk_yVtx, mnt_disTrk_zVtx);
2265 mnt_disTrk_nVtx = v_zvtx.size();
2266 if(v_zvtx.size()>0) {
2267 mnt_disTrk_xVtx = v_xvtx[0];
2268 mnt_disTrk_yVtx = v_yvtx[0];
2269 mnt_disTrk_zVtx = v_zvtx[0];
2270 }
2271}
2272
2273bool TrigFastTrackFinder::isGoodForDisTrackVertex(Trk::Track* t, const EventContext& ctx) const
2274{
2275 const double TRKCUT_CHI2_OV_NDOF = 3.0;
2276 const double TRKCUT_PT = 1.0;
2277 const double TRKCUT_D0 = 2.0;
2278 const int TRKCUT_N_HITS_INNER = 1;
2279 const int TRKCUT_N_HITS_PIX = 3;
2280 const int TRKCUT_N_HITS = 7;
2281
2282 // sanity check
2283 if ( ! t->perigeeParameters() ) return false;
2284 if ( ! t->fitQuality() ) return false;
2285 if ( t->trackSummary()==0 ) {
2286 m_trackSummaryTool->updateTrack(ctx, *t);
2287 if ( t->trackSummary()==0 ) return false;
2288 }
2289
2290 // chi2
2291 double chi2 = t->fitQuality()->chiSquared();
2292 double ndof = t->fitQuality()->doubleNumberDoF();
2293 if( std::abs(ndof) < 1e-2 ) return false;
2294 double chi2_ov_ndof = chi2/ndof;
2295 if( chi2_ov_ndof > TRKCUT_CHI2_OV_NDOF ) return false;
2296
2297 // pt
2298 double theta = t->perigeeParameters()->parameters()[Trk::theta];
2299 double qOverP = std::abs(t->perigeeParameters()->parameters()[Trk::qOverP]);
2300 if ( qOverP < 1e-12 ) qOverP = 1e-12;
2301 double pt = std::sin(theta)/qOverP;
2302 pt /= 1000.0;
2303 if( pt < TRKCUT_PT ) return false;
2304
2305 // d0
2306 double d0 = t->perigeeParameters()->parameters()[Trk::d0];
2307 if( std::abs(d0) > TRKCUT_D0 ) return false;
2308
2309 // nr hits
2310 int n_hits_innermost = t->trackSummary()->get(Trk::SummaryType::numberOfInnermostPixelLayerHits);
2311 int n_hits_next_to_innermost = t->trackSummary()->get(Trk::SummaryType::numberOfNextToInnermostPixelLayerHits);
2312 int n_hits_inner = n_hits_innermost + n_hits_next_to_innermost;
2313 int n_hits_pix = t->trackSummary()->get(Trk::SummaryType::numberOfPixelHits);
2314 int n_hits_sct = t->trackSummary()->get(Trk::SummaryType::numberOfSCTHits);
2315 if( n_hits_inner < TRKCUT_N_HITS_INNER ) return false;
2316 if( n_hits_pix < TRKCUT_N_HITS_PIX ) return false;
2317 if( (n_hits_pix+n_hits_sct) < TRKCUT_N_HITS ) return false;
2318
2319 // ok
2320 return true;
2321}
2322
2323void TrigFastTrackFinder::filterSharedDisTracks(std::vector<std::tuple<bool, double,Trk::Track*>>& QT) const
2324{
2325 const int N_FREE_PIX_HITS_CUT = 2;
2326
2327 std::set<const Trk::PrepRawData*> clusters;
2328
2329 const Trk::PrepRawData* prd[100];
2330
2331 std::sort(QT.begin(), QT.end(),
2332 [](const std::tuple<bool, double, Trk::Track*>& lhs, const std::tuple<bool, double, Trk::Track*>& rhs) {
2333 return std::get<1>(lhs) < std::get<1>(rhs); } );
2334
2335 for (auto& q : QT) {
2337 m = std::get<2>(q)->measurementsOnTrack()->begin(),
2338 me = std::get<2>(q)->measurementsOnTrack()->end ();
2339
2340 int nf = 0, nc = 0;
2341 for(; m!=me; ++m ) {
2342 const Trk::PrepRawData* pr = ((const Trk::RIO_OnTrack*)(*m))->prepRawData();
2343 if(pr) {
2344 const InDet::PixelClusterOnTrack *pixclus = dynamic_cast<const InDet::PixelClusterOnTrack*>((*m));
2345 if (pixclus) {
2346 ++nc;
2347 if(clusters.find(pr)==clusters.end()) {prd[nf++]=pr; if(nf==100) break;}
2348 }
2349 }
2350 }
2351 if((nf >= N_FREE_PIX_HITS_CUT) || (nf == nc) ) {
2352 for(int n=0; n!=nf; ++n) clusters.insert(prd[n]);
2353 }
2354 else {
2355 std::get<0>(q) = false;
2356 }
2357 }
2358}
2359
2360StatusCode TrigFastTrackFinder::findDisTracks(const EventContext& ctx,
2361 TrackCollection& tracks,
2362 std::vector<std::tuple<bool, double, Trk::Track*>>& qualityDisFailTrks,
2363 std::vector<std::tuple<bool, double, Trk::Track*>>& qualityDisCombTrks,
2364 TrackCollection& fittedDisCombTrks,
2365 const std::vector<double>& v_xvtx,
2366 const std::vector<double>& v_yvtx,
2367 const std::vector<double>& v_zvtx) const
2368{
2370 ATH_CHECK( disTrkCandHandle.record(std::make_unique<xAOD::TrigCompositeContainer>(), std::make_unique<xAOD::TrigCompositeAuxContainer>()) );
2371 auto disTrkCandContainer = disTrkCandHandle.ptr();
2372
2373 // monitoring
2374 auto mnt_disFailTrk_n = Monitored::Scalar<int>("disFailTrk_n", 0);
2375 auto mnt_disFailTrk_nclone = Monitored::Scalar<int>("disFailTrk_nclone", 0);
2376 auto mnt_disFailTrk_ncand = Monitored::Scalar<int>("disFailTrk_ncand", 0);
2377 auto mnt_disCombTrk_n = Monitored::Scalar<int>("disCombTrk_n", 0);
2378 auto mnt_disCombTrk_nclone = Monitored::Scalar<int>("disCombTrk_nclone", 0);
2379 auto mnt_disCombTrk_ncand = Monitored::Scalar<int>("disCombTrk_ncand", 0);
2380 auto monDisTrk = Monitored::Group(m_monTool, mnt_disFailTrk_n, mnt_disFailTrk_nclone, mnt_disFailTrk_ncand, mnt_disCombTrk_n, mnt_disCombTrk_nclone, mnt_disCombTrk_ncand);
2381
2382 // select tracks to be used for isolation calculation
2383 std::vector<Trk::Track*> tracksForIso;
2384 for (auto t=tracks.begin(); t!=tracks.end(); ++t) {
2385 if( isGoodForDisTrackVertex(*t,ctx) ) tracksForIso.push_back(*t);
2386 }
2387
2388 //
2389 const std::string prefix = "disTrkCand";
2390
2391 // disFailTrk
2392 TrackCollection initialDisFailTrks;
2393 initialDisFailTrks.reserve(qualityDisFailTrks.size());
2394 std::vector<int> resultCodes;
2395 for(const auto& q : qualityDisFailTrks) {
2396 if (std::get<0>(q)==true) {
2397 initialDisFailTrks.emplace_back(std::get<2>(q));
2398 }
2399 else {
2400 delete std::get<2>(q);
2401 }
2402 }
2403 ATH_MSG_VERBOSE("===> nr of disFailTrk=" << qualityDisFailTrks.size() << " -> clone removal=" << initialDisFailTrks.size());
2404
2405 TrackCollection fittedDisFailTrks;
2406 m_trigInDetTrackFitter->fit(initialDisFailTrks, fittedDisFailTrks, ctx, m_particleHypothesis);
2407 int n_disFailTrkCands = recoAndFillDisTrkCand(prefix, &fittedDisFailTrks, tracksForIso, disTrkCandContainer, v_xvtx, v_yvtx, v_zvtx, true, ctx);
2408 ATH_MSG_VERBOSE("disFailTrk: nr of cands = " << n_disFailTrkCands);
2409
2410 mnt_disFailTrk_n = qualityDisFailTrks.size();
2411 mnt_disFailTrk_nclone = initialDisFailTrks.size();
2412 mnt_disFailTrk_ncand = n_disFailTrkCands;
2413
2414 // disCombTrk
2415 ATH_MSG_VERBOSE("===> nr of disCombTrk=" << qualityDisCombTrks.size() << " -> clone removal=" << fittedDisCombTrks.size());
2416 int n_disCombTrkCands = recoAndFillDisTrkCand(prefix, &fittedDisCombTrks, tracksForIso, disTrkCandContainer, v_xvtx, v_yvtx, v_zvtx, false, ctx);
2417 ATH_MSG_VERBOSE("disCombTrk: nr of cands = " << n_disCombTrkCands);
2418
2419 mnt_disCombTrk_n = qualityDisCombTrks.size();
2420 mnt_disCombTrk_nclone = fittedDisCombTrks.size();
2421 mnt_disCombTrk_ncand = n_disCombTrkCands;
2422
2423 return StatusCode::SUCCESS;
2424}
2425
2426bool TrigFastTrackFinder::isPreselPassDisTrackAfterRefit(Trk::Track* trk, Trk::Track* refitTrk, double refit_d0_wrtVtx, double refit_z0_wrtVtx) const
2427{
2428 const float PRESEL_PT_GEV = 5.0;
2429 const float PRESEL_REFIT_PT_GEV_P3S1 = 10.0;
2430 const double PRESEL_D0_WRTVTX = 5.0;
2431 const double PRESEL_Z0_WRTVTX = 50.0;
2432
2433 // sanity check
2434 if( trk == nullptr ) return false;
2435
2437 if( cat==DisTrkCategory::Pix4l_Sct1p || cat==DisTrkCategory::Pix3l_Sct1p ) { if( refitTrk == nullptr ) return false; }
2438
2439 // refit d0
2440 if( std::abs(refit_d0_wrtVtx) > PRESEL_D0_WRTVTX ) return false;
2441
2442 // refit z0
2443 if( std::abs(refit_z0_wrtVtx) > PRESEL_Z0_WRTVTX ) return false;
2444
2445 // pt (either trk or refit trk should have pt beyond cut)
2446 std::vector<float> v_ptGeV;
2447 std::vector<Trk::Track*> v_trk;
2448 v_trk.push_back(trk);
2449 if( refitTrk != nullptr ) v_trk.push_back(refitTrk);
2450 for(auto t : v_trk) {
2451 float theta = t->perigeeParameters()->parameters()[Trk::theta];
2452 float qOverP = std::abs(t->perigeeParameters()->parameters()[Trk::qOverP]);
2453 if ( qOverP < 1e-12 ) qOverP = 1e-12;
2454 float ptGeV = sin(theta)/qOverP/Gaudi::Units::GeV;
2455 v_ptGeV.push_back(ptGeV);
2456 }
2457 bool isLowPt = true;
2458 for(auto pt : v_ptGeV) {
2459 if( pt > PRESEL_PT_GEV ) { isLowPt = false; break; }
2460 }
2461 if( isLowPt ) return false;
2462
2463 // refit pt cut for Pix3l_Sct1p which dominates rates
2464 if( cat==DisTrkCategory::Pix3l_Sct1p ) {
2465 float refitPt = v_ptGeV[1];
2466 if( refitPt < PRESEL_REFIT_PT_GEV_P3S1 ) return false;
2467 }
2468
2469 // cut passed
2470 return true;
2471}
2472
2473bool TrigFastTrackFinder::isPreselPassDisTrackBeforeRefit(Trk::Track* trk, double d0_wrtVtx, double z0_wrtVtx) const
2474{
2475 const double PRESEL_D0_WRTVTX = 5.0;
2476 const double PRESEL_Z0_WRTVTX = 50.0;
2477 const int PRESEL_N_GOOD_BR_LAYERS_PIX = 3;
2478 const double PRESEL_CHI2_OV_NDOF_PIX_BR_CUT = 5.0;
2479
2480 // sanity check
2481 if( trk == nullptr ) return false;
2482 if( trk->perigeeParameters() == nullptr ) return false;
2483
2484 // barrel hits
2485 const auto & barrelLayerInfo = getTrkBarrelLayerInfo(trk);
2486
2487 // PIX cuts
2488 double chi2_pixbr = 0.0;
2489 int ndof_pixbr = 0;
2490 int n_good_brlayers_pix = 0;
2491 for(unsigned int ily=0; ily<=3; ily++) {
2492 if( barrelLayerInfo[ily].nGood >= 1 ) n_good_brlayers_pix++;
2493 chi2_pixbr += barrelLayerInfo[ily].chiSq;
2494 ndof_pixbr += barrelLayerInfo[ily].nDof;
2495 }
2496 if( n_good_brlayers_pix < PRESEL_N_GOOD_BR_LAYERS_PIX ) return false;
2497
2498 if( ndof_pixbr < 1 ) return false;
2499 double chi2_ov_ndof_pixbr = chi2_pixbr / ndof_pixbr;
2500 if( chi2_ov_ndof_pixbr > PRESEL_CHI2_OV_NDOF_PIX_BR_CUT ) return false;
2501
2502 // d0
2503 if( std::abs(d0_wrtVtx) > PRESEL_D0_WRTVTX ) return false;
2504
2505 // z0
2506 if( std::abs(z0_wrtVtx) > PRESEL_Z0_WRTVTX ) return false;
2507
2508 // cut passed
2509 return true;
2510}
2511
2512std::unique_ptr<const Trk::TrackParameters> TrigFastTrackFinder::extrapolateDisTrackToBS(
2513 Trk::Track* t, const std::vector<double>& v_xvtx, const std::vector<double>& v_yvtx, const std::vector<double>& v_zvtx, const EventContext& ctx) const
2514{
2515 float vtx_x = 0;
2516 float vtx_y = 0;
2517 float vtx_z = 9999;
2518 float trk_z0 = t->perigeeParameters()->parameters()[Trk::z0];
2519 float z0_min = 9999;
2520 for(unsigned int i_vtx=0; i_vtx<v_zvtx.size(); i_vtx++) {
2521 float z = v_zvtx[i_vtx];
2522 if( std::abs(trk_z0-z) < z0_min ) {
2523 z0_min = std::abs(trk_z0-z);
2524 vtx_z = z;
2525 vtx_x = v_xvtx[i_vtx];
2526 vtx_y = v_yvtx[i_vtx];
2527 }
2528 }
2529
2530 Amg::Vector3D gp(vtx_x, vtx_y, vtx_z);
2531 Trk::PerigeeSurface persf(gp);
2532 std::unique_ptr<const Trk::TrackParameters> tmp =
2533 m_extrapolator->extrapolateDirectly(ctx, (*(t->perigeeParameters())), persf);
2534 if (tmp && tmp->associatedSurface().type() == Trk::SurfaceType::Perigee) {
2535 return tmp;
2536 }
2537 return nullptr;
2538}
2539
2541{
2542 const auto & result = getTrkBarrelLayerInfo(trk);
2543
2544 int n_good_brlayers_pix = 0;
2545 int n_hits_sct = 0;
2546 for(unsigned int ily=0; ily<8; ily++) {
2547 if( ily<=3 && result[ily].nGood >= 1 ) n_good_brlayers_pix++;
2548 if( 4<=ily ) {
2549 n_hits_sct += result[ily].nHits;
2550 }
2551 }
2552 if( trk->trackSummary()!=0 ) { n_hits_sct = trk->trackSummary()->get(Trk::SummaryType::numberOfSCTHits); }
2553
2554 // category
2556 if( n_good_brlayers_pix == 4 ) {
2557 if( n_hits_sct==0 ) { cat=DisTrkCategory::Pix4l_Sct0; }
2558 else { cat=DisTrkCategory::Pix4l_Sct1p; }
2559 }
2560 else if( n_good_brlayers_pix == 3 ) {
2561 if( n_hits_sct==0 ) { cat=DisTrkCategory::Pix3l_Sct0; }
2562 else { cat=DisTrkCategory::Pix3l_Sct1p; }
2563 }
2564 return cat;
2565}
2566
2567void TrigFastTrackFinder::fillDisTrkCand(xAOD::TrigComposite* comp, const std::string& prefix, Trk::Track* trk, const std::unique_ptr<const Trk::TrackParameters>& vertexPerigee) const
2568{
2569 std::vector<Trk::Track*> vtmp;
2570 fillDisTrkCand(comp,prefix,trk,vertexPerigee,false,vtmp);
2571}
2572
2573void TrigFastTrackFinder::fillDisTrkCand(xAOD::TrigComposite* comp, const std::string& prefix, Trk::Track* trk, const std::unique_ptr<const Trk::TrackParameters>& vertexPerigee,
2574 bool fillIso, std::vector<Trk::Track*>& tracksForIso) const
2575{
2576 // category
2577 int category = (trk != nullptr) ? (int)getDisTrkCategory(trk) : -1;
2578 if( prefix.find("refit") == std::string::npos ) comp->setDetail<int16_t>(prefix+"_category",(int16_t)category);
2579
2580 // track
2581 float theta=0; float eta=0; float pt=0; float d0=0; float z0=0; float phi=0; float chi2=0; float ndof=0;
2582 int n_hits_innermost=-1; int n_hits_next_to_innermost=-1; int n_hits_inner=-1; int n_hits_pix=-1; int n_hits_sct=-1;
2583 if( trk != nullptr ) {
2584 theta = trk->perigeeParameters()->parameters()[Trk::theta];
2585 eta = -std::log(std::tan(0.5*theta));
2586 float qOverP = std::abs(trk->perigeeParameters()->parameters()[Trk::qOverP]);
2587 if ( qOverP < 1e-12 ) qOverP = 1e-12;
2588 pt = sin(theta)/qOverP;
2589 d0 = trk->perigeeParameters()->parameters()[Trk::d0];
2590 z0 = trk->perigeeParameters()->parameters()[Trk::z0];
2591 phi = trk->perigeeParameters()->parameters()[Trk::phi];
2592 chi2 = trk->fitQuality()->chiSquared();
2593 ndof = trk->fitQuality()->doubleNumberDoF();
2594 if( trk->trackSummary()!=0 ) {
2599 n_hits_inner = n_hits_innermost + n_hits_next_to_innermost;
2600 }
2601 }
2602 comp->setDetail<float>(prefix+"_pt", pt);
2603 comp->setDetail<float>(prefix+"_eta", eta);
2604 comp->setDetail<float>(prefix+"_phi", phi);
2605 comp->setDetail<float>(prefix+"_d0", d0);
2606 comp->setDetail<float>(prefix+"_z0", z0);
2607 comp->setDetail<float>(prefix+"_chi2", chi2);
2608 comp->setDetail<float>(prefix+"_ndof", ndof);
2609 comp->setDetail<int16_t>(prefix+"_n_hits_innermost", (int16_t)n_hits_innermost);
2610 comp->setDetail<int16_t>(prefix+"_n_hits_inner", (int16_t)n_hits_inner);
2611 comp->setDetail<int16_t>(prefix+"_n_hits_pix", (int16_t)n_hits_pix);
2612 comp->setDetail<int16_t>(prefix+"_n_hits_sct", (int16_t)n_hits_sct);
2613
2614 // extrapolate
2615 float theta_wrtVtx=0; float eta_wrtVtx=0; float pt_wrtVtx=0; float d0_wrtVtx=0; float z0_wrtVtx=0; float phi_wrtVtx=0;
2616 if( vertexPerigee != nullptr ) {
2617 theta_wrtVtx = vertexPerigee->parameters()[Trk::theta];
2618 eta_wrtVtx = -std::log(std::tan(0.5*theta_wrtVtx));
2619 float qOverP_wrtVtx = std::abs(vertexPerigee->parameters()[Trk::qOverP]);
2620 if ( qOverP_wrtVtx < 1e-12 ) qOverP_wrtVtx = 1e-12;
2621 pt_wrtVtx = std::sin(theta_wrtVtx)/qOverP_wrtVtx;
2622 d0_wrtVtx = vertexPerigee->parameters()[Trk::d0];
2623 z0_wrtVtx = vertexPerigee->parameters()[Trk::z0];
2624 phi_wrtVtx = vertexPerigee->parameters()[Trk::phi];
2625 }
2626 comp->setDetail<float>(prefix+"_pt_wrtVtx", pt_wrtVtx);
2627 comp->setDetail<float>(prefix+"_eta_wrtVtx", eta_wrtVtx);
2628 comp->setDetail<float>(prefix+"_phi_wrtVtx", phi_wrtVtx);
2629 comp->setDetail<float>(prefix+"_d0_wrtVtx", d0_wrtVtx);
2630 comp->setDetail<float>(prefix+"_z0_wrtVtx", z0_wrtVtx);
2631
2632 // barrel hits
2633 std::array<OneLayerInfo_t, N_BARREL_LAYERS> barrelInfo{};
2634 barrelInfo = getTrkBarrelLayerInfo(trk);
2635 comp->setDetail<float>(prefix+"_chi2sum_br_ibl", barrelInfo[0].chiSq);
2636 comp->setDetail<float>(prefix+"_chi2sum_br_pix1", barrelInfo[1].chiSq);
2637 comp->setDetail<float>(prefix+"_chi2sum_br_pix2", barrelInfo[2].chiSq);
2638 comp->setDetail<float>(prefix+"_chi2sum_br_pix3", barrelInfo[3].chiSq);
2639 comp->setDetail<float>(prefix+"_chi2sum_br_sct1", barrelInfo[4].chiSq);
2640 comp->setDetail<float>(prefix+"_chi2sum_br_sct2", barrelInfo[5].chiSq);
2641 comp->setDetail<float>(prefix+"_chi2sum_br_sct3", barrelInfo[6].chiSq);
2642 comp->setDetail<float>(prefix+"_chi2sum_br_sct4", barrelInfo[7].chiSq);
2643 comp->setDetail<float>(prefix+"_ndofsum_br_ibl", barrelInfo[0].nDof);
2644 comp->setDetail<float>(prefix+"_ndofsum_br_pix1", barrelInfo[1].nDof);
2645 comp->setDetail<float>(prefix+"_ndofsum_br_pix2", barrelInfo[2].nDof);
2646 comp->setDetail<float>(prefix+"_ndofsum_br_pix3", barrelInfo[3].nDof);
2647 comp->setDetail<float>(prefix+"_ndofsum_br_sct1", barrelInfo[4].nDof);
2648 comp->setDetail<float>(prefix+"_ndofsum_br_sct2", barrelInfo[5].nDof);
2649 comp->setDetail<float>(prefix+"_ndofsum_br_sct3", barrelInfo[6].nDof);
2650 comp->setDetail<float>(prefix+"_ndofsum_br_sct4", barrelInfo[7].nDof);
2651
2652 // isolation
2653 if( fillIso ) {
2654 const float ISOL_CALC_Z0_DIFF_CUT = 2.5;
2655 const float ISOL_CALC_DR_CUT_TO_AVOID_ZERO = 0.015;
2656 float iso1_dr01=0; float iso1_dr02=0;
2657 float iso2_dr01=0; float iso2_dr02=0;
2658 float iso3_dr01=0; float iso3_dr02=0;
2659 for(auto t=tracksForIso.begin(); t!=tracksForIso.end(); t++) {
2660 float z0_t = (*t)->perigeeParameters()->parameters()[Trk::z0];
2661 if( std::abs(z0_t - z0) <= ISOL_CALC_Z0_DIFF_CUT ) {
2662 float theta_t = (*t)->perigeeParameters()->parameters()[Trk::theta];
2663 float qOverP_t= std::abs((*t)->perigeeParameters()->parameters()[Trk::qOverP]);
2664 if ( qOverP_t < 1e-12 ) qOverP_t = 1e-12;
2665 float pt_t = std::sin(theta_t)/qOverP_t;
2666 float phi_t = (*t)->perigeeParameters()->parameters()[Trk::phi];
2667 float eta_t = -std::log(std::tan(theta_t/2.0));
2668 float deta = eta_t - eta;
2669 float dphi = std::abs(phi_t - phi);
2670 if( dphi > CLHEP::pi ) dphi = CLHEP::pi*2 - dphi;
2671 float dr = std::sqrt(deta*deta + dphi*dphi);
2672 if( dr > ISOL_CALC_DR_CUT_TO_AVOID_ZERO && dr<0.1 && pt_t > 1.0*Gaudi::Units::GeV ) iso1_dr01 += pt_t;
2673 if( dr > ISOL_CALC_DR_CUT_TO_AVOID_ZERO && dr<0.2 && pt_t > 1.0*Gaudi::Units::GeV ) iso1_dr02 += pt_t;
2674 //
2675 if( dr > ISOL_CALC_DR_CUT_TO_AVOID_ZERO && dr<0.1 && pt_t > 2.0*Gaudi::Units::GeV ) iso2_dr01 += pt_t;
2676 if( dr > ISOL_CALC_DR_CUT_TO_AVOID_ZERO && dr<0.2 && pt_t > 2.0*Gaudi::Units::GeV ) iso2_dr02 += pt_t;
2677 //
2678 if( dr > ISOL_CALC_DR_CUT_TO_AVOID_ZERO && dr<0.1 && pt_t > 3.0*Gaudi::Units::GeV ) iso3_dr01 += pt_t;
2679 if( dr > ISOL_CALC_DR_CUT_TO_AVOID_ZERO && dr<0.2 && pt_t > 3.0*Gaudi::Units::GeV ) iso3_dr02 += pt_t;
2680 }
2681 }
2682 comp->setDetail<float>(prefix+"_iso1_dr01", iso1_dr01);
2683 comp->setDetail<float>(prefix+"_iso1_dr02", iso1_dr02);
2684 comp->setDetail<float>(prefix+"_iso2_dr01", iso2_dr01);
2685 comp->setDetail<float>(prefix+"_iso2_dr02", iso2_dr02);
2686 comp->setDetail<float>(prefix+"_iso3_dr01", iso3_dr01);
2687 comp->setDetail<float>(prefix+"_iso3_dr02", iso3_dr02);
2688 }
2689}
2690
2691int TrigFastTrackFinder::recoAndFillDisTrkCand(const std::string& base_prefix,
2692 TrackCollection* tracks, std::vector<Trk::Track*>& tracksForIso,
2693 xAOD::TrigCompositeContainer* trigCompositeContainer,
2694 const std::vector<double>& v_xvtx,
2695 const std::vector<double>& v_yvtx,
2696 const std::vector<double>& v_zvtx,
2697 bool isFail,
2698 const EventContext& ctx) const
2699{
2700 std::string prefix;
2701
2702 int n_stored_tracks = 0;
2703
2704 for (auto trk = tracks->begin(); trk!=tracks->end(); ++trk) {
2705
2706 Trk::Track* ptrk = *trk;
2707
2708 if( ptrk == nullptr ) continue;
2709 if( ptrk->perigeeParameters()==nullptr ) continue;
2710
2711 // extrapolate to vertex
2712 std::unique_ptr<const Trk::TrackParameters> vertexPerigee = extrapolateDisTrackToBS(ptrk,v_xvtx,v_yvtx,v_zvtx, ctx);
2713 double d0 = ptrk->perigeeParameters()->parameters()[Trk::d0];
2714 double z0 = ptrk->perigeeParameters()->parameters()[Trk::z0];
2715 double d0_wrtVtx = 0;
2716 double z0_wrtVtx = 0;
2717 if( vertexPerigee != nullptr ) {
2718 d0_wrtVtx = vertexPerigee->parameters()[Trk::d0];
2719 z0_wrtVtx = vertexPerigee->parameters()[Trk::z0];
2720 ATH_MSG_VERBOSE("d0 : " << d0 << " -> extrapolate -> " << d0_wrtVtx);
2721 ATH_MSG_VERBOSE("z0 : " << z0 << " -> extrapolate -> " << z0_wrtVtx);
2722 }
2723
2724 m_trackSummaryTool->updateTrack(ctx, *ptrk);
2725
2726 // pre-selection before refit
2727 if( ! isPreselPassDisTrackBeforeRefit(ptrk,d0_wrtVtx,z0_wrtVtx) ) continue;
2728
2729 // refit
2730 std::unique_ptr<Trk::Track> refit_trk = disTrk_refit(ptrk, ctx);
2731 if( refit_trk != nullptr ) m_trackSummaryTool->updateTrack(ctx, *refit_trk);
2732
2733 // extrapolate refitted track to vertex
2734 double refit_d0 = 0;
2735 double refit_z0 = 0;
2736 double refit_d0_wrtVtx = 0;
2737 double refit_z0_wrtVtx = 0;
2738 std::unique_ptr<const Trk::TrackParameters> refitVertexPerigee = nullptr;
2739 if( refit_trk != nullptr ) {
2740 refitVertexPerigee = extrapolateDisTrackToBS(refit_trk.get(),v_xvtx,v_yvtx,v_zvtx,ctx);
2741 if( refitVertexPerigee == nullptr ) {
2742 ATH_MSG_VERBOSE("extrapote to BS fails for refit track");
2743 }
2744 else {
2745 refit_d0 = refit_trk.get()->perigeeParameters()->parameters()[Trk::d0];
2746 refit_z0 = refit_trk.get()->perigeeParameters()->parameters()[Trk::z0];
2747 refit_d0_wrtVtx = refitVertexPerigee->parameters()[Trk::d0];
2748 refit_z0_wrtVtx = refitVertexPerigee->parameters()[Trk::z0];
2749 ATH_MSG_VERBOSE("refit trk d0 : " << refit_d0 << " -> extrapolate -> " << refit_d0_wrtVtx);
2750 ATH_MSG_VERBOSE("refit trk z0 : " << refit_z0 << " -> extrapolate -> " << refit_z0_wrtVtx);
2751 }
2752 }
2753
2754 // pre-selection after refit
2755 if( ! isPreselPassDisTrackAfterRefit(ptrk,refit_trk.get(),refit_d0_wrtVtx,refit_z0_wrtVtx) ) continue;
2756
2757 // store it!
2758 n_stored_tracks++;
2759
2761 comp->makePrivateStore();
2762 trigCompositeContainer->push_back(comp);
2763
2764 //
2765 int is_fail = isFail ? 1 : 0;
2766 comp->setDetail<int16_t>(base_prefix+"_is_fail",(int16_t)is_fail);
2767
2768 // store trk info
2769 prefix = base_prefix;
2770 fillDisTrkCand(comp,prefix,ptrk,vertexPerigee,true,tracksForIso);
2771
2772 // store refit trk info
2773 prefix = base_prefix + "_refit";
2774 if( refit_trk != nullptr ) {
2775 fillDisTrkCand(comp,prefix,refit_trk.get(),refitVertexPerigee);
2776 }
2777 else {
2778 fillDisTrkCand(comp,prefix,nullptr,refitVertexPerigee);
2779 }
2780 }
2781
2782 //
2783 ATH_MSG_VERBOSE("========> filling trigcomposite for " << prefix << " end");
2784 ATH_MSG_VERBOSE("nr of " << prefix << " tracks / stored = " << tracks->size() << " / " << n_stored_tracks);
2785
2786 //
2787 return n_stored_tracks;
2788}
2789
2790std::unique_ptr<Trk::Track> TrigFastTrackFinder::disTrk_refit(Trk::Track* t, const EventContext& ctx) const
2791{
2792 std::unique_ptr<Trk::Track> newtrack = nullptr;
2793
2794 if( t == nullptr ) return newtrack;
2795 if( t->trackSummary() == nullptr ) m_trackSummaryTool->updateTrack(ctx, *t);
2796
2797 ATH_MSG_VERBOSE("refitting - input track:");
2798 print_disTrk(t);
2799
2800 const Trk::Perigee* origPerigee = t->perigeeParameters();
2801 if( origPerigee == nullptr ) return newtrack;
2802 ATH_MSG_VERBOSE("... origPerigee is there");
2803
2804 // remove SCT hits
2805 std::vector<const Trk::MeasurementBase*> vec;
2806 int n_measurements = 0;
2807 int n_measurements_refit = 0;
2808 const Trk::TrackStates* recoTrackStates = t->trackStateOnSurfaces();
2809 if (recoTrackStates) {
2810 Trk::TrackStates::const_iterator tsosIter = recoTrackStates->begin();
2811 Trk::TrackStates::const_iterator tsosIterEnd = recoTrackStates->end();
2812 for ( ; tsosIter != tsosIterEnd; ++tsosIter) {
2813 const Trk::MeasurementBase *measurement = (*tsosIter)->measurementOnTrack();
2814 if (measurement) {
2815 n_measurements++;
2816 const InDet::PixelClusterOnTrack *pixclus = dynamic_cast<const InDet::PixelClusterOnTrack*>(measurement);
2817 const InDet::SCT_ClusterOnTrack *sctclus = dynamic_cast<const InDet::SCT_ClusterOnTrack*>(measurement);
2818 bool to_add = true;
2819 if ( !pixclus && sctclus ) to_add = false;
2820 if( to_add ) {
2821 vec.push_back(measurement);
2822 n_measurements_refit++;
2823 }
2824 }
2825 }
2826 }
2827 ATH_MSG_VERBOSE("... Nr of measurments / refit = " << n_measurements << " / " << n_measurements_refit);
2828
2829 // perform refit
2830 newtrack = m_disTrkFitter->fit(ctx,vec, *origPerigee, false, m_particleHypothesis); // false to run outlier switch
2831 ATH_MSG_VERBOSE("... ---> refit track:");
2832 if( newtrack!=0 && newtrack.get() ) {
2833 print_disTrk(dynamic_cast<const Trk::Track*>(newtrack.get()));
2834 }
2835 else {
2836 ATH_MSG_VERBOSE("... refit failed");
2837 }
2838
2839 //
2840 return newtrack;
2841}
2842
2844{
2845 float chi2=0; float ndof=0; float d0=0; float z0=0; float phi=0; float theta=0; float pt=0;
2846 if( t!=nullptr ) {
2847 chi2 = t->fitQuality()->chiSquared();
2848 ndof = t->fitQuality()->doubleNumberDoF();
2849 d0 = t->perigeeParameters()->parameters()[Trk::d0];
2850 z0 = t->perigeeParameters()->parameters()[Trk::z0];
2851 phi = t->perigeeParameters()->parameters()[Trk::phi];
2852 theta = t->perigeeParameters()->parameters()[Trk::theta];
2853 float qOverP = std::abs(t->perigeeParameters()->parameters()[Trk::qOverP]);
2854 if ( qOverP < 1e-12 ) qOverP = 1e-12;
2855 pt = sin(theta)/qOverP;
2856 pt /= Gaudi::Units::GeV;
2857 }
2858 ATH_MSG_DEBUG("... pt / theta / phi / d0 / z0 = " << pt << " / " << theta << " / " << phi << " / " << d0 << " / " << z0);
2859 ATH_MSG_DEBUG("... chi2 / ndof = " << chi2 << " / " << ndof);
2860}
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
double charge(const T &p)
Definition AtlasPID.h:997
std::vector< size_t > vec
Header file to be included by clients of the Monitored infrastructure.
This is an Identifier helper class for the Pixel subdetector.
This is an Identifier helper class for the SCT subdetector.
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
Athena::TPCnvVers::Current TrigRoiDescriptor
class TrigTrackSeedGenerator TRIG_TRACK_SEED_GENERATOR
#define z
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
An algorithm that can be simultaneously executed in multiple threads.
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
value_type emplace_back(value_type pElem)
Add an element to the end of the collection.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
iterator erase(iterator position)
Remove element at a given position.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
Describes the API of the Region of Ineterest geometry.
virtual double eta() const =0
virtual double phiPlus() const =0
extreme phi values
virtual double zedPlus() const =0
the zed and eta values at the most forward and most rear ends of the RoI
virtual double phiMinus() const =0
virtual double phi() const =0
Methods to retrieve data members.
virtual double zedMinus() const =0
virtual double zed() const =0
virtual double etaMinus() const =0
virtual double etaPlus() const =0
Specific class to represent the pixel measurements.
virtual const PixelCluster * prepRawData() const override final
returns the PrepRawData - is a SiCluster in this scope
Specific class to represent the SCT measurements.
RIO_OnTrack base class for Silicon detector in the InnerDetector.
SiCombinatorialTrackFinderData_xk::ResultCode resultCode() const
void setFlagToReturnFailedTrack(const bool)
Setter for flagToReturnFailedTrack (for disappearing track trigger).
InDet::SiTrackMakerEventData_xk holds event dependent data used by ISiTrackMaker.
SiCombinatorialTrackFinderData_xk & combinatorialData()
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
A monitored timer.
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
virtual double etaMinus() const override final
gets eta at zMinus
virtual double etaPlus() const override final
gets eta at zedPlus
virtual double zed() const override final
virtual double phi() const override final
Methods to retrieve data members.
virtual double phiMinus() const override final
gets phiMinus
virtual double zedPlus() const override final
z at the most forward end of the RoI
virtual double zedMinus() const override final
z at the most backward end of the RoI
virtual const IRoiDescriptor * at(int i) const override final
find an RoiDescriptor constituent
virtual unsigned size() const override final
number of constituents
virtual double eta() const override final
virtual bool composite() const override final
SuperRoI compatability methods.
virtual double phiPlus() const override final
gets phiPlus
const_pointer_type ptr()
Dereference the pointer.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
virtual bool run()=0
virtual std::shared_ptr< OffloadBuffer > getOutput()=0
void updateClusterMap(long int, const Trk::Track *, std::map< Identifier, std::vector< long int > > &) const
ToolHandle< ITrigInDetTrackFitter > m_trigInDetTrackFitter
ToolHandle< ITrigSpacePointConversionTool > m_spacePointTool
virtual StatusCode execute(const EventContext &ctx) const override
void runResidualMonitoring(const Trk::Track &track, const EventContext &) const
bool isGoodForDisTrackVertex(Trk::Track *, const EventContext &) const
TrigFastTrackFinder::DisTrkCategory getDisTrkCategory(Trk::Track *trk) const
std::unique_ptr< const Trk::TrackParameters > extrapolateDisTrackToBS(Trk::Track *, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const EventContext &) const
SG::WriteHandleKey< xAOD::TrigCompositeContainer > m_dEdxHitKey
void filterSharedDisTracks(std::vector< std::tuple< bool, double, Trk::Track * > > &) const
ToolHandle< ITrigL2LayerNumberTool > m_numberingTool
ToolHandle< ITrigInDetTrackSeedingTool > m_seedingTool
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
virtual StatusCode start() override
SG::ReadHandleKey< Trk::PRDtoTrackMap > m_prdToTrackMap
ToolHandle< ITrigInDetAccelerationTool > m_accelTool
Gaudi::Property< bool > m_useTracklets
Gaudi::Property< bool > m_doCloneRemoval
void fillMon(const TrackCollection &tracks, const TrigVertexCollection &vertices, const TrigRoiDescriptor &roi, const EventContext &ctx) const
bool isPreselPassDisTrackBeforeRefit(Trk::Track *, double, double) const
int recoAndFillDisTrkCand(const std::string &, TrackCollection *, std::vector< Trk::Track * > &, xAOD::TrigCompositeContainer *, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, bool, const EventContext &) const
SG::ReadHandleKey< TrackCollection > m_inputTracksKey
StatusCode findTracks(InDet::SiTrackMakerEventData_xk &event_data, const TrigRoiDescriptor &roi, const TrackCollection *inputTracks, TrackCollection &outputTracks, const EventContext &ctx) const
Trk::ParticleHypothesis m_particleHypothesis
void extractClusterIds(const Trk::SpacePoint *, std::vector< Identifier > &) const
Gaudi::Property< bool > m_doTrackRefit
const AtlasDetectorID * m_idHelper
SG::ReadHandleKey< TrigRoiDescriptorCollection > m_roiCollectionKey
double trackQuality(const Trk::Track *Tr) const
void fillDisTrkCand(xAOD::TrigComposite *, const std::string &, Trk::Track *, const std::unique_ptr< const Trk::TrackParameters > &) const
ToolHandle< Trk::ITrackSummaryTool > m_trackSummaryTool
double disTrackQuality(const Trk::Track *) const
virtual StatusCode initialize() override
std::array< OneLayerInfo_t, N_BARREL_LAYERS > getTrkBarrelLayerInfo(Trk::Track *aTrack) const
void recoVertexForDisTrack(const EventContext &, TrackCollection &, std::vector< double > &, std::vector< double > &, std::vector< double > &) const
void print_disTrk(const Trk::Track *t) const
SG::WriteHandleKey< xAOD::TrigCompositeContainer > m_dEdxTrkKey
SG::WriteHandleKey< TrackCollection > m_outputTracksKey
std::atomic< unsigned int > m_countRoIwithEnoughHits
bool isPreselPassDisTrackAfterRefit(Trk::Track *, Trk::Track *, double, double) const
std::atomic< unsigned int > m_countRoIwithTracks
std::unique_ptr< Trk::Track > disTrk_refit(Trk::Track *t, const EventContext &ctx) const
StatusCode finddEdxTrk(const EventContext &, const TrackCollection &) const
std::atomic< unsigned int > m_countTotalRoI
ToolHandle< ITrigZFinder > m_trigZFinder
SG::WriteHandleKey< xAOD::TrigCompositeContainer > m_disTrkCandKey
int getSPLayer(int, float) const
void filterSharedTracks(std::vector< std::tuple< bool, double, Trk::Track * > > &QT) const
ToolHandle< InDet::ISiTrackMaker > m_trackMaker
TrigCombinatorialSettings m_tcs
ToolHandle< Trk::ITrackFitter > m_disTrkFitter
ToolHandle< Trk::IExtrapolator > m_extrapolator
virtual StatusCode finalize() override
ServiceHandle< ITrigInDetAccelerationSvc > m_accelSvc
ToolHandle< GenericMonitoringTool > m_monTool
StatusCode createEmptyUTTEDMs(const EventContext &) const
StatusCode findDisTracks(const EventContext &, TrackCollection &, std::vector< std::tuple< bool, double, Trk::Track * > > &, std::vector< std::tuple< bool, double, Trk::Track * > > &, TrackCollection &, const std::vector< double > &, const std::vector< double > &, const std::vector< double > &) const
bool usedByAnyTrack(const std::vector< Identifier > &, std::map< Identifier, std::vector< long int > > &) const
void makeSeedsOnGPU(const TrigCombinatorialSettings &, const IRoiDescriptor *, const std::vector< TrigSiSpacePointBase > &, std::vector< TrigInDetTriplet > &) const
bool isCleaningPassDisTrack(const TrigInDetTriplet &, Trk::Track *, bool) const
float dEdx(const Trk::Track *, int &, int &, std::vector< float > &, std::vector< float > &, std::vector< float > &, std::vector< float > &, std::vector< int > &, std::vector< int > &, std::vector< int > &) const
TrigFastTrackFinder(const std::string &name, ISvcLocator *pSvcLocator)
nope - should be used for standalone also, perhaps need to protect the class def bits ifndef XAOD_ANA...
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
Definition FitQuality.h:60
double chiSquared() const
returns the of the overall track fit
Definition FitQuality.h:56
double doubleNumberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as double
Definition FitQuality.h:68
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition FitQuality.h:97
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
Definition FitQuality.h:60
double chiSquared() const
returns the of the overall track fit
Definition FitQuality.h:56
double doubleNumberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as double
Definition FitQuality.h:68
This class is the pure abstract base class for all fittable tracking measurements.
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
const Amg::Vector3D & momentum() const
Access method for the momentum.
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
Class describing the Line to which the Perigee refers to.
Identifier identify() const
return the identifier
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
Identifier identify() const
return the identifier -extends MeasurementBase
const std::pair< const PrepRawData *, const PrepRawData * > & clusterList() const
return the pair of cluster pointers by reference
virtual const Amg::Vector3D & normal() const
Returns the normal vector of the Surface (i.e.
@ FastTrackFinderSeed
for tracks seeded by the FastTrackFinder
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
int get(const SummaryType &type) const
returns the summary information for the passed SummaryType.
const Trk::TrackStates * trackStateOnSurfaces() const
return a pointer to a const DataVector of const TrackStateOnSurfaces.
const DataVector< const MeasurementBase > * measurementsOnTrack() const
return a pointer to a vector of MeasurementBase (NOT including any that come from outliers).
const Perigee * perigeeParameters() const
return Perigee.
const Trk::TrackSummary * trackSummary() const
Returns a pointer to the const Trk::TrackSummary owned by this const track (could be nullptr).
const FitQuality * fitQuality() const
return a pointer to the fit quality const-overload
bool setDetail(const std::string &name, const TYPE &value)
Set an TYPE detail on the object.
double chi2(TH1 *h0, TH1 *h1)
double a0
Definition globals.cxx:27
std::string base
Definition hcg.cxx:83
Eigen::Matrix< double, 3, 1 > Vector3D
T wrapToPi(T phi)
Wrap angle in radians to [-pi, pi].
Definition phihelper.h:24
void getBeamSpotShift(float &shift_x, float &shift_y, const InDet::BeamSpotData &beamSpotHandle)
bool isGoodTrackUTT(const Trk::Track *track, trackInfo &theTrackInfo, const float shift_x, const float shift_y, float trkcut_ptgev)
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
struct TrigAccel::DataExportBuffer DATA_EXPORT_BUFFER
Ensure that the ATLAS eigen extensions are properly loaded.
DataVector< const Trk::TrackStateOnSurface > TrackStates
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
@ phi0
Definition ParamDefs.h:65
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ phi
Definition ParamDefs.h:75
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
ParametersBase< TrackParametersDim, Charged > TrackParameters
@ numberOfPixelHits
number of pixel layers on track with absence of hits
@ numberOfNextToInnermostPixelLayerHits
these are the pixel hits, including the b-layer
@ numberOfInnermostPixelLayerHits
these are the hits in the 1st pixel layer
STL namespace.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
TrigCompositeContainer_v1 TrigCompositeContainer
Declare the latest version of the container.
TrigComposite_v1 TrigComposite
Declare the latest version of the class.
Helper for azimuthal angle calculations.
int n_hits_innermost