ATLAS Offline Software
TrigHitDVHypoAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 
4  * Trigger Hypo Tool, that is aimed at triggering displaced vertex
5  * author Kunihiro Nagano <kunihiro.nagano@cern.ch> - KEK
6 */
7 #include "TrigHitDVHypoAlg.h"
8 #include "AthViews/ViewHelper.h"
10 #include "GaudiKernel/SystemOfUnits.h"
12 #include "GaudiKernel/PhysicalConstants.h"
15 
17 #include "CxxUtils/phihelper.h"
19 
20 #include "TFile.h"
21 #include "TTree.h"
22 
23 #include <vector>
24 #include <unordered_map>
25 
40 
41 using xAOD::JetContainer;
42 
43 // ------------------------------------------------------------------------------------------------
44 // ------------------------------------------------------------------------------------------------
45 
47  ISvcLocator* pSvcLocator ) :
48  ::HypoBase( name, pSvcLocator ),
49  m_lumiBlockMuTool("LumiBlockMuTool/LumiBlockMuTool")
50 {}
51 
52 // ------------------------------------------------------------------------------------------------
53 // ------------------------------------------------------------------------------------------------
54 
56 {
57  m_tools_lowest_jetEt = 1000;
59  CHECK( m_hypoTools.retrieve() );
60  for ( auto & tool: m_hypoTools ) {
61  ATH_MSG_VERBOSE( "+++++ Hypo Tool name: " << tool->name() );
62  std::cmatch results;
63  if( std::regex_search(tool->name().c_str(),results,std::regex("hitdvjet(\\d+)_(\\w+)_")) ) {
64  std::string sth = results[1].str();
65  std::string swp = results[2].str();
66  ATH_MSG_VERBOSE( " thres = " << sth << ", wp = " << swp );
67  int thres = std::stoi(sth);
68  if( thres < m_tools_lowest_jetEt ) m_tools_lowest_jetEt = thres;
69  if( swp == "loose" && m_tools_loosest_wp >= 1 ) m_tools_loosest_wp = 1;
70  if( swp == "medium" && m_tools_loosest_wp >= 2 ) m_tools_loosest_wp = 2;
71  if( swp == "tight" && m_tools_loosest_wp >= 3 ) m_tools_loosest_wp = 3;
72  }
73  }
74  ATH_MSG_DEBUG( "Lowest jetEt used in hypo tools = " << m_tools_lowest_jetEt << " (GeV)" );
75  ATH_MSG_DEBUG( "Loosest WP used in hypo tools = " << m_tools_loosest_wp << " (loose=1,medium=2,tight=3)");
76  // loose : eta<2.0, SP seed=true, BDT eff=0.9
77  // medium: eta<2.0, SP seed=false, BDT eff=0.75
78  // tight : eta<1.0, SP seed=false, BDT eff=0.75
79 
81  CHECK( m_hitDVKey.initialize());
82  CHECK( m_tracksKey.initialize());
85 
86  if ( !m_monTool.empty() ) CHECK( m_monTool.retrieve() );
87 
89  ATH_CHECK(m_spacePointTool.retrieve() );
90 
91  // MVAUtils BDT initialisation
92  // could make this configurable as a property
93  std::string weightfile[2];
94  weightfile[0] = PathResolver::find_calib_file("TrigHitDVHypo/HitDV.BDT.weights.0eta1.v22a.root");
95  weightfile[1] = PathResolver::find_calib_file("TrigHitDVHypo/HitDV.BDT.weights.1eta2.v22a.root");
96  for (unsigned int i=0; i<2; ++i) {
97  std::unique_ptr<TFile> rootFile(TFile::Open(weightfile[i].c_str(), "READ"));
98  if (!rootFile) {
99  ATH_MSG_ERROR("Can not open BDT root file: " << weightfile[i] );
100  return StatusCode::FAILURE;
101  }
102  std::unique_ptr<TTree> tree((TTree*)rootFile->Get("BDT"));
103  if (!tree) {
104  ATH_MSG_ERROR("Can not find BDT tree in file: " << weightfile[i]);
105  return StatusCode::FAILURE;
106  }
107  ATH_MSG_INFO("Loading BDT tree from file: " << weightfile[i]);
108  m_bdt_eta[i] = std::make_unique<MVAUtils::BDT>(tree.get());
109  }
110 
111  return StatusCode::SUCCESS;
112 }
113 
114 // ------------------------------------------------------------------------------------------------
115 // ------------------------------------------------------------------------------------------------
116 
117 StatusCode TrigHitDVHypoAlg::execute( const EventContext& context ) const
118 {
119 
120  const TrigRoiDescriptor roi = TrigRoiDescriptor(0, -4.5, 4.5, 0, -M_PI, M_PI, 0, -168.0, 168.0);
121  std::vector<TrigSiSpacePointBase> convertedSpacePoints;
122  convertedSpacePoints.reserve(5000);
123  int mnt_roi_nSPsPIX;
124  int mnt_roi_nSPsSCT;
125  ATH_CHECK(m_spacePointTool->getSpacePoints(roi, convertedSpacePoints, mnt_roi_nSPsPIX, mnt_roi_nSPsSCT, context));
126 
127  // monitoring
128  auto mon_n_dvtrks = Monitored::Scalar<int>( "n_dvtrks", 0 );
129  auto mon_n_dvsps = Monitored::Scalar<int>( "n_dvsps", 0 );
130  auto mon_n_jetseeds = Monitored::Scalar<int>( "n_jetseeds", 0 );
131  auto mon_n_jetseedsdel= Monitored::Scalar<int>( "n_jetseedsdel",0 );
132  auto mon_n_spseeds = Monitored::Scalar<int>( "n_spseeds", 0 );
133  auto mon_n_spseedsdel = Monitored::Scalar<int>( "n_spseedsdel", 0 );
134  auto mon_average_mu = Monitored::Scalar<float>( "average_mu", 0.);
135  auto monitorIt = Monitored::Group( m_monTool, mon_n_dvtrks, mon_n_dvsps, mon_n_jetseeds, mon_n_jetseedsdel, mon_n_spseeds, mon_n_spseedsdel, mon_average_mu );
136 
137  // previous decisions
138  ATH_MSG_DEBUG( "Retrieving pervious decision: \"" << decisionInput().key() << "\"" );
139  auto previousDecisionsHandle = SG::makeHandle( decisionInput(), context );
140  ATH_CHECK( previousDecisionsHandle.isValid() );
141 
142  ATH_MSG_DEBUG( "Running with " << previousDecisionsHandle->size() << " previous decisions" );
143  if( previousDecisionsHandle->size()!=1 ) {
144  ATH_MSG_ERROR( "Previous decision handle size is not 1. It is" << previousDecisionsHandle->size() );
145  return StatusCode::FAILURE;
146  }
147  const Decision * previousDecision = previousDecisionsHandle->at(0);
148 
149  TrigCompositeUtils::DecisionIDContainer previousDecisionIDs;
150  TrigCompositeUtils::decisionIDs(previousDecision, previousDecisionIDs);
151  ATH_MSG_DEBUG( "IDs of active legs:" );
152  for(auto decisionID: previousDecisionIDs) { ATH_MSG_DEBUG( " " << decisionID ); }
153 
154  // new output decisions
155  ATH_MSG_DEBUG( "Creating new output decision handle" );
157  auto outputDecisions = outputHandle.ptr();
158 
159  // input objects
160 
161  // jets
162  auto jetsHandle = SG::makeHandle(m_jetsKey, context );
163  ATH_CHECK( jetsHandle.isValid() );
164  ATH_MSG_DEBUG( "jet handle size: " << jetsHandle->size() );
165 
166  const xAOD::JetContainer* jetsContainer = jetsHandle.get();
167  if( jetsContainer == nullptr ) {
168  ATH_MSG_ERROR( "ERROR Cannot get jet container" );
169  return StatusCode::FAILURE;
170  }
171  bool isJetEtPassToolsCut = false;
172  float jetEtaToolsCut = 2.0;
173  if( m_tools_loosest_wp >= 3 ) jetEtaToolsCut = 1.0;
174  for ( const xAOD::Jet* jet : *jetsContainer ) {
175  float jet_pt = static_cast<float>(jet->pt() / Gaudi::Units::GeV );
176  float jet_eta = static_cast<float>(jet->eta());
177  if( jet_pt >= m_tools_lowest_jetEt && std::abs(jet_eta)<=jetEtaToolsCut ) {
178  isJetEtPassToolsCut = true;
179  break;
180  }
181  }
182 
183  auto tracks = SG::makeHandle( m_tracksKey, context );
184  ATH_CHECK(tracks.isValid());
185 
186  std::vector<HitDVSeed> hitDVSeedsContainer;
187  std::vector<HitDVTrk> hitDVTrksContainer;
188  std::vector<HitDVSpacePoint> hitDVSPsContainer;
189 
190 
191  ATH_CHECK( findHitDV(context, convertedSpacePoints, *tracks, hitDVSeedsContainer, hitDVTrksContainer, hitDVSPsContainer) );
192 
193  mon_n_dvtrks = hitDVTrksContainer.size();
194  mon_n_dvsps = hitDVSPsContainer.size();
195  const unsigned int N_MAX_SP_STORED = 100000;
196  bool isSPOverflow = false;
197  if( hitDVSPsContainer.size() >= N_MAX_SP_STORED ) isSPOverflow = true;
198  ATH_MSG_DEBUG( "hitDVSP size=" << mon_n_dvsps );
199 
200  // average mu
201  float averageMu = 0;
202  if( m_isMC ) {
203  if( m_lumiBlockMuTool ) {
204  averageMu = static_cast<float>(m_lumiBlockMuTool->averageInteractionsPerCrossing(context));
205  ATH_MSG_DEBUG( "offline averageMu = " << averageMu );
206  }
207  }
208  else {
210  averageMu = lcd.cptr()->lbAverageInteractionsPerCrossing();
211  ATH_MSG_DEBUG( "online averageMu = " << averageMu );
212  }
213  mon_average_mu = averageMu;
214 
215  // find seeds based on HLT jets
216  std::vector<float> jetSeeds_pt;
217  std::vector<float> jetSeeds_eta;
218  std::vector<float> jetSeeds_phi;
219  ATH_CHECK( findJetSeeds(jetsContainer, m_jetSeed_ptMin, m_jetSeed_etaMax, jetSeeds_pt, jetSeeds_eta, jetSeeds_phi) );
220  int n_alljetseeds = jetSeeds_eta.size();
221  ATH_CHECK( selectSeedsNearby(hitDVSeedsContainer, jetSeeds_eta, jetSeeds_phi, jetSeeds_pt) );
222  mon_n_jetseeds = jetSeeds_eta.size();
223  mon_n_jetseedsdel = n_alljetseeds - jetSeeds_eta.size();
224 
225  // find seeds based on SP frac itself
226  std::vector<float> spSeeds_eta;
227  std::vector<float> spSeeds_phi;
228  std::vector<float> void_pt;
229  int n_allspseeds = 0;
230  if( m_tools_loosest_wp <= 1 ) {
231  ATH_CHECK( findSPSeeds(context, hitDVSPsContainer, spSeeds_eta, spSeeds_phi) );
232  n_allspseeds = spSeeds_eta.size();
233  ATH_CHECK( selectSeedsNearby(hitDVSeedsContainer, spSeeds_eta, spSeeds_phi, void_pt) );
234  mon_n_spseeds = spSeeds_eta.size();
235  mon_n_spseedsdel = n_allspseeds - spSeeds_eta.size();
236  }
237  else {
238  mon_n_spseeds = 0;
239  mon_n_spseedsdel = 0;
240  }
241 
242  // output EDM object
243  auto hitDVContainer = std::make_unique<xAOD::TrigCompositeContainer>();
244  auto hitDVContainerAux = std::make_unique<xAOD::TrigCompositeAuxContainer>();
245  hitDVContainer->setStore(hitDVContainerAux.get());
246 
247  xAOD::TrigCompositeContainer* dvContainer = hitDVContainer.get();
248  std::vector<TrigHitDVHypoTool::HitDVHypoInfo> hitDVHypoInputs;
249  std::unordered_map<Decision*, size_t> mapDecIdx;
250 
251  // calculate BDT and create hitDVContainer EDM
252  if( isJetEtPassToolsCut ) {
253  const float preselBDTthreshold = -0.6;
254 
255  int n_passed_jet = 0;
256  int seed_type = SeedType::HLTJet;
257  ATH_CHECK( calculateBDT(hitDVSPsContainer, hitDVTrksContainer, jetSeeds_pt, jetSeeds_eta, jetSeeds_phi, preselBDTthreshold, seed_type, dvContainer, n_passed_jet) );
258 
259  int n_passed_sp = 0;
260  if( m_tools_loosest_wp <= 1 ) {
261  seed_type = SeedType::SP;
262  ATH_CHECK( calculateBDT(hitDVSPsContainer, hitDVTrksContainer, void_pt, spSeeds_eta, spSeeds_phi, preselBDTthreshold, seed_type, dvContainer, n_passed_sp) );
263  }
264 
265  ATH_MSG_DEBUG( "nr of dv container / jet-seeded / sp-seed candidates = " << dvContainer->size() << " / " << n_passed_jet << " / " << n_passed_sp );
266 
267  // Prepare inputs to HypoTool
268  for ( auto dv : *dvContainer ) {
269  Decision* newDecision = TrigCompositeUtils::newDecisionIn( outputDecisions, previousDecision, TrigCompositeUtils::hypoAlgNodeName(), context);
270  mapDecIdx.emplace( newDecision, dv->index() );
271  TrigHitDVHypoTool::HitDVHypoInfo hypoInfo{ newDecision, isSPOverflow, averageMu, dv, previousDecisionIDs };
272  hitDVHypoInputs.push_back( hypoInfo );
273  }
274  }
275 
276  // monitor
277  ATH_CHECK( doMonitor(dvContainer) );
278 
279  // Loop over all hypoToolinputs and get their decisions
280  for ( auto & tool: m_hypoTools ) {
281  ATH_MSG_DEBUG( "+++++ Now computing decision for " << tool->name() );
282  ATH_CHECK( tool->decide( hitDVHypoInputs ) );
283  }
284 
285  // record hitDV object
287  ATH_CHECK( hitDVHandle.record( std::move( hitDVContainer ), std::move( hitDVContainerAux ) ) );
288  ATH_MSG_DEBUG( "recorded hitDV object to SG" );
289 
290  DecisionContainer::iterator it = outputDecisions->begin();
291  while(it != outputDecisions->end()) {
292  ATH_MSG_DEBUG( "+++++ outputDecision: " << *it << " +++++" );
293  if ( allFailed( *it ) ) {
294  ATH_MSG_DEBUG( "---> all failed, erasing" );
295  it = outputDecisions->erase(it);
296  } else {
297  ATH_MSG_DEBUG( "---> not all failed" );
298 
299  // Link hitDV object
300  auto decision = *it;
301  size_t idx = mapDecIdx.at(*it);
302 
304  ATH_CHECK( dvEL.isValid() );
305 
306  ATH_CHECK( decision->setObjectLink<xAOD::TrigCompositeContainer>(featureString(), dvEL) );
307 
308  ATH_MSG_DEBUG(*decision);
309  ++it;
310  }
311  }
312 
313  //
314  ATH_CHECK( hypoBaseOutputProcessing(outputHandle) );
315 
316  //
317  return StatusCode::SUCCESS;
318 }
319 
320 // ------------------------------------------------------------------------------------------------
321 // ------------------------------------------------------------------------------------------------
322 
323 float TrigHitDVHypoAlg::deltaR2(float eta_1, float phi_1, float eta_2, float phi_2) const {
324  float dPhi = CxxUtils::wrapToPi(phi_1 - phi_2);
325  float dEta = eta_1 - eta_2;
326  return (dPhi*dPhi)+(dEta*dEta);
327 }
328 
329 // ------------------------------------------------------------------------------------------------
330 // ------------------------------------------------------------------------------------------------
331 
333 {
334  float abseta = std::fabs(eta);
335 
336  // if Pixel/SCT barrel, layer number is as it is
337  if( 0<=layer && layer <=7 ) {
338  ATH_MSG_VERBOSE("layer=" << layer << ", eta=" << abseta);
339  return layer;
340  }
341 
342  // for Pixel/SCT endcap, assign layer number of 0-7 depending on eta range
343 
344  int base = 0;
345 
346  //
347  const float PixBR6limit = 1.29612;
348  const float PixBR5limit = 1.45204;
349  const float PixBR4limit = 1.64909;
350  const float PixBR3limit = 1.90036;
351  const float PixBR2limit = 2.2146;
352 
353  // Pixel Endcap #1
354  base = 8;
355  if( layer==base || layer==(base+12) ) {
356  ATH_MSG_VERBOSE("Pix EC1, eta=" << abseta);
357  if( abseta > PixBR2limit ) return 2;
358  return 3;
359  }
360 
361  // Pixel Endcap #2
362  base = 9;
363  if( layer==base || layer==(base+12) ) {
364  ATH_MSG_VERBOSE("Pix EC2, eta=" << abseta);
365  if( abseta > PixBR2limit ) return 2;
366  return 3;
367  }
368 
369  // Pixel Endcap #3
370  base = 10;
371  if( layer==base || layer==(base+12) ) {
372  ATH_MSG_VERBOSE("Pix EC3, eta=" << abseta);
373  return 3;
374  }
375 
376  // SCT Endcap #1
377  base = 11;
378  if( layer==base || layer==(base+12) ) {
379  ATH_MSG_VERBOSE("Sct EC1, eta=" << abseta);
380  if( abseta < PixBR6limit ) return 7;
381  else if( abseta < PixBR5limit ) return 6;
382  return 5;
383  }
384 
385  // SCT Endcap #2
386  base = 12;
387  if( layer==base || layer==(base+12) ) {
388  ATH_MSG_VERBOSE("Sct EC2, eta=" << abseta);
389  if( abseta < PixBR5limit ) return 7;
390  else if( abseta < PixBR4limit ) return 6;
391  return 4;
392  }
393 
394  // SCT Endcap #3
395  base = 13;
396  if( layer==base || layer==(base+12) ) {
397  ATH_MSG_VERBOSE("Sct EC3, eta=" << abseta);
398  if( abseta < PixBR4limit ) return 7;
399  return 5;
400  }
401 
402  // SCT Endcap #4
403  base = 14;
404  if( layer==base || layer==(base+12) ) {
405  ATH_MSG_VERBOSE("Sct EC4, eta=" << abseta);
406  if( abseta < PixBR4limit ) return 6;
407  else if( abseta < PixBR3limit ) return 6;
408  return 4;
409  }
410 
411  // SCT Endcap #5
412  base = 15;
413  if( layer==base || layer==(base+12) ) {
414  ATH_MSG_VERBOSE("Sct EC5, eta=" << abseta);
415  if( abseta < PixBR3limit ) return 7;
416  return 5;
417  }
418 
419  // SCT Endcap #6
420  base = 16;
421  if( layer==base || layer==(base+12) ) {
422  ATH_MSG_VERBOSE("Sct EC6, eta=" << abseta);
423  if( abseta < PixBR3limit ) return 6;
424  return 4;
425  }
426 
427  // SCT Endcap #7
428  base = 17;
429  if( layer==base || layer==(base+12) ) {
430  ATH_MSG_VERBOSE("Sct EC7, eta=" << abseta);
431  if( abseta < PixBR3limit ) return 7;
432  return 5;
433  }
434 
435  // SCT Endcap #8
436  base = 18;
437  if( layer==base || layer==(base+12) ) {
438  ATH_MSG_VERBOSE("Sct EC8, eta=" << abseta);
439  if( abseta < PixBR3limit ) return 7;
440  return 6;
441  }
442 
443  // SCT Endcap #9
444  base = 19;
445  if( layer==base || layer==(base+12) ) {
446  ATH_MSG_VERBOSE("Sct EC9, eta=" << abseta);
447  return 7;
448  }
449 
450  return 0;
451 }
452 
453 // ------------------------------------------------------------------------------------------------
454 // ------------------------------------------------------------------------------------------------
455 
457 {
458  auto mon_ly0_spfr = Monitored::Collection(
459  "ly0_spfr", *dvContainer, [&](const Decision* d){ return d->getDetail<float>("hitDV_ly0_sp_frac"); });
460  auto mon_ly1_spfr = Monitored::Collection(
461  "ly1_spfr", *dvContainer, [&](const Decision* d){ return d->getDetail<float>("hitDV_ly1_sp_frac"); });
462  auto mon_ly2_spfr = Monitored::Collection(
463  "ly2_spfr", *dvContainer, [&](const Decision* d){ return d->getDetail<float>("hitDV_ly2_sp_frac"); });
464  auto mon_ly3_spfr = Monitored::Collection(
465  "ly3_spfr", *dvContainer, [&](const Decision* d){ return d->getDetail<float>("hitDV_ly3_sp_frac"); });
466  auto mon_ly4_spfr = Monitored::Collection(
467  "ly4_spfr", *dvContainer, [&](const Decision* d){ return d->getDetail<float>("hitDV_ly4_sp_frac"); });
468  auto mon_ly5_spfr = Monitored::Collection(
469  "ly5_spfr", *dvContainer, [&](const Decision* d){ return d->getDetail<float>("hitDV_ly5_sp_frac"); });
470  auto mon_ly6_spfr = Monitored::Collection(
471  "ly6_spfr", *dvContainer, [&](const Decision* d){ return d->getDetail<float>("hitDV_ly6_sp_frac"); });
472  auto mon_ly7_spfr = Monitored::Collection(
473  "ly7_spfr", *dvContainer, [&](const Decision* d){ return d->getDetail<float>("hitDV_ly7_sp_frac"); });
474  auto mon_bdtscore = Monitored::Collection(
475  "bdtscore", *dvContainer, [&](const Decision* d){ return d->getDetail<float>("hitDV_bdt_score"); });
476  auto mon_n_qtrk = Monitored::Collection(
477  "n_qtrk", *dvContainer, [&](const Decision* d){ return d->getDetail<int>("hitDV_n_track_qual"); });
478 
479  // fill CutMask to split spacespoints into eta regions
480  std::vector<char> mask_eta1(dvContainer->size(), 0);
481  std::vector<char> mask_1eta2(dvContainer->size(), 0);
482  auto mon_eta1_mask = Monitored::Collection( "cutEta1", mask_eta1 );
483  auto mon_1eta2_mask = Monitored::Collection( "cut1Eta2", mask_1eta2 );
484 
485  for (size_t i = 0; i<dvContainer->size(); ++i) {
486  const Decision* dv = (*dvContainer)[i];
487 
488  // do not fill sp-seeded candidates
489  if( dv->getDetail<int>("hitDV_seed_type") == SeedType::SP ) continue;
490 
491  // fill the cut mask according to eta range
492  const float abs_eta = std::abs(dv->getDetail<float>("hitDV_seed_eta"));
493  if ( abs_eta < 1.0 ) mask_eta1[i] = 1;
494  else if( abs_eta < 2.0 ) mask_1eta2[i] = 1;
495  }
496 
497  auto monitorIt = Monitored::Group( m_monTool,
498  mon_ly0_spfr, mon_ly1_spfr, mon_ly2_spfr, mon_ly3_spfr,
499  mon_ly4_spfr, mon_ly5_spfr, mon_ly6_spfr, mon_ly7_spfr,
500  mon_n_qtrk, mon_bdtscore, mon_eta1_mask, mon_1eta2_mask );
501 
502  return StatusCode::SUCCESS;
503 }
504 
505 // ------------------------------------------------------------------------------------------------
506 // ------------------------------------------------------------------------------------------------
507 
508 StatusCode TrigHitDVHypoAlg::calculateBDT(const std::vector<HitDVSpacePoint>& spsContainer,
509  const std::vector<HitDVTrk>& trksContainer,
510  const std::vector<float>& seeds_pt,
511  const std::vector<float>& seeds_eta, const std::vector<float>& seeds_phi,
512  const float& cutBDTthreshold, const int seed_type,
513  xAOD::TrigCompositeContainer* dvContainer, int& n_passed) const
514 {
515  if( seeds_eta.size() != seeds_phi.size() ) return StatusCode::SUCCESS;
516  n_passed = 0;
517 
518  for(unsigned int iseed=0; iseed<seeds_eta.size(); iseed++) {
519 
520  float seed_eta = seeds_eta[iseed];
521  float seed_phi = seeds_phi[iseed];
522 
523  ATH_MSG_VERBOSE("+++++ seed eta: " << seed_eta << ", phi:" << seed_phi << " +++++");
524 
525  // loop on space points
526  const int N_LAYER = 8;
527  const float DR_SQUARED_TO_REF_CUT = 0.16; // const float DR_TO_REF_CUT = 0.4;
528 
529  int n_sp_injet = 0;
530  int n_sp_injet_usedByTrk = 0;
531  int v_n_sp_injet[N_LAYER];
532  int v_n_sp_injet_usedByTrk[N_LAYER];
533  for(int i=0; i<N_LAYER; i++) { v_n_sp_injet[i]=0; v_n_sp_injet_usedByTrk[i]=0; }
534 
535  for ( const auto & spData : spsContainer ) {
536  // match within dR
537  float sp_eta = spData.eta;
538  float sp_phi = spData.phi;
539  float dR2 = deltaR2(sp_eta,sp_phi,seed_eta,seed_phi);
540  if( dR2 > DR_SQUARED_TO_REF_CUT ) continue;
541 
542  //
543  int sp_layer = (int)spData.layer;
544  int sp_trkid = (int)spData.usedTrkId;
545  bool isUsedByTrk = (sp_trkid != -1);
546 
547  int ilayer = getSPLayer(sp_layer,sp_eta);
548 
549  if( ilayer<=7 ) { // Pixel barrel or Sct barrel
550  n_sp_injet++;
551  v_n_sp_injet[ilayer]++;
552  if( isUsedByTrk ) {
553  n_sp_injet_usedByTrk++;
554  v_n_sp_injet_usedByTrk[ilayer]++;
555  }
556  }
557  }
558  ATH_MSG_VERBOSE("nr of SPs in jet: usedByTrk / all = " << n_sp_injet_usedByTrk << " / " << n_sp_injet);
559  float v_ly_sp_frac[N_LAYER];
560  for(int i=0; i<N_LAYER; i++) {
561  float frac = 0.;
562  if( v_n_sp_injet[i] > 0 ) frac = 1.0 - static_cast<float>(v_n_sp_injet_usedByTrk[i]) / static_cast<float>(v_n_sp_injet[i]);
563  v_ly_sp_frac[i] = frac;
564  ATH_MSG_VERBOSE("Layer " << i << ": frac=" << v_ly_sp_frac[i] << ", n used / all = " << v_n_sp_injet_usedByTrk[i] << " / " << v_n_sp_injet[i]);
565  }
566 
567  // loop on tracks
568  const float TRK_PT_GEV_CUT = 2.0;
569 
570  unsigned int n_qtrk_injet = 0;
571  for ( const auto& trk : trksContainer ) {
572  float trk_ptGeV = trk.pt;
573  trk_ptGeV /= Gaudi::Units::GeV;
574  if( trk_ptGeV < TRK_PT_GEV_CUT ) continue;
575  float dR2 = deltaR2(trk.eta,trk.phi,seed_eta,seed_phi);
576  if( dR2 > DR_SQUARED_TO_REF_CUT ) continue;
577  n_qtrk_injet++;
578  }
579  ATH_MSG_DEBUG("nr of all / quality tracks matched = " << trksContainer.size() << " / " << n_qtrk_injet);
580 
581  // evaluate BDT
582  bool isSeedOutOfRange = false;
583  if( n_qtrk_injet == 0 ) {
584  isSeedOutOfRange = true;
585  for(int i=0; i<N_LAYER; i++) {
586  if( std::fabs(v_ly_sp_frac[i]) > 1e-3 ) {
587  isSeedOutOfRange = false; break;
588  }
589  }
590  }
591  float bdt_score = -2.0;
592  if( ! isSeedOutOfRange ) {
593  const std::vector<float> input_values = {
594  static_cast<float>(n_qtrk_injet),
595  v_ly_sp_frac[0],
596  v_ly_sp_frac[1],
597  v_ly_sp_frac[2],
598  v_ly_sp_frac[3],
599  v_ly_sp_frac[4],
600  v_ly_sp_frac[5],
601  v_ly_sp_frac[6],
602  v_ly_sp_frac[7] };
603 
604  if ( std::abs(seed_eta) < 1 ) {
605  bdt_score = m_bdt_eta[0]->GetClassification(input_values);
606  } else if ( std::abs(seed_eta) < 2 ) {
607  bdt_score = m_bdt_eta[1]->GetClassification(input_values);
608  }
609  }
610 
611  // BDT threshold
612  if( bdt_score < cutBDTthreshold ) continue;
613 
614  // passed selection
615  ATH_MSG_VERBOSE("Passed selection");
616  n_passed++;
617 
618  // create EDM object
620  dv->makePrivateStore();
621  dvContainer->push_back(dv);
622 
623  float seed_pt = 0;
624  if ( seed_type == SeedType::HLTJet ) seed_pt = seeds_pt[iseed];
625  dv->setDetail<float>("hitDV_seed_pt", seed_pt);
626  dv->setDetail<float>("hitDV_seed_eta", seed_eta);
627  dv->setDetail<float>("hitDV_seed_phi", seed_phi);
628  dv->setDetail<int> ("hitDV_seed_type", seed_type);
629  dv->setDetail<int> ("hitDV_n_track_qual", n_qtrk_injet);
630  dv->setDetail<float>("hitDV_ly0_sp_frac", v_ly_sp_frac[0]);
631  dv->setDetail<float>("hitDV_ly1_sp_frac", v_ly_sp_frac[1]);
632  dv->setDetail<float>("hitDV_ly2_sp_frac", v_ly_sp_frac[2]);
633  dv->setDetail<float>("hitDV_ly3_sp_frac", v_ly_sp_frac[3]);
634  dv->setDetail<float>("hitDV_ly4_sp_frac", v_ly_sp_frac[4]);
635  dv->setDetail<float>("hitDV_ly5_sp_frac", v_ly_sp_frac[5]);
636  dv->setDetail<float>("hitDV_ly6_sp_frac", v_ly_sp_frac[6]);
637  dv->setDetail<float>("hitDV_ly7_sp_frac", v_ly_sp_frac[7]);
638  dv->setDetail<float>("hitDV_bdt_score", bdt_score);
639 
640  ATH_MSG_VERBOSE("Created a new entry EDM");
641  }
642  ATH_MSG_DEBUG("nr of BDT passed = " << n_passed);
643 
644  //
645  return StatusCode::SUCCESS;
646 }
647 
648 // ------------------------------------------------------------------------------------------------
649 // ------------------------------------------------------------------------------------------------
650 
651 StatusCode TrigHitDVHypoAlg::findJetSeeds(const xAOD::JetContainer* jetsContainer, const float cutJetPt, const float cutJetEta,
652  std::vector<float>& jetSeeds_pt, std::vector<float>& jetSeeds_eta, std::vector<float>& jetSeeds_phi) const
653 {
654  std::vector<float> mnt_jet_pt;
655  std::vector<float> mnt_jet_eta;
656  auto mon_jet_pt = Monitored::Collection("jet_pt", mnt_jet_pt);
657  auto mon_jet_eta = Monitored::Collection("jet_eta", mnt_jet_eta);
658  auto monitorIt = Monitored::Group( m_monTool, mon_jet_pt, mon_jet_eta );
659 
660  ATH_MSG_VERBOSE("looking for jet seed with pt cut=" << cutJetPt << ", eta cut=" << cutJetEta);
661  for ( const xAOD::Jet* jet : *jetsContainer ) {
662  float jet_pt = static_cast<float>(jet->pt() / Gaudi::Units::GeV );
663  if( jet_pt < cutJetPt ) {
664  ATH_MSG_VERBOSE("Fails jet pt cut, pt = " << jet_pt);
665  continue;
666  }
667  mnt_jet_pt.push_back(jet_pt);
668  float jet_eta = static_cast<float>(jet->eta());
669  mnt_jet_eta.push_back(jet_eta);
670  if( std::fabs(jet_eta) > cutJetEta ) {
671  ATH_MSG_VERBOSE("Fails jet eta cut, eta = " << jet_eta);
672  continue;
673  }
674  float jet_phi = static_cast<float>(jet->phi());
675  jetSeeds_pt.push_back(jet_pt);
676  jetSeeds_eta.push_back(jet_eta);
677  jetSeeds_phi.push_back(jet_phi);
678  }
679  ATH_MSG_VERBOSE("nr of jet seeds=" << jetSeeds_eta.size());
680 
681  return StatusCode::SUCCESS;
682 }
683 
684 // ------------------------------------------------------------------------------------------------
685 // ------------------------------------------------------------------------------------------------
686 
687 StatusCode TrigHitDVHypoAlg::findSPSeeds( const EventContext& ctx, const std::vector<HitDVSpacePoint>& spsContainer,
688  std::vector<float>& seeds_eta, std::vector<float>& seeds_phi ) const
689 {
690  seeds_eta.clear();
691  seeds_phi.clear();
692 
693  const int NBINS_ETA = 50;
694  const float ETA_MIN = -2.5;
695  const float ETA_MAX = 2.5;
696 
697  const int NBINS_PHI = 80;
698  const float PHI_MIN = -4.0;
699  const float PHI_MAX = 4.0;
700 
701  char hname[64];
702 
703  unsigned int slotnr = ctx.slot();
704  unsigned int subSlotnr = ctx.subSlot();
705 
706  sprintf(hname,"hitdv_s%u_ss%u_ly6_h2_nsp",slotnr,subSlotnr);
707  std::unique_ptr<TH2F> ly6_h2_nsp = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
708  sprintf(hname,"hitdv_s%u_ss%u_ly7_h2_nsp",slotnr,subSlotnr);
709  std::unique_ptr<TH2F> ly7_h2_nsp = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
710 
711  sprintf(hname,"hitdv_s%u_ss%u_ly6_h2_nsp_notrk",slotnr,subSlotnr);
712  std::unique_ptr<TH2F> ly6_h2_nsp_notrk = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
713  sprintf(hname,"hitdv_s%u_ss%u_ly7_h2_nsp_notrk",slotnr,subSlotnr);
714  std::unique_ptr<TH2F> ly7_h2_nsp_notrk = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
715 
716  for ( const auto& spData : spsContainer ) {
717  int16_t sp_layer = spData.layer;
718  float sp_eta = spData.eta;
719  int ilayer = getSPLayer(sp_layer,sp_eta);
720  if( ilayer<6 ) continue;
721 
722  int sp_trkid = (int)spData.usedTrkId;
723  bool isUsedByTrk = (sp_trkid != -1);
724  float sp_phi = spData.phi;
725 
726  bool fill_out_of_pi = false;
727  float sp_phi2 = 0;
728  if( sp_phi < 0 ) {
729  sp_phi2 = 2*TMath::Pi() + sp_phi;
730  if( sp_phi2 < PHI_MAX ) fill_out_of_pi = true;
731  }
732  else {
733  sp_phi2 = -2*TMath::Pi() + sp_phi;
734  if( PHI_MIN < sp_phi2 ) fill_out_of_pi = true;
735  }
736  if( ilayer==6 ) {
737  ly6_h2_nsp->Fill(sp_eta,sp_phi);
738  if( fill_out_of_pi ) ly6_h2_nsp->Fill(sp_eta,sp_phi2);
739  if( ! isUsedByTrk ) ly6_h2_nsp_notrk->Fill(sp_eta,sp_phi);
740  if( ! isUsedByTrk && fill_out_of_pi) ly6_h2_nsp_notrk->Fill(sp_eta,sp_phi2);
741  }
742  if( ilayer==7 ) {
743  ly7_h2_nsp->Fill(sp_eta,sp_phi);
744  if( fill_out_of_pi ) ly7_h2_nsp->Fill(sp_eta,sp_phi2);
745  if( ! isUsedByTrk ) ly7_h2_nsp_notrk->Fill(sp_eta,sp_phi);
746  if( ! isUsedByTrk && fill_out_of_pi) ly7_h2_nsp_notrk->Fill(sp_eta,sp_phi2);
747  }
748  }
749 
750  ATH_MSG_VERBOSE("looking for ly6/ly6 doublet seeds");
751 
752  // (idx, sort/weight, eta, phi)
753  std::vector<std::tuple<int,float,float,float>> QT;
754 
755  for(int ly6_ieta=1; ly6_ieta<=NBINS_ETA; ly6_ieta++) {
756  float ly6_eta = (ly6_h2_nsp->GetXaxis()->GetBinLowEdge(ly6_ieta) + ly6_h2_nsp->GetXaxis()->GetBinUpEdge(ly6_ieta))/2.0;
757  for(int ly6_iphi=1; ly6_iphi<=NBINS_PHI; ly6_iphi++) {
758  float ly6_phi = (ly6_h2_nsp->GetYaxis()->GetBinLowEdge(ly6_iphi) + ly6_h2_nsp->GetYaxis()->GetBinUpEdge(ly6_iphi))/2.0;
759 
760  float ly6_nsp = ly6_h2_nsp ->GetBinContent(ly6_ieta,ly6_iphi);
761  float ly6_nsp_notrk = ly6_h2_nsp_notrk->GetBinContent(ly6_ieta,ly6_iphi);
762  float ly6_frac = ( ly6_nsp > 0 ) ? ly6_nsp_notrk / ly6_nsp : 0;
763  if( ly6_nsp < 10 || ly6_frac < 0.85 ) continue;
764 
765  float ly7_frac_max = 0;
766  float ly7_eta_max = 0;
767  float ly7_phi_max = 0;
768  for(int ly7_ieta=std::max(1,ly6_ieta-1); ly7_ieta<std::min(NBINS_ETA,ly6_ieta+1); ly7_ieta++) {
769  for(int ly7_iphi=std::max(1,ly6_iphi-1); ly7_iphi<=std::min(NBINS_PHI,ly6_iphi+1); ly7_iphi++) {
770  float ly7_nsp = ly7_h2_nsp ->GetBinContent(ly7_ieta,ly7_iphi);
771  float ly7_nsp_notrk = ly7_h2_nsp_notrk->GetBinContent(ly7_ieta,ly7_iphi);
772  float ly7_frac = ( ly7_nsp > 0 ) ? ly7_nsp_notrk / ly7_nsp : 0;
773  if( ly7_nsp < 10 ) continue;
774  if( ly7_frac > ly7_frac_max ) {
775  ly7_frac_max = ly7_frac;
776  ly7_eta_max = (ly7_h2_nsp->GetXaxis()->GetBinLowEdge(ly7_ieta) + ly7_h2_nsp->GetXaxis()->GetBinUpEdge(ly7_ieta))/2.0;
777  ly7_phi_max = (ly7_h2_nsp->GetXaxis()->GetBinLowEdge(ly7_iphi) + ly7_h2_nsp->GetXaxis()->GetBinUpEdge(ly7_iphi))/2.0;
778  }
779  }
780  }
781  if( ly7_frac_max < 0.85 ) continue;
782  //
783  float wsum = ly6_frac + ly7_frac_max;
784  float weta = (ly6_eta*ly6_frac + ly7_eta_max*ly7_frac_max) / wsum;
785  float wphi = (ly6_phi*ly6_frac + ly7_phi_max*ly7_frac_max) / wsum;
786  float w = wsum / 2.0;
787  QT.push_back(std::make_tuple(-1,w,weta,wphi));
788  }
789  }
790  ATH_MSG_VERBOSE("nr of ly6/ly7 doublet candidate seeds=" << QT.size() << ", doing clustering...");
791 
792  // sort
793  std::sort(QT.begin(), QT.end(),
794  [](const std::tuple<int,float,float,float>& lhs, const std::tuple<int,float,float,float>& rhs) {
795  return std::get<1>(lhs) > std::get<1>(rhs); } );
796 
797  // clustering
798  const double CLUSTCUT_DIST_SQUARED = 0.04; // const double CLUSTCUT_DIST = 0.2;
799  const double CLUSTCUT_SEED_FRAC = 0.9;
800 
801  std::vector<float> seeds_wsum;
802 
803  for(unsigned int i=0; i<QT.size(); i++) {
804  float phi = std::get<3>(QT[i]);
805  float eta = std::get<2>(QT[i]);
806  float w = std::get<1>(QT[i]);
807  if(i==0) {
808  seeds_eta.push_back(w*eta); seeds_phi.push_back(w*phi);
809  seeds_wsum.push_back(w);
810  continue;
811  }
812  const int IDX_INITIAL = 100;
813  float dist2_min = 100.0;
814  int idx_min = IDX_INITIAL;
815  for(unsigned j=0; j<seeds_eta.size(); j++) {
816  float ceta = seeds_eta[j]/seeds_wsum[j];
817  float cphi = seeds_phi[j]/seeds_wsum[j];
818  // intentionally calculate in this way as phi is defined beyond -Pi/Pi (no boundary)
819  float deta = std::fabs(ceta-eta);
820  float dphi = std::fabs(cphi-phi);
821  float dist2 = dphi*dphi+deta*deta;
822  if( dist2 < dist2_min ) {
823  dist2_min = dist2;
824  idx_min = j;
825  }
826  }
827  int match_idx = IDX_INITIAL;
828  if( idx_min != IDX_INITIAL ) {
829  if( dist2_min < CLUSTCUT_DIST_SQUARED ) { match_idx = idx_min; }
830  }
831  if( match_idx == IDX_INITIAL ) {
832  if( w > CLUSTCUT_SEED_FRAC && dist2_min > CLUSTCUT_DIST_SQUARED ) {
833  seeds_eta.push_back(w*eta); seeds_phi.push_back(w*phi);
834  seeds_wsum.push_back(w);
835  }
836  continue;
837  }
838  float new_eta = seeds_eta[match_idx] + w*eta;
839  float new_phi = seeds_phi[match_idx] + w*phi;
840  float new_wsum = seeds_wsum[match_idx] + w;
841  seeds_eta[match_idx] = new_eta;
842  seeds_phi[match_idx] = new_phi;
843  seeds_wsum[match_idx] = new_wsum;
844  }
845  QT.clear();
846  for(unsigned int i=0; i<seeds_eta.size(); i++) {
847  float eta = seeds_eta[i] / seeds_wsum[i];
848  float phi = seeds_phi[i] / seeds_wsum[i];
849  seeds_eta[i] = eta;
850  seeds_phi[i] = phi;
851  if( phi < -TMath::Pi() ) phi = 2*TMath::Pi() + phi;
852  if( phi > TMath::Pi() ) phi = -2*TMath::Pi() + phi;
853  seeds_phi[i] = phi;
854  }
855  ATH_MSG_VERBOSE("after clustering, nr of seeds = " << seeds_eta.size());
856 
857  // delete overlap (can happen at phi=-Pi/Pi bounadry)
858  std::vector<unsigned int> idx_to_delete;
859  for(unsigned int i=0; i<seeds_eta.size(); i++) {
860  if( std::find(idx_to_delete.begin(),idx_to_delete.end(),i) != idx_to_delete.end() ) continue;
861  float eta_i = seeds_eta[i];
862  float phi_i = seeds_phi[i];
863  for(unsigned int j=i+1; j<seeds_eta.size(); j++) {
864  if( std::find(idx_to_delete.begin(),idx_to_delete.end(),j) != idx_to_delete.end() ) continue;
865  float eta_j = seeds_eta[j];
866  float phi_j = seeds_phi[j];
867  float dR2 = deltaR2(eta_i,phi_i,eta_j,phi_j);
868  if( dR2 < CLUSTCUT_DIST_SQUARED ) idx_to_delete.push_back(j);
869  }
870  }
871  ATH_MSG_VERBOSE("nr of duplicated seeds to be removed = " << idx_to_delete.size());
872  if( idx_to_delete.size() > 0 ) {
873  std::sort(idx_to_delete.begin(),idx_to_delete.end());
874  for(unsigned int j=idx_to_delete.size(); j>0; j--) {
875  unsigned int idx = idx_to_delete[j-1];
876  seeds_eta.erase(seeds_eta.begin()+idx);
877  seeds_phi.erase(seeds_phi.begin()+idx);
878  }
879  }
880 
881  ATH_MSG_VERBOSE("nr of ly6/ly7 seeds=" << seeds_eta.size());
882 
883  // return
884  return StatusCode::SUCCESS;
885 }
886 
887 // ------------------------------------------------------------------------------------------------
888 // ------------------------------------------------------------------------------------------------
889 
890 StatusCode TrigHitDVHypoAlg::selectSeedsNearby(const std::vector<HitDVSeed>& hitDVSeedsContainer,
891  std::vector<float>& jetSeeds_eta, std::vector<float>& jetSeeds_phi, std::vector<float>& jetSeeds_pt) const
892 {
893  std::vector<unsigned int> idx_to_delete;
894  for(unsigned int idx=0; idx<jetSeeds_eta.size(); ++idx) {
895  const float DR_SQUARED_CUT_TO_FTFSEED = 0.09; // const float DR_CUT_TO_FTFSEED = 0.3;
896  float eta = jetSeeds_eta[idx];
897  float phi = jetSeeds_phi[idx];
898  float dR2min = 9999;
899  for ( const auto& seed : hitDVSeedsContainer ) {
900  float dR2 = deltaR2(eta,phi,seed.eta,seed.phi);
901  if( dR2 < dR2min ) dR2min = dR2;
902  }
903  if( dR2min > DR_SQUARED_CUT_TO_FTFSEED ) idx_to_delete.push_back(idx);
904  }
905  if( idx_to_delete.size() > 0 ) {
906  std::sort(idx_to_delete.begin(),idx_to_delete.end());
907  for(unsigned int j=idx_to_delete.size(); j>0; j--) {
908  unsigned int idx = idx_to_delete[j-1];
909  jetSeeds_eta.erase(jetSeeds_eta.begin()+idx);
910  jetSeeds_phi.erase(jetSeeds_phi.begin()+idx);
911  if( jetSeeds_pt.size() > 0 ) jetSeeds_pt.erase(jetSeeds_pt.begin()+idx);
912  }
913  }
914  return StatusCode::SUCCESS;
915 }
916 
917 // ------------------------------------------------------------------------------------------------
918 // ------------------------------------------------------------------------------------------------
919 
920 StatusCode TrigHitDVHypoAlg::findSPSeeds( const EventContext& ctx,
921  const std::vector<float>& v_sp_eta, const std::vector<float>& v_sp_phi,
922  const std::vector<int>& v_sp_layer, const std::vector<int>& v_sp_usedTrkId,
923  std::vector<float>& seeds_eta, std::vector<float>& seeds_phi ) const
924 {
925  const int NBINS_ETA = 50;
926  const float ETA_MIN = -2.5;
927  const float ETA_MAX = 2.5;
928 
929  const int NBINS_PHI = 80;
930  const float PHI_MIN = -4.0;
931  const float PHI_MAX = 4.0;
932 
933  char hname[64];
934 
935  unsigned int slotnr = ctx.slot();
936  unsigned int subSlotnr = ctx.subSlot();
937 
938  sprintf(hname,"ftf_s%u_ss%u_ly6_h2_nsp",slotnr,subSlotnr);
939  std::unique_ptr<TH2F> ly6_h2_nsp = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
940  sprintf(hname,"ftf_s%u_ss%u_ly7_h2_nsp",slotnr,subSlotnr);
941  std::unique_ptr<TH2F> ly7_h2_nsp = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
942 
943  sprintf(hname,"ftf_s%u_ss%u_ly6_h2_nsp_notrk",slotnr,subSlotnr);
944  std::unique_ptr<TH2F> ly6_h2_nsp_notrk = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
945  sprintf(hname,"ftf_s%u_ss%u_ly7_h2_nsp_notrk",slotnr,subSlotnr);
946  std::unique_ptr<TH2F> ly7_h2_nsp_notrk = std::make_unique<TH2F>(hname,hname,NBINS_ETA,ETA_MIN,ETA_MAX,NBINS_PHI,PHI_MIN,PHI_MAX);
947 
948  for(unsigned int iSeed=0; iSeed<v_sp_eta.size(); ++iSeed) {
949 
950  int sp_layer = v_sp_layer[iSeed];
951  float sp_eta = v_sp_eta[iSeed];
952  int ilayer = getSPLayer(sp_layer,sp_eta);
953  if( ilayer<6 ) continue;
954 
955  int sp_trkid = v_sp_usedTrkId[iSeed];
956  bool isUsedByTrk = (sp_trkid != -1);
957  float sp_phi = v_sp_phi[iSeed];
958 
959  bool fill_out_of_pi = false;
960  float sp_phi2 = 0;
961  if( sp_phi < 0 ) {
962  sp_phi2 = 2*TMath::Pi() + sp_phi;
963  if( sp_phi2 < PHI_MAX ) fill_out_of_pi = true;
964  }
965  else {
966  sp_phi2 = -2*TMath::Pi() + sp_phi;
967  if( PHI_MIN < sp_phi2 ) fill_out_of_pi = true;
968  }
969  if( ilayer==6 ) {
970  ly6_h2_nsp->Fill(sp_eta,sp_phi);
971  if( fill_out_of_pi ) ly6_h2_nsp->Fill(sp_eta,sp_phi2);
972  if( ! isUsedByTrk ) ly6_h2_nsp_notrk->Fill(sp_eta,sp_phi);
973  if( ! isUsedByTrk && fill_out_of_pi) ly6_h2_nsp_notrk->Fill(sp_eta,sp_phi2);
974  }
975  if( ilayer==7 ) {
976  ly7_h2_nsp->Fill(sp_eta,sp_phi);
977  if( fill_out_of_pi ) ly7_h2_nsp->Fill(sp_eta,sp_phi2);
978  if( ! isUsedByTrk ) ly7_h2_nsp_notrk->Fill(sp_eta,sp_phi);
979  if( ! isUsedByTrk && fill_out_of_pi) ly7_h2_nsp_notrk->Fill(sp_eta,sp_phi2);
980  }
981  }
982 
983  ATH_MSG_VERBOSE("looking for ly6/ly6 doublet seeds");
984 
985  // (idx, sort/weight, eta, phi)
986  std::vector<std::tuple<int,float,float,float>> QT;
987 
988  for(int ly6_ieta=1; ly6_ieta<=NBINS_ETA; ly6_ieta++) {
989  float ly6_eta = (ly6_h2_nsp->GetXaxis()->GetBinLowEdge(ly6_ieta) + ly6_h2_nsp->GetXaxis()->GetBinUpEdge(ly6_ieta))/2.0;
990  for(int ly6_iphi=1; ly6_iphi<=NBINS_PHI; ly6_iphi++) {
991  float ly6_phi = (ly6_h2_nsp->GetYaxis()->GetBinLowEdge(ly6_iphi) + ly6_h2_nsp->GetYaxis()->GetBinUpEdge(ly6_iphi))/2.0;
992 
993  float ly6_nsp = ly6_h2_nsp ->GetBinContent(ly6_ieta,ly6_iphi);
994  float ly6_nsp_notrk = ly6_h2_nsp_notrk->GetBinContent(ly6_ieta,ly6_iphi);
995  float ly6_frac = ( ly6_nsp > 0 ) ? ly6_nsp_notrk / ly6_nsp : 0;
996  if( ly6_nsp < 10 || ly6_frac < 0.85 ) continue;
997 
998  float ly7_frac_max = 0;
999  float ly7_eta_max = 0;
1000  float ly7_phi_max = 0;
1001  for(int ly7_ieta=std::max(1,ly6_ieta-1); ly7_ieta<std::min(NBINS_ETA,ly6_ieta+1); ly7_ieta++) {
1002  for(int ly7_iphi=std::max(1,ly6_iphi-1); ly7_iphi<=std::min(NBINS_PHI,ly6_iphi+1); ly7_iphi++) {
1003  float ly7_nsp = ly7_h2_nsp ->GetBinContent(ly7_ieta,ly7_iphi);
1004  float ly7_nsp_notrk = ly7_h2_nsp_notrk->GetBinContent(ly7_ieta,ly7_iphi);
1005  float ly7_frac = ( ly7_nsp > 0 ) ? ly7_nsp_notrk / ly7_nsp : 0;
1006  if( ly7_nsp < 10 ) continue;
1007  if( ly7_frac > ly7_frac_max ) {
1008  ly7_frac_max = ly7_frac;
1009  ly7_eta_max = (ly7_h2_nsp->GetXaxis()->GetBinLowEdge(ly7_ieta) + ly7_h2_nsp->GetXaxis()->GetBinUpEdge(ly7_ieta))/2.0;
1010  ly7_phi_max = (ly7_h2_nsp->GetXaxis()->GetBinLowEdge(ly7_iphi) + ly7_h2_nsp->GetXaxis()->GetBinUpEdge(ly7_iphi))/2.0;
1011  }
1012  }
1013  }
1014  if( ly7_frac_max < 0.85 ) continue;
1015  //
1016  float wsum = ly6_frac + ly7_frac_max;
1017  float weta = (ly6_eta*ly6_frac + ly7_eta_max*ly7_frac_max) / wsum;
1018  float wphi = (ly6_phi*ly6_frac + ly7_phi_max*ly7_frac_max) / wsum;
1019  float w = wsum / 2.0;
1020  QT.push_back(std::make_tuple(-1,w,weta,wphi));
1021  }
1022  }
1023  ATH_MSG_VERBOSE("nr of ly6/ly7 doublet candidate seeds=" << QT.size() << ", doing clustering...");
1024 
1025  // sort
1026  std::sort(QT.begin(), QT.end(),
1027  [](const std::tuple<int,float,float,float>& lhs, const std::tuple<int,float,float,float>& rhs) {
1028  return std::get<1>(lhs) > std::get<1>(rhs); } );
1029 
1030  // clustering
1031  const double CLUSTCUT_DIST_SQUARED = 0.04; // const double CLUSTCUT_DIST = 0.2;
1032  const double CLUSTCUT_SEED_FRAC = 0.9;
1033 
1034  std::vector<float> seeds_wsum;
1035 
1036  for(unsigned int i=0; i<QT.size(); i++) {
1037  float phi = std::get<3>(QT[i]);
1038  float eta = std::get<2>(QT[i]);
1039  float w = std::get<1>(QT[i]);
1040  if(i==0) {
1041  seeds_eta.push_back(w*eta); seeds_phi.push_back(w*phi);
1042  seeds_wsum.push_back(w);
1043  continue;
1044  }
1045  const int IDX_INITIAL = 100;
1046  float dist2_min = 100.0;
1047  int idx_min = IDX_INITIAL;
1048  for(unsigned j=0; j<seeds_eta.size(); j++) {
1049  float ceta = seeds_eta[j]/seeds_wsum[j];
1050  float cphi = seeds_phi[j]/seeds_wsum[j];
1051  // intentionally calculate in this way as phi is defined beyond -Pi/Pi (no boundary)
1052  float deta = std::fabs(ceta-eta);
1053  float dphi = std::fabs(cphi-phi);
1054  float dist2 = dphi*dphi+deta*deta;
1055  if( dist2 < dist2_min ) {
1056  dist2_min = dist2;
1057  idx_min = j;
1058  }
1059  }
1060  int match_idx = IDX_INITIAL;
1061  if( idx_min != IDX_INITIAL ) {
1062  if( dist2_min < CLUSTCUT_DIST_SQUARED ) { match_idx = idx_min; }
1063  }
1064  if( match_idx == IDX_INITIAL ) {
1065  if( w > CLUSTCUT_SEED_FRAC && dist2_min > CLUSTCUT_DIST_SQUARED ) {
1066  seeds_eta.push_back(w*eta); seeds_phi.push_back(w*phi);
1067  seeds_wsum.push_back(w);
1068  }
1069  continue;
1070  }
1071  float new_eta = seeds_eta[match_idx] + w*eta;
1072  float new_phi = seeds_phi[match_idx] + w*phi;
1073  float new_wsum = seeds_wsum[match_idx] + w;
1074  seeds_eta[match_idx] = new_eta;
1075  seeds_phi[match_idx] = new_phi;
1076  seeds_wsum[match_idx] = new_wsum;
1077  }
1078  QT.clear();
1079  for(unsigned int i=0; i<seeds_eta.size(); i++) {
1080  float eta = seeds_eta[i] / seeds_wsum[i];
1081  float phi = seeds_phi[i] / seeds_wsum[i];
1082  seeds_eta[i] = eta;
1083  if( phi < -TMath::Pi() ) phi = 2*TMath::Pi() + phi;
1084  if( phi > TMath::Pi() ) phi = -2*TMath::Pi() + phi;
1085  seeds_phi[i] = phi;
1086  }
1087  ATH_MSG_VERBOSE("after clustering, nr of seeds = " << seeds_eta.size());
1088 
1089  // delete overlap (can happen at phi=-Pi/Pi bounadry)
1090  std::vector<unsigned int> idx_to_delete;
1091  for(unsigned int i=0; i<seeds_eta.size(); i++) {
1092  if( std::find(idx_to_delete.begin(),idx_to_delete.end(),i) != idx_to_delete.end() ) continue;
1093  float eta_i = seeds_eta[i];
1094  float phi_i = seeds_phi[i];
1095  for(unsigned int j=i+1; j<seeds_eta.size(); j++) {
1096  if( std::find(idx_to_delete.begin(),idx_to_delete.end(),j) != idx_to_delete.end() ) continue;
1097  float eta_j = seeds_eta[j];
1098  float phi_j = seeds_phi[j];
1099  float dR2 = deltaR2(eta_i,phi_i,eta_j,phi_j);
1100  if( dR2 < CLUSTCUT_DIST_SQUARED ) idx_to_delete.push_back(j);
1101  }
1102  }
1103  ATH_MSG_VERBOSE("nr of duplicated seeds to be removed = " << idx_to_delete.size());
1104  if( idx_to_delete.size() > 0 ) {
1105  std::sort(idx_to_delete.begin(),idx_to_delete.end());
1106  for(unsigned int j=idx_to_delete.size(); j>0; j--) {
1107  unsigned int idx = idx_to_delete[j-1];
1108  seeds_eta.erase(seeds_eta.begin()+idx);
1109  seeds_phi.erase(seeds_phi.begin()+idx);
1110  }
1111  }
1112 
1113  ATH_MSG_VERBOSE("nr of ly6/ly7 seeds=" << seeds_eta.size());
1114 
1115  // return
1116  return StatusCode::SUCCESS;
1117 }
1118 
1119 StatusCode TrigHitDVHypoAlg::findHitDV(const EventContext& ctx, const std::vector<TrigSiSpacePointBase>& convertedSpacePoints,
1120  const DataVector<Trk::Track>& tracks, std::vector<HitDVSeed>& hitDVSeedsContainer,
1121  std::vector<HitDVTrk>& hitDVTrksContainer,
1122  std::vector<HitDVSpacePoint>& hitDVSPsContainer) const
1123 {
1124  std::vector<int> v_dvtrk_id;
1125  std::vector<float> v_dvtrk_pt;
1126  std::vector<float> v_dvtrk_eta;
1127  std::vector<float> v_dvtrk_phi;
1128  std::vector<int> v_dvtrk_n_hits_inner;
1129  std::vector<int> v_dvtrk_n_hits_pix;
1130  std::vector<int> v_dvtrk_n_hits_sct;
1131  std::vector<float> v_dvtrk_a0beam;
1132  std::unordered_map<Identifier, int> umap_fittedTrack_identifier;
1133  int fittedTrack_id = -1;
1134 
1135  static constexpr float TRKCUT_PTGEV_HITDV = 0.5;
1136 
1137  for (const auto track: tracks) {
1138  float shift_x = 0; float shift_y = 0;
1139  if(m_useBeamSpot) {
1141  FTF::getBeamSpotShift(shift_x, shift_y, **beamSpotHandle);
1142  }
1143  trackInfo theTrackInfo;
1144  bool igt = FTF::isGoodTrackUTT(track, theTrackInfo, shift_x, shift_y, TRKCUT_PTGEV_HITDV);
1145  if (not igt) {continue;}
1146 
1147  fittedTrack_id++;
1148  ATH_MSG_DEBUG("Selected track pT = " << theTrackInfo.ptGeV << " GeV");
1149 
1150 
1152  m = track->measurementsOnTrack()->begin(),
1153  me = track->measurementsOnTrack()->end ();
1154  for(; m!=me; ++m ) {
1155  const Trk::PrepRawData* prd = ((const Trk::RIO_OnTrack*)(*m))->prepRawData();
1156  if( prd == nullptr ) continue;
1157  Identifier id_prd = prd->identify();
1158  if( umap_fittedTrack_identifier.find(id_prd) == umap_fittedTrack_identifier.end() ) {
1159  umap_fittedTrack_identifier.insert(std::make_pair(id_prd,fittedTrack_id));
1160  }
1161  }
1162  float phi = track->perigeeParameters()->parameters()[Trk::phi];
1163  v_dvtrk_id.push_back(fittedTrack_id);
1164  v_dvtrk_pt.push_back(theTrackInfo.ptGeV*Gaudi::Units::GeV);
1165  v_dvtrk_eta.push_back(theTrackInfo.eta);
1166  v_dvtrk_phi.push_back(phi);
1167  v_dvtrk_n_hits_inner.push_back(theTrackInfo.n_hits_inner);
1168  v_dvtrk_n_hits_pix.push_back(theTrackInfo.n_hits_pix);
1169  v_dvtrk_n_hits_sct.push_back(theTrackInfo.n_hits_sct);
1170  v_dvtrk_a0beam.push_back(theTrackInfo.a0beam);
1171  }
1172  ATH_MSG_DEBUG("Nr of selected tracks / all = " << fittedTrack_id << " / " << tracks.size());
1173  ATH_MSG_DEBUG("Nr of Identifiers used by selected tracks = " << umap_fittedTrack_identifier.size());
1174 
1175  // space points
1176  int n_sp = 0;
1177  int n_sp_usedByTrk = 0;
1178 
1179  std::unordered_map<Identifier, int> umap_sp_identifier;
1180  umap_sp_identifier.reserve(1.3*convertedSpacePoints.size());//up to 2 Identifiers per spacepoint, end up with 1.3 from measurements
1181 
1182  auto add_to_sp_map = [&](const Trk::PrepRawData* prd) {
1183  if (prd) {
1184  Identifier id_prd = prd->identify();
1185  if( umap_sp_identifier.find(id_prd) == umap_sp_identifier.end() ) {
1186  umap_sp_identifier.insert(std::make_pair(id_prd,-1));
1187  }
1188  }
1189  };
1190 
1191  for(unsigned int iSp=0; iSp<convertedSpacePoints.size(); ++iSp) {
1192  bool isPix = convertedSpacePoints[iSp].isPixel();
1193  bool isSct = convertedSpacePoints[iSp].isSCT();
1194  if( ! isPix && ! isSct ) continue;
1195  const Trk::SpacePoint* sp = convertedSpacePoints[iSp].offlineSpacePoint();
1196  add_to_sp_map(sp->clusterList().first);
1197  add_to_sp_map(sp->clusterList().second);
1198  }
1199  int n_id_usedByTrack = 0;
1200  for(auto it=umap_sp_identifier.begin(); it!=umap_sp_identifier.end(); ++it) {
1201  Identifier id_sp = it->first;
1202  if( umap_fittedTrack_identifier.find(id_sp) != umap_fittedTrack_identifier.end() ) {
1203  umap_sp_identifier[id_sp] = umap_fittedTrack_identifier[id_sp];
1204  ++n_id_usedByTrack;
1205  }
1206  }
1207  ATH_MSG_DEBUG("Nr of SPs / Identifiers (all) / Identifiers (usedByTrack) = " << convertedSpacePoints.size() << " / " << umap_sp_identifier.size() << " / " << n_id_usedByTrack);
1208 
1209  auto sp_map_used_id = [&](const Trk::PrepRawData* prd) {
1210  int usedTrack_id = -1;
1211  if (prd) {
1212  Identifier id_prd = prd->identify();
1213  if( umap_sp_identifier.find(id_prd) != umap_sp_identifier.end() ) {
1214  usedTrack_id = umap_sp_identifier[id_prd];
1215  }
1216  }
1217  return usedTrack_id;
1218  };
1219 
1220  std::vector<float> v_sp_eta;
1221  v_sp_eta.reserve(convertedSpacePoints.size());
1222  std::vector<float> v_sp_r;
1223  v_sp_r.reserve(convertedSpacePoints.size());
1224  std::vector<float> v_sp_phi;
1225  v_sp_phi.reserve(convertedSpacePoints.size());
1226  std::vector<int> v_sp_layer;
1227  v_sp_layer.reserve(convertedSpacePoints.size());
1228  std::vector<bool> v_sp_isPix;
1229  v_sp_isPix.reserve(convertedSpacePoints.size());
1230  std::vector<bool> v_sp_isSct;
1231  v_sp_isSct.reserve(convertedSpacePoints.size());
1232  std::vector<int> v_sp_usedTrkId;
1233  v_sp_usedTrkId.reserve(convertedSpacePoints.size());
1234 
1235  for(const auto& sp : convertedSpacePoints) {
1236  bool isPix = sp.isPixel();
1237  bool isSct = sp.isSCT();
1238  if( ! isPix && ! isSct ) continue;
1239  const Trk::SpacePoint* osp = sp.offlineSpacePoint();
1240 
1241  int usedTrack_id = -1;
1242  int usedTrack_id_first = sp_map_used_id(osp->clusterList().first);
1243  if (usedTrack_id_first != -1) {
1244  usedTrack_id = usedTrack_id_first;
1245  }
1246  int usedTrack_id_second = sp_map_used_id(osp->clusterList().second);
1247  if (usedTrack_id_second != -1) {
1248  usedTrack_id = usedTrack_id_second;
1249  }
1250 
1251  //
1252  n_sp++;
1253  if( usedTrack_id != -1 ) n_sp_usedByTrk++;
1254  int layer = sp.layer();
1255  float sp_r = sp.r();
1256 
1257  const Amg::Vector3D& pos_sp = osp->globalPosition();//Go back to globalPosition to get the non-shifted spacepoint positions
1258  float sp_eta = pos_sp.eta();
1259  float sp_phi = pos_sp.phi();
1260 
1261  v_sp_eta.push_back(sp_eta);
1262  v_sp_r.push_back(sp_r);
1263  v_sp_phi.push_back(sp_phi);
1264  v_sp_layer.push_back(layer);
1265  v_sp_isPix.push_back(isPix);
1266  v_sp_isSct.push_back(isSct);
1267  v_sp_usedTrkId.push_back(usedTrack_id);
1268 
1269  ATH_MSG_VERBOSE("+++ SP eta / phi / layer / ixPix / usedTrack_id = " << sp_eta << " / " << sp_phi << " / " << layer << " / " << isPix << " / " << usedTrack_id);
1270 
1271  }
1272  ATH_MSG_DEBUG("Nr of SPs / all = " << n_sp << " / " << convertedSpacePoints.size());
1273  ATH_MSG_DEBUG("Nr of SPs used by selected tracks = " << n_sp_usedByTrk);
1274 
1275  // Seed
1276  std::vector<float> v_seeds_eta;
1277  std::vector<float> v_seeds_phi;
1278  std::vector<int16_t> v_seeds_type;
1279 
1280  if( m_doHitDV_Seeding ) {
1281 
1282  // add L1 Jet seeds
1283  const unsigned int L1JET_ET_CUT = 27; // Mapping from legacy J30, make configurable?
1284 
1285  auto jetRoiCollectionHandle = SG::makeHandle( m_jetRoiCollectionKey, ctx );
1286  const DataVector<xAOD::jFexSRJetRoI> *jetRoiCollection = jetRoiCollectionHandle.cptr();
1287  if (!jetRoiCollectionHandle.isValid()){
1288  ATH_MSG_ERROR("ReadHandle for DataVector<xAOD::jFexSRJetRoI> key:" << m_jetRoiCollectionKey.key() << " isn't Valid");
1289  return StatusCode::FAILURE;
1290  }
1291  for (size_t size=0; size<jetRoiCollection->size(); ++size){
1292  const xAOD::jFexSRJetRoI* jetRoI = jetRoiCollection->at(size);
1293  if( jetRoI == nullptr ) continue;
1294  // Good seed
1295  if( jetRoI->et() >= L1JET_ET_CUT ) {
1296  v_seeds_eta.push_back(jetRoI->eta());
1297  v_seeds_phi.push_back(jetRoI->phi());
1298  v_seeds_type.push_back(0); // L1_J:0
1299  }
1300  }
1301  ATH_MSG_DEBUG("Nr of L1_J" << L1JET_ET_CUT << " seeds = " << v_seeds_eta.size());
1302 
1303  // space-point based (unseeded mode)
1304  std::vector<float> v_spseeds_eta;
1305  std::vector<float> v_spseeds_phi;
1306  ATH_CHECK( findSPSeeds(ctx, v_sp_eta, v_sp_phi, v_sp_layer, v_sp_usedTrkId, v_spseeds_eta, v_spseeds_phi) );
1307  ATH_MSG_DEBUG("Nr of SP seeds = " << v_spseeds_eta.size());
1308  for(size_t idx=0; idx<v_spseeds_eta.size(); ++idx) {
1309  v_seeds_eta.push_back(v_spseeds_eta[idx]);
1310  v_seeds_phi.push_back(v_spseeds_phi[idx]);
1311  v_seeds_type.push_back(1); // SP: 1
1312  }
1313  ATH_MSG_DEBUG("Nr of SP + L1_J" << L1JET_ET_CUT << " seeds = " << v_seeds_eta.size());
1314  }
1315 
1316  // fill objects
1317 
1318  // seeds
1319  const int N_MAX_SEEDS = 200;
1320  int n_seeds = std::min(N_MAX_SEEDS,(int)v_seeds_eta.size());
1321  hitDVSeedsContainer.reserve(n_seeds);
1322  for(auto iSeed=0; iSeed < n_seeds; ++iSeed) {
1323  HitDVSeed seed;
1324  seed.eta = v_seeds_eta[iSeed];
1325  seed.phi = v_seeds_phi[iSeed];
1326  seed.type = v_seeds_type[iSeed];
1327  hitDVSeedsContainer.push_back(seed);
1328  }
1329 
1330  // track
1331  const float TRKCUT_DELTA_R_TO_SEED = 1.0;
1332  hitDVTrksContainer.reserve(v_dvtrk_pt.size());
1333  for(unsigned int iTrk=0; iTrk<v_dvtrk_pt.size(); ++iTrk) {
1334  float trk_eta = v_dvtrk_eta[iTrk];
1335  float trk_phi = v_dvtrk_phi[iTrk];
1336  if( m_doHitDV_Seeding ) {
1337  bool isNearSeed = false;
1338  for (unsigned int iSeed=0; iSeed<v_seeds_eta.size(); ++iSeed) {
1339  float seed_eta = v_seeds_eta[iSeed];
1340  float seed_phi = v_seeds_phi[iSeed];
1341  float dR2 = deltaR2(trk_eta,trk_phi,seed_eta,seed_phi);
1342  if( dR2 <= TRKCUT_DELTA_R_TO_SEED*TRKCUT_DELTA_R_TO_SEED ) { isNearSeed = true; break; }
1343  }
1344  if( ! isNearSeed ) continue;
1345  }
1346  HitDVTrk hitDVTrk;
1347  hitDVTrk.id = v_dvtrk_id[iTrk];
1348  hitDVTrk.pt = v_dvtrk_pt[iTrk];
1349  hitDVTrk.eta = v_dvtrk_eta[iTrk];
1350  hitDVTrk.phi = v_dvtrk_phi[iTrk];
1351  hitDVTrk.n_hits_inner = v_dvtrk_n_hits_inner[iTrk];
1352  hitDVTrk.n_hits_pix = v_dvtrk_n_hits_pix[iTrk];
1353  hitDVTrk.n_hits_sct = v_dvtrk_n_hits_sct[iTrk];
1354  hitDVTrk.a0beam = v_dvtrk_a0beam[iTrk];
1355 
1356  hitDVTrksContainer.push_back(hitDVTrk);
1357  }
1358 
1359  // space points
1360  const float SPCUT_DELTA_R_TO_SEED = 1.0;
1361  const size_t n_sp_max = std::min<size_t>(100000, v_sp_eta.size());
1362  size_t n_sp_stored = 0;
1363 
1364  hitDVSPsContainer.reserve(n_sp_max);
1365 
1366  for(size_t iSp=0; iSp<v_sp_eta.size(); ++iSp) {
1367  if( m_doHitDV_Seeding ) {
1368  const float sp_eta = v_sp_eta[iSp];
1369  const float sp_phi = v_sp_phi[iSp];
1370  bool isNearSeed = false;
1371  for (size_t iSeed=0; iSeed<v_seeds_eta.size(); ++iSeed) {
1372  const float seed_eta = v_seeds_eta[iSeed];
1373  const float seed_phi = v_seeds_phi[iSeed];
1374  const float dR2 = deltaR2(sp_eta, sp_phi, seed_eta, seed_phi);
1375  if( dR2 <= SPCUT_DELTA_R_TO_SEED*SPCUT_DELTA_R_TO_SEED ) { isNearSeed = true; break; }
1376  }
1377  if( ! isNearSeed ) continue;
1378  }
1379  if( n_sp_stored >= n_sp_max ) break;
1380  HitDVSpacePoint hitDVSP;
1381  hitDVSP.eta = v_sp_eta[iSp];
1382  hitDVSP.r = v_sp_r[iSp];
1383  hitDVSP.phi = v_sp_phi[iSp];
1384  hitDVSP.layer = v_sp_layer[iSp];
1385  hitDVSP.isPix = v_sp_isPix[iSp];
1386  hitDVSP.isSct = v_sp_isSct[iSp];
1387  hitDVSP.usedTrkId = v_sp_usedTrkId[iSp];
1388  hitDVSPsContainer.push_back(hitDVSP);
1389  ++n_sp_stored;
1390  }
1391  ATH_MSG_DEBUG("Nr of SPs stored = " << n_sp_stored);
1392 
1393  return StatusCode::SUCCESS;
1394 }
Trk::SpacePoint::clusterList
const std::pair< const PrepRawData *, const PrepRawData * > & clusterList() const
return the pair of cluster pointers by reference
Definition: Tracking/TrkEvent/TrkSpacePoint/TrkSpacePoint/SpacePoint.h:127
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
HitDVSpacePoint::isPix
bool isPix
Definition: TrigHitDVHypoAlg.h:58
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
base
std::string base
Definition: hcg.cxx:78
TrigCompositeUtils::featureString
const std::string & featureString()
Definition: TrigCompositeUtils.h:420
PathResolver::find_calib_file
static std::string find_calib_file(const std::string &logical_file_name)
Definition: PathResolver.cxx:235
TrigHitDVHypoAlg::m_bdt_eta
std::unique_ptr< MVAUtils::BDT > m_bdt_eta[2]
Definition: TrigHitDVHypoAlg.h:112
Trk::SpacePoint
Definition: Tracking/TrkEvent/TrkSpacePoint/TrkSpacePoint/SpacePoint.h:35
TrigHitDVHypoAlg::TrigHitDVHypoAlg
TrigHitDVHypoAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: TrigHitDVHypoAlg.cxx:46
HitDVTrk::n_hits_inner
int16_t n_hits_inner
Definition: TrigHitDVHypoAlg.h:47
xAOD::jFexSRJetRoI_v1
Class describing properties of a LVL1 jFEX global Trigger Object (TOB) in the xAOD format.
Definition: jFexSRJetRoI_v1.h:23
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:18
trackInfo::ptGeV
float ptGeV
Definition: TrigInDetUtils.h:15
TrigDefs::Group
Group
Properties of a chain group.
Definition: GroupProperties.h:13
trackInfo::n_hits_inner
int n_hits_inner
Definition: TrigInDetUtils.h:14
HitDVSpacePoint::r
float r
Definition: TrigHitDVHypoAlg.h:55
PlotCalibFromCool.dv
dv
Definition: PlotCalibFromCool.py:762
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
TrigCompositeUtils::DecisionContainer
xAOD::TrigCompositeContainer DecisionContainer
Definition: Event/xAOD/xAODTrigger/xAODTrigger/TrigCompositeContainer.h:21
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
FTF::isGoodTrackUTT
bool isGoodTrackUTT(const Trk::Track *track, trackInfo &theTrackInfo, const float shift_x, const float shift_y, float trkcut_ptgev)
Definition: TrigInDetUtils.cxx:4
TrigHitDVHypoAlg::m_spacePointTool
ToolHandle< ITrigSpacePointConversionTool > m_spacePointTool
Definition: TrigHitDVHypoAlg.h:73
xAOD::TrigComposite
TrigComposite_v1 TrigComposite
Declare the latest version of the class.
Definition: Event/xAOD/xAODTrigger/xAODTrigger/TrigComposite.h:16
Trk::SpacePoint::globalPosition
virtual const Amg::Vector3D & globalPosition() const override final
Interface method to get the global Position.
Definition: Tracking/TrkEvent/TrkSpacePoint/TrkSpacePoint/SpacePoint.h:146
TrigL2MuonSA::N_LAYER
constexpr int N_LAYER
Definition: MuonRoad.h:17
HitDVSpacePoint
Definition: TrigHitDVHypoAlg.h:53
dqt_zlumi_pandas.hname
string hname
Definition: dqt_zlumi_pandas.py:280
TrigCompositeUtils::newDecisionIn
Decision * newDecisionIn(DecisionContainer *dc, const std::string &name)
Helper method to create a Decision object, place it in the container and return a pointer to it.
Definition: TrigCompositeUtilsRoot.cxx:44
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
hist_file_dump.d
d
Definition: hist_file_dump.py:142
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
CxxUtils::wrapToPi
T wrapToPi(T phi)
Wrap angle in radians to [-pi, pi].
Definition: phihelper.h:24
tree
TChain * tree
Definition: tile_monitor.h:30
TrigHitDVHypoAlg::m_jetRoiCollectionKey
SG::ReadHandleKey< xAOD::jFexSRJetRoIContainer > m_jetRoiCollectionKey
Definition: TrigHitDVHypoAlg.h:124
skel.it
it
Definition: skel.GENtoEVGEN.py:407
M_PI
#define M_PI
Definition: ActiveFraction.h:11
TrigHitDVHypoAlg::m_useBeamSpot
bool m_useBeamSpot
Definition: TrigHitDVHypoAlg.h:119
DataVector::get
const T * get(size_type n) const
Access an element, as an rvalue.
HypoBase::decisionInput
const SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > & decisionInput() const
methods for derived classes to access handles of the base class input other read/write handles may be...
Definition: HypoBase.cxx:18
TrigHitDVHypoAlg::m_tools_loosest_wp
int m_tools_loosest_wp
Definition: TrigHitDVHypoAlg.h:116
TrigHitDVHypoAlg::m_monTool
ToolHandle< GenericMonitoringTool > m_monTool
Definition: TrigHitDVHypoAlg.h:97
Trk::RIO_OnTrack
Definition: RIO_OnTrack.h:70
TrigRoiDescriptor
nope - should be used for standalone also, perhaps need to protect the class def bits #ifndef XAOD_AN...
Definition: TrigRoiDescriptor.h:56
xAOD::jFexSRJetRoI_v1::eta
float eta() const
xAOD::jFexSRJetRoI_v1::phi
float phi() const
FTF::getBeamSpotShift
void getBeamSpotShift(float &shift_x, float &shift_y, const InDet::BeamSpotData &beamSpotHandle)
Definition: TrigInDetUtils.cxx:30
HitDVTrk::phi
float phi
Definition: TrigHitDVHypoAlg.h:46
HitDVTrk::pt
float pt
Definition: TrigHitDVHypoAlg.h:44
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
HitDVSeed
Definition: TrigHitDVHypoAlg.h:36
ViewHelper.h
TrigCompositeUtils::createAndStore
SG::WriteHandle< DecisionContainer > createAndStore(const SG::WriteHandleKey< DecisionContainer > &key, const EventContext &ctx)
Creates and right away records the DecisionContainer with the key.
Definition: TrigCompositeUtilsRoot.cxx:28
xAOD::int16_t
setScaleOne setStatusOne setSaturated int16_t
Definition: gFexGlobalRoI_v1.cxx:55
HypoBase::decisionOutput
const SG::WriteHandleKey< TrigCompositeUtils::DecisionContainer > & decisionOutput() const
methods for derived classes to access handles of the base class output other read/write handles may b...
Definition: HypoBase.cxx:22
HitDVTrk::a0beam
float a0beam
Definition: TrigHitDVHypoAlg.h:50
Monitored::Collection
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
Definition: MonitoredCollection.h:38
TrigHitDVHypoAlg::m_jetSeed_etaMax
Gaudi::Property< float > m_jetSeed_etaMax
Definition: TrigHitDVHypoAlg.h:89
TrigHitDVHypoTool::HitDVHypoInfo
Definition: TrigHitDVHypoTool.h:33
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
HitDVTrk::n_hits_pix
int16_t n_hits_pix
Definition: TrigHitDVHypoAlg.h:48
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:274
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
TrigInDetUtils.h
trackInfo::eta
float eta
Definition: TrigInDetUtils.h:15
TrigCompositeUtils.h
TrigHitDVHypoAlg::deltaR2
float deltaR2(float, float, float, float) const
Definition: TrigHitDVHypoAlg.cxx:323
HitDVSpacePoint::phi
float phi
Definition: TrigHitDVHypoAlg.h:56
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
jFexSRJetRoI.h
TrigHitDVHypoAlg::m_doHitDV_Seeding
bool m_doHitDV_Seeding
Definition: TrigHitDVHypoAlg.h:122
trackInfo::n_hits_pix
int n_hits_pix
Definition: TrigInDetUtils.h:14
perfmonmt-refit.idx_min
idx_min
Definition: perfmonmt-refit.py:83
TrigHitDVHypoAlg::selectSeedsNearby
StatusCode selectSeedsNearby(const std::vector< HitDVSeed > &hitDVSeedsContainer, std::vector< float > &jetSeeds_eta, std::vector< float > &jetSeeds_phi, std::vector< float > &jetSeeds_pt) const
Definition: TrigHitDVHypoAlg.cxx:890
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
HitDVTrk::n_hits_sct
int16_t n_hits_sct
Definition: TrigHitDVHypoAlg.h:49
lumiFormat.i
int i
Definition: lumiFormat.py:85
HypoBase::hypoBaseOutputProcessing
StatusCode hypoBaseOutputProcessing(SG::WriteHandle< TrigCompositeUtils::DecisionContainer > &outputHandle, MSG::Level lvl=MSG::DEBUG) const
Base class function to be called once slice specific code has finished. Handles debug printing and va...
Definition: HypoBase.cxx:35
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
checkxAOD.frac
frac
Definition: Tools/PyUtils/bin/checkxAOD.py:259
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
TauGNNUtils::Variables::Track::dEta
bool dEta(const xAOD::TauJet &tau, const xAOD::TauTrack &track, float &out)
Definition: TauGNNUtils.cxx:401
TrigHitDVHypoAlg::m_lumiBlockMuTool
ToolHandle< ILumiBlockMuTool > m_lumiBlockMuTool
Definition: TrigHitDVHypoAlg.h:82
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
makeComparison.rootFile
rootFile
Definition: makeComparison.py:27
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
add-xsec-uncert-quadrature-N.results
dictionary results
Definition: add-xsec-uncert-quadrature-N.py:39
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
trackInfo::n_hits_sct
int n_hits_sct
Definition: TrigInDetUtils.h:14
xAOD::TrigComposite_v1
Class used to describe composite objects in the HLT.
Definition: TrigComposite_v1.h:49
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
TrigHitDVHypoAlg::doMonitor
StatusCode doMonitor(const xAOD::TrigCompositeContainer *) const
Definition: TrigHitDVHypoAlg.cxx:456
TrigHitDVHypoAlg::m_beamSpotKey
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
Definition: TrigHitDVHypoAlg.h:125
Monitored.h
Header file to be included by clients of the Monitored infrastructure.
trackInfo
Definition: TrigInDetUtils.h:13
TrigCompositeUtils::DecisionAuxContainer
xAOD::TrigCompositeAuxContainer DecisionAuxContainer
Definition: TrigCompositeAuxContainer.h:20
ITrigSpacePointConversionTool.h
TrigHitDVHypoAlg.h
Trk::PrepRawData
Definition: PrepRawData.h:62
keylayer_zslicemap.isPix
isPix
Definition: keylayer_zslicemap.py:127
Trk::PrepRawData::identify
Identifier identify() const
return the identifier
PathResolver.h
TrigHitDVHypoAlg::findJetSeeds
StatusCode findJetSeeds(const xAOD::JetContainer *, const float, const float, std::vector< float > &, std::vector< float > &, std::vector< float > &) const
Definition: TrigHitDVHypoAlg.cxx:651
trackInfo::a0beam
float a0beam
Definition: TrigInDetUtils.h:15
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
TrigHitDVHypoAlg::m_tracksKey
SG::ReadHandleKey< TrackCollection > m_tracksKey
Definition: TrigHitDVHypoAlg.h:79
HypoBase
Hypothesis algorithms take the output of reco algorithms and the decision from the preceeding InputMa...
Definition: HypoBase.h:13
TrigCompositeUtils::Decision
xAOD::TrigComposite Decision
Definition: Event/xAOD/xAODTrigger/xAODTrigger/TrigComposite.h:20
LuminosityCondData::lbAverageInteractionsPerCrossing
float lbAverageInteractionsPerCrossing() const
Definition: LuminosityCondData.cxx:26
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:452
TrigHitDVHypoAlg::execute
virtual StatusCode execute(const EventContext &context) const override
Definition: TrigHitDVHypoAlg.cxx:117
HitDVTrk::eta
float eta
Definition: TrigHitDVHypoAlg.h:45
phihelper.h
Helper for azimuthal angle calculations.
TrigHitDVHypoAlg::m_jetsKey
SG::ReadHandleKey< xAOD::JetContainer > m_jetsKey
Definition: TrigHitDVHypoAlg.h:77
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
TrigHitDVHypoAlg::calculateBDT
StatusCode calculateBDT(const std::vector< HitDVSpacePoint > &, const std::vector< HitDVTrk > &, const std::vector< float > &, const std::vector< float > &, const std::vector< float > &, const float &, const int, xAOD::TrigCompositeContainer *, int &) const
Definition: TrigHitDVHypoAlg.cxx:508
TrigCompositeUtils::viewString
const std::string & viewString()
Definition: TrigCompositeUtils.h:419
TrigHitDVHypoAlg::m_hitDVKey
SG::WriteHandleKey< xAOD::TrigCompositeContainer > m_hitDVKey
Definition: TrigHitDVHypoAlg.h:78
TrigHitDVHypoAlg::initialize
virtual StatusCode initialize() override
Definition: TrigHitDVHypoAlg.cxx:55
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
TrigHitDVHypoAlg::m_lumiDataKey
SG::ReadCondHandleKey< LuminosityCondData > m_lumiDataKey
Definition: TrigHitDVHypoAlg.h:84
TrigHitDVHypoAlg::m_isMC
Gaudi::Property< bool > m_isMC
Definition: TrigHitDVHypoAlg.h:86
HitDVSpacePoint::layer
int16_t layer
Definition: TrigHitDVHypoAlg.h:57
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
TrigCompositeUtils::linkToPrevious
void linkToPrevious(Decision *d, const std::string &previousCollectionKey, size_t previousIndex)
Links to the previous object, location of previous 'seed' decision supplied by hand.
Definition: TrigCompositeUtilsRoot.cxx:140
TrigCompositeUtils::LinkInfo
Helper to keep a Decision object, ElementLink and ActiveState (with respect to some requested ChainGr...
Definition: LinkInfo.h:29
TrigCompositeUtils::DecisionIDContainer
std::set< DecisionID > DecisionIDContainer
Definition: TrigComposite_v1.h:28
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
TrigHitDVHypoAlg::m_jetSeed_ptMin
Gaudi::Property< float > m_jetSeed_ptMin
Definition: TrigHitDVHypoAlg.h:88
TrigCompositeUtils::findLink
LinkInfo< T > findLink(const Decision *start, const std::string &linkName, const bool suppressMultipleLinksWarning=false)
Perform a recursive search for ElementLinks of type T and name 'linkName', starting from Decision obj...
TrigCompositeUtils::hypoAlgNodeName
const std::string & hypoAlgNodeName()
Definition: TrigCompositeUtils.h:426
HitDVSpacePoint::eta
float eta
Definition: TrigHitDVHypoAlg.h:54
TrigHitDVHypoAlg::findSPSeeds
StatusCode findSPSeeds(const EventContext &, const std::vector< HitDVSpacePoint > &, std::vector< float > &, std::vector< float > &) const
Definition: TrigHitDVHypoAlg.cxx:687
TrigCompositeUtils::allFailed
bool allFailed(const Decision *d)
return true if there is no positive decision stored
Definition: TrigCompositeUtilsRoot.cxx:104
TrigCompositeUtils::decisionIDs
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
Definition: TrigCompositeUtilsRoot.cxx:65
TauGNNUtils::Variables::Track::dPhi
bool dPhi(const xAOD::TauJet &tau, const xAOD::TauTrack &track, float &out)
Definition: TauGNNUtils.cxx:412
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
HitDVSpacePoint::usedTrkId
int16_t usedTrkId
Definition: TrigHitDVHypoAlg.h:60
Trk::phi
@ phi
Definition: ParamDefs.h:75
Trk::jet_phi
@ jet_phi
Definition: JetVtxParamDefs.h:28
TrigRoiDescriptor
Athena::TPCnvVers::Current TrigRoiDescriptor
Definition: TrigSteeringEventTPCnv.cxx:68
xAOD::JetContainer
JetContainer_v1 JetContainer
Definition of the current "jet container version".
Definition: JetContainer.h:17
xAOD::track
@ track
Definition: TrackingPrimitives.h:513
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
TrigHitDVHypoAlg::m_hypoTools
ToolHandleArray< TrigHitDVHypoTool > m_hypoTools
Definition: TrigHitDVHypoAlg.h:74
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:198
TrigHitDVHypoAlg::findHitDV
StatusCode findHitDV(const EventContext &ctx, const std::vector< TrigSiSpacePointBase > &convertedSpacePoints, const DataVector< Trk::Track > &tracks, std::vector< HitDVSeed > &hitDVSeedsContainer, std::vector< HitDVTrk > &hitDVTrksContainer, std::vector< HitDVSpacePoint > &hitDVSPContainer) const
Definition: TrigHitDVHypoAlg.cxx:1119
TrigHitDVHypoAlg::m_tools_lowest_jetEt
int m_tools_lowest_jetEt
Definition: TrigHitDVHypoAlg.h:115
HitDVTrk::id
int id
Definition: TrigHitDVHypoAlg.h:43
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
HitDVSpacePoint::isSct
bool isSct
Definition: TrigHitDVHypoAlg.h:59
HitDVTrk
Definition: TrigHitDVHypoAlg.h:42
python.SystemOfUnits.m
float m
Definition: SystemOfUnits.py:106
TrigHitDVHypoAlg::getSPLayer
int getSPLayer(int, float) const
Definition: TrigHitDVHypoAlg.cxx:332
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
SG::ReadCondHandle::cptr
const_pointer_type cptr()
Definition: ReadCondHandle.h:71
xAOD::jFexSRJetRoI_v1::et
unsigned int et() const
Methods that require combining results or applying scales.
Definition: jFexSRJetRoI_v1.cxx:138
Identifier
Definition: IdentifierFieldParser.cxx:14