Back to home page

Project CMSSW displayed by LXR

 
 

    


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   // default constructor, trying to need space as proper constructed object
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   // method to count number of unique data formats
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   // proper constructor
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   // constructs data formats of all unique used variables and flavours
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   // helper (loop) data formats of all unique used variables and flavours
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 }  // namespace trackerTFP