Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-03 00:12:17

0001 #include "L1Trigger/TrackerTFP/interface/KalmanFilterFormats.h"
0002 
0003 #include <vector>
0004 #include <deque>
0005 #include <cmath>
0006 #include <tuple>
0007 #include <iterator>
0008 #include <algorithm>
0009 #include <limits>
0010 #include <cstring>
0011 
0012 namespace trackerTFP {
0013 
0014   constexpr auto variableKFstrs_ = {
0015       "x0",         "x1",         "x2",         "x3",         "H00",          "H12",          "m0",        "m1",
0016       "v0",         "v1",         "r0",         "r1",         "S00",          "S01",          "S12",       "S13",
0017       "S00Shifted", "S01Shifted", "S12Shifted", "S13Shifted", "K00",          "K10",          "K21",       "K31",
0018       "R00",        "R11",        "R00Rough",   "R11Rough",   "invR00Approx", "invR11Approx", "invR00Cor", "invR11Cor",
0019       "invR00",     "invR11",     "C00",        "C01",        "C11",          "C22",          "C23",       "C33",
0020       "r0Shifted",  "r1Shifted",  "r02",        "r12",        "chi20",        "chi21"};
0021 
0022   void KalmanFilterFormats::endJob(std::stringstream& ss) {
0023     const int wName =
0024         std::strlen(*std::max_element(variableKFstrs_.begin(), variableKFstrs_.end(), [](const auto& a, const auto& b) {
0025           return std::strlen(a) < std::strlen(b);
0026         }));
0027     for (VariableKF v = VariableKF::begin; v != VariableKF::dH; v = VariableKF(+v + 1)) {
0028       const double r =
0029           format(v).twos() ? std::max(std::abs(format(v).min()), std::abs(format(v).max())) * 2. : format(v).max();
0030       const int delta = format(v).width() - ceil(log2(r / format(v).base()));
0031       ss << std::setw(wName) << *std::next(variableKFstrs_.begin(), +v) << ": ";
0032       ss << std::setw(3) << (delta == -2147483648 ? "-" : std::to_string(delta)) << std::endl;
0033     }
0034   }
0035 
0036   KalmanFilterFormats::KalmanFilterFormats() { formats_.reserve(+VariableKF::end); }
0037 
0038   void KalmanFilterFormats::beginRun(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0039     dataFormats_ = dataFormats;
0040     iConfig_ = iConfig;
0041     fillFormats();
0042   }
0043 
0044   template <VariableKF it>
0045   void KalmanFilterFormats::fillFormats() {
0046     formats_.emplace_back(makeDataFormat<it>(dataFormats_, iConfig_));
0047     if constexpr (it + 1 != VariableKF::end)
0048       fillFormats<it + 1>();
0049   }
0050 
0051   DataFormatKF::DataFormatKF(
0052       const VariableKF& v, bool twos, bool enableIntegerEmulation, int width, double base, double range)
0053       : v_(v),
0054         twos_(twos),
0055         enableIntegerEmulation_(enableIntegerEmulation),
0056         width_(width),
0057         base_(base),
0058         range_(range),
0059         min_(std::numeric_limits<double>::max()),
0060         abs_(std::numeric_limits<double>::max()),
0061         max_(std::numeric_limits<double>::lowest()) {}
0062 
0063   // returns false if data format would oferflow for this double value
0064   bool DataFormatKF::inRange(double d) const {
0065     if (twos_)
0066       return d >= -range_ / 2. && d < range_ / 2.;
0067     return d >= 0 && d < range_;
0068   }
0069 
0070   void DataFormatKF::updateRangeActual(double d) {
0071     min_ = std::min(min_, d);
0072     abs_ = std::min(abs_, std::abs(d));
0073     max_ = std::max(max_, d);
0074     if (enableIntegerEmulation_ && !inRange(d)) {
0075       std::string v = *std::next(variableKFstrs_.begin(), +v_);
0076       cms::Exception exception("out_of_range");
0077       exception.addContext("trackerTFP:DataFormatKF::updateRangeActual");
0078       exception << "Variable " << v << " = " << d << " is out of range " << (twos_ ? -range_ / 2. : 0) << " to "
0079                 << (twos_ ? range_ / 2. : range_) << "." << std::endl;
0080       if (twos_ || d >= 0.)
0081         exception.addAdditionalInfo("Consider raising BaseShift" + v + " in KalmanFilterFormats_cfi.py");
0082       exception.addAdditionalInfo("Consider disabling integer emulation in KalmanFilterFormats_cfi.py");
0083       throw exception;
0084     }
0085   }
0086 
0087   template <>
0088   DataFormatKF makeDataFormat<VariableKF::x0>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0089     const DataFormat& input = dataFormats->format(Variable::inv2R, Process::kf);
0090     const int baseShift = iConfig.baseShiftx0_;
0091     const double base = std::pow(2, baseShift) * input.base();
0092     const int width = dataFormats->setup()->widthDSPbb();
0093     const double range = base * std::pow(2, width);
0094     return DataFormatKF(VariableKF::x0, true, iConfig.enableIntegerEmulation_, width, base, range);
0095   }
0096 
0097   template <>
0098   DataFormatKF makeDataFormat<VariableKF::x1>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0099     const DataFormat& input = dataFormats->format(Variable::phiT, Process::kf);
0100     const int baseShift = iConfig.baseShiftx1_;
0101     const double base = std::pow(2, baseShift) * input.base();
0102     const int width = dataFormats->setup()->widthDSPbb();
0103     const double range = base * std::pow(2, width);
0104     return DataFormatKF(VariableKF::x1, true, iConfig.enableIntegerEmulation_, width, base, range);
0105   }
0106 
0107   template <>
0108   DataFormatKF makeDataFormat<VariableKF::x2>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0109     const DataFormat& input = dataFormats->format(Variable::cot, Process::kf);
0110     const int baseShift = iConfig.baseShiftx2_;
0111     const double base = std::pow(2, baseShift) * input.base();
0112     const int width = dataFormats->setup()->widthDSPbb();
0113     const double range = base * std::pow(2, width);
0114     return DataFormatKF(VariableKF::x2, true, iConfig.enableIntegerEmulation_, width, base, range);
0115   }
0116 
0117   template <>
0118   DataFormatKF makeDataFormat<VariableKF::x3>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0119     const DataFormat& input = dataFormats->format(Variable::zT, Process::kf);
0120     const int baseShift = iConfig.baseShiftx3_;
0121     const double base = std::pow(2, baseShift) * input.base();
0122     const int width = dataFormats->setup()->widthDSPbb();
0123     const double range = base * std::pow(2, width);
0124     return DataFormatKF(VariableKF::x3, true, iConfig.enableIntegerEmulation_, width, base, range);
0125   }
0126 
0127   template <>
0128   DataFormatKF makeDataFormat<VariableKF::H00>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0129     const DataFormat& ctb = dataFormats->format(Variable::r, Process::ctb);
0130     const double base = ctb.base();
0131     const int width = ctb.width();
0132     const double range = base * std::pow(2, width);
0133     return DataFormatKF(VariableKF::H00, true, iConfig.enableIntegerEmulation_, width, base, range);
0134   }
0135 
0136   template <>
0137   DataFormatKF makeDataFormat<VariableKF::H12>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0138     const DataFormat& ctb = dataFormats->format(Variable::r, Process::ctb);
0139     const double base = ctb.base();
0140     const double rangeMin = 2. * dataFormats->setup()->maxRz();
0141     const int width = std::ceil(std::log2(rangeMin / base));
0142     const double range = base * std::pow(2, width);
0143     return DataFormatKF(VariableKF::H12, true, iConfig.enableIntegerEmulation_, width, base, range);
0144   }
0145 
0146   template <>
0147   DataFormatKF makeDataFormat<VariableKF::m0>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0148     const DataFormat& ctb = dataFormats->format(Variable::phi, Process::ctb);
0149     const double base = ctb.base();
0150     const int width = ctb.width();
0151     const double range = base * std::pow(2, width);
0152     return DataFormatKF(VariableKF::m0, true, iConfig.enableIntegerEmulation_, width, base, range);
0153   }
0154 
0155   template <>
0156   DataFormatKF makeDataFormat<VariableKF::m1>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0157     const DataFormat& ctb = dataFormats->format(Variable::z, Process::ctb);
0158     const double base = ctb.base();
0159     const int width = ctb.width();
0160     const double range = base * std::pow(2, width);
0161     return DataFormatKF(VariableKF::m1, true, iConfig.enableIntegerEmulation_, width, base, range);
0162   }
0163 
0164   template <>
0165   DataFormatKF makeDataFormat<VariableKF::v0>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0166     const DataFormat& dPhi = dataFormats->format(Variable::dPhi, Process::ctb);
0167     const DataFormatKF S01 = makeDataFormat<VariableKF::S01>(dataFormats, iConfig);
0168     const double range = dPhi.range() * dPhi.range() * 4.;
0169     const double base = S01.base();
0170     const int width = std::ceil(std::log2(range / base) - 1.e-11);
0171     return DataFormatKF(VariableKF::v0, false, iConfig.enableIntegerEmulation_, width, base, range);
0172   }
0173 
0174   template <>
0175   DataFormatKF makeDataFormat<VariableKF::v1>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0176     const DataFormat& dZ = dataFormats->format(Variable::dZ, Process::ctb);
0177     const DataFormatKF S13 = makeDataFormat<VariableKF::S13>(dataFormats, iConfig);
0178     const double range = dZ.range() * dZ.range() * 4.;
0179     const double base = S13.base();
0180     const int width = std::ceil(std::log2(range / base) - 1.e-11);
0181     return DataFormatKF(VariableKF::v1, false, iConfig.enableIntegerEmulation_, width, base, range);
0182   }
0183 
0184   template <>
0185   DataFormatKF makeDataFormat<VariableKF::r0>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0186     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0187     const int baseShift = iConfig.baseShiftr0_;
0188     const double base = std::pow(2., baseShift) * x1.base();
0189     const int width = dataFormats->setup()->widthDSPbb();
0190     const double range = base * std::pow(2, width);
0191     return DataFormatKF(VariableKF::r0, true, iConfig.enableIntegerEmulation_, width, base, range);
0192   }
0193 
0194   template <>
0195   DataFormatKF makeDataFormat<VariableKF::r1>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0196     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0197     const int baseShift = iConfig.baseShiftr1_;
0198     const double base = std::pow(2., baseShift) * x3.base();
0199     const int width = dataFormats->setup()->widthDSPbb();
0200     const double range = base * std::pow(2, width);
0201     return DataFormatKF(VariableKF::r1, true, iConfig.enableIntegerEmulation_, width, base, range);
0202   }
0203 
0204   template <>
0205   DataFormatKF makeDataFormat<VariableKF::S00>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0206     const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf);
0207     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0208     const int baseShift = iConfig.baseShiftS00_;
0209     const double base = std::pow(2., baseShift) * x0.base() * x1.base();
0210     const int width = dataFormats->setup()->widthDSPab();
0211     const double range = base * std::pow(2, width);
0212     return DataFormatKF(VariableKF::S00, true, iConfig.enableIntegerEmulation_, width, base, range);
0213   }
0214 
0215   template <>
0216   DataFormatKF makeDataFormat<VariableKF::S01>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0217     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0218     const int baseShift = iConfig.baseShiftS01_;
0219     const double base = std::pow(2., baseShift) * x1.base() * x1.base();
0220     const int width = dataFormats->setup()->widthDSPab();
0221     const double range = base * std::pow(2, width);
0222     return DataFormatKF(VariableKF::S01, true, iConfig.enableIntegerEmulation_, width, base, range);
0223   }
0224 
0225   template <>
0226   DataFormatKF makeDataFormat<VariableKF::S12>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0227     const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf);
0228     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0229     const int baseShift = iConfig.baseShiftS12_;
0230     const double base = std::pow(2., baseShift) * x2.base() * x3.base();
0231     const int width = dataFormats->setup()->widthDSPab();
0232     const double range = base * std::pow(2, width);
0233     return DataFormatKF(VariableKF::S12, true, iConfig.enableIntegerEmulation_, width, base, range);
0234   }
0235 
0236   template <>
0237   DataFormatKF makeDataFormat<VariableKF::S13>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0238     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0239     const int baseShift = iConfig.baseShiftS13_;
0240     const double base = std::pow(2., baseShift) * x3.base() * x3.base();
0241     const int width = dataFormats->setup()->widthDSPab();
0242     const double range = base * std::pow(2, width);
0243     return DataFormatKF(VariableKF::S13, true, iConfig.enableIntegerEmulation_, width, base, range);
0244   }
0245 
0246   template <>
0247   DataFormatKF makeDataFormat<VariableKF::S00Shifted>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0248     const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf);
0249     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0250     const int baseShift = iConfig.baseShiftS00Shifted_;
0251     const double base = std::pow(2., baseShift) * x0.base() * x1.base();
0252     const int width = dataFormats->setup()->widthDSPab();
0253     const double range = base * std::pow(2, width);
0254     return DataFormatKF(VariableKF::S00Shifted, true, iConfig.enableIntegerEmulation_, width, base, range);
0255   }
0256 
0257   template <>
0258   DataFormatKF makeDataFormat<VariableKF::S01Shifted>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0259     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0260     const int baseShift = iConfig.baseShiftS01Shifted_;
0261     const double base = std::pow(2., baseShift) * x1.base() * x1.base();
0262     const int width = dataFormats->setup()->widthDSPab();
0263     const double range = base * std::pow(2, width);
0264     return DataFormatKF(VariableKF::S01Shifted, true, iConfig.enableIntegerEmulation_, width, base, range);
0265   }
0266 
0267   template <>
0268   DataFormatKF makeDataFormat<VariableKF::S12Shifted>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0269     const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf);
0270     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0271     const int baseShift = iConfig.baseShiftS12Shifted_;
0272     const double base = std::pow(2., baseShift) * x2.base() * x3.base();
0273     const int width = dataFormats->setup()->widthDSPab();
0274     const double range = base * std::pow(2, width);
0275     return DataFormatKF(VariableKF::S12Shifted, true, iConfig.enableIntegerEmulation_, width, base, range);
0276   }
0277 
0278   template <>
0279   DataFormatKF makeDataFormat<VariableKF::S13Shifted>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0280     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0281     const int baseShift = iConfig.baseShiftS13Shifted_;
0282     const double base = std::pow(2., baseShift) * x3.base() * x3.base();
0283     const int width = dataFormats->setup()->widthDSPab();
0284     const double range = base * std::pow(2, width);
0285     return DataFormatKF(VariableKF::S13Shifted, true, iConfig.enableIntegerEmulation_, width, base, range);
0286   }
0287 
0288   template <>
0289   DataFormatKF makeDataFormat<VariableKF::K00>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0290     const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf);
0291     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0292     const int baseShift = iConfig.baseShiftK00_;
0293     const double base = std::pow(2., baseShift) * x0.base() / x1.base();
0294     const int width = dataFormats->setup()->widthDSPbb();
0295     const double range = base * std::pow(2, width);
0296     return DataFormatKF(VariableKF::K00, true, iConfig.enableIntegerEmulation_, width, base, range);
0297   }
0298 
0299   template <>
0300   DataFormatKF makeDataFormat<VariableKF::K10>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0301     const int baseShift = iConfig.baseShiftK10_;
0302     const double base = std::pow(2., baseShift);
0303     const int width = dataFormats->setup()->widthDSPbb();
0304     const double range = base * std::pow(2, width);
0305     return DataFormatKF(VariableKF::K10, true, iConfig.enableIntegerEmulation_, width, base, range);
0306   }
0307 
0308   template <>
0309   DataFormatKF makeDataFormat<VariableKF::K21>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0310     const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf);
0311     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0312     const int baseShift = iConfig.baseShiftK21_;
0313     const double base = std::pow(2., baseShift) * x2.base() / x3.base();
0314     const int width = dataFormats->setup()->widthDSPbb();
0315     const double range = base * std::pow(2, width);
0316     return DataFormatKF(VariableKF::K21, true, iConfig.enableIntegerEmulation_, width, base, range);
0317   }
0318 
0319   template <>
0320   DataFormatKF makeDataFormat<VariableKF::K31>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0321     const int baseShift = iConfig.baseShiftK31_;
0322     const double base = std::pow(2., baseShift);
0323     const int width = dataFormats->setup()->widthDSPbb();
0324     const double range = base * std::pow(2, width);
0325     return DataFormatKF(VariableKF::K31, true, iConfig.enableIntegerEmulation_, width, base, range);
0326   }
0327 
0328   template <>
0329   DataFormatKF makeDataFormat<VariableKF::R00>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0330     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0331     const int baseShift = iConfig.baseShiftR00_;
0332     const int width = iConfig.widthR00_;
0333     const double base = std::pow(2., baseShift) * x1.base() * x1.base();
0334     const double range = base * std::pow(2, width);
0335     return DataFormatKF(VariableKF::R00, false, iConfig.enableIntegerEmulation_, width, base, range);
0336   }
0337 
0338   template <>
0339   DataFormatKF makeDataFormat<VariableKF::R11>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0340     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0341     const int baseShift = iConfig.baseShiftR11_;
0342     const int width = iConfig.widthR11_;
0343     const double base = std::pow(2., baseShift) * x3.base() * x3.base();
0344     const double range = base * std::pow(2, width);
0345     return DataFormatKF(VariableKF::R11, false, iConfig.enableIntegerEmulation_, width, base, range);
0346   }
0347 
0348   template <>
0349   DataFormatKF makeDataFormat<VariableKF::R00Rough>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0350     const DataFormatKF R00 = makeDataFormat<VariableKF::R00>(dataFormats, iConfig);
0351     const int width = dataFormats->setup()->widthAddrBRAM18();
0352     const double range = R00.range();
0353     const int baseShift = R00.width() - width - 1;
0354     const double base = std::pow(2., baseShift) * R00.base();
0355     return DataFormatKF(VariableKF::R00Rough, false, iConfig.enableIntegerEmulation_, width, base, range);
0356   }
0357 
0358   template <>
0359   DataFormatKF makeDataFormat<VariableKF::R11Rough>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0360     const DataFormatKF R11 = makeDataFormat<VariableKF::R11>(dataFormats, iConfig);
0361     const int width = dataFormats->setup()->widthAddrBRAM18();
0362     const double range = R11.range();
0363     const int baseShift = R11.width() - width - 1;
0364     const double base = std::pow(2., baseShift) * R11.base();
0365     return DataFormatKF(VariableKF::R11Rough, false, iConfig.enableIntegerEmulation_, width, base, range);
0366   }
0367 
0368   template <>
0369   DataFormatKF makeDataFormat<VariableKF::invR00Approx>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0370     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0371     const int baseShift = iConfig.baseShiftInvR00Approx_;
0372     const double base = std::pow(2., baseShift) / x1.base() / x1.base();
0373     const int width = dataFormats->setup()->widthDSPbu();
0374     const double range = base * std::pow(2, width);
0375     return DataFormatKF(VariableKF::invR00Approx, false, iConfig.enableIntegerEmulation_, width, base, range);
0376   }
0377 
0378   template <>
0379   DataFormatKF makeDataFormat<VariableKF::invR11Approx>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0380     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0381     const int baseShift = iConfig.baseShiftInvR11Approx_;
0382     const double base = std::pow(2., baseShift) / x3.base() / x3.base();
0383     const int width = dataFormats->setup()->widthDSPbu();
0384     const double range = base * std::pow(2, width);
0385     return DataFormatKF(VariableKF::invR11Approx, false, iConfig.enableIntegerEmulation_, width, base, range);
0386   }
0387 
0388   template <>
0389   DataFormatKF makeDataFormat<VariableKF::invR00Cor>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0390     const int baseShift = iConfig.baseShiftInvR00Cor_;
0391     const double base = std::pow(2., baseShift);
0392     const int width = dataFormats->setup()->widthDSPau();
0393     const double range = base * std::pow(2, width);
0394     return DataFormatKF(VariableKF::invR00Cor, false, iConfig.enableIntegerEmulation_, width, base, range);
0395   }
0396 
0397   template <>
0398   DataFormatKF makeDataFormat<VariableKF::invR11Cor>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0399     const int baseShift = iConfig.baseShiftInvR11Cor_;
0400     const double base = std::pow(2., baseShift);
0401     const int width = dataFormats->setup()->widthDSPau();
0402     const double range = base * std::pow(2, width);
0403     return DataFormatKF(VariableKF::invR11Cor, false, iConfig.enableIntegerEmulation_, width, base, range);
0404   }
0405 
0406   template <>
0407   DataFormatKF makeDataFormat<VariableKF::invR00>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0408     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0409     const int baseShift = iConfig.baseShiftInvR00_;
0410     const double base = std::pow(2., baseShift) / x1.base() / x1.base();
0411     const int width = dataFormats->setup()->widthDSPbu();
0412     const double range = base * std::pow(2, width);
0413     return DataFormatKF(VariableKF::invR00, false, iConfig.enableIntegerEmulation_, width, base, range);
0414   }
0415 
0416   template <>
0417   DataFormatKF makeDataFormat<VariableKF::invR11>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0418     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0419     const int baseShift = iConfig.baseShiftInvR11_;
0420     const double base = std::pow(2., baseShift) / x3.base() / x3.base();
0421     const int width = dataFormats->setup()->widthDSPbu();
0422     const double range = base * std::pow(2, width);
0423     return DataFormatKF(VariableKF::invR11, false, iConfig.enableIntegerEmulation_, width, base, range);
0424   }
0425 
0426   template <>
0427   DataFormatKF makeDataFormat<VariableKF::C00>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0428     const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf);
0429     const int baseShift = iConfig.baseShiftC00_;
0430     const int width = iConfig.widthC00_;
0431     const double base = std::pow(2., baseShift) * x0.base() * x0.base();
0432     const double range = base * std::pow(2, width);
0433     return DataFormatKF(VariableKF::C00, false, iConfig.enableIntegerEmulation_, width, base, range);
0434   }
0435 
0436   template <>
0437   DataFormatKF makeDataFormat<VariableKF::C01>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0438     const DataFormat& x0 = dataFormats->format(Variable::inv2R, Process::kf);
0439     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0440     const int baseShift = iConfig.baseShiftC01_;
0441     const int width = iConfig.widthC01_;
0442     const double base = std::pow(2., baseShift) * x0.base() * x1.base();
0443     const double range = base * std::pow(2, width);
0444     return DataFormatKF(VariableKF::C01, true, iConfig.enableIntegerEmulation_, width, base, range);
0445   }
0446 
0447   template <>
0448   DataFormatKF makeDataFormat<VariableKF::C11>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0449     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0450     const int baseShift = iConfig.baseShiftC11_;
0451     const int width = iConfig.widthC11_;
0452     const double base = std::pow(2., baseShift) * x1.base() * x1.base();
0453     const double range = base * std::pow(2, width);
0454     return DataFormatKF(VariableKF::C11, false, iConfig.enableIntegerEmulation_, width, base, range);
0455   }
0456 
0457   template <>
0458   DataFormatKF makeDataFormat<VariableKF::C22>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0459     const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf);
0460     const int baseShift = iConfig.baseShiftC22_;
0461     const int width = iConfig.widthC22_;
0462     const double base = std::pow(2., baseShift) * x2.base() * x2.base();
0463     const double range = base * std::pow(2, width);
0464     return DataFormatKF(VariableKF::C22, false, iConfig.enableIntegerEmulation_, width, base, range);
0465   }
0466 
0467   template <>
0468   DataFormatKF makeDataFormat<VariableKF::C23>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0469     const DataFormat& x2 = dataFormats->format(Variable::cot, Process::kf);
0470     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0471     const int baseShift = iConfig.baseShiftC23_;
0472     const int width = iConfig.widthC23_;
0473     const double base = std::pow(2., baseShift) * x2.base() * x3.base();
0474     const double range = base * std::pow(2, width);
0475     return DataFormatKF(VariableKF::C23, true, iConfig.enableIntegerEmulation_, width, base, range);
0476   }
0477 
0478   template <>
0479   DataFormatKF makeDataFormat<VariableKF::C33>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0480     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0481     const int baseShift = iConfig.baseShiftC33_;
0482     const int width = iConfig.widthC33_;
0483     const double base = std::pow(2., baseShift) * x3.base() * x3.base();
0484     const double range = base * std::pow(2, width);
0485     return DataFormatKF(VariableKF::C33, false, iConfig.enableIntegerEmulation_, width, base, range);
0486   }
0487 
0488   template <>
0489   DataFormatKF makeDataFormat<VariableKF::r0Shifted>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0490     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0491     const int baseShift = iConfig.baseShiftr0Shifted_;
0492     const double base = std::pow(2., baseShift) * x1.base();
0493     const int width = dataFormats->setup()->widthDSPbb();
0494     const double range = base * std::pow(2, width);
0495     return DataFormatKF(VariableKF::r0Shifted, true, iConfig.enableIntegerEmulation_, width, base, range);
0496   }
0497 
0498   template <>
0499   DataFormatKF makeDataFormat<VariableKF::r1Shifted>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0500     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0501     const int baseShift = iConfig.baseShiftr1Shifted_;
0502     const double base = std::pow(2., baseShift) * x3.base();
0503     const int width = dataFormats->setup()->widthDSPbb();
0504     const double range = base * std::pow(2, width);
0505     return DataFormatKF(VariableKF::r1Shifted, true, iConfig.enableIntegerEmulation_, width, base, range);
0506   }
0507 
0508   template <>
0509   DataFormatKF makeDataFormat<VariableKF::r02>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0510     const DataFormat& x1 = dataFormats->format(Variable::phiT, Process::kf);
0511     const int baseShift = iConfig.baseShiftr02_;
0512     const double base = std::pow(2., baseShift) * x1.base() * x1.base();
0513     const int width = dataFormats->setup()->widthDSPbu();
0514     const double range = base * std::pow(2, width);
0515     return DataFormatKF(VariableKF::r02, false, iConfig.enableIntegerEmulation_, width, base, range);
0516   }
0517 
0518   template <>
0519   DataFormatKF makeDataFormat<VariableKF::r12>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0520     const DataFormat& x3 = dataFormats->format(Variable::zT, Process::kf);
0521     const int baseShift = iConfig.baseShiftr12_;
0522     const double base = std::pow(2., baseShift) * x3.base() * x3.base();
0523     const int width = dataFormats->setup()->widthDSPbu();
0524     const double range = base * std::pow(2, width);
0525     return DataFormatKF(VariableKF::r12, false, iConfig.enableIntegerEmulation_, width, base, range);
0526   }
0527 
0528   template <>
0529   DataFormatKF makeDataFormat<VariableKF::chi20>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0530     const int baseShift = iConfig.baseShiftchi20_;
0531     const double base = std::pow(2., baseShift);
0532     const int width = dataFormats->setup()->widthDSPbu();
0533     const double range = base * std::pow(2, width);
0534     return DataFormatKF(VariableKF::chi20, false, iConfig.enableIntegerEmulation_, width, base, range);
0535   }
0536 
0537   template <>
0538   DataFormatKF makeDataFormat<VariableKF::chi21>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0539     const int baseShift = iConfig.baseShiftchi21_;
0540     const double base = std::pow(2., baseShift);
0541     const int width = dataFormats->setup()->widthDSPbu();
0542     const double range = base * std::pow(2, width);
0543     return DataFormatKF(VariableKF::chi21, false, iConfig.enableIntegerEmulation_, width, base, range);
0544   }
0545 
0546   template <>
0547   DataFormatKF makeDataFormat<VariableKF::dH>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0548     const DataFormat& ctb = dataFormats->format(Variable::r, Process::ctb);
0549     const int width = dataFormats->setup()->widthAddrBRAM18();
0550     const double range = dataFormats->setup()->outerRadius() - dataFormats->setup()->innerRadius();
0551     const double base = ctb.base() * std::pow(2, std::ceil(std::log2(range / ctb.base())) - width);
0552     return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range);
0553   }
0554 
0555   template <>
0556   DataFormatKF makeDataFormat<VariableKF::invdH>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0557     const DataFormatKF H00 = makeDataFormat<VariableKF::H00>(dataFormats, iConfig);
0558     const int width = dataFormats->setup()->widthDSPbu();
0559     const double range = 1. / dataFormats->setup()->kfMinSeedDeltaR();
0560     const int baseShift = std::ceil(std::log2(range * std::pow(2., -width) * H00.base()));
0561     const double base = std::pow(2., baseShift) / H00.base();
0562     return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range);
0563   }
0564 
0565   template <>
0566   DataFormatKF makeDataFormat<VariableKF::invdH2>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0567     const DataFormatKF H00 = makeDataFormat<VariableKF::H00>(dataFormats, iConfig);
0568     const int width = dataFormats->setup()->widthDSPbu();
0569     const double range = 1. / pow(dataFormats->setup()->kfMinSeedDeltaR(), 2);
0570     const double baseH2 = H00.base() * H00.base();
0571     const int baseShift = std::ceil(std::log2(range * std::pow(2., -width) * baseH2));
0572     const double base = std::pow(2., baseShift) / baseH2;
0573     return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range);
0574   }
0575 
0576   template <>
0577   DataFormatKF makeDataFormat<VariableKF::H2>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0578     const DataFormatKF H00 = makeDataFormat<VariableKF::H00>(dataFormats, iConfig);
0579     const int width = H00.width() + H00.width();
0580     const double base = H00.base() * H00.base();
0581     const double range = H00.range() * H00.range();
0582     return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range);
0583   }
0584 
0585   template <>
0586   DataFormatKF makeDataFormat<VariableKF::Hm0>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0587     const DataFormatKF H00 = makeDataFormat<VariableKF::H00>(dataFormats, iConfig);
0588     const DataFormatKF m0 = makeDataFormat<VariableKF::m0>(dataFormats, iConfig);
0589     const int width = H00.width() + m0.width();
0590     const double base = H00.base() * m0.base();
0591     const double range = H00.range() * m0.range();
0592     return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range);
0593   }
0594 
0595   template <>
0596   DataFormatKF makeDataFormat<VariableKF::Hm1>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0597     const DataFormatKF H12 = makeDataFormat<VariableKF::H12>(dataFormats, iConfig);
0598     const DataFormatKF m1 = makeDataFormat<VariableKF::m1>(dataFormats, iConfig);
0599     const int width = H12.width() + m1.width();
0600     const double base = H12.base() * m1.base();
0601     const double range = H12.range() * m1.range();
0602     return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range);
0603   }
0604 
0605   template <>
0606   DataFormatKF makeDataFormat<VariableKF::Hv0>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0607     const DataFormatKF H00 = makeDataFormat<VariableKF::H00>(dataFormats, iConfig);
0608     const DataFormatKF v0 = makeDataFormat<VariableKF::v0>(dataFormats, iConfig);
0609     const int width = dataFormats->setup()->widthDSPab();
0610     const double base = H00.base() * v0.base() * pow(2, H00.width() + v0.width() - width);
0611     const double range = H00.range() * v0.range();
0612     return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range);
0613   }
0614 
0615   template <>
0616   DataFormatKF makeDataFormat<VariableKF::Hv1>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0617     const DataFormatKF H12 = makeDataFormat<VariableKF::H12>(dataFormats, iConfig);
0618     const DataFormatKF v1 = makeDataFormat<VariableKF::v1>(dataFormats, iConfig);
0619     const int width = dataFormats->setup()->widthDSPab();
0620     const double base = H12.base() * v1.base() * pow(2, H12.width() + v1.width() - width);
0621     const double range = H12.range() * v1.range();
0622     return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range);
0623   }
0624 
0625   template <>
0626   DataFormatKF makeDataFormat<VariableKF::H2v0>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0627     const DataFormatKF H00 = makeDataFormat<VariableKF::H00>(dataFormats, iConfig);
0628     const DataFormatKF v0 = makeDataFormat<VariableKF::v0>(dataFormats, iConfig);
0629     const int width = dataFormats->setup()->widthDSPau();
0630     const double base = H00.base() * H00.base() * v0.base() * pow(2, 2 * H00.width() + v0.width() - width);
0631     const double range = H00.range() * H00.range() * v0.range();
0632     return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range);
0633   }
0634 
0635   template <>
0636   DataFormatKF makeDataFormat<VariableKF::H2v1>(const DataFormats* dataFormats, const ConfigKF& iConfig) {
0637     const DataFormatKF H12 = makeDataFormat<VariableKF::H12>(dataFormats, iConfig);
0638     const DataFormatKF v1 = makeDataFormat<VariableKF::v1>(dataFormats, iConfig);
0639     const int width = dataFormats->setup()->widthDSPau();
0640     const double base = H12.base() * H12.base() * v1.base() * pow(2, 2 * H12.width() + v1.width() - width);
0641     const double range = H12.range() * H12.range() * v1.range();
0642     return DataFormatKF(VariableKF::end, false, iConfig.enableIntegerEmulation_, width, base, range);
0643   }
0644 
0645 }  // namespace trackerTFP