File indexing completed on 2025-06-03 00:12:22
0001 #include "L1Trigger/TrackFindingTracklet/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 trklet {
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 channelAssignment_ = nullptr;
0023 countFormats();
0024 dataFormats_.reserve(numDataFormats_);
0025 }
0026
0027
0028 template <Variable v, Process p>
0029 void DataFormats::countFormats() {
0030 if constexpr (config_[+v][+p] == p)
0031 numDataFormats_++;
0032 if constexpr (++p != Process::end)
0033 countFormats<v, ++p>();
0034 else if constexpr (++v != Variable::end)
0035 countFormats<++v>();
0036 }
0037
0038
0039 DataFormats::DataFormats(const ChannelAssignment* channelAssignment) : DataFormats() {
0040 channelAssignment_ = channelAssignment;
0041 fillDataFormats();
0042 for (const Process p : Processes)
0043 for (const Variable v : stubs_[+p])
0044 numUnusedBitsStubs_[+p] -= formats_[+v][+p] ? formats_[+v][+p]->width() : 0;
0045 for (const Process p : Processes)
0046 for (const Variable v : tracks_[+p])
0047 numUnusedBitsTracks_[+p] -= formats_[+v][+p] ? formats_[+v][+p]->width() : 0;
0048 }
0049
0050
0051 template <Variable v, Process p>
0052 void DataFormats::fillDataFormats() {
0053 if constexpr (config_[+v][+p] == p) {
0054 dataFormats_.emplace_back(makeDataFormat<v, p>(channelAssignment_));
0055 fillFormats<v, p>();
0056 }
0057 if constexpr (++p != Process::end)
0058 fillDataFormats<v, ++p>();
0059 else if constexpr (++v != Variable::end)
0060 fillDataFormats<++v>();
0061 }
0062
0063
0064 template <Variable v, Process p, Process it>
0065 void DataFormats::fillFormats() {
0066 if (config_[+v][+it] == p) {
0067 formats_[+v][+it] = &dataFormats_.back();
0068 }
0069 if constexpr (++it != Process::end)
0070 fillFormats<v, p, ++it>();
0071 }
0072
0073 template <>
0074 DataFormat makeDataFormat<Variable::inv2R, Process::tfp>(const ChannelAssignment* ca) {
0075 const int width = TTTrack_TrackWord::TrackBitWidths::kRinvSize;
0076 const double range = -2. * TTTrack_TrackWord::minRinv;
0077 const double base = range * std::pow(2, -width);
0078 return DataFormat(true, width, base, range);
0079 }
0080 template <>
0081 DataFormat makeDataFormat<Variable::phiT, Process::tfp>(const ChannelAssignment* ca) {
0082 const int width = TTTrack_TrackWord::TrackBitWidths::kPhiSize;
0083 const double range = -2. * TTTrack_TrackWord::minPhi0;
0084 const double base = range * std::pow(2, -width);
0085 return DataFormat(true, width, base, range);
0086 }
0087 template <>
0088 DataFormat makeDataFormat<Variable::cot, Process::tfp>(const ChannelAssignment* ca) {
0089 const int width = TTTrack_TrackWord::TrackBitWidths::kTanlSize;
0090 const double range = -2. * TTTrack_TrackWord::minTanl;
0091 const double base = range * std::pow(2, -width);
0092 return DataFormat(true, width, base, range);
0093 }
0094 template <>
0095 DataFormat makeDataFormat<Variable::zT, Process::tfp>(const ChannelAssignment* ca) {
0096 const int width = TTTrack_TrackWord::TrackBitWidths::kZ0Size;
0097 const double range = -2. * TTTrack_TrackWord::minZ0;
0098 const double base = range * std::pow(2, -width);
0099 return DataFormat(true, width, base, range);
0100 }
0101
0102 template <>
0103 DataFormat makeDataFormat<Variable::inv2R, Process::tm>(const ChannelAssignment* ca) {
0104 const tt::Setup* s = ca->setup();
0105 const double thight = s->htNumBinsInv2R();
0106 const double loose = thight + 2;
0107 const double range = 2. * s->invPtToDphi() / s->minPt() * loose / thight;
0108 const double base = range / loose;
0109 const int width = std::ceil(std::log2(range / base));
0110 return DataFormat(true, width, base, range);
0111 }
0112 template <>
0113 DataFormat makeDataFormat<Variable::phiT, Process::tm>(const ChannelAssignment* ca) {
0114 const tt::Setup* s = ca->setup();
0115 const double thight = s->gpNumBinsPhiT() * s->htNumBinsPhiT();
0116 const double loose = thight + 2 * s->gpNumBinsPhiT();
0117 const double range = 2. * M_PI / s->numRegions() * loose / thight;
0118 const double base = range / loose;
0119 const int width = std::ceil(std::log2(range / base));
0120 return DataFormat(true, width, base, range);
0121 }
0122 template <>
0123 DataFormat makeDataFormat<Variable::zT, Process::tm>(const ChannelAssignment* ca) {
0124 const tt::Setup* s = ca->setup();
0125 const double thight = s->gpNumBinsZT();
0126 const double loose = thight + 2;
0127 const double range = 2. * std::sinh(s->maxEta()) * s->chosenRofZ() * loose / thight;
0128 const double base = range / loose;
0129 const int width = std::ceil(std::log2(range / base));
0130 return DataFormat(true, width, base, range);
0131 }
0132 template <>
0133 DataFormat makeDataFormat<Variable::cot, Process::tm>(const ChannelAssignment* ca) {
0134 const tt::Setup* s = ca->setup();
0135 const DataFormat zT = makeDataFormat<Variable::zT, Process::tm>(ca);
0136 const double range = (zT.range() + 2. * s->beamWindowZ()) / s->chosenRofZ();
0137 const double base = (zT.base() + 2. * s->beamWindowZ()) / s->chosenRofZ();
0138 const int width = std::ceil(std::log2(range / base));
0139 return DataFormat(true, width, base, range);
0140 }
0141
0142 template <>
0143 DataFormat makeDataFormat<Variable::stubId, Process::tm>(const ChannelAssignment* ca) {
0144 const int width = ca->tmWidthStubId() + 1;
0145 const double base = 1.;
0146 const double range = std::pow(2, width);
0147 return DataFormat(false, width, base, range);
0148 }
0149 template <>
0150 DataFormat makeDataFormat<Variable::r, Process::tm>(const ChannelAssignment* ca) {
0151 const tt::Setup* s = ca->setup();
0152 const DataFormat phiT = makeDataFormat<Variable::phiT, Process::tm>(ca);
0153 const DataFormat inv2R = makeDataFormat<Variable::inv2R, Process::tm>(ca);
0154 const double range = 2. * s->maxRphi();
0155 const double baseShifted = phiT.base() / inv2R.base();
0156 const int shift = std::ceil(std::log2(range / baseShifted)) - s->tmttWidthR();
0157 const double base = baseShifted * std::pow(2., shift);
0158 const int width = std::ceil(std::log2(range / base));
0159 return DataFormat(true, width, base, range);
0160 }
0161 template <>
0162 DataFormat makeDataFormat<Variable::phi, Process::tm>(const ChannelAssignment* ca) {
0163 const tt::Setup* s = ca->setup();
0164 const DataFormat phiT = makeDataFormat<Variable::phiT, Process::tm>(ca);
0165 const DataFormat inv2R = makeDataFormat<Variable::inv2R, Process::tm>(ca);
0166 const double rangeMin = s->baseRegion() + s->maxRphi() * inv2R.range();
0167 const double range = phiT.base() + s->maxRphi() * inv2R.base();
0168 const int shift = std::ceil(std::log2(rangeMin / phiT.base())) - s->tmttWidthPhi();
0169 const double base = phiT.base() * std::pow(2., shift);
0170 const int width = std::ceil(std::log2(range / base));
0171 return DataFormat(true, width, base, range);
0172 }
0173 template <>
0174 DataFormat makeDataFormat<Variable::z, Process::tm>(const ChannelAssignment* ca) {
0175 const tt::Setup* s = ca->setup();
0176 const DataFormat zT = makeDataFormat<Variable::zT, Process::tm>(ca);
0177 const DataFormat cot = makeDataFormat<Variable::cot, Process::tm>(ca);
0178 const double rangeMin = 2. * s->halfLength();
0179 const double range = zT.base() + s->maxRz() * cot.base();
0180 const int shift = std::ceil(std::log2(rangeMin / zT.base())) - s->tmttWidthZ();
0181 const double base = zT.base() * std::pow(2., shift);
0182 const int width = std::ceil(std::log2(range / base));
0183 return DataFormat(true, width, base, range);
0184 }
0185 template <>
0186 DataFormat makeDataFormat<Variable::dPhi, Process::tm>(const ChannelAssignment* ca) {
0187 const tt::Setup* s = ca->setup();
0188 const DataFormat phi = makeDataFormat<Variable::phi, Process::tm>(ca);
0189 const DataFormat inv2R = makeDataFormat<Variable::inv2R, Process::tm>(ca);
0190 const double range =
0191 .5 * s->pitchRowPS() / s->innerRadius() + .25 * (s->pitchCol2S() + s->scattering()) * inv2R.range();
0192 const double base = phi.base();
0193 const int width = std::ceil(std::log2(range / base));
0194 return DataFormat(false, width, base, range);
0195 }
0196 template <>
0197 DataFormat makeDataFormat<Variable::dZ, Process::tm>(const ChannelAssignment* ca) {
0198 const tt::Setup* s = ca->setup();
0199 const DataFormat z = makeDataFormat<Variable::z, Process::tm>(ca);
0200 const double range = .5 * s->pitchCol2S() * std::sinh(s->maxEta());
0201 const double base = z.base();
0202 const int width = std::ceil(std::log2(range / base));
0203 return DataFormat(false, width, base, range);
0204 }
0205
0206 template <>
0207 DataFormat makeDataFormat<Variable::inv2R, Process::kf>(const ChannelAssignment* ca) {
0208 const DataFormat tfp = makeDataFormat<Variable::inv2R, Process::tfp>(ca);
0209 const DataFormat tm = makeDataFormat<Variable::inv2R, Process::tm>(ca);
0210 const double range = tm.range();
0211 const double base = tm.base() * std::pow(2., std::floor(std::log2(.5 * tfp.base() / tm.base())));
0212 const int width = std::ceil(std::log2(range / base));
0213 return DataFormat(true, width, base, range);
0214 }
0215 template <>
0216 DataFormat makeDataFormat<Variable::phiT, Process::kf>(const ChannelAssignment* ca) {
0217 const DataFormat tfp = makeDataFormat<Variable::phiT, Process::tfp>(ca);
0218 const DataFormat tm = makeDataFormat<Variable::phiT, Process::tm>(ca);
0219 const double range = tm.range();
0220 const double base = tm.base() * std::pow(2., std::floor(std::log2(tfp.base() / tm.base())));
0221 const int width = std::ceil(std::log2(range / base));
0222 return DataFormat(true, width, base, range);
0223 }
0224 template <>
0225 DataFormat makeDataFormat<Variable::cot, Process::kf>(const ChannelAssignment* ca) {
0226 const DataFormat tfp = makeDataFormat<Variable::cot, Process::tfp>(ca);
0227 const DataFormat cot = makeDataFormat<Variable::cot, Process::tm>(ca);
0228 const DataFormat z = makeDataFormat<Variable::z, Process::tm>(ca);
0229 const DataFormat r = makeDataFormat<Variable::r, Process::tm>(ca);
0230 const double range = cot.range();
0231 const double base = z.base() / r.base() * std::pow(2., std::floor(std::log2(tfp.base() / z.base() * r.base())));
0232 const int width = std::ceil(std::log2(range / base));
0233 return DataFormat(true, width, base, range);
0234 }
0235 template <>
0236 DataFormat makeDataFormat<Variable::zT, Process::kf>(const ChannelAssignment* ca) {
0237 const DataFormat tfp = makeDataFormat<Variable::zT, Process::tfp>(ca);
0238 const DataFormat tm = makeDataFormat<Variable::zT, Process::tm>(ca);
0239 const double range = tm.range();
0240 const double base = tm.base() * pow(2., std::floor(std::log2(tfp.base() / tm.base())));
0241 const int width = std::ceil(std::log2(range / base));
0242 return DataFormat(true, width, base, range);
0243 }
0244
0245 }