37 if (conn_fileName.empty()) {
38 ATH_MSG_FATAL(
"Cannot find layer connections file " << conn_fileName);
39 return StatusCode::FAILURE;
43 std::ifstream ifs(conn_fileName.c_str());
50 ATH_MSG_INFO(
"Layer connections are initialized from file " << conn_fileName);
55 std::copy(pVL->begin(),pVL->end(), std::back_inserter(
m_layerGeometry));
62 if (lut_fileName.empty()) {
63 ATH_MSG_FATAL(
"Cannot find ML predictor LUT file " << lut_fileName);
64 return StatusCode::FAILURE;
68 std::ifstream ifs(lut_fileName.c_str());
70 float cl_width, min1, max1, min2, max2;
71 ifs >> cl_width >> min1 >> max1 >> min2 >> max2;
73 std::array<float, 5> lut_line = {cl_width, min1, max1, min2, max2};
77 ATH_MSG_INFO(
"ML predictor is initialized from file " << lut_fileName<<
" LUT has "<<
m_mlLUT.size()<<
" entries");
90 return StatusCode::SUCCESS;
94 StatusCode
sc = AthAlgTool::finalize();
102 const float cut_dphi_max =
m_LRTmode ? 0.07f : 0.012f;
103 const float cut_dcurv_max =
m_LRTmode ? 0.015f : 0.001f;
107 const float min_deltaPhi =
m_LRTmode ? 0.01f : 0.001f;
108 const float tau_ratio_precut = 0.009f;
110 const float maxOuterRadius =
m_LRTmode ? 1050.0 : 550.0;
112 const float cut_zMinU = min_z0 + maxOuterRadius*roi.
dzdrMinus();
113 const float cut_zMaxU = max_z0 + maxOuterRadius*roi.
dzdrPlus();
115 constexpr float ptCoeff = 0.29997*1.9972/2.0;
117 float tripletPtMin = 0.8f*
m_minPt;
118 const float pt_scale = 900.0f/
m_minPt;
120 float maxCurv = ptCoeff/tripletPtMin;
122 float maxKappa_high_eta =
m_LRTmode ? 1.0f*maxCurv : std::sqrt(0.8f)*maxCurv;
123 float maxKappa_low_eta =
m_LRTmode ? 1.0f*maxCurv : std::sqrt(0.6f)*maxCurv;
126 maxKappa_high_eta = 4.75e-4f*pt_scale;
127 maxKappa_low_eta = 3.75e-4f*pt_scale;
130 const float dphi_coeff =
m_LRTmode ? 1.0f*maxCurv : 0.68f*maxCurv;
132 const float minDeltaRadius = 2.0;
136 unsigned int nConnections = 0;
142 for(
const auto& bg :
m_geo->bin_groups()) {
146 if(B1.
empty())
continue;
152 for(
const auto& b2_idx : bg.second) {
156 if(B2.
empty())
continue;
161 float abs_dr = std::fabs(rb2-rb1);
163 deltaPhi = min_deltaPhi + dphi_coeff*abs_dr;
167 deltaPhi = 0.002f + 4.33e-4f*pt_scale*abs_dr;
169 deltaPhi = 0.015f + 2.2e-4f*pt_scale*abs_dr;
174 unsigned int first_it = 0;
176 for(
unsigned int n1Idx = 0;n1Idx<B1.
m_vn.size();n1Idx++) {
178 std::vector<unsigned int>& v1In = B1.
m_in[n1Idx];
182 const std::array<float, 5>& n1pars = B1.
m_params[n1Idx];
184 float phi1 = n1pars[2];
185 float r1 = n1pars[3];
186 float z1 = n1pars[4];
193 for(
unsigned int n2PhiIdx = first_it; n2PhiIdx<B2.
m_vPhiNodes.size();n2PhiIdx++) {
201 if(phi2 > maxPhi)
break;
203 unsigned int n2Idx = B2.
m_vPhiNodes[n2PhiIdx].second;
205 const std::vector<unsigned int>& v2In = B2.
m_in[n2Idx];
209 const std::array<float, 5>& n2pars = B2.
m_params[n2Idx];
211 float r2 = n2pars[3];
215 if(dr < minDeltaRadius) {
219 float z2 = n2pars[4];
223 float ftau = std::fabs(tau);
228 if(ftau < n1pars[0])
continue;
229 if(ftau > n1pars[1])
continue;
231 if(ftau < n2pars[0])
continue;
232 if(ftau > n2pars[1])
continue;
236 float z0 = z1 - r1*tau;
238 if(z0 < min_z0 || z0 > max_z0)
continue;
240 float zouter = z0 + maxOuterRadius*tau;
242 if(zouter < cut_zMinU || zouter > cut_zMaxU)
continue;
245 float curv = (phi2-phi1)/dr;
246 float abs_curv = std::abs(curv);
249 if(abs_curv > maxKappa_low_eta) {
254 if(abs_curv > maxKappa_high_eta) {
259 float exp_eta = std::sqrt(1.f+tau*tau)-tau;
263 bool isGood = v2In.size() <= 2;
267 float uat_1 = 1.0f/exp_eta;
269 for(
const auto& n2_in_idx : v2In) {
271 float tau2 = edgeStorage.at(n2_in_idx).m_p[0];
272 float tau_ratio = tau2*uat_1 - 1.0f;
274 if(std::fabs(tau_ratio) > tau_ratio_precut){
287 float dPhi2 = curv*r2;
288 float dPhi1 = curv*r1;
292 edgeStorage.emplace_back(B1.
m_vn[n1Idx], B2.
m_vn[n2Idx], exp_eta, curv, phi1 + dPhi1);
296 int outEdgeIdx = nEdges;
298 float uat_2 = 1.f/exp_eta;
299 float Phi2 = phi2 + dPhi2;
302 for(
const auto& inEdgeIdx : v2In) {
308 float tau_ratio = pS->
m_p[0]*uat_2 - 1.0f;
310 if(std::abs(tau_ratio) > cut_tau_ratio_max){
314 float dPhi = Phi2 - pS->
m_p[2];
319 if(std::abs(dPhi) > cut_dphi_max) {
323 float dcurv = curv2 - pS->
m_p[1];
325 if(dcurv < -cut_dcurv_max || dcurv > cut_dcurv_max) {
342 ATH_MSG_WARNING(
"Maximum number of graph edges exceeded - possible efficiency loss "<< nEdges);
345 return std::make_pair(nEdges, nConnections);
350 constexpr int maxIter = 15;
356 std::vector<TrigFTF_GNN_Edge*> v_old;
358 for(
int edgeIndex=0;edgeIndex<nEdges;edgeIndex++) {
361 if(pS->
m_nNei == 0)
continue;
366 std::vector<TrigFTF_GNN_Edge*> v_new;
367 v_new.reserve(v_old.size());
369 for(;iter<maxIter;iter++) {
374 for(
auto pS : v_old) {
376 int next_level = pS->m_level;
378 for(
int nIdx=0;nIdx<pS->m_nNei;nIdx++) {
380 unsigned int nextEdgeIdx = pS->m_vNei[nIdx];
384 if(pS->m_level == pN->
m_level) {
385 next_level = pS->m_level + 1;
391 pS->m_next = next_level;
398 for(
auto pS : v_new) {
399 if(pS->m_next != pS->m_level) {
401 pS->m_level = pS->m_next;
402 if(maxLevel < pS->m_level) maxLevel = pS->m_level;
406 if(nChanges == 0)
break;
418 const float edge_mask_min_eta = 1.5;
419 const float hit_share_threshold = 0.49;
421 vSeedCandidates.clear();
429 if(maxLevel < minLevel)
return;
431 std::vector<GNN_Edge*> vSeeds;
433 vSeeds.reserve(nEdges/2);
435 for(
int edgeIndex = 0; edgeIndex < nEdges; edgeIndex++) {
437 GNN_Edge* pS = &(edgeStorage.at(edgeIndex));
439 if(pS->
m_level < minLevel)
continue;
441 vSeeds.push_back(pS);
444 if(vSeeds.empty())
return;
450 vSeedCandidates.reserve(vSeeds.size());
452 auto tFilter = std::make_unique<TrigFTF_GNN_TrackingFilter>(
m_layerGeometry, edgeStorage);
454 for(
auto pS : vSeeds) {
456 if(pS->m_level == -1)
continue;
460 tFilter->followTrack(pS,
rs);
462 if(!
rs.m_initialized) {
466 if(
static_cast<int>(
rs.m_vs.size()) < minLevel)
continue;
468 float seed_eta = std::abs(-std::log(pS->m_p[0]));
470 std::vector<const GNN_Node*> vN;
472 for(std::vector<GNN_Edge*>::reverse_iterator sIt=
rs.m_vs.rbegin();sIt!=
rs.m_vs.rend();++sIt) {
474 if (seed_eta > edge_mask_min_eta) {
475 (*sIt)->m_level = -1;
478 if(sIt ==
rs.m_vs.rbegin()) {
479 vN.push_back((*sIt)->m_n1);
482 vN.push_back((*sIt)->m_n2);
486 if(vN.size()<3)
continue;
488 std::vector<unsigned int> vSpIdx;
490 vSpIdx.resize(vN.size());
492 for(
unsigned int k = 0; k < vN.size(); k++) {
493 vSpIdx[k] = vN[k]->sp_idx();
496 vSeedCandidates.emplace_back(-
rs.m_J/vN.size(), 0, vSpIdx);
502 std::sort(vSeedCandidates.begin(), vSeedCandidates.end());
504 std::vector<int> vTrackIds(vSeedCandidates.size());
508 std::iota(vTrackIds.begin(), vTrackIds.end(), 1);
510 std::vector<int> H2T(
nHits + 1, 0);
514 for(
const auto& seed : vSeedCandidates) {
516 for(
const auto&
h : std::get<2>(seed) ) {
518 unsigned int hit_id =
h + 1;
520 int tid = H2T[hit_id];
521 int trackId = vTrackIds[seedIdx];
523 if(tid == 0 || tid > trackId) {
525 H2T[hit_id] = trackId;
534 for(
unsigned int trackIdx = 0; trackIdx < vSeedCandidates.size(); trackIdx++) {
536 int nTotal = std::get<2>(vSeedCandidates[trackIdx]).size();
539 int trackId = vTrackIds[trackIdx];
541 for(
const auto&
h : std::get<2>(vSeedCandidates[trackIdx]) ) {
543 unsigned int hit_id =
h + 1;
545 int tid = H2T[hit_id];
552 if (nOther > hit_share_threshold*nTotal) {
553 std::get<1>(vSeedCandidates[trackIdx]) = -1;
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
static const uint32_t nHits
This is an Identifier helper class for the Pixel subdetector.
This is an Identifier helper class for the SCT subdetector.
const ServiceHandle< StoreGateSvc > & detStore() const
Header file for AthHistogramAlgorithm.
Describes the API of the Region of Ineterest geometry.
virtual double zedPlus() const =0
the zed and eta values at the most forward and most rear ends of the RoI
virtual double dzdrMinus() const =0
return the gradients
virtual double zedMinus() const =0
virtual double dzdrPlus() const =0
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
unsigned int m_vNei[N_SEG_CONNS]
std::vector< const TrigFTF_GNN_Node * > m_vn
float getMinBinRadius() const
float getMaxBinRadius() const
std::vector< std::vector< unsigned int > > m_in
std::vector< std::pair< float, unsigned int > > m_vPhiNodes
std::vector< std::array< float, 5 > > m_params
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.