Back to home page

Project CMSSW displayed by LXR

 
 

    


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   // 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     channelAssignment_ = nullptr;
0023     countFormats();
0024     dataFormats_.reserve(numDataFormats_);
0025   }
0026 
0027   // method to count number of unique data formats
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   // proper constructor
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   // constructs data formats of all unique used variables and flavours
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   // helper (loop) data formats of all unique used variables and flavours
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 }  // namespace trklet