72 const int MaxEdges = 2000000;
83 const float cut_zMinU = min_z0 + maxOuterRadius*roiDescriptor->
dzdrMinus();
84 const float cut_zMaxU = max_z0 + maxOuterRadius*roiDescriptor->
dzdrPlus();
94 unsigned int nConnections = 0;
98 std::vector<TrigFTF_GNN_Edge> edgeStorage;
100 edgeStorage.reserve(MaxEdges);
104 for(std::map<
int, std::vector<FASTRACK_CONNECTOR::LayerGroup> >::const_iterator
it =
conn.m_layerGroups.begin();
it!=
conn.m_layerGroups.end();++
it, currentStage++) {
120 unsigned int src =
conn->m_src;
128 int nDstBins = pL1->
m_bins.size();
129 int nSrcBins = pL2->
m_bins.size();
131 for(
int b1=0;b1<nDstBins;b1++) {
135 if(B1.
empty())
continue;
141 for(
int b2=0;b2<nSrcBins;b2++) {
144 if(
conn->m_binTable[b1 + b2*nDstBins] != 1)
continue;
149 if(B2.
empty())
continue;
159 unsigned int first_it = 0;
161 for(
unsigned int n1Idx = 0;n1Idx<B1.
m_vn.size();n1Idx++) {
165 const std::array<float, 5>& n1pars = B1.
m_params[n1Idx];
167 float phi1 = n1pars[2];
168 float r1 = n1pars[3];
169 float z1 = n1pars[4];
176 for(
unsigned int n2PhiIdx = first_it; n2PhiIdx<B2.
m_vPhiNodes.size();n2PhiIdx++) {
184 if(phi2 > maxPhi)
break;
186 unsigned int n2Idx = B2.
m_vPhiNodes[n2PhiIdx].second;
188 const std::vector<unsigned int>& v2In = B2.
m_in[n2Idx];
189 const std::array<float, 5>& n2pars = B2.
m_params[n2Idx];
193 float r2 = n2pars[3];
201 float z2 = n2pars[4];
205 float ftau = std::fabs(tau);
210 if(ftau < n1pars[0])
continue;
211 if(ftau < n2pars[0])
continue;
212 if(ftau > n1pars[1])
continue;
213 if(ftau > n2pars[1])
continue;
217 float z0 = z1 -
r1*tau;
219 if(z0 < min_z0 || z0 > max_z0)
continue;
221 float zouter =
z0 + maxOuterRadius*tau;
223 if(zouter < cut_zMinU || zouter > cut_zMaxU)
continue;
226 float curv = (phi2-phi1)/
dr;
227 float abs_curv = std::abs(curv);
230 if(abs_curv > maxKappa_low_eta) {
236 if(abs_curv > maxKappa_high_eta) {
243 float exp_eta = std::sqrt(1+tau*tau)-tau;
245 bool isGood = v2In.size() <= 2;
249 float uat_1 = 1.0f/exp_eta;
251 for(
const auto& n2_in_idx : v2In) {
253 float tau2 = edgeStorage.at(n2_in_idx).m_p[0];
254 float tau_ratio = tau2*uat_1 - 1.0f;
256 if(std::fabs(tau_ratio) > cut_tau_ratio_max){
263 if(!isGood)
continue;
265 float dPhi2 = curv*
r2;
266 float dPhi1 = curv*
r1;
268 if(nEdges < MaxEdges) {
270 edgeStorage.emplace_back(B1.
m_vn[n1Idx], B2.
m_vn[n2Idx], exp_eta, curv, phi1 + dPhi1);
272 std::vector<unsigned int>& v1In = B1.
m_in[n1Idx];
276 int outEdgeIdx = nEdges;
278 float uat_2 = 1/exp_eta;
279 float Phi2 = phi2 + dPhi2;
282 for(
const auto& inEdgeIdx : v2In) {
288 float tau_ratio = pS->
m_p[0]*uat_2 - 1.0f;
290 if(std::abs(tau_ratio) > cut_tau_ratio_max){
294 float dPhi = Phi2 - pS->
m_p[2];
299 if(dPhi < -cut_dphi_max || dPhi > cut_dphi_max) {
303 float dcurv = curv2 - pS->
m_p[1];
305 if(dcurv < -cut_dcurv_max || dcurv > cut_dcurv_max) {
323 if(nConnections == 0)
return;
325 const int maxIter = 15;
331 std::vector<TrigFTF_GNN_Edge*> v_old;
333 for(
int edgeIndex=0;edgeIndex<nEdges;edgeIndex++) {
336 if(pS->
m_nNei == 0)
continue;
340 for(;iter<maxIter;iter++) {
343 std::vector<TrigFTF_GNN_Edge*> v_new;
346 for(
auto pS : v_old) {
350 for(
int nIdx=0;nIdx<pS->
m_nNei;nIdx++) {
352 unsigned int nextEdgeIdx = pS->
m_vNei[nIdx];
370 for(
auto pS : v_new) {
374 if(maxLevel < pS->m_level) maxLevel = pS->
m_level;
378 if(nChanges == 0)
break;
381 v_old = std::move(v_new);
393 std::vector<TrigFTF_GNN_Edge*> vSeeds;
395 vSeeds.reserve(MaxEdges/2);
397 for(
int edgeIndex=0;edgeIndex<nEdges;edgeIndex++) {
400 if(pS->
m_level < minLevel)
continue;
402 vSeeds.push_back(pS);
409 if(vSeeds.empty())
return;
415 for(
auto pS : vSeeds) {
417 if(pS->
m_level == -1)
continue;
421 tFilter.followTrack(pS, rs);
423 if(!rs.m_initialized) {
427 if(
static_cast<int>(rs.m_vs.size()) < minLevel)
continue;
429 std::vector<const TrigSiSpacePointBase*> vSP;
431 for(std::vector<TrigFTF_GNN_Edge*>::reverse_iterator sIt=rs.m_vs.rbegin();sIt!=rs.m_vs.rend();++sIt) {
433 (*sIt)->m_level = -1;
435 if(sIt == rs.m_vs.rbegin()) {
436 vSP.push_back((*sIt)->m_n1);
438 vSP.push_back((*sIt)->m_n2);
441 if(vSP.size()<3)
continue;
445 unsigned int nTriplets = 0;
447 std::vector<TrigInDetTriplet>
output;
453 for(
unsigned int idx_m = 1;idx_m < vSP.size()-1;idx_m++) {
456 const double pS_r = spM.
r();
457 const double pS_x = spM.
x();
458 const double pS_y = spM.
y();
459 const double cosA = pS_x/pS_r;
460 const double sinA = pS_y/pS_r;
462 for(
unsigned int idx_o = idx_m+1; idx_o < vSP.size(); idx_o++) {
466 double dx = spO.
x() - pS_x;
467 double dy = spO.
y() - pS_y;
469 double xn =
dx*cosA +
dy*sinA;
470 double yn =-
dx*sinA +
dy*cosA;
472 const double uo = xn*R2inv;
473 const double vo = yn*R2inv;
475 for(
unsigned int idx_i = 0; idx_i < idx_m; idx_i++) {
482 xn =
dx*cosA +
dy*sinA;
483 yn =-
dx*sinA +
dy*cosA;
485 const double ui = xn*R2inv;
486 const double vi = yn*R2inv;
490 const double du = uo - ui;
491 if(du==0.0)
continue;
492 const double A = (vo - vi)/du;
493 const double B = vi -
A*ui;
495 const double triplet_curv2 =
B*
B/(1 +
A*
A);
497 if(triplet_curv2 > maxCurv2) {
503 const double fabs_d0 = std::abs(pS_r*(
B*pS_r -
A));
512 const double uc = 2*
B*pS_r -
A;
513 const double phi0 = std::atan2(sinA - uc*cosA, cosA + uc*sinA);
521 const double Q = fabs_d0*fabs_d0;
523 output.emplace_back(spI, spM, spO, Q);
533 if(
output.empty())
continue;
536 vTracks.emplace_back(vSP,
output);