34 const double ptCoeff = 0.29997*1.9972/2.0;
47 for(std::vector<TrigSiSpacePointBase>::const_iterator
it = vSP.begin();
it != vSP.end();++
it) {
49 bool isPixel = (*it).isPixel();
51 if(!isPixel)
continue;
62 const int MaxEdges = 2000000;
64 const float cut_dphi_max = 0.012;
65 const float cut_dcurv_max = 0.001;
66 const float cut_tau_ratio_max = 0.007;
67 const float min_z0 = roiDescriptor->
zedMinus();
68 const float max_z0 = roiDescriptor->
zedPlus();
70 const float maxOuterRadius = 550.0;
71 const float cut_zMinU = min_z0 + maxOuterRadius*roiDescriptor->
dzdrMinus();
72 const float cut_zMaxU = max_z0 + maxOuterRadius*roiDescriptor->
dzdrPlus();
74 const float maxKappa_high_eta = 0.8/
m_minR_squ;
83 std::vector<TrigFTF_GNN_Edge> edgeStorage;
85 edgeStorage.reserve(MaxEdges);
89 for(std::map<
int, std::vector<FASTRACK_CONNECTOR::LayerGroup> >::const_iterator
it =
conn.m_layerGroups.begin();
it!=
conn.m_layerGroups.end();++
it, currentStage++) {
105 unsigned int src =
conn->m_src;
113 int nDstBins = pL1->
m_bins.size();
114 int nSrcBins = pL2->
m_bins.size();
116 for(
int b1=0;b1<nDstBins;b1++) {
120 if(B1.
empty())
continue;
126 for(
int b2=0;b2<nSrcBins;b2++) {
129 if(
conn->m_binTable[b1 + b2*nDstBins] != 1)
continue;
134 if(B2.
empty())
continue;
146 unsigned int first_it = 0;
148 for(std::vector<TrigFTF_GNN_Node*>::const_iterator n1It = B1.
m_vn.begin();n1It!=B1.
m_vn.end();++n1It) {
154 float phi1 =
n1->m_sp.phi();
155 float r1 =
n1->m_sp.r();
156 float x1 =
n1->m_sp.x();
157 float y1 =
n1->m_sp.y();
158 float z1 =
n1->m_sp.z();
165 for(
unsigned int n2PhiIdx = first_it; n2PhiIdx<B2.
m_vPhiNodes.size();n2PhiIdx++) {
173 if(phi2 > maxPhi)
break;
178 if(n2->
isFull())
continue;
180 float r2 = n2->
m_sp.
r();
187 float z2 = n2->
m_sp.
z();
191 float ftau = std::fabs(tau);
196 if(ftau < n1->m_minCutOnTau)
continue;
197 if(ftau < n2->m_minCutOnTau)
continue;
198 if(ftau >
n1->m_maxCutOnTau)
continue;
203 float z0 = z1 - r1*tau;
205 if(z0 < min_z0 || z0 > max_z0)
continue;
207 float zouter =
z0 + maxOuterRadius*tau;
209 if(zouter < cut_zMinU || zouter > cut_zMaxU)
continue;
219 float kappa = D*D*
L2;
222 if(kappa > maxKappa_low_eta) {
228 if(kappa > maxKappa_high_eta) {
235 float exp_eta = std::sqrt(1+tau*tau)-tau;
237 bool isGood = n2->
m_in.size() <= 2;
241 float uat_1 = 1.0f/exp_eta;
243 for(
const auto& n2_in_idx : n2->
m_in) {
244 float tau2 = edgeStorage.at(n2_in_idx).m_p[0];
245 float tau_ratio = tau2*uat_1 - 1.0f;
247 if(std::fabs(tau_ratio) > cut_tau_ratio_max){
254 if(!isGood)
continue;
256 float curv = D*std::sqrt(
L2);
257 float dPhi2 = std::asin(curv*r2);
258 float dPhi1 = std::asin(curv*r1);
260 if(nEdges < MaxEdges) {
262 edgeStorage.emplace_back(
n1, n2, exp_eta, curv, phi1 + dPhi1, phi2 + dPhi2);
277 std::vector<const TrigFTF_GNN_Node*> vNodes;
281 if(vNodes.empty())
return;
283 int nNodes = vNodes.size();
285 for(
int nodeIdx=0;nodeIdx<nNodes;nodeIdx++) {
289 std::vector<std::pair<float, int > > in_sort, out_sort;
290 in_sort.resize(pN->
m_in.size());
291 out_sort.resize(pN->
m_out.size());
293 for(
int inIdx = 0;inIdx<static_cast<int>(pN->
m_in.size());inIdx++) {
294 int inEdgeIdx = pN->
m_in.at(inIdx);
296 in_sort[inIdx].second = inEdgeIdx;
297 in_sort[inIdx].first = pS->
m_p[0];
299 for(
int outIdx = 0;outIdx<static_cast<int>(pN->
m_out.size());outIdx++) {
300 int outEdgeIdx = pN->
m_out.at(outIdx);
302 out_sort[outIdx].second = outEdgeIdx;
303 out_sort[outIdx].first = pS->
m_p[0];
306 std::sort(in_sort.begin(), in_sort.end());
307 std::sort(out_sort.begin(), out_sort.end());
309 unsigned int last_out = 0;
311 for(
unsigned int in_idx=0;in_idx<in_sort.size();in_idx++) {
313 int inEdgeIdx = in_sort[in_idx].second;
318 float tau1 = pS->
m_p[0];
319 float uat_1 = 1.0f/tau1;
320 float curv1 = pS->
m_p[1];
321 float Phi1 = pS->
m_p[2];
323 for(
unsigned int out_idx = last_out;out_idx<out_sort.size();out_idx++) {
325 int outEdgeIdx = out_sort[out_idx].second;
330 float tau2 = pNS->
m_p[0];
331 float tau_ratio = tau2*uat_1 - 1.0f;
333 if(tau_ratio < -cut_tau_ratio_max) {
337 if(tau_ratio > cut_tau_ratio_max)
break;
340 float dPhi = pNS->
m_p[3] - Phi1;
345 if(dPhi < -cut_dphi_max || dPhi > cut_dphi_max) {
349 float curv2 = pNS->
m_p[1];
350 float dcurv = curv2-curv1;
352 if(dcurv < -cut_dcurv_max || dcurv > cut_dcurv_max) {
363 const int maxIter = 15;
370 std::vector<TrigFTF_GNN_Edge*> v_old;
372 for(
int edgeIndex=0;edgeIndex<nEdges;edgeIndex++) {
375 if(pS->
m_nNei == 0)
continue;
379 for(;iter<maxIter;iter++) {
383 std::vector<TrigFTF_GNN_Edge*> v_new;
386 for(
auto pS : v_old) {
388 int next_level = pS->m_level;
390 for(
int nIdx=0;nIdx<pS->m_nNei;nIdx++) {
392 unsigned int nextEdgeIdx = pS->m_vNei[nIdx];
396 if(pS->m_level == pN->
m_level) {
403 pS->m_next = next_level;
410 for(
auto pS : v_new) {
411 if(pS->m_next != pS->m_level) {
413 pS->m_level = pS->m_next;
414 if(maxLevel < pS->m_level) maxLevel = pS->m_level;
418 if(nChanges == 0)
break;
421 v_old = std::move(v_new);
429 std::vector<TrigFTF_GNN_Edge*> vSeeds;
431 vSeeds.reserve(MaxEdges/2);
433 for(
int edgeIndex=0;edgeIndex<nEdges;edgeIndex++) {
436 if(pS->
m_level < minLevel)
continue;
438 vSeeds.push_back(pS);
445 if(vSeeds.empty())
return;
451 for(
auto pS : vSeeds) {
453 if(pS->m_level == -1)
continue;
457 tFilter.followTrack(pS, rs);
463 if(
static_cast<int>(rs.
m_vs.size()) < minLevel)
continue;
465 std::vector<const TrigSiSpacePointBase*> vSP;
467 for(std::vector<TrigFTF_GNN_Edge*>::reverse_iterator sIt=rs.
m_vs.rbegin();sIt!=rs.
m_vs.rend();++sIt) {
469 (*sIt)->m_level = -1;
471 if(sIt == rs.
m_vs.rbegin()) {
472 vSP.push_back(&(*sIt)->m_n1->m_sp);
474 vSP.push_back(&(*sIt)->m_n2->m_sp);
477 if(vSP.size()<3)
continue;
481 unsigned int nTriplets = 0;
483 std::vector<TrigInDetTriplet>
output;
487 for(
unsigned int idx_m = 1;idx_m < vSP.size()-1;idx_m++) {
490 const double pS_r = spM.
r();
491 const double pS_x = spM.
x();
492 const double pS_y = spM.
y();
493 const double cosA = pS_x/pS_r;
494 const double sinA = pS_y/pS_r;
496 for(
unsigned int idx_o = idx_m+1; idx_o < vSP.size(); idx_o++) {
500 double dx = spO.
x() - pS_x;
501 double dy = spO.
y() - pS_y;
503 double xn =
dx*cosA +
dy*sinA;
504 double yn =-
dx*sinA +
dy*cosA;
506 const double uo = xn*R2inv;
507 const double vo = yn*R2inv;
509 for(
unsigned int idx_i = 0; idx_i < idx_m; idx_i++) {
516 xn =
dx*cosA +
dy*sinA;
517 yn =-
dx*sinA +
dy*cosA;
519 const double ui = xn*R2inv;
520 const double vi = yn*R2inv;
524 const double du = uo - ui;
525 if(du==0.0)
continue;
526 const double A = (vo - vi)/du;
527 const double B = vi -
A*ui;
529 const double R_squ = (1 +
A*
A)/(
B*
B);
537 const double fabs_d0 = std::abs(pS_r*(
B*pS_r -
A));
546 const double uc = 2*
B*pS_r -
A;
547 const double phi0 = std::atan2(sinA - uc*cosA, cosA + uc*sinA);
555 const double Q = fabs_d0*fabs_d0;
557 output.emplace_back(spI, spM, spO, Q);
567 if(
output.empty())
continue;
570 vTracks.emplace_back(vSP,
output);
577 std::vector<GNN_TrigTracklet> vTracks;
579 vTracks.reserve(5000);
583 if(vTracks.empty())
return;
587 for(
auto&
track : vTracks) {
588 for(
auto& seed :
track.m_seeds) {
590 float newQ = seed.Q();
594 if(seed.s1().isPixel()) newQ+=1000;
595 if(seed.s2().isPixel()) newQ+=1000;
596 if(seed.s3().isPixel()) newQ+=1000;
599 if(seed.s3().isSCT()) {
600 newQ += seed.s1().isSCT() ? 1000.0 : 10000.0;
624 return A.Q() < B.Q();