1031 {
1032
1033
1034 struct ProtoSeed {
1035 public:
1036 ProtoSeed(
const TrigSiSpacePointBase* s,
double c,
double Q,
bool conf =
false) : m_sp(
s), m_curv(
c), m_Q(Q), m_confirmed(
conf) {};
1037 ProtoSeed(
const ProtoSeed& ps) : m_sp(
ps.m_sp), m_curv(
ps.m_curv), m_Q(
ps.m_Q), m_confirmed(
ps.m_confirmed) {};
1038 const TrigSiSpacePointBase* m_sp;
1039 double m_curv, m_Q;
1040 bool m_confirmed;
1041 };
1042
1043 if(nInner==0 || nOuter==0) return;
1044
1047
1048
1049 int nSP = nInner + nOuter;
1050
1051 const double pS_r = pS->
r();
1052 const double pS_x = pS->
x();
1053 const double pS_y = pS->
y();
1054 const double pS_dr = pS->
dr();
1055 const double pS_dz = pS->
dz();
1056 const double cosA = pS_x/pS_r;
1057 const double sinA = pS_y/pS_r;
1058 const double covZ = pS_dz*pS_dz;
1059 const double covR = pS_dr*pS_dr;
1060 const bool isPixel = pS->
isPixel();
1061
1062
1063 double bestQ = 1e8;
1064
1065
1066 int idx = 0;
1067 for(;idx<nInner;idx++) {
1068 const TrigSiSpacePointBase* pSP = m_SoA.m_spi[idx];
1069
1070
1071
1072 const double dx = pSP->x() - pS_x;
1073 const double dy = pSP->y() - pS_y;
1074 const double R2inv = 1.0/(dx*dx+dy*dy);
1075 const double Rinv = std::sqrt(R2inv);
1076 const double xn = dx*cosA + dy*sinA;
1077 const double yn =-dx*sinA + dy*cosA;
1078 const double dz = pSP->z() - pS->z();
1079 const double t = Rinv*dz;
1080
1081
1082
1083 m_SoA.m_r[idx] = Rinv;
1084 m_SoA.m_u[idx] = xn*R2inv;
1085 m_SoA.m_v[idx] = yn*R2inv;
1086
1087
1088
1089 const double covZP = pSP->dz()*pSP->dz();
1090 const double covRP = pSP->dr()*pSP->dr();
1091
1092 m_SoA.m_t[idx] = t;
1093 m_SoA.m_tCov[idx] = R2inv*(covZ + covZP + t*t*(covR+covRP));
1094 }
1095
1096 for(int k=0;k<nOuter;k++,idx++) {
1097 const TrigSiSpacePointBase* pSP = m_SoA.m_spo[k];
1098
1099
1100
1101 const double dx = pSP->x() - pS_x;
1102 const double dy = pSP->y() - pS_y;
1103 const double R2inv = 1.0/(dx*dx+dy*dy);
1104 const double Rinv = std::sqrt(R2inv);
1105 const double xn = dx*cosA + dy*sinA;
1106 const double yn =-dx*sinA + dy*cosA;
1107 const double dz = -pSP->z() + pS->z();
1108 const double t = Rinv*dz;
1109
1110
1111
1112 m_SoA.m_r[idx] = Rinv;
1113 m_SoA.m_u[idx] = xn*R2inv;
1114 m_SoA.m_v[idx] = yn*R2inv;
1115
1116
1117
1118 const double covZP = pSP->dz()*pSP->dz();
1119 const double covRP = pSP->dr()*pSP->dr();
1120
1121 m_SoA.m_t[idx] = t;
1122 m_SoA.m_tCov[idx] = R2inv*(covZ + covZP + t*t*(covR+covRP));
1123 }
1124
1125
1126
1127 for(int innIdx=0;innIdx<nInner;innIdx++) {
1128
1129
1130
1131 const double r_inn = m_SoA.m_r[innIdx];
1132 const double t_inn = m_SoA.m_t[innIdx];
1133 const double v_inn = m_SoA.m_v[innIdx];
1134 const double u_inn = m_SoA.m_u[innIdx];
1135 const double tCov_inn = m_SoA.m_tCov[innIdx];
1136 const double dCov = m_CovMS*(1+t_inn*t_inn);
1137
1138 std::vector<ProtoSeed> vPro;
1139 vPro.reserve(100);
1140
1141 for(int outIdx=nInner;outIdx<nSP;outIdx++) {
1142
1143
1144 const double t_out = m_SoA.m_t[outIdx];
1145
1146 const double dt2 = std::pow((t_inn - t_out), 2)*(1.0/9.0);
1147
1148
1149 double covdt = (t_inn*t_out*covR + covZ);
1150 covdt *= 2*r_inn*m_SoA.m_r[outIdx];
1151 covdt += tCov_inn + m_SoA.m_tCov[outIdx];
1152
1153 if(dt2 > covdt+dCov) continue;
1154
1155
1156
1157 const double du = m_SoA.m_u[outIdx] - u_inn;
1158 if(du==0.0) continue;
1159 const double A = (m_SoA.m_v[outIdx] - v_inn)/du;
1160 const double B = v_inn - A*u_inn;
1161 const double R_squ = (1 + A*A)/(B*B);
1162
1163 if(R_squ < m_minR_squ) continue;
1164
1165
1166
1167
1168 const double frac = m_minR_squ/R_squ;
1169 if(dt2 > covdt+frac*dCov) continue;
1170
1171
1172
1173 const double fabs_d0 = std::fabs(pS_r*(B*pS_r - A));
1174
1175 if(fabs_d0 > m_settings.m_tripletD0Max) continue;
1176
1177 if (m_SoA.m_spo[outIdx-nInner]->isSCT() && isPixel) {
1178 if(fabs_d0 > m_settings.m_tripletD0_PPS_Max) continue;
1179 }
1180
1181
1182
1183 const double Q= (m_settings.m_LRTmode ? 0 : fabs_d0*fabs_d0);
1184
1185 bool isOuterPixel = m_SoA.m_spo[outIdx-nInner]->isPixel();
1186
1187 if(!m_settings.m_LRTmode) {
1188 if (isOuterPixel && (bestQ < Q)) continue;
1189 }
1190
1191
1192
1193 if ( !fullPhi ) {
1194 const double uc = 2*B*pS_r - A;
1195 const double phi0 = atan2(sinA - uc*cosA, cosA + uc*sinA);
1196
1197 if ( !RoiUtil::containsPhi( *roiDescriptor, phi0 ) ) {
1198 continue;
1199 }
1200 }
1201
1202
1203
1204 const double Curv = B/std::sqrt(1+A*A);
1205
1206
1207 bool isConfirmed = false;
1208
1209 for(auto& ps : vPro) {
1210 double diffC = 1 - Curv/ps.m_curv;
1211 if(std::fabs(diffC) < m_settings.m_curv_delta) {
1212 ps.m_confirmed = true;
1213 isConfirmed = true;
1214 }
1215 }
1216
1217 if(!isOuterPixel) {
1218 continue;
1219 }
1220
1221 vPro.emplace_back(ProtoSeed(m_SoA.m_spo[outIdx-nInner], Curv, Q, isConfirmed));
1222
1223 }
1224
1225 for(const auto& ps : vPro) {
1226 if(!ps.m_confirmed) continue;
1227 if(output.size()>=m_settings.m_maxTripletBufferLength) {
1228 if (m_settings.m_LRTmode) {
1229 continue;
1230 }
1231 else {
1232
1233 std::sort(output.begin(), output.end(),
1234 [](const TrigInDetTriplet& A, const TrigInDetTriplet& B) {
1235 return A.Q() < B.Q();
1236 }
1237 );
1238 double QL = output.back().Q();
1239 if(bestQ > QL) {
1240 bestQ = QL;
1241 }
1242 if( ps.m_Q >= QL) {
1243 continue;
1244 }
1245 output.pop_back();
1246 }
1247 }
1248
1250 }
1251 }
1252}
virtual bool isFullscan() const =0
is this a full detector RoI?
virtual double phiPlus() const =0
extreme phi values
virtual double phiMinus() const =0