File indexing completed on 2025-06-03 00:12:23
0001 #include "L1Trigger/TrackFindingTracklet/interface/KalmanFilter.h"
0002 #include "L1Trigger/TrackFindingTMTT/interface/L1track3D.h"
0003 #include "L1Trigger/TrackFindingTMTT/interface/Stub.h"
0004 #include "L1Trigger/TrackFindingTMTT/interface/L1fittedTrack.h"
0005
0006 #include <numeric>
0007 #include <algorithm>
0008 #include <iterator>
0009 #include <deque>
0010 #include <vector>
0011 #include <set>
0012 #include <cmath>
0013
0014 namespace trklet {
0015
0016 KalmanFilter::KalmanFilter(const tt::Setup* setup,
0017 const DataFormats* dataFormats,
0018 KalmanFilterFormats* kalmanFilterFormats,
0019 tmtt::Settings* settings,
0020 tmtt::KFParamsComb* tmtt,
0021 int region,
0022 tt::TTTracks& ttTracks)
0023 : setup_(setup),
0024 dataFormats_(dataFormats),
0025 kalmanFilterFormats_(kalmanFilterFormats),
0026 settings_(settings),
0027 tmtt_(tmtt),
0028 region_(region),
0029 ttTracks_(ttTracks),
0030 layer_(0) {
0031 zTs_.reserve(settings_->etaRegions().size());
0032 for (double eta : settings_->etaRegions())
0033 zTs_.emplace_back(std::sinh(eta) * settings_->chosenRofZ());
0034 }
0035
0036
0037 void KalmanFilter::consume(const tt::StreamsTrack& streamsTrack, const tt::StreamsStub& streamsStub) {
0038 const int offset = region_ * setup_->numLayers();
0039 const tt::StreamTrack& streamTrack = streamsTrack[region_];
0040 const int numTracks =
0041 std::accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const tt::FrameTrack& f) {
0042 return sum + (f.first.isNull() ? 0 : 1);
0043 });
0044 int numStubs(0);
0045 for (int layer = 0; layer < setup_->numLayers(); layer++) {
0046 const tt::StreamStub& streamStub = streamsStub[offset + layer];
0047 numStubs += std::accumulate(streamStub.begin(), streamStub.end(), 0, [](int sum, const tt::FrameStub& f) {
0048 return sum + (f.first.isNull() ? 0 : 1);
0049 });
0050 }
0051 tracks_.reserve(numTracks);
0052 stubs_.reserve(numStubs);
0053 int trackId(0);
0054 for (int frame = 0; frame < static_cast<int>(streamTrack.size()); frame++) {
0055 const tt::FrameTrack& frameTrack = streamTrack[frame];
0056 if (frameTrack.first.isNull()) {
0057 stream_.push_back(nullptr);
0058 continue;
0059 }
0060 tracks_.emplace_back(frameTrack, dataFormats_);
0061 TrackDR* track = &tracks_.back();
0062 std::vector<Stub*> stubs(setup_->numLayers(), nullptr);
0063 TTBV hitPattern(0, setup_->numLayers());
0064 for (int layer = 0; layer < setup_->numLayers(); layer++) {
0065 const tt::FrameStub& frameStub = streamsStub[offset + layer][frame];
0066 if (frameStub.first.isNull())
0067 continue;
0068 stubs_.emplace_back(kalmanFilterFormats_, frameStub);
0069 stubs[layer] = &stubs_.back();
0070 hitPattern.set(layer);
0071 }
0072 if (hitPattern.count(0, setup_->kfMaxSeedingLayer()) < setup_->kfNumSeedStubs()) {
0073 stream_.push_back(nullptr);
0074 continue;
0075 }
0076 states_.emplace_back(kalmanFilterFormats_, track, stubs, trackId++);
0077 stream_.push_back(&states_.back());
0078 if (setup_->enableTruncation() && trackId == setup_->kfMaxTracks())
0079 break;
0080 }
0081 }
0082
0083
0084 void KalmanFilter::simulate(tt::StreamsStub& streamsStub, tt::StreamsTrack& streamsTrack) {
0085
0086 finals_.reserve(states_.size());
0087 for (const State& state : states_) {
0088
0089 TrackDR* trackFound = state.track();
0090 const TTTrackRef& ttTrackRef = trackFound->frame().first;
0091 const double qOverPt = -trackFound->inv2R() / setup_->invPtToDphi();
0092 const double phi0 = tt::deltaPhi(trackFound->phiT() - setup_->chosenRofPhi() * trackFound->inv2R() +
0093 region_ * setup_->baseRegion());
0094 const double tanLambda = trackFound->zT() / setup_->chosenRofZ();
0095 static constexpr double z0 = 0;
0096 static constexpr double helixD0 = 0.;
0097
0098 std::vector<tmtt::Stub> stubs;
0099 std::vector<tmtt::Stub*> stubsFound;
0100 stubs.reserve(state.trackPattern().count());
0101 stubsFound.reserve(state.trackPattern().count());
0102 const std::vector<Stub*>& stubsState = state.stubs();
0103 for (int layer = 0; layer < setup_->numLayers(); layer++) {
0104 if (!stubsState[layer])
0105 continue;
0106 const StubDR& stub = stubsState[layer]->stubDR_;
0107 const TTStubRef& ttStubRef = stub.frame().first;
0108 tt::SensorModule* sensorModule = setup_->sensorModule(ttStubRef);
0109
0110 double r, phi, z;
0111 if (setup_->kfUseTTStubResiduals()) {
0112 const GlobalPoint gp = setup_->stubPos(ttStubRef);
0113 r = gp.perp();
0114 phi = gp.phi();
0115 z = gp.z();
0116 } else {
0117 r = stub.r() + setup_->chosenRofPhi();
0118 phi = tt::deltaPhi(stub.phi() + trackFound->phiT() + stub.r() * trackFound->inv2R() +
0119 region_ * setup_->baseRegion());
0120 z = stub.z() + trackFound->zT() + (r - setup_->chosenRofZ()) * tanLambda;
0121 }
0122
0123 int layerId = setup_->layerId(ttStubRef);
0124 if (layerId > 10 && z < 0.)
0125 layerId += 10;
0126 int layerIdReduced = setup_->layerId(ttStubRef);
0127 if (layerIdReduced == 6)
0128 layerIdReduced = 11;
0129 else if (layerIdReduced == 5)
0130 layerIdReduced = 12;
0131 else if (layerIdReduced == 4)
0132 layerIdReduced = 13;
0133 else if (layerIdReduced == 3)
0134 layerIdReduced = 15;
0135 if (layerIdReduced > 10)
0136 layerIdReduced -= 8;
0137 const double stripPitch = sensorModule->pitchRow();
0138 const double stripLength = sensorModule->pitchCol();
0139 const bool psModule = sensorModule->psModule();
0140 const bool barrel = sensorModule->barrel();
0141 const bool tiltedBarrel = sensorModule->tilted();
0142 stubs.emplace_back(
0143 ttStubRef, r, phi, z, layerId, layerIdReduced, stripPitch, stripLength, psModule, barrel, tiltedBarrel);
0144 stubsFound.push_back(&stubs.back());
0145 }
0146
0147 const int iPhiSec = region_;
0148 const double zTtrack = ttTrackRef->z0() + settings_->chosenRofZ() * ttTrackRef->tanL();
0149 int iEtaReg = 0;
0150 for (; iEtaReg < 15; iEtaReg++)
0151 if (zTtrack < zTs_[iEtaReg + 1])
0152 break;
0153 const tmtt::L1track3D l1track3D(settings_, stubsFound, qOverPt, phi0, z0, tanLambda, helixD0, iPhiSec, iEtaReg);
0154
0155 const tmtt::L1fittedTrack trackFitted(tmtt_->fit(l1track3D));
0156 if (!trackFitted.accepted())
0157 continue;
0158
0159 static constexpr int trackId = 0;
0160 static constexpr int numConsistent = 0;
0161 static constexpr int numConsistentPS = 0;
0162 const double inv2R = -trackFitted.qOverPt() * setup_->invPtToDphi();
0163 const double phiT =
0164 tt::deltaPhi(trackFitted.phi0() + inv2R * setup_->chosenRofPhi() - region_ * setup_->baseRegion());
0165 const double cot = trackFitted.tanLambda();
0166 const double zT = trackFitted.z0() + cot * setup_->chosenRofZ();
0167
0168 if (!dataFormats_->format(Variable::inv2R, Process::kf).inRange(inv2R, true))
0169 continue;
0170 if (!dataFormats_->format(Variable::phiT, Process::kf).inRange(phiT, true))
0171 continue;
0172 if (!dataFormats_->format(Variable::cot, Process::kf).inRange(cot, true))
0173 continue;
0174 if (!dataFormats_->format(Variable::zT, Process::kf).inRange(zT, true))
0175 continue;
0176 const double d0 = trackFitted.d0();
0177 const double x0 = inv2R - trackFound->inv2R();
0178 const double x1 = phiT - trackFound->phiT();
0179 const double x2 = cot - tanLambda;
0180 const double x3 = zT - trackFound->zT();
0181 const double x4 = d0;
0182
0183 TTBV hitPattern(0, setup_->numLayers());
0184 std::vector<StubKF> stubsKF;
0185 stubsKF.reserve(setup_->numLayers());
0186 for (tmtt::Stub* stub : trackFitted.stubs()) {
0187 if (!stub)
0188 continue;
0189
0190 const auto it = std::find_if(stubsState.begin(), stubsState.end(), [stub](Stub* state) {
0191 return state && (stub->ttStubRef() == state->stubDR_.frame().first);
0192 });
0193 const StubDR& s = (*it)->stubDR_;
0194
0195 const double r = s.r();
0196 const double r0 = r + setup_->chosenRofPhi();
0197 const double phi = s.phi() - (x1 + r * x0 + x4 / r0);
0198 const double z = s.z() - (x3 + (r0 - setup_->chosenRofZ()) * x2);
0199 const double dPhi = s.dPhi();
0200 const double dZ = s.dZ();
0201 const int layer = std::distance(stubsState.begin(), it);
0202
0203 if (!dataFormats_->format(Variable::phi, Process::kf).inRange(phi, true))
0204 continue;
0205 if (!dataFormats_->format(Variable::z, Process::kf).inRange(z, true))
0206 continue;
0207 hitPattern.set(layer);
0208 stubsKF.emplace_back(s, r, phi, z, dPhi, dZ);
0209 }
0210
0211 if (hitPattern.count() < setup_->kfMinLayers())
0212 continue;
0213
0214 const TrackKF trackKF(*trackFound, inv2R, phiT, cot, zT);
0215 finals_.emplace_back(trackId, numConsistent, numConsistentPS, d0, hitPattern, trackKF, stubsKF);
0216 }
0217 conv(streamsStub, streamsTrack);
0218 }
0219
0220
0221 void KalmanFilter::produce(tt::StreamsStub& streamsStub,
0222 tt::StreamsTrack& streamsTrack,
0223 int& numAcceptedStates,
0224 int& numLostStates) {
0225 if (setup_->kfUseSimmulation())
0226 return simulate(streamsStub, streamsTrack);
0227
0228 if (setup_->kfUse5ParameterFit()) {
0229
0230 for (layer_ = 0; layer_ < setup_->numLayers(); layer_++)
0231 addLayer();
0232 } else {
0233
0234 for (layer_ = 0; layer_ < setup_->kfMaxSeedingLayer(); layer_++)
0235 addLayer(true);
0236
0237 calcSeeds();
0238
0239 for (layer_ = setup_->kfNumSeedStubs(); layer_ < setup_->numLayers(); layer_++)
0240 addLayer();
0241 }
0242
0243 const int nStates =
0244 std::accumulate(stream_.begin(), stream_.end(), 0, [](int sum, State* state) { return sum + (state ? 1 : 0); });
0245
0246 if (setup_->enableTruncation() && static_cast<int>(stream_.size()) > setup_->numFramesHigh())
0247 stream_.resize(setup_->numFramesHigh());
0248
0249 stream_.erase(std::remove(stream_.begin(), stream_.end(), nullptr), stream_.end());
0250
0251 numAcceptedStates += stream_.size();
0252
0253 numLostStates += nStates - stream_.size();
0254
0255 finalize();
0256
0257 accumulator();
0258
0259 conv(streamsStub, streamsTrack);
0260 }
0261
0262
0263 void KalmanFilter::finalize() {
0264 finals_.reserve(stream_.size());
0265 for (State* state : stream_) {
0266 int numConsistent(0);
0267 int numConsistentPS(0);
0268 TTBV hitPattern = state->hitPattern();
0269 std::vector<StubKF> stubsKF;
0270 stubsKF.reserve(setup_->numLayers());
0271
0272 State* s = state;
0273 while ((s = s->parent())) {
0274 const double dPhi = state->x1() + s->H00() * state->x0() + state->x4() / s->H04();
0275 const double dZ = state->x3() + s->H12() * state->x2();
0276 const double phi = digi(VariableKF::m0, s->m0() - dPhi);
0277 const double z = digi(VariableKF::m1, s->m1() - dZ);
0278 const bool validPhi = dataFormats_->format(Variable::phi, Process::kf).inRange(phi);
0279 const bool validZ = dataFormats_->format(Variable::z, Process::kf).inRange(z);
0280 if (validPhi && validZ) {
0281 const double r = s->H00();
0282 const double dPhi = s->d0();
0283 const double dZ = s->d1();
0284 const StubDR& stubDR = s->stub()->stubDR_;
0285 stubsKF.emplace_back(stubDR, r, phi, z, dPhi, dZ);
0286 if (abs(phi) <= dPhi && abs(z) <= dZ) {
0287 numConsistent++;
0288 if (setup_->psModule(stubDR.frame().first))
0289 numConsistentPS++;
0290 }
0291 } else
0292 hitPattern.reset(s->layer());
0293 }
0294 std::reverse(stubsKF.begin(), stubsKF.end());
0295
0296 bool validLayers = hitPattern.count() >= setup_->kfMinLayers();
0297
0298 const double cotTrack =
0299 dataFormats_->format(Variable::cot, Process::kf).digi(state->track()->zT() / setup_->chosenRofZ());
0300 const double inv2R = state->x0() + state->track()->inv2R();
0301 const double phiT = state->x1() + state->track()->phiT();
0302 const double cot = state->x2() + cotTrack;
0303 const double zT = state->x3() + state->track()->zT();
0304 const double d0 = state->x4();
0305
0306 const bool validX0 = dataFormats_->format(Variable::inv2R, Process::kf).inRange(inv2R);
0307
0308 const bool validX1 = abs(phiT) < setup_->baseRegion() / 2.;
0309
0310 const bool validX2 = dataFormats_->format(Variable::cot, Process::kf).inRange(cot);
0311
0312 const bool validX3 = dataFormats_->format(Variable::zT, Process::kf).inRange(zT);
0313 if (!validLayers || !validX0 || !validX1 || !validX2 || !validX3)
0314 continue;
0315 const int trackId = state->trackId();
0316 const TrackKF trackKF(*state->track(), inv2R, phiT, cot, zT);
0317 finals_.emplace_back(trackId, numConsistent, numConsistentPS, d0, hitPattern, trackKF, stubsKF);
0318 }
0319 }
0320
0321
0322 void KalmanFilter::accumulator() {
0323
0324 std::vector<Track*> finals;
0325 finals.reserve(finals_.size());
0326 std::transform(finals_.begin(), finals_.end(), std::back_inserter(finals), [](Track& track) { return &track; });
0327
0328 std::vector<int> trackIds;
0329 trackIds.reserve(tracks_.size());
0330 for (Track* track : finals) {
0331 const int trackId = track->trackId_;
0332 if (std::find_if(trackIds.begin(), trackIds.end(), [trackId](int id) { return id == trackId; }) == trackIds.end())
0333 trackIds.push_back(trackId);
0334 }
0335
0336 auto moreConsistentLayers = [](Track* lhs, Track* rhs) { return lhs->numConsistent_ > rhs->numConsistent_; };
0337 std::stable_sort(finals.begin(), finals.end(), moreConsistentLayers);
0338
0339 auto moreConsistentLayersPS = [](Track* lhs, Track* rhs) { return lhs->numConsistentPS_ > rhs->numConsistentPS_; };
0340 std::stable_sort(finals.begin(), finals.end(), moreConsistentLayersPS);
0341
0342 auto order = [&trackIds](auto lhs, auto rhs) {
0343 const auto l = find(trackIds.begin(), trackIds.end(), lhs->trackId_);
0344 const auto r = find(trackIds.begin(), trackIds.end(), rhs->trackId_);
0345 return std::distance(r, l) < 0;
0346 };
0347 std::stable_sort(finals.begin(), finals.end(), order);
0348
0349 const auto it = std::unique(
0350 finals.begin(), finals.end(), [](Track* lhs, Track* rhs) { return lhs->trackId_ == rhs->trackId_; });
0351 finals.erase(it, finals.end());
0352
0353 int i(0);
0354 for (Track* track : finals)
0355 finals_[i++] = *track;
0356 finals_.resize(i);
0357 }
0358
0359
0360 void KalmanFilter::conv(tt::StreamsStub& streamsStub, tt::StreamsTrack& streamsTrack) {
0361 const int offset = region_ * setup_->numLayers();
0362 tt::StreamTrack& streamTrack = streamsTrack[region_];
0363 streamTrack.reserve(stream_.size());
0364 for (int layer = 0; layer < setup_->numLayers(); layer++)
0365 streamsStub[offset + layer].reserve(stream_.size());
0366 for (const Track& track : finals_) {
0367 streamTrack.emplace_back(track.trackKF_.frame());
0368 const TTBV& hitPattern = track.hitPattern_;
0369 const std::vector<StubKF>& stubsKF = track.stubsKF_;
0370 int i(0);
0371 for (int layer = 0; layer < setup_->numLayers(); layer++)
0372 streamsStub[offset + layer].emplace_back(hitPattern.test(layer) ? stubsKF[i++].frame() : tt::FrameStub());
0373
0374 if (setup_->kfUse5ParameterFit()) {
0375 const TTTrackRef& ttTrackRef = track.trackKF_.frame().first;
0376 ttTracks_.emplace_back(ttTrackRef->rInv(),
0377 ttTrackRef->phi(),
0378 ttTrackRef->tanL(),
0379 ttTrackRef->z0(),
0380 track.d0_,
0381 ttTrackRef->chi2XY(),
0382 ttTrackRef->chi2Z(),
0383 ttTrackRef->trkMVA1(),
0384 ttTrackRef->trkMVA2(),
0385 ttTrackRef->trkMVA3(),
0386 ttTrackRef->hitPattern(),
0387 5,
0388 setup_->bField());
0389 ttTracks_.back().setPhiSector(ttTrackRef->phiSector());
0390 ttTracks_.back().setEtaSector(ttTrackRef->etaSector());
0391 ttTracks_.back().setTrackSeedType(ttTrackRef->trackSeedType());
0392 ttTracks_.back().setStubPtConsistency(ttTrackRef->stubPtConsistency());
0393 ttTracks_.back().setStubRefs(ttTrackRef->getStubRefs());
0394 }
0395 }
0396 }
0397
0398
0399 void KalmanFilter::calcSeeds() {
0400 auto update = [this](State* s) {
0401 updateRangeActual(VariableKF::m0, s->m0());
0402 updateRangeActual(VariableKF::m1, s->m1());
0403 updateRangeActual(VariableKF::v0, s->v0());
0404 updateRangeActual(VariableKF::v1, s->v1());
0405 updateRangeActual(VariableKF::H00, s->H00());
0406 updateRangeActual(VariableKF::H12, s->H12());
0407 };
0408 for (State*& state : stream_) {
0409 if (!state)
0410 continue;
0411 State* s1 = state->parent();
0412 State* s0 = s1->parent();
0413 update(s0);
0414 update(s1);
0415 const double dH = digi(VariableKF::dH, s1->H00() - s0->H00());
0416 const double invdH = digi(VariableKF::invdH, 1.0 / dH);
0417 const double invdH2 = digi(VariableKF::invdH2, 1.0 / dH / dH);
0418 const double H12 = digi(VariableKF::H2, s1->H00() * s1->H00());
0419 const double H02 = digi(VariableKF::H2, s0->H00() * s0->H00());
0420 const double H32 = digi(VariableKF::H2, s1->H12() * s1->H12());
0421 const double H22 = digi(VariableKF::H2, s0->H12() * s0->H12());
0422 const double H1m0 = digi(VariableKF::Hm0, s1->H00() * s0->m0());
0423 const double H0m1 = digi(VariableKF::Hm0, s0->H00() * s1->m0());
0424 const double H3m2 = digi(VariableKF::Hm1, s1->H12() * s0->m1());
0425 const double H2m3 = digi(VariableKF::Hm1, s0->H12() * s1->m1());
0426 const double H1v0 = digi(VariableKF::Hv0, s1->H00() * s0->v0());
0427 const double H0v1 = digi(VariableKF::Hv0, s0->H00() * s1->v0());
0428 const double H3v2 = digi(VariableKF::Hv1, s1->H12() * s0->v1());
0429 const double H2v3 = digi(VariableKF::Hv1, s0->H12() * s1->v1());
0430 const double H12v0 = digi(VariableKF::H2v0, H12 * s0->v0());
0431 const double H02v1 = digi(VariableKF::H2v0, H02 * s1->v0());
0432 const double H32v2 = digi(VariableKF::H2v1, H32 * s0->v1());
0433 const double H22v3 = digi(VariableKF::H2v1, H22 * s1->v1());
0434 const double x0 = digi(VariableKF::x0, (s1->m0() - s0->m0()) * invdH);
0435 const double x2 = digi(VariableKF::x2, (s1->m1() - s0->m1()) * invdH);
0436 const double x1 = digi(VariableKF::x1, (H1m0 - H0m1) * invdH);
0437 const double x3 = digi(VariableKF::x3, (H3m2 - H2m3) * invdH);
0438 const double C00 = digi(VariableKF::C00, (s1->v0() + s0->v0()) * invdH2);
0439 const double C22 = digi(VariableKF::C22, (s1->v1() + s0->v1()) * invdH2);
0440 const double C01 = -digi(VariableKF::C01, (H1v0 + H0v1) * invdH2);
0441 const double C23 = -digi(VariableKF::C23, (H3v2 + H2v3) * invdH2);
0442 const double C11 = digi(VariableKF::C11, (H12v0 + H02v1) * invdH2);
0443 const double C33 = digi(VariableKF::C33, (H32v2 + H22v3) * invdH2);
0444
0445 states_.emplace_back(State(s1, {x0, x1, x2, x3, 0., C00, C11, C22, C33, C01, C23, 0., 0., 0.}));
0446 state = &states_.back();
0447 updateRangeActual(VariableKF::x0, x0);
0448 updateRangeActual(VariableKF::x1, x1);
0449 updateRangeActual(VariableKF::x2, x2);
0450 updateRangeActual(VariableKF::x3, x3);
0451 updateRangeActual(VariableKF::C00, C00);
0452 updateRangeActual(VariableKF::C01, C01);
0453 updateRangeActual(VariableKF::C11, C11);
0454 updateRangeActual(VariableKF::C22, C22);
0455 updateRangeActual(VariableKF::C23, C23);
0456 updateRangeActual(VariableKF::C33, C33);
0457 }
0458 }
0459
0460
0461 void KalmanFilter::addLayer(bool seed) {
0462 auto comb = [seed, this](State*& s) {
0463 if (s)
0464 s = seed ? s->combSeed(states_, layer_) : s->comb(states_, layer_);
0465 };
0466 auto param = [this](State*& s) { setup_->kfUse5ParameterFit() ? this->update5(s) : this->update4(s); };
0467 auto update = [seed, param, this](State*& s) {
0468 if (s && (seed || s->hitPattern().pmEncode() == layer_)) {
0469 if (seed)
0470 s = s->update(states_, layer_);
0471 else
0472 param(s);
0473 }
0474 };
0475
0476 static constexpr int latency = 5;
0477
0478 std::deque<State*> streamOutput;
0479
0480 std::deque<State*> stack;
0481
0482 std::deque<State*> delay(latency, nullptr);
0483
0484
0485 while (!stream_.empty() || !stack.empty() ||
0486 !std::all_of(delay.begin(), delay.end(), [](const State* state) { return state == nullptr; })) {
0487 State* state = pop_front(stream_);
0488
0489 if (!state)
0490 state = pop_front(stack);
0491 streamOutput.push_back(state);
0492
0493 comb(state);
0494 delay.push_back(state);
0495 state = pop_front(delay);
0496 if (state)
0497 stack.push_back(state);
0498 }
0499 stream_ = streamOutput;
0500
0501 for (State*& state : stream_)
0502 update(state);
0503 }
0504
0505
0506 void KalmanFilter::update4(State*& state) {
0507
0508
0509 const double m0 = state->m0();
0510
0511 const double m1 = state->m1();
0512
0513 const double v0 = state->v0();
0514
0515 const double v1 = state->v1();
0516
0517 const double H00 = state->H00();
0518
0519 const double H12 = state->H12();
0520 updateRangeActual(VariableKF::m0, m0);
0521 updateRangeActual(VariableKF::m1, m1);
0522 updateRangeActual(VariableKF::v0, v0);
0523 updateRangeActual(VariableKF::v1, v1);
0524 updateRangeActual(VariableKF::H00, H00);
0525 updateRangeActual(VariableKF::H12, H12);
0526
0527 double x0 = state->x0();
0528
0529 double x1 = state->x1();
0530
0531 double x2 = state->x2();
0532
0533 double x3 = state->x3();
0534
0535 double C00 = state->C00();
0536 double C01 = state->C01();
0537 double C11 = state->C11();
0538 double C22 = state->C22();
0539 double C23 = state->C23();
0540 double C33 = state->C33();
0541
0542 const double r0C = digi(VariableKF::x1, m0 - x1);
0543 const double r0 = digi(VariableKF::r0, r0C - x0 * H00);
0544
0545 const double r1C = digi(VariableKF::x3, m1 - x3);
0546 const double r1 = digi(VariableKF::r1, r1C - x2 * H12);
0547
0548 const double S00 = digi(VariableKF::S00, C01 + H00 * C00);
0549 const double S01 = digi(VariableKF::S01, C11 + H00 * C01);
0550 const double S12 = digi(VariableKF::S12, C23 + H12 * C22);
0551 const double S13 = digi(VariableKF::S13, C33 + H12 * C23);
0552
0553 const double R00 = digi(VariableKF::R00, v0 + S01 + H00 * S00);
0554 const double R11 = digi(VariableKF::R11, v1 + S13 + H12 * S12);
0555
0556 const int msb0 = std::max(0, static_cast<int>(std::ceil(std::log2(R00 / base(VariableKF::R00)))));
0557 const int msb1 = std::max(0, static_cast<int>(std::ceil(std::log2(R11 / base(VariableKF::R11)))));
0558 const int shift0 = width(VariableKF::R00) - msb0;
0559 const int shift1 = width(VariableKF::R11) - msb1;
0560 const double R00Shifted = R00 * std::pow(2., shift0);
0561 const double R11Shifted = R11 * std::pow(2., shift1);
0562 const double R00Rough = digi(VariableKF::R00Rough, R00Shifted);
0563 const double R11Rough = digi(VariableKF::R11Rough, R11Shifted);
0564 const double invR00Approx = digi(VariableKF::invR00Approx, 1. / R00Rough);
0565 const double invR11Approx = digi(VariableKF::invR11Approx, 1. / R11Rough);
0566 const double invR00Cor = digi(VariableKF::invR00Cor, 2. - invR00Approx * R00Shifted);
0567 const double invR11Cor = digi(VariableKF::invR11Cor, 2. - invR11Approx * R11Shifted);
0568 const double invR00 = digi(VariableKF::invR00, invR00Approx * invR00Cor);
0569 const double invR11 = digi(VariableKF::invR11, invR11Approx * invR11Cor);
0570
0571 auto digiShifted = [](double val, double base) { return std::floor(val / base * 2. + 1.e-11) * base / 2.; };
0572 const double S00Shifted = digiShifted(S00 * std::pow(2., shift0), base(VariableKF::S00Shifted));
0573 const double S01Shifted = digiShifted(S01 * std::pow(2., shift0), base(VariableKF::S01Shifted));
0574 const double S12Shifted = digiShifted(S12 * std::pow(2., shift1), base(VariableKF::S12Shifted));
0575 const double S13Shifted = digiShifted(S13 * std::pow(2., shift1), base(VariableKF::S13Shifted));
0576
0577 const double K00 = digi(VariableKF::K00, S00Shifted * invR00);
0578 const double K10 = digi(VariableKF::K10, S01Shifted * invR00);
0579 const double K21 = digi(VariableKF::K21, S12Shifted * invR11);
0580 const double K31 = digi(VariableKF::K31, S13Shifted * invR11);
0581
0582 x0 = digi(VariableKF::x0, x0 + r0 * K00);
0583 x1 = digi(VariableKF::x1, x1 + r0 * K10);
0584 x2 = digi(VariableKF::x2, x2 + r1 * K21);
0585 x3 = digi(VariableKF::x3, x3 + r1 * K31);
0586 C00 = digi(VariableKF::C00, C00 - S00 * K00);
0587 C01 = digi(VariableKF::C01, C01 - S01 * K00);
0588 C11 = digi(VariableKF::C11, C11 - S01 * K10);
0589 C22 = digi(VariableKF::C22, C22 - S12 * K21);
0590 C23 = digi(VariableKF::C23, C23 - S13 * K21);
0591 C33 = digi(VariableKF::C33, C33 - S13 * K31);
0592
0593 updateRangeActual(VariableKF::r0, r0);
0594 updateRangeActual(VariableKF::r1, r1);
0595 updateRangeActual(VariableKF::S00, S00);
0596 updateRangeActual(VariableKF::S01, S01);
0597 updateRangeActual(VariableKF::S12, S12);
0598 updateRangeActual(VariableKF::S13, S13);
0599 updateRangeActual(VariableKF::S00Shifted, S00Shifted);
0600 updateRangeActual(VariableKF::S01Shifted, S01Shifted);
0601 updateRangeActual(VariableKF::S12Shifted, S12Shifted);
0602 updateRangeActual(VariableKF::S13Shifted, S13Shifted);
0603 updateRangeActual(VariableKF::R00, R00);
0604 updateRangeActual(VariableKF::R11, R11);
0605 updateRangeActual(VariableKF::R00Rough, R00Rough);
0606 updateRangeActual(VariableKF::R11Rough, R11Rough);
0607 updateRangeActual(VariableKF::invR00Approx, invR00Approx);
0608 updateRangeActual(VariableKF::invR11Approx, invR11Approx);
0609 updateRangeActual(VariableKF::invR00Cor, invR00Cor);
0610 updateRangeActual(VariableKF::invR11Cor, invR11Cor);
0611 updateRangeActual(VariableKF::invR00, invR00);
0612 updateRangeActual(VariableKF::invR11, invR11);
0613 updateRangeActual(VariableKF::K00, K00);
0614 updateRangeActual(VariableKF::K10, K10);
0615 updateRangeActual(VariableKF::K21, K21);
0616 updateRangeActual(VariableKF::K31, K31);
0617
0618 states_.emplace_back(State(state, {x0, x1, x2, x3, 0., C00, C11, C22, C33, C01, C23, 0., 0., 0.}));
0619 state = &states_.back();
0620 updateRangeActual(VariableKF::x0, x0);
0621 updateRangeActual(VariableKF::x1, x1);
0622 updateRangeActual(VariableKF::x2, x2);
0623 updateRangeActual(VariableKF::x3, x3);
0624 updateRangeActual(VariableKF::C00, C00);
0625 updateRangeActual(VariableKF::C01, C01);
0626 updateRangeActual(VariableKF::C11, C11);
0627 updateRangeActual(VariableKF::C22, C22);
0628 updateRangeActual(VariableKF::C23, C23);
0629 updateRangeActual(VariableKF::C33, C33);
0630 }
0631
0632
0633 void KalmanFilter::update5(State*& state) {
0634 const double m0 = state->m0();
0635 const double m1 = state->m1();
0636 const double v0 = state->v0();
0637 const double v1 = state->v1();
0638 const double H00 = state->H00();
0639 const double H12 = state->H12();
0640 const double H04 = state->H04();
0641 double x0 = state->x0();
0642 double x1 = state->x1();
0643 double x2 = state->x2();
0644 double x3 = state->x3();
0645 double x4 = state->x4();
0646 double C00 = state->C00();
0647 double C01 = state->C01();
0648 double C11 = state->C11();
0649 double C22 = state->C22();
0650 double C23 = state->C23();
0651 double C33 = state->C33();
0652 double C44 = state->C44();
0653 double C40 = state->C40();
0654 double C41 = state->C41();
0655 const double r0 = m0 - x1 - x0 * H00 - x4 / H04;
0656 const double r1 = m1 - x3 - x2 * H12;
0657 const double S00 = C01 + H00 * C00 + C40 / H04;
0658 const double S01 = C11 + H00 * C01 + C41 / H04;
0659 const double S12 = C23 + H12 * C22;
0660 const double S13 = C33 + H12 * C23;
0661 const double S04 = C41 + H00 * C40 + C44 / H04;
0662 const double R00 = v0 + S01 + H00 * S00 + S04 / H04;
0663 const double R11 = v1 + S13 + H12 * S12;
0664 const double K00 = S00 / R00;
0665 const double K10 = S01 / R00;
0666 const double K21 = S12 / R11;
0667 const double K31 = S13 / R11;
0668 const double K40 = S04 / R00;
0669 x0 += r0 * K00;
0670 x1 += r0 * K10;
0671 x2 += r1 * K21;
0672 x3 += r1 * K31;
0673 x4 += r0 * K40;
0674 C00 -= S00 * K00;
0675 C01 -= S01 * K00;
0676 C11 -= S01 * K10;
0677 C22 -= S12 * K21;
0678 C23 -= S13 * K21;
0679 C33 -= S13 * K31;
0680 C44 -= S04 * K40;
0681 C40 -= S04 * K00;
0682 C41 -= S04 * K10;
0683 states_.emplace_back(State(state, {x0, x1, x2, x3, x4, C00, C11, C22, C33, C01, C23, C44, C40, C41}));
0684 state = &states_.back();
0685 }
0686
0687
0688 template <class T>
0689 T* KalmanFilter::pop_front(std::deque<T*>& ts) const {
0690 T* t = nullptr;
0691 if (!ts.empty()) {
0692 t = ts.front();
0693 ts.pop_front();
0694 }
0695 return t;
0696 }
0697
0698 }