File indexing completed on 2025-06-03 00:12:16
0001 #include "L1Trigger/TrackerTFP/interface/DataFormats.h"
0002 #include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h"
0003
0004 #include <vector>
0005 #include <deque>
0006 #include <cmath>
0007 #include <tuple>
0008 #include <iterator>
0009 #include <algorithm>
0010 #include <string>
0011 #include <iostream>
0012 #include <numeric>
0013
0014 namespace trackerTFP {
0015
0016
0017 DataFormats::DataFormats()
0018 : numDataFormats_(0),
0019 formats_(+Variable::end, std::vector<DataFormat*>(+Process::end, nullptr)),
0020 numUnusedBitsStubs_(+Process::end, TTBV::S_ - 1),
0021 numUnusedBitsTracks_(+Process::end, TTBV::S_ - 1),
0022 numChannel_(+Process::end, 0) {
0023 setup_ = nullptr;
0024 countFormats();
0025 dataFormats_.reserve(numDataFormats_);
0026 numStreamsStubs_.reserve(+Process::end);
0027 numStreamsTracks_.reserve(+Process::end);
0028 }
0029
0030
0031 template <Variable v, Process p>
0032 void DataFormats::countFormats() {
0033 if constexpr (config_[+v][+p] == p)
0034 numDataFormats_++;
0035 constexpr Process nextP = p + 1;
0036 if constexpr (nextP != Process::end)
0037 countFormats<v, nextP>();
0038 else {
0039 constexpr Variable nextV = v + 1;
0040 if constexpr (nextV != Variable::end)
0041 countFormats<nextV>();
0042 }
0043 }
0044
0045
0046 DataFormats::DataFormats(const tt::Setup* setup) : DataFormats() {
0047 setup_ = setup;
0048 fillDataFormats();
0049 for (const Process p : Processes)
0050 for (const Variable v : stubs_[+p])
0051 numUnusedBitsStubs_[+p] -= formats_[+v][+p] ? formats_[+v][+p]->width() : 0;
0052 for (const Process p : Processes)
0053 for (const Variable v : tracks_[+p])
0054 numUnusedBitsTracks_[+p] -= formats_[+v][+p] ? formats_[+v][+p]->width() : 0;
0055 numChannel_[+Process::dtc] = setup_->numDTCsPerRegion();
0056 numChannel_[+Process::pp] = setup_->numDTCsPerTFP();
0057 numChannel_[+Process::gp] = setup_->numSectors();
0058 numChannel_[+Process::ht] = setup_->htNumBinsInv2R();
0059 numChannel_[+Process::ctb] = setup_->kfNumWorker();
0060 numChannel_[+Process::kf] = setup_->kfNumWorker();
0061 numChannel_[+Process::dr] = 1;
0062 for (const Process& p : {Process::dtc, Process::pp, Process::gp, Process::ht}) {
0063 numStreamsStubs_.push_back(numChannel_[+p] * setup_->numRegions());
0064 numStreamsTracks_.push_back(0);
0065 }
0066 for (const Process& p : {Process::ctb, Process::kf, Process::dr}) {
0067 numStreamsTracks_.emplace_back(numChannel_[+p] * setup_->numRegions());
0068 numStreamsStubs_.emplace_back(numStreamsTracks_.back() * setup_->numLayers());
0069 }
0070 }
0071
0072
0073 template <Variable v, Process p>
0074 void DataFormats::fillDataFormats() {
0075 if constexpr (config_[+v][+p] == p) {
0076 dataFormats_.emplace_back(makeDataFormat<v, p>(setup_));
0077 fillFormats<v, p>();
0078 }
0079 constexpr Process nextP = p + 1;
0080 if constexpr (nextP != Process::end)
0081 fillDataFormats<v, nextP>();
0082 else {
0083 constexpr Variable nextV = v + 1;
0084 if constexpr (nextV != Variable::end)
0085 fillDataFormats<nextV>();
0086 }
0087 }
0088
0089
0090 template <Variable v, Process p, Process it>
0091 void DataFormats::fillFormats() {
0092 if (config_[+v][+it] == p) {
0093 formats_[+v][+it] = &dataFormats_.back();
0094 }
0095 constexpr Process nextIt = it + 1;
0096 if constexpr (nextIt != Process::end)
0097 fillFormats<v, p, nextIt>();
0098 }
0099
0100 template <>
0101 DataFormat makeDataFormat<Variable::inv2R, Process::tfp>(const tt::Setup* setup) {
0102 const int width = TTTrack_TrackWord::TrackBitWidths::kRinvSize;
0103 const double range = -2. * TTTrack_TrackWord::minRinv;
0104 const double base = range * std::pow(2, -width);
0105 return DataFormat(true, width, base, range);
0106 }
0107 template <>
0108 DataFormat makeDataFormat<Variable::phiT, Process::tfp>(const tt::Setup* setup) {
0109 const int width = TTTrack_TrackWord::TrackBitWidths::kPhiSize;
0110 const double range = -2. * TTTrack_TrackWord::minPhi0;
0111 const double base = range * std::pow(2, -width);
0112 return DataFormat(true, width, base, range);
0113 }
0114 template <>
0115 DataFormat makeDataFormat<Variable::cot, Process::tfp>(const tt::Setup* setup) {
0116 const int width = TTTrack_TrackWord::TrackBitWidths::kTanlSize;
0117 const double range = -2. * TTTrack_TrackWord::minTanl;
0118 const double base = range * std::pow(2, -width);
0119 return DataFormat(true, width, base, range);
0120 }
0121 template <>
0122 DataFormat makeDataFormat<Variable::zT, Process::tfp>(const tt::Setup* setup) {
0123 const int width = TTTrack_TrackWord::TrackBitWidths::kZ0Size;
0124 const double range = -2. * TTTrack_TrackWord::minZ0;
0125 const double base = range * std::pow(2, -width);
0126 return DataFormat(true, width, base, range);
0127 }
0128
0129 template <>
0130 DataFormat makeDataFormat<Variable::r, Process::dtc>(const tt::Setup* setup) {
0131 const DataFormat phiT = makeDataFormat<Variable::phiT, Process::ht>(setup);
0132 const DataFormat inv2R = makeDataFormat<Variable::inv2R, Process::ht>(setup);
0133 const int width = setup->tmttWidthR();
0134 const double range = 2. * setup->maxRphi();
0135 const double baseShifted = phiT.base() / inv2R.base();
0136 const int shift = std::ceil(std::log2(range / baseShifted)) - width;
0137 const double base = baseShifted * std::pow(2., shift);
0138 return DataFormat(true, width, base, range);
0139 }
0140 template <>
0141 DataFormat makeDataFormat<Variable::phi, Process::dtc>(const tt::Setup* setup) {
0142 const DataFormat phiT = makeDataFormat<Variable::phiT, Process::gp>(setup);
0143 const DataFormat inv2R = makeDataFormat<Variable::inv2R, Process::ht>(setup);
0144 const int width = setup->tmttWidthPhi();
0145 const double range = phiT.range() + inv2R.range() * setup->maxRphi();
0146 const int shift = std::ceil(std::log2(range / phiT.base())) - width;
0147 const double base = phiT.base() * std::pow(2., shift);
0148 return DataFormat(true, width, base, range);
0149 }
0150 template <>
0151 DataFormat makeDataFormat<Variable::z, Process::dtc>(const tt::Setup* setup) {
0152 const DataFormat zT = makeDataFormat<Variable::zT, Process::gp>(setup);
0153 const int width = setup->tmttWidthZ();
0154 const double range = 2. * setup->halfLength();
0155 const int shift = std::ceil(std::log2(range / zT.base())) - width;
0156 const double base = zT.base() * std::pow(2., shift);
0157 return DataFormat(true, width, base, range);
0158 }
0159 template <>
0160 DataFormat makeDataFormat<Variable::layer, Process::dtc>(const tt::Setup* setup) {
0161 const int width = 5;
0162 return DataFormat(false, width, 1., width);
0163 }
0164
0165 template <>
0166 DataFormat makeDataFormat<Variable::phi, Process::gp>(const tt::Setup* setup) {
0167 const DataFormat phi = makeDataFormat<Variable::phi, Process::dtc>(setup);
0168 const DataFormat inv2R = makeDataFormat<Variable::inv2R, Process::ht>(setup);
0169 const DataFormat phiT = makeDataFormat<Variable::phiT, Process::gp>(setup);
0170 const double base = phi.base();
0171 const double range = phiT.base() + inv2R.range() * setup->maxRphi();
0172 const int width = std::ceil(std::log2(range / base));
0173 return DataFormat(true, width, base, range);
0174 }
0175 template <>
0176 DataFormat makeDataFormat<Variable::z, Process::gp>(const tt::Setup* setup) {
0177 const DataFormat z = makeDataFormat<Variable::z, Process::dtc>(setup);
0178 const DataFormat zT = makeDataFormat<Variable::zT, Process::gp>(setup);
0179 const double rangeCot = (zT.base() + 2. * setup->beamWindowZ()) / setup->chosenRofZ();
0180 const double base = z.base();
0181 const double range = zT.base() + rangeCot * setup->maxRz();
0182 const int width = std::ceil(std::log2(range / base));
0183 return DataFormat(true, width, base, range);
0184 }
0185 template <>
0186 DataFormat makeDataFormat<Variable::phiT, Process::gp>(const tt::Setup* setup) {
0187 const double range = 2. * M_PI / setup->numRegions();
0188 const int width = std::ceil(std::log2(setup->gpNumBinsPhiT()));
0189 const double base = range / std::pow(2., width);
0190 return DataFormat(true, width, base, range);
0191 }
0192 template <>
0193 DataFormat makeDataFormat<Variable::zT, Process::gp>(const tt::Setup* setup) {
0194 const double range = 2. * std::sinh(setup->maxEta()) * setup->chosenRofZ();
0195 const double base = range / setup->gpNumBinsZT();
0196 const int width = std::ceil(std::log2(setup->gpNumBinsZT()));
0197 return DataFormat(true, width, base, range);
0198 }
0199 template <>
0200 DataFormat makeDataFormat<Variable::cot, Process::gp>(const tt::Setup* setup) {
0201 const DataFormat zT = makeDataFormat<Variable::zT, Process::gp>(setup);
0202 const DataFormat r = makeDataFormat<Variable::r, Process::dtc>(setup);
0203 const int width = setup->widthDSPbb();
0204 const double range = (zT.range() - zT.base() + 2. * setup->beamWindowZ()) / setup->chosenRofZ();
0205 const double baseShifted = zT.base() / r.base();
0206 const int baseShift = std::ceil(std::log2(range / baseShifted)) - width;
0207 const double base = baseShifted * std::pow(2, baseShift);
0208 return DataFormat(true, width, base, range);
0209 }
0210 template <>
0211 DataFormat makeDataFormat<Variable::layer, Process::gp>(const tt::Setup* setup) {
0212 const int width = 6;
0213 return DataFormat(false, width, 1., width);
0214 }
0215
0216 template <>
0217 DataFormat makeDataFormat<Variable::phi, Process::ht>(const tt::Setup* setup) {
0218 const DataFormat phi = makeDataFormat<Variable::phi, Process::dtc>(setup);
0219 const DataFormat phiT = makeDataFormat<Variable::phiT, Process::ht>(setup);
0220 const DataFormat inv2R = makeDataFormat<Variable::inv2R, Process::ht>(setup);
0221 const double range = phiT.base() + setup->maxRphi() * inv2R.base();
0222 const double base = phi.base();
0223 const int width = std::ceil(std::log2(range / base));
0224 return DataFormat(true, width, base, range);
0225 }
0226 template <>
0227 DataFormat makeDataFormat<Variable::inv2R, Process::ht>(const tt::Setup* setup) {
0228 const double range = 2. * setup->invPtToDphi() / setup->minPt();
0229 const double base = range / setup->htNumBinsInv2R();
0230 const int width = std::ceil(std::log2(setup->htNumBinsInv2R()));
0231 return DataFormat(true, width, base, range);
0232 }
0233 template <>
0234 DataFormat makeDataFormat<Variable::phiT, Process::ht>(const tt::Setup* setup) {
0235 const DataFormat phiT = makeDataFormat<Variable::phiT, Process::gp>(setup);
0236 const double range = phiT.range();
0237 const double base = phiT.base() / setup->htNumBinsPhiT();
0238 const int width = std::ceil(std::log2(range / base));
0239 return DataFormat(true, width, base, range);
0240 }
0241
0242 template <>
0243 DataFormat makeDataFormat<Variable::dPhi, Process::ctb>(const tt::Setup* setup) {
0244 const DataFormat phi = makeDataFormat<Variable::phi, Process::dtc>(setup);
0245 const DataFormat inv2R = makeDataFormat<Variable::inv2R, Process::ht>(setup);
0246 const double sigma = setup->pitchRowPS() / 2. / setup->innerRadius();
0247 const double pt = (setup->pitchCol2S() + setup->scattering()) / 2. * inv2R.range() / 2.;
0248 const double range = sigma + pt;
0249 const double base = phi.base();
0250 const int width = std::ceil(std::log2(range / base));
0251 return DataFormat(false, width, base, range);
0252 }
0253 template <>
0254 DataFormat makeDataFormat<Variable::dZ, Process::ctb>(const tt::Setup* setup) {
0255 const DataFormat z = makeDataFormat<Variable::z, Process::dtc>(setup);
0256 const double range = setup->pitchCol2S() / 2. * std::sinh(setup->maxEta());
0257 const double base = z.base();
0258 const int width = std::ceil(std::log2(range / base));
0259 return DataFormat(false, width, base, range);
0260 }
0261 template <>
0262 DataFormat makeDataFormat<Variable::layer, Process::ctb>(const tt::Setup* setup) {
0263 const double range = setup->numLayers();
0264 const int width = std::ceil(std::log2(range));
0265 return DataFormat(false, width, 1., range);
0266 }
0267
0268 template <>
0269 DataFormat makeDataFormat<Variable::inv2R, Process::kf>(const tt::Setup* setup) {
0270 const DataFormat tfp = makeDataFormat<Variable::inv2R, Process::tfp>(setup);
0271 const DataFormat ht = makeDataFormat<Variable::inv2R, Process::ht>(setup);
0272 const double range = ht.range() + 2. * ht.base();
0273 const double base = ht.base() * std::pow(2., std::floor(std::log2(.5 * tfp.base() / ht.base())));
0274 const int width = std::ceil(std::log2(range / base));
0275 return DataFormat(true, width, base, range);
0276 }
0277 template <>
0278 DataFormat makeDataFormat<Variable::phiT, Process::kf>(const tt::Setup* setup) {
0279 const DataFormat tfp = makeDataFormat<Variable::phiT, Process::tfp>(setup);
0280 const DataFormat ht = makeDataFormat<Variable::phiT, Process::ht>(setup);
0281 const double range = ht.range() + 2. * ht.base();
0282 const double base = ht.base() * std::pow(2., std::floor(std::log2(tfp.base() / ht.base())));
0283 const int width = std::ceil(std::log2(range / base));
0284 return DataFormat(true, width, base, range);
0285 }
0286 template <>
0287 DataFormat makeDataFormat<Variable::cot, Process::kf>(const tt::Setup* setup) {
0288 const DataFormat tfp = makeDataFormat<Variable::cot, Process::tfp>(setup);
0289 const DataFormat zT = makeDataFormat<Variable::zT, Process::gp>(setup);
0290 const DataFormat r = makeDataFormat<Variable::r, Process::dtc>(setup);
0291 const double range = (zT.base() + 2. * setup->beamWindowZ()) / setup->chosenRofZ();
0292 const double base = zT.base() / r.base() * std::pow(2., std::floor(std::log2(tfp.base() / zT.base() * r.base())));
0293 const int width = ceil(log2(range / base));
0294 return DataFormat(true, width, base, range);
0295 }
0296 template <>
0297 DataFormat makeDataFormat<Variable::zT, Process::kf>(const tt::Setup* setup) {
0298 const DataFormat tfp = makeDataFormat<Variable::zT, Process::tfp>(setup);
0299 const DataFormat gp = makeDataFormat<Variable::zT, Process::gp>(setup);
0300 const double range = gp.range();
0301 const double base = gp.base() * std::pow(2., std::floor(std::log2(tfp.base() / gp.base())));
0302 const int width = std::ceil(std::log2(range / base));
0303 return DataFormat(true, width, base, range);
0304 }
0305 template <>
0306 DataFormat makeDataFormat<Variable::phi, Process::kf>(const tt::Setup* setup) {
0307 const DataFormat phi = makeDataFormat<Variable::phi, Process::dtc>(setup);
0308 const DataFormat phiT = makeDataFormat<Variable::phiT, Process::kf>(setup);
0309 const DataFormat inv2R = makeDataFormat<Variable::inv2R, Process::kf>(setup);
0310 const double range = phiT.base() + setup->maxRphi() * inv2R.base();
0311 const double base = phi.base();
0312 const int width = std::ceil(std::log2(range / base));
0313 return DataFormat(true, width, base, range);
0314 }
0315 template <>
0316 DataFormat makeDataFormat<Variable::match, Process::kf>(const tt::Setup* setup) {
0317 const int width = 1;
0318 return DataFormat(false, width, 1., width);
0319 }
0320
0321 template <>
0322 DataFormat makeDataFormat<Variable::cot, Process::dr>(const tt::Setup* setup) {
0323 const DataFormat kf = makeDataFormat<Variable::cot, Process::kf>(setup);
0324 const DataFormat zT = makeDataFormat<Variable::zT, Process::kf>(setup);
0325 const double range = (zT.range() + 2. * setup->beamWindowZ()) / setup->chosenRofZ();
0326 const double base = kf.base();
0327 const int width = std::ceil(std::log2(range / base));
0328 return DataFormat(true, width, base, range);
0329 }
0330
0331 }