File indexing completed on 2025-06-11 03:00:13
0001 #ifndef L1Trigger_TrackFindingTracklet_DataFormats_h
0002 #define L1Trigger_TrackFindingTracklet_DataFormats_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "FWCore/Framework/interface/data_default_record_trait.h"
0013 #include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h"
0014 #include "L1Trigger/TrackTrigger/interface/Setup.h"
0015 #include "DataFormats/L1TrackTrigger/interface/TTBV.h"
0016
0017 #include <vector>
0018 #include <cmath>
0019 #include <initializer_list>
0020 #include <tuple>
0021 #include <iostream>
0022 #include <string>
0023
0024 namespace trklet {
0025
0026
0027 enum class Process { begin, tm = begin, dr, kf, tfp, end, x };
0028
0029 enum class Variable { begin, stubId = begin, r, phi, z, dPhi, dZ, inv2R, phiT, cot, zT, end, x };
0030
0031 constexpr std::initializer_list<Process> Processes = {Process::tm, Process::dr, Process::kf, Process::tfp};
0032
0033 inline constexpr int operator+(Process p) { return static_cast<int>(p); }
0034
0035 inline constexpr int operator+(Variable v) { return static_cast<int>(v); }
0036
0037 inline constexpr Process operator++(Process p) { return Process(+p + 1); }
0038
0039 inline constexpr Variable operator++(Variable v) { return Variable(+v + 1); }
0040
0041
0042 class DataFormat {
0043 public:
0044 DataFormat(bool twos, bool biased = true) : twos_(twos), width_(0), base_(1.), range_(0.) {}
0045 DataFormat(bool twos, int width, double base, double range)
0046 : twos_(twos), width_(width), base_(base), range_(range) {}
0047 DataFormat() {}
0048 ~DataFormat() = default;
0049
0050 TTBV ttBV(int i) const { return TTBV(i, width_, twos_); }
0051
0052 TTBV ttBV(double d) const { return TTBV(d, base_, width_, twos_); }
0053
0054 void extract(TTBV& in, int& out) const { out = in.extract(width_, twos_); }
0055
0056 void extract(TTBV& in, double& out) const { out = in.extract(base_, width_, twos_); }
0057
0058 void extract(TTBV& in, TTBV& out) const { out = in.slice(width_, twos_); }
0059
0060 void extract(TTBV& in, bool& out) const { out = in.extract(); }
0061
0062 void attach(const int i, TTBV& ttBV) const { ttBV += TTBV(i, width_, twos_); }
0063
0064 void attach(const double d, TTBV& ttBV) const { ttBV += TTBV(d, base_, width_, twos_); }
0065
0066 void attach(const TTBV& bv, TTBV& ttBV) const { ttBV += bv; }
0067
0068 double floating(int i) const { return (i + .5) * base_; }
0069
0070 int integer(double d) const { return std::floor(d / base_ + 1.e-12); }
0071
0072 double digi(double d) const { return floating(integer(d)); }
0073
0074 int toSigned(int i) const { return i - std::pow(2, width_) / 2; }
0075
0076 int toUnsigned(int i) const { return i + std::pow(2, width_) / 2; }
0077
0078 int toUnsigned(double d) const { return this->integer(d) + std::pow(2, width_) / 2; }
0079
0080 double limit() const { return (range_ - base_) / (twos_ ? 2. : 1.); }
0081
0082 bool inRange(double d, bool digi = true) const {
0083 const double range = digi ? base_ * pow(2, width_) : range_;
0084 return d >= -range / 2. && d < range / 2.;
0085 }
0086
0087 bool inRange(int i) const { return inRange(floating(i)); }
0088
0089 bool twos() const { return twos_; }
0090
0091 int width() const { return width_; }
0092
0093 double base() const { return base_; }
0094
0095 double range() const { return range_; }
0096
0097 protected:
0098
0099 bool twos_;
0100
0101 int width_;
0102
0103 double base_;
0104
0105 double range_;
0106 };
0107
0108
0109 template <Variable v, Process p>
0110 DataFormat makeDataFormat(const ChannelAssignment* ca);
0111
0112 template <>
0113 DataFormat makeDataFormat<Variable::inv2R, Process::tfp>(const ChannelAssignment* ca);
0114 template <>
0115 DataFormat makeDataFormat<Variable::phiT, Process::tfp>(const ChannelAssignment* ca);
0116 template <>
0117 DataFormat makeDataFormat<Variable::cot, Process::tfp>(const ChannelAssignment* ca);
0118 template <>
0119 DataFormat makeDataFormat<Variable::zT, Process::tfp>(const ChannelAssignment* ca);
0120
0121 template <>
0122 DataFormat makeDataFormat<Variable::inv2R, Process::tm>(const ChannelAssignment* ca);
0123 template <>
0124 DataFormat makeDataFormat<Variable::phiT, Process::tm>(const ChannelAssignment* ca);
0125 template <>
0126 DataFormat makeDataFormat<Variable::zT, Process::tm>(const ChannelAssignment* ca);
0127 template <>
0128 DataFormat makeDataFormat<Variable::cot, Process::tm>(const ChannelAssignment* ca);
0129
0130 template <>
0131 DataFormat makeDataFormat<Variable::stubId, Process::tm>(const ChannelAssignment* ca);
0132 template <>
0133 DataFormat makeDataFormat<Variable::r, Process::tm>(const ChannelAssignment* ca);
0134 template <>
0135 DataFormat makeDataFormat<Variable::phi, Process::tm>(const ChannelAssignment* ca);
0136 template <>
0137 DataFormat makeDataFormat<Variable::z, Process::tm>(const ChannelAssignment* ca);
0138 template <>
0139 DataFormat makeDataFormat<Variable::dPhi, Process::tm>(const ChannelAssignment* ca);
0140 template <>
0141 DataFormat makeDataFormat<Variable::dZ, Process::tm>(const ChannelAssignment* ca);
0142
0143 template <>
0144 DataFormat makeDataFormat<Variable::inv2R, Process::kf>(const ChannelAssignment* ca);
0145 template <>
0146 DataFormat makeDataFormat<Variable::phiT, Process::kf>(const ChannelAssignment* ca);
0147 template <>
0148 DataFormat makeDataFormat<Variable::cot, Process::kf>(const ChannelAssignment* ca);
0149 template <>
0150 DataFormat makeDataFormat<Variable::zT, Process::kf>(const ChannelAssignment* ca);
0151
0152
0153
0154
0155
0156
0157 class DataFormats {
0158 private:
0159
0160 static constexpr std::array<std::array<Process, +Process::end>, +Variable::end> config_ = {{
0161
0162 {{Process::tm, Process::x, Process::x, Process::x}},
0163 {{Process::tm, Process::tm, Process::tm, Process::x}},
0164 {{Process::tm, Process::tm, Process::tm, Process::x}},
0165 {{Process::tm, Process::tm, Process::tm, Process::x}},
0166 {{Process::tm, Process::tm, Process::tm, Process::x}},
0167 {{Process::tm, Process::tm, Process::tm, Process::x}},
0168 {{Process::tm, Process::tm, Process::kf, Process::tfp}},
0169 {{Process::tm, Process::tm, Process::kf, Process::tfp}},
0170 {{Process::tm, Process::tm, Process::kf, Process::tfp}},
0171 {{Process::tm, Process::tm, Process::kf, Process::tfp}}
0172 }};
0173
0174 static constexpr std::array<std::initializer_list<Variable>, +Process::end> stubs_ = {{
0175 {Variable::stubId, Variable::r, Variable::phi, Variable::z},
0176 {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ},
0177 {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ},
0178 {}
0179 }};
0180
0181 static constexpr std::array<std::initializer_list<Variable>, +Process::end> tracks_ = {{
0182 {Variable::inv2R, Variable::phiT, Variable::zT},
0183 {Variable::inv2R, Variable::phiT, Variable::zT},
0184 {Variable::inv2R, Variable::phiT, Variable::cot, Variable::zT},
0185 {}
0186 }};
0187
0188 public:
0189 DataFormats();
0190 DataFormats(const ChannelAssignment* ca);
0191 ~DataFormats() = default;
0192
0193 template <typename... Ts>
0194 void convertStub(Process p, const tt::Frame& bv, std::tuple<Ts...>& data) const {
0195 TTBV ttBV(bv);
0196 extractStub(p, ttBV, data);
0197 }
0198
0199 template <typename... Ts>
0200 void convertStub(Process p, const std::tuple<Ts...>& data, tt::Frame& bv) const {
0201 TTBV ttBV(1, 1 + numUnusedBitsStubs_[+p]);
0202 attachStub(p, data, ttBV);
0203 bv = ttBV.bs();
0204 }
0205
0206 template <typename... Ts>
0207 void convertTrack(Process p, const tt::Frame& bv, std::tuple<Ts...>& data) const {
0208 TTBV ttBV(bv);
0209 extractTrack(p, ttBV, data);
0210 }
0211
0212 template <typename... Ts>
0213 void convertTrack(Process p, const std::tuple<Ts...>& data, tt::Frame& bv) const {
0214 TTBV ttBV(1, 1 + numUnusedBitsTracks_[+p]);
0215 attachTrack(p, data, ttBV);
0216 bv = ttBV.bs();
0217 }
0218
0219 const tt::Setup* setup() const { return channelAssignment_->setup(); }
0220
0221 int width(Variable v, Process p) const { return formats_[+v][+p]->width(); }
0222
0223 double base(Variable v, Process p) const { return formats_[+v][+p]->base(); }
0224
0225 double range(Variable v, Process p) const { return formats_[+v][+p]->range(); }
0226
0227 const DataFormat& format(Variable v, Process p) const { return *formats_[+v][+p]; }
0228
0229 private:
0230
0231 int numDataFormats_;
0232
0233 template <Variable v = Variable::begin, Process p = Process::begin>
0234 void countFormats();
0235
0236 template <Variable v = Variable::begin, Process p = Process::begin>
0237 void fillDataFormats();
0238
0239 template <Variable v, Process p, Process it = Process::begin>
0240 void fillFormats();
0241
0242 template <int it = 0, typename... Ts>
0243 void extractStub(Process p, TTBV& ttBV, std::tuple<Ts...>& data) const {
0244 Variable v = *std::next(stubs_[+p].begin(), sizeof...(Ts) - 1 - it);
0245 formats_[+v][+p]->extract(ttBV, std::get<sizeof...(Ts) - 1 - it>(data));
0246 if constexpr (it + 1 != sizeof...(Ts))
0247 extractStub<it + 1>(p, ttBV, data);
0248 }
0249
0250 template <int it = 0, typename... Ts>
0251 void extractTrack(Process p, TTBV& ttBV, std::tuple<Ts...>& data) const {
0252 Variable v = *std::next(tracks_[+p].begin(), sizeof...(Ts) - 1 - it);
0253 formats_[+v][+p]->extract(ttBV, std::get<sizeof...(Ts) - 1 - it>(data));
0254 if constexpr (it + 1 != sizeof...(Ts))
0255 extractTrack<it + 1>(p, ttBV, data);
0256 }
0257
0258 template <int it = 0, typename... Ts>
0259 void attachStub(Process p, const std::tuple<Ts...>& data, TTBV& ttBV) const {
0260 Variable v = *std::next(stubs_[+p].begin(), it);
0261 formats_[+v][+p]->attach(std::get<it>(data), ttBV);
0262 if constexpr (it + 1 != sizeof...(Ts))
0263 attachStub<it + 1>(p, data, ttBV);
0264 }
0265
0266 template <int it = 0, typename... Ts>
0267 void attachTrack(Process p, const std::tuple<Ts...>& data, TTBV& ttBV) const {
0268 Variable v = *std::next(tracks_[+p].begin(), it);
0269 formats_[+v][+p]->attach(std::get<it>(data), ttBV);
0270 if constexpr (it + 1 != sizeof...(Ts))
0271 attachTrack<it + 1>(p, data, ttBV);
0272 }
0273
0274 const ChannelAssignment* channelAssignment_;
0275
0276 std::vector<DataFormat> dataFormats_;
0277
0278 std::vector<std::vector<DataFormat*>> formats_;
0279
0280 std::vector<int> numUnusedBitsStubs_;
0281
0282 std::vector<int> numUnusedBitsTracks_;
0283 };
0284
0285
0286 template <typename... Ts>
0287 class Stub {
0288 public:
0289
0290 Stub(const tt::FrameStub& fs, const DataFormats* df, Process p) : dataFormats_(df), p_(p), frame_(fs) {
0291 dataFormats_->convertStub(p_, frame_.second, data_);
0292 }
0293 template <typename... Others>
0294
0295 Stub(const Stub<Others...>& stub, Ts... data)
0296 : dataFormats_(stub.dataFormats()), p_(++stub.p()), frame_(stub.frame()), data_(data...) {
0297 dataFormats_->convertStub(p_, data_, frame_.second);
0298 }
0299
0300 Stub(const TTStubRef& ttStubRef, const DataFormats* df, Process p, Ts... data)
0301 : dataFormats_(df), p_(p), frame_(ttStubRef, tt::Frame()), data_(data...) {
0302 dataFormats_->convertStub(p_, data_, frame_.second);
0303 }
0304 Stub() {}
0305 virtual ~Stub() = default;
0306
0307 explicit operator bool() const { return frame_.first.isNonnull(); }
0308
0309 const DataFormats* dataFormats() const { return dataFormats_; }
0310
0311 Process p() const { return p_; }
0312
0313 const tt::FrameStub& frame() const { return frame_; }
0314
0315 protected:
0316
0317 const DataFormats* dataFormats_;
0318
0319 Process p_;
0320
0321 tt::FrameStub frame_;
0322
0323 std::tuple<Ts...> data_;
0324 };
0325
0326
0327 class StubTM : public Stub<int, double, double, double> {
0328 public:
0329
0330 StubTM(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::tm) {}
0331
0332 StubTM(const TTStubRef& ttStubRef, const DataFormats* df, int stubId, double r, double phi, double z)
0333 : Stub(ttStubRef, df, Process::tm, stubId, r, phi, z) {}
0334 ~StubTM() override = default;
0335
0336 int stubId() const { return std::get<0>(data_); }
0337
0338 double r() const { return std::get<1>(data_); }
0339
0340 double phi() const { return std::get<2>(data_); }
0341
0342 double z() const { return std::get<3>(data_); }
0343 };
0344
0345
0346 class StubDR : public Stub<double, double, double, double, double> {
0347 public:
0348
0349 StubDR(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::dr) {}
0350
0351 StubDR(const StubTM& stub, double r, double phi, double z, double dPhi, double dZ)
0352 : Stub(stub, r, phi, z, dPhi, dZ) {}
0353 ~StubDR() override = default;
0354
0355 double r() const { return std::get<0>(data_); }
0356
0357 double phi() const { return std::get<1>(data_); }
0358
0359 double z() const { return std::get<2>(data_); }
0360
0361 double dPhi() const { return std::get<3>(data_); }
0362
0363 double dZ() const { return std::get<4>(data_); }
0364 };
0365
0366
0367 class StubKF : public Stub<double, double, double, double, double> {
0368 public:
0369
0370 StubKF(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::kf) {}
0371
0372 StubKF(const StubDR& stub, double r, double phi, double z, double dPhi, double dZ)
0373 : Stub(stub, r, phi, z, dPhi, dZ) {}
0374 ~StubKF() override = default;
0375
0376 double r() const { return std::get<0>(data_); };
0377
0378 double phi() const { return std::get<1>(data_); };
0379
0380 double z() const { return std::get<2>(data_); };
0381
0382 double dPhi() const { return std::get<3>(data_); }
0383
0384 double dZ() const { return std::get<4>(data_); }
0385 };
0386
0387
0388 template <typename... Ts>
0389 class Track {
0390 public:
0391
0392 Track(const tt::FrameTrack& ft, const DataFormats* df, Process p) : dataFormats_(df), p_(p), frame_(ft) {
0393 dataFormats_->convertTrack(p_, frame_.second, data_);
0394 }
0395
0396 Track(const TTTrackRef& ttTrackRef, const DataFormats* df, Process p, Ts... data)
0397 : dataFormats_(df), p_(p), frame_(ttTrackRef, tt::Frame()), data_(data...) {
0398 dataFormats_->convertTrack(p_, data_, frame_.second);
0399 }
0400
0401 template <typename... Others>
0402 Track(const Track<Others...>& track, Ts... data)
0403 : dataFormats_(track.dataFormats()), p_(++track.p()), frame_(track.frame()), data_(data...) {
0404 dataFormats_->convertTrack(p_, data_, frame_.second);
0405 }
0406 Track() {}
0407 virtual ~Track() = default;
0408
0409 explicit operator bool() const { return frame_.first.isNonnull(); }
0410
0411 const DataFormats* dataFormats() const { return dataFormats_; }
0412
0413 Process p() const { return p_; }
0414
0415 const tt::FrameTrack& frame() const { return frame_; }
0416
0417 protected:
0418
0419 const DataFormats* dataFormats_;
0420
0421 Process p_;
0422
0423 tt::FrameTrack frame_;
0424
0425 std::tuple<Ts...> data_;
0426 };
0427
0428
0429 class TrackTM : public Track<double, double, double> {
0430 public:
0431
0432 TrackTM(const tt::FrameTrack& ft, const DataFormats* df) : Track(ft, df, Process::tm) {}
0433
0434 TrackTM(const TTTrackRef& tTTrackRef, const DataFormats* df, double inv2R, double phiT, double zT)
0435 : Track(tTTrackRef, df, Process::tm, inv2R, phiT, zT) {}
0436 ~TrackTM() override = default;
0437
0438 double inv2R() const { return std::get<0>(data_); }
0439
0440 double phiT() const { return std::get<1>(data_); }
0441
0442 double zT() const { return std::get<2>(data_); }
0443 };
0444
0445
0446 class TrackDR : public Track<double, double, double> {
0447 public:
0448
0449 TrackDR(const tt::FrameTrack& ft, const DataFormats* df) : Track(ft, df, Process::dr) {}
0450
0451 TrackDR(const TrackTM& track) : Track(track, track.inv2R(), track.phiT(), track.zT()) {}
0452 ~TrackDR() override = default;
0453
0454 double inv2R() const { return std::get<0>(data_); }
0455
0456 double phiT() const { return std::get<1>(data_); }
0457
0458 double zT() const { return std::get<2>(data_); }
0459 };
0460
0461
0462 class TrackKF : public Track<double, double, double, double> {
0463 public:
0464
0465 TrackKF(const tt::FrameTrack& ft, const DataFormats* df) : Track(ft, df, Process::kf) {}
0466
0467 TrackKF(const TrackDR& track, double inv2R, double phiT, double cot, double zT)
0468 : Track(track, inv2R, phiT, cot, zT) {}
0469 TrackKF() {}
0470 ~TrackKF() override = default;
0471
0472 double inv2R() const { return std::get<0>(data_); }
0473
0474 double phiT() const { return std::get<1>(data_); }
0475
0476 double cot() const { return std::get<2>(data_); }
0477
0478 double zT() const { return std::get<3>(data_); }
0479 };
0480
0481 }
0482
0483 EVENTSETUP_DATA_DEFAULT_RECORD(trklet::DataFormats, trklet::ChannelAssignmentRcd);
0484
0485 #endif