29 KFbase::KFbase(
const Settings *settings,
const uint nHelixPar,
const string &fitterName,
const uint nMeas)
30 : TrackFitGeneric(settings, fitterName) {
31 nHelixPar_ = nHelixPar;
44 vector<Stub *> stubs = l1track3D.
stubs();
46 auto orderByLayer = [](
const Stub *
a,
const Stub *
b) {
return bool(
a->layerId() <
b->layerId()); };
47 sort(stubs.begin(), stubs.end(), orderByLayer);
50 const TP *tpa(
nullptr);
58 PrintL1trk() <<
"===============================================================================";
59 std::stringstream
text;
61 text <<
"Input track cand: [phiSec,etaReg]=[" << l1track3D.
iPhiSec() <<
"," << l1track3D.
iEtaReg() <<
"]";
63 <<
") q/pt=" << l1track3D.
qOverPt() <<
" tanL=" << l1track3D.
tanLambda() <<
" z0=" << l1track3D.
z0()
64 <<
" phi0=" << l1track3D.
phi0() <<
" nStubs=" << l1track3D.
numStubs() <<
" d0=" << l1track3D.
d0();
78 if (
cand !=
nullptr) {
103 double chi2rphi_bcon = 0.;
109 bool accepted =
true;
110 if (chi2scaled > kfLayerVsChiSqCut[
cand->nStubLayers()])
113 fitTrk.setBeamConstr(trackPars_bcon[
QOVERPT], trackPars_bcon[
PHI0], chi2rphi_bcon, accepted);
122 fitTrk.digitizeTrack(
"KF4ParamsComb");
124 if (!fitTrk.consistentSector()) {
126 PrintL1trk() <<
"Track rejected by sector consistency test";
137 bool goodTrack = (tpa && tpa->useForAlgEff());
139 int tpin = tpa->index();
140 PrintL1trk() <<
"TRACK LOST: eta=" << l1track3D.
iEtaReg() <<
" pt=" << l1track3D.
pt() <<
" tp=" << tpin;
142 for (
auto stub : stubs) {
144 this->
kalmanLayer(l1track3D.
iEtaReg(), stub->layerIdReduced(), stub->barrel(), stub->r(), stub->z());
145 std::stringstream
text;
147 text <<
" Stub: lay_red=" << stub->layerIdReduced() <<
" KFlay=" << kalmanLay <<
" r=" << stub->r()
148 <<
" z=" << stub->z() <<
" assoc TPs =";
149 for (
const TP *tp_i : stub->assocTPs())
150 text <<
" " << tp_i->index();
152 if (stub->assocTPs().empty())
161 if (tpa && tpa->useForAlgEff()) {
162 PrintL1trk() <<
"TP for eff. missed addr. index : " << tpa <<
" " << tpa->index();
177 map<unsigned int, const KalmanState *, std::greater<unsigned int>>
178 best_state_by_nstubs;
181 TVectorD x0 =
seedX(l1track3D);
182 TMatrixD pxx0 =
seedC(l1track3D);
186 const KalmanState *state0 =
mkState(l1track3D, 0, -1,
nullptr, x0, pxx0, K, dcov,
nullptr, 0, 0);
189 vector<const KalmanState *> new_states;
190 vector<const KalmanState *> prev_states;
191 prev_states.push_back(state0);
198 int etaReg = l1track3D.
iEtaReg();
199 map<int, vector<Stub *>> layerStubs;
201 for (
auto stub : stubs) {
203 int kalmanLay = this->
kalmanLayer(etaReg, stub->layerIdReduced(), stub->barrel(), stub->r(), stub->z());
205 constexpr
unsigned int invalidKFlayer = 7;
206 if (kalmanLay != invalidKFlayer) {
208 layerStubs[kalmanLay].push_back(stub);
211 layerStubs[kalmanLay].back() = stub;
217 constexpr
unsigned int nTypicalLayers = 6;
221 int combinations_per_iteration = 0;
224 unsigned int kalmanMaxSkipLayers =
228 vector<const KalmanState *>::const_iterator i_state = prev_states.begin();
229 for (; i_state != prev_states.end(); i_state++) {
239 unsigned nSkippedDeadLayers = 0;
240 unsigned nSkippedAmbiguousLayers = 0;
241 while (kfDeadLayers.find(
layer) != kfDeadLayers.end() && layerStubs[
layer].empty()) {
243 ++nSkippedDeadLayers;
247 ++nSkippedAmbiguousLayers;
251 vector<const KalmanState *> next_states;
252 vector<const KalmanState *> next_states_skipped;
256 vector<Stub *> thislay_stubs = layerStubs[
layer];
260 vector<Stub *> nextlay_stubs;
264 unsigned nSkippedDeadLayers_nextStubs = 0;
265 unsigned nSkippedAmbiguousLayers_nextStubs = 0;
266 if (nSkipped < kalmanMaxSkipLayers) {
267 if (kfDeadLayers.find(
layer + 1) != kfDeadLayers.end() && layerStubs[
layer + 1].empty()) {
268 nextlay_stubs = layerStubs[
layer + 2];
269 nSkippedDeadLayers_nextStubs++;
271 nextlay_stubs = layerStubs[
layer + 2];
272 nSkippedAmbiguousLayers_nextStubs++;
274 nextlay_stubs = layerStubs[
layer + 1];
281 nextlay_stubs.empty())
283 <<
" : #thislay_stubs=" << thislay_stubs.size() <<
" #nextlay_stubs=" << nextlay_stubs.size()
284 <<
" layer=" <<
layer <<
" eta=" << l1track3D.
iEtaReg();
287 nSkipped += nSkippedDeadLayers;
288 nSkipped += nSkippedAmbiguousLayers;
294 vector<Stub *> temp_thislaystubs;
295 vector<Stub *> temp_nextlaystubs;
296 for (
auto stub : thislay_stubs) {
297 if (stub->psModule())
298 temp_thislaystubs.push_back(stub);
300 for (
auto stub : nextlay_stubs) {
301 if (stub->psModule())
302 temp_nextlaystubs.push_back(stub);
304 thislay_stubs = temp_thislaystubs;
305 nextlay_stubs = temp_nextlaystubs;
308 combinations_per_iteration += thislay_stubs.size() + nextlay_stubs.size();
311 for (
unsigned i = 0;
i < thislay_stubs.size();
i++) {
312 Stub *stub = thislay_stubs[
i];
319 next_states.push_back(new_state);
323 for (
unsigned i = 0;
i < nextlay_stubs.size();
i++) {
324 Stub *stub = nextlay_stubs[
i];
327 kalmanUpdate(nSkipped + 1 + nSkippedDeadLayers_nextStubs + nSkippedAmbiguousLayers_nextStubs,
328 layer + 1 + nSkippedDeadLayers_nextStubs + nSkippedAmbiguousLayers_nextStubs,
334 next_states_skipped.push_back(new_state);
339 return bool(
a->chi2scaled() <
b->chi2scaled());
341 sort(next_states.begin(), next_states.end(), orderByChi2);
342 sort(next_states_skipped.begin(), next_states_skipped.end(), orderByChi2);
344 new_states.insert(new_states.end(), next_states.begin(), next_states.end());
345 new_states.insert(new_states.end(), next_states_skipped.begin(), next_states_skipped.end());
365 return bool((
a->chi2scaled()) * (
a->nSkippedLayers() + 1) < (
b->chi2scaled()) * (
b->nSkippedLayers() + 1));
367 sort(new_states.begin(), new_states.end(), orderByMinSkipChi2);
372 best_state_by_nstubs[nStubs] = new_states[0];
381 prev_states = new_states;
386 if (not best_state_by_nstubs.empty()) {
388 finished_state = best_state_by_nstubs.begin()->second;
390 std::stringstream
text;
392 text <<
"Track found! final state selection: nLay=" << finished_state->
nStubLayers()
394 <<
" phiSec=" << l1track3D.
iPhiSec() <<
" etaReg=" << l1track3D.
iEtaReg() <<
" HT(m,c)=(" 397 text <<
" q/pt=" << y[
QOVERPT] <<
" tanL=" << y[
T] <<
" z0=" << y[
Z0] <<
" phi0=" << y[
PHI0];
400 text <<
" chosen from states:";
401 for (
const auto &
p : best_state_by_nstubs)
402 text <<
" " <<
p.second->chi2() <<
"/" <<
p.second->nStubLayers();
411 return finished_state;
428 TVectorD vecX =
state->vectorX();
429 TMatrixD matC =
state->matrixC();
432 PrintL1trk() <<
"STATE BARREL TO ENDCAP BEFORE ";
433 PrintL1trk() <<
"state : " << vecX[0] <<
" " << vecX[1] <<
" " << vecX[2] <<
" " << vecX[3];
438 PrintL1trk() <<
"STATE BARREL TO ENDCAP AFTER ";
439 PrintL1trk() <<
"state : " << vecX[0] <<
" " << vecX[1] <<
" " << vecX[2] <<
" " << vecX[3];
446 TMatrixD matFtrans(TMatrixD::kTransposed, matF);
453 TVectorD vecXref = matF * vecX;
482 TMatrixD matCref = matF * matC * matFtrans + matScat;
494 TMatrixD matRinv =
matrixRinv(matH, matCref, matV);
513 double new_chi2rphi = 0, new_chi2rz = 0;
518 PrintL1trk() <<
"adjusted x = " << new_vecX[0] <<
", " << new_vecX[1] <<
", " << new_vecX[2] <<
", " 521 PrintL1trk() <<
"adjusted x = " << new_vecX[0] <<
", " << new_vecX[1] <<
", " << new_vecX[2] <<
", " 522 << new_vecX[3] <<
", " << new_vecX[4];
525 PrintL1trk() <<
"adjust chi2rphi=" << new_chi2rphi <<
" chi2rz=" << new_chi2rz;
529 state->candidate(), nSkipped,
layer,
state, new_vecX, new_matC, matK, matV, stub, new_chi2rphi, new_chi2rz);
540 const TVectorD &vecX,
541 const TMatrixD &matC,
542 const TMatrixD &matK,
543 const TMatrixD &matV,
547 auto new_state = std::make_unique<const KalmanState>(
548 settings_, candidate, nSkipped,
layer, last_state, vecX, matC, matK, matV, stub, chi2rphi, chi2rz);
558 TMatrixD matHtrans(TMatrixD::kTransposed, matH);
559 return matH * matC * matHtrans;
564 TMatrixD
KFbase::matrixRinv(
const TMatrixD &matH,
const TMatrixD &matCref,
const TMatrixD &matV)
const {
566 TMatrixD matR = matV + matHCHt;
567 TMatrixD matRinv(2, 2);
568 if (matR.Determinant() > 0) {
569 matRinv = TMatrixD(TMatrixD::kInverted, matR);
573 const double big = 9.9e9;
574 matRinv =
big * unitMatrix;
588 TMatrixD matHtrans(TMatrixD::kTransposed, matH);
589 TMatrixD matCrefht = matCref * matHtrans;
590 TMatrixD matK = matCrefht * matRinv;
599 TVectorD hx =
h * vecX;
608 float tanL = vecX[
T];
614 double corr = stub->
r() * inv2R;
619 deltaS = (1. / 6.) * (stub->
r()) *
pow(
corr, 2);
625 float rShift = (stub->
z() -
z0) / tanL - stub->
r();
653 const TMatrixD &matCref,
654 const TVectorD &vecXref,
655 const TMatrixD &matH,
656 const TVectorD &
delta,
658 TMatrixD &new_matC)
const {
659 new_vecX = vecXref + matK *
delta;
661 TMatrixD
tmp = unitMatrix - matK * matH;
662 new_matC =
tmp * matCref;
668 const TMatrixD &matRinv,
669 const TVectorD &
delta,
671 double &chi2rz)
const {
677 PrintL1trk() <<
"delta(chi2rphi)=" << delChi2rphi <<
" delta(chi2rz)= " << delChi2rz;
679 chi2rphi =
state->chi2rphi() + delChi2rphi;
680 chi2rz =
state->chi2rz() + delChi2rz;
691 unsigned int iEtaReg,
unsigned int layerIDreduced,
bool barrel,
float r,
float z)
const {
700 const unsigned int nEta = 16;
701 const unsigned int nGPlayID = 7;
705 <<
"ERROR KFbase::getKalmanLayer hardwired value of nEta differs from NumEtaRegions cfg param";
709 constexpr
unsigned layerMap[
nEta / 2][nGPlayID + 1] = {
710 {7, 0, 1, 5, 4, 3, 7, 2},
711 {7, 0, 1, 5, 4, 3, 7, 2},
712 {7, 0, 1, 5, 4, 3, 7, 2},
713 {7, 0, 1, 5, 4, 3, 7, 2},
714 {7, 0, 1, 5, 4, 3, 7, 2},
715 {7, 0, 1, 3, 4, 2, 6, 2},
716 {7, 0, 1, 1, 2, 3, 4, 5},
717 {7, 0, 7, 1, 2, 3, 4, 5},
720 unsigned int kfEtaReg;
727 unsigned int kalmanLay = layerMap[kfEtaReg][layerIDreduced];
733 if (layerIDreduced == 6) {
738 if (layerIDreduced > 2) {
752 if (layerIDreduced == 3) {
754 }
else if (layerIDreduced == 4) {
756 }
else if (layerIDreduced == 5) {
762 if (layerIDreduced == 5) {
764 }
else if (layerIDreduced == 7) {
815 const unsigned int nEta = 16;
816 const unsigned int nKFlayer = 7;
817 constexpr
bool ambiguityMap[
nEta / 2][nKFlayer] = {
818 {
false,
false,
false,
false,
false,
false,
false},
819 {
false,
false,
false,
false,
false,
false,
false},
820 {
false,
false,
false,
false,
false,
false,
false},
821 {
false,
false,
false,
false,
false,
false,
false},
822 {
false,
false,
false,
false,
false,
false,
false},
823 {
false,
false,
true,
false,
false,
false,
false},
824 {
true,
true,
false,
false,
false,
false,
false},
825 {
true,
false,
false,
false,
false,
false,
false},
828 unsigned int kfEtaReg;
835 bool ambiguous =
false;
837 ambiguous = ambiguityMap[kfEtaReg][kfLayer];
852 set<pair<unsigned, bool>> deadGPlayers;
858 deadGPlayers.insert(pair<unsigned, bool>(4,
true));
861 if (iEtaReg_ <= 7 && iPhiSec_ >= 1 &&
iPhiSec_ <= 5) {
862 deadGPlayers.insert(pair<unsigned, bool>(1,
true));
866 if (iEtaReg_ <= 7 && iPhiSec_ >= 1 &&
iPhiSec_ <= 5) {
867 deadGPlayers.insert(pair<unsigned, bool>(1,
true));
870 deadGPlayers.insert(pair<unsigned, bool>(2,
true));
874 if (iEtaReg_ <= 7 && iPhiSec_ >= 1 &&
iPhiSec_ <= 5) {
875 deadGPlayers.insert(pair<unsigned, bool>(1,
true));
877 if (iEtaReg_ <= 3 && iPhiSec_ >= 1 &&
iPhiSec_ <= 5) {
878 deadGPlayers.insert(pair<unsigned, bool>(3,
false));
884 set<unsigned> kfDeadLayers;
885 for (
const auto &
p : deadGPlayers) {
886 unsigned int layer =
p.first;
891 kfDeadLayers.insert(kalmanLay);
906 TVectorD tpParams(5);
907 bool useForAlgEff(
false);
909 useForAlgEff =
tp->useForAlgEff();
911 tpParams[
PHI0] =
tp->phi0();
912 tpParams[
Z0] =
tp->z0();
913 tpParams[
T] =
tp->tanLambda();
914 tpParams[
D0] =
tp->d0();
916 std::stringstream
text;
919 text <<
" TP index = " <<
tp->index() <<
" useForAlgEff = " << useForAlgEff <<
" ";
920 const string helixNames[5] = {
"qOverPt",
"phi0",
"z0",
"tanL",
"d0"};
921 for (
int i = 0;
i < tpParams.GetNrows();
i++) {
922 text << helixNames[
i] <<
":" << tpParams[
i] <<
", ";
934 std::stringstream
text;
937 text <<
"stub layers = []\n";
939 text <<
"stub layers = [ ";
940 for (
unsigned i = 0;
i < stubs.size();
i++) {
941 text << stubs[
i]->layerId();
942 if (
i != stubs.size() - 1)
946 text <<
"KF stub layers = [ ";
947 for (
unsigned j = 0;
j < stubs.size();
j++) {
948 unsigned int kalmanLay =
951 if (
j != stubs.size() - 1)
962 std::stringstream
text;
965 text <<
"index=" << stub->
index() <<
" ";
967 text <<
"r=" << stub->
r() <<
" ";
968 text <<
"phi=" << stub->
phi() <<
" ";
969 text <<
"z=" << stub->
z() <<
" ";
973 std::set<const TP *> tps = stub->
assocTPs();
975 text <<
tp->index() <<
",";
982 for (
auto &stub : stubs) {
unsigned int kalmanMaxStubsPerLayer() const
unsigned int iEtaReg() const override
constexpr double deltaPhi(double phi1, double phi2)
bool kalmanHOhelixExp() const
unsigned int layerId() const
float phi0() const override
unsigned nextLayer() const
bool enableDigitize() const
unsigned nSkippedLayers() const
unsigned int kalmanHOalpha() const
const Settings * settings() const
float qOverPt() const override
double bApprox_intercept() const
void printStubLayers(const std::vector< Stub *> &stubs, unsigned int iEtaReg) const
void adjustState(const TMatrixD &K, const TMatrixD &pxcov, const TVectorD &x, const TMatrixD &h, const TVectorD &delta, TVectorD &new_x, TMatrixD &new_xcov) const
void printTP(const TP *tp) const
virtual unsigned int kalmanLayer(unsigned int iEtaReg, unsigned int layerIDreduced, bool barrel, float r, float z) const
const TP * matchedTP() const override
void printStubs(const std::vector< Stub *> &stubs) const
unsigned int killScenario() const
L1fittedTrack fit(const L1track3D &l1track3D) override
bool kalmanRemove2PScut() const
std::set< unsigned > kalmanDeadLayers(bool &remove2PSCut) const
float approxB(float z, float r) const
const std::vector< Stub * > & stubs() const override
unsigned int kalmanMaxStubsEasy() const
std::pair< unsigned int, unsigned int > cellLocationHT() const override
unsigned int numEtaRegions() const
virtual TVectorD trackParams(const KalmanState *state) const =0
constexpr std::array< uint8_t, layerIndexSize > layer
unsigned int index() const
unsigned nStubLayers() const
unsigned kalmanDebugLevel() const
unsigned int iPhiSec() const override
const KalmanState * mkState(const L1track3D &candidate, unsigned nSkipped, unsigned layer, const KalmanState *last_state, const TVectorD &x, const TMatrixD &pxx, const TMatrixD &K, const TMatrixD &dcov, Stub *stub, double chi2rphi, double chi2rz)
virtual const KalmanState * kalmanUpdate(unsigned nSkipped, unsigned layer, Stub *stub, const KalmanState *state, const TP *tp)
bool goodTrack(const reco::Track *pTrack, math::XYZPoint leadPV, trackSelectionParameters parameters, bool debug=false)
bool kalmanAddBeamConstr() const
virtual bool kalmanAmbiguousLayer(unsigned int iEtaReg, unsigned int kfLayer)
virtual TMatrixD matrixV(const Stub *stub, const KalmanState *state) const =0
Abs< T >::type abs(const T &t)
virtual TVectorD seedX(const L1track3D &l1track3D) const =0
const KalmanState * doKF(const L1track3D &l1track3D, const std::vector< Stub *> &stubs, const TP *tpa)
const Settings * settings_
void printStub(const Stub *stub) const
double bApprox_gradient() const
unsigned int kalmanMinNumStubs() const
virtual TMatrixD seedC(const L1track3D &l1track3D) const =0
std::vector< DeviationSensor2D * > vd
unsigned int kalmanMaxSkipLayersEasy() const
virtual TMatrixD matrixH(const Stub *stub) const =0
TMatrixD matrixHCHt(const TMatrixD &h, const TMatrixD &c) const
virtual TVectorD trackParams_BeamConstr(const KalmanState *state, double &chi2rphi_bcon) const =0
virtual TVectorD residual(const Stub *stub, const TVectorD &x, double candQoverPt) const
unsigned int kalmanMaxNumStubs() const
static constexpr float d0
void setInfoKF(unsigned int nSkippedLayers, unsigned int numUpdateCalls)
TMatrixD matrixRinv(const TMatrixD &matH, const TMatrixD &matCref, const TMatrixD &matV) const
TMatrixD getKalmanGainMatrix(const TMatrixD &h, const TMatrixD &pxcov, const TMatrixD &covRinv) const
=== This is the base class for the linearised chi-squared track fit algorithms.
unsigned int kalmanMaxSkipLayersHard() const
const std::set< const TP * > & assocTPs() const
virtual bool isGoodState(const KalmanState &state) const =0
unsigned int numUpdateCalls_
unsigned int numStubs() const override
unsigned int kalmanHOprojZcorr() const
unsigned int kalmanChi2RphiScale() const
virtual TVectorD vectorM(const Stub *stub) const =0
const std::vector< double > & kfLayerVsChiSq5() const
std::vector< std::unique_ptr< const KalmanState > > listAllStates_
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
unsigned int hitPattern() const
virtual TMatrixD matrixF(const Stub *stub=nullptr, const KalmanState *state=nullptr) const =0
Power< A, B >::type pow(const A &a, const B &b)
bool kfUseMaybeLayers() const
virtual void adjustChi2(const KalmanState *state, const TMatrixD &covRinv, const TVectorD &delta, double &chi2rphi, double &chi2rz) const
double invPtToInvR() const