Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-11 03:00:13

0001 #ifndef L1Trigger_TrackerTFP_DataFormats_h
0002 #define L1Trigger_TrackerTFP_DataFormats_h
0003 
0004 /*----------------------------------------------------------------------
0005 Classes to calculate and provide dataformats used by Track Trigger emulator
0006 enabling automated conversions from frames to stubs/tracks and vice versa
0007 In data members of classes Stub* & Track* below, the variables describing
0008 stubs/tracks are stored both in digitial format as a 64b word in frame_,
0009 and in undigitized format in an std::tuple. (This saves CPU)
0010 ----------------------------------------------------------------------*/
0011 
0012 #include "FWCore/Framework/interface/data_default_record_trait.h"
0013 #include "L1Trigger/TrackerTFP/interface/DataFormatsRcd.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 trackerTFP {
0025 
0026   // track trigger processes
0027   enum class Process { begin, dtc = begin, pp, gp, ht, ctb, kf, dr, tfp, end, x };
0028   // track trigger variables
0029   enum class Variable { begin, r = begin, phi, z, dPhi, dZ, inv2R, phiT, cot, zT, layer, match, end, x };
0030   // track trigger process order
0031   constexpr std::initializer_list<Process> Processes = {
0032       Process::dtc, Process::pp, Process::gp, Process::ht, Process::ctb, Process::kf, Process::dr, Process::tfp};
0033   // conversion: Process to int
0034   inline constexpr int operator+(Process p) { return static_cast<int>(p); }
0035   // conversion: Variable to int
0036   inline constexpr int operator+(Variable v) { return static_cast<int>(v); }
0037   inline constexpr Process operator+(Process p, int i) { return Process(+p + i); }
0038   inline constexpr Variable operator+(Variable v, int i) { return Variable(+v + i); }
0039 
0040   //Base class representing format of a variable
0041   class DataFormat {
0042   public:
0043     DataFormat() {}
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() = default;
0048     // converts int to bitvector
0049     TTBV ttBV(int i) const { return TTBV(i, width_, twos_); }
0050     // converts double to bitvector
0051     TTBV ttBV(double d) const { return TTBV(d, base_, width_, twos_); }
0052     // extracts int from bitvector, removing these bits from bitvector
0053     void extract(TTBV& in, int& out) const { out = in.extract(width_, twos_); }
0054     // extracts double from bitvector, removing these bits from bitvector
0055     void extract(TTBV& in, double& out) const { out = in.extract(base_, width_, twos_); }
0056     // extracts double from bitvector, removing these bits from bitvector
0057     void extract(TTBV& in, TTBV& out) const { out = in.slice(width_, twos_); }
0058     // extracts bool from bitvector, removing these bits from bitvector
0059     void extract(TTBV& in, bool& out) const { out = in.extract(); }
0060     // attaches integer to bitvector
0061     void attach(const int i, TTBV& ttBV) const { ttBV += TTBV(i, width_, twos_); }
0062     // attaches double to bitvector
0063     void attach(const double d, TTBV& ttBV) const { ttBV += TTBV(d, base_, width_, twos_); }
0064     // attaches bitvector to bitvector
0065     void attach(const TTBV& bv, TTBV& ttBV) const { ttBV += bv; }
0066     // converts int to double
0067     double floating(int i) const { return (i + .5) * base_; }
0068     // converts double to int
0069     int integer(double d) const { return std::floor(d / base_ + 1.e-12); }
0070     // converts double to int and back to double
0071     double digi(double d) const { return floating(integer(d)); }
0072     // converts binary integer value to twos complement integer value
0073     int toSigned(int i) const { return i - std::pow(2, width_) / 2; }
0074     // converts twos complement integer value to binary integer value
0075     int toUnsigned(int i) const { return i + std::pow(2, width_) / 2; }
0076     // converts floating point value to binary integer value
0077     int toUnsigned(double d) const { return this->integer(d) + std::pow(2, width_) / 2; }
0078     // biggest representable floating point value
0079     //double limit() const { return (range_ - base_) / (twos_ ? 2. : 1.); }
0080     // returns false if data format would oferflow for this double value
0081     bool inRange(double d, bool digi = true) const {
0082       const double range = digi ? base_ * pow(2, width_) : range_;
0083       return d >= -range / 2. && d < range / 2.;
0084     }
0085     // returns false if data format would oferflow for this int value
0086     bool inRange(int i) const { return inRange(floating(i)); }
0087     // true if twos'complement or false if binary representation is chosen
0088     bool twos() const { return twos_; }
0089     // number of used bits
0090     int width() const { return width_; }
0091     // precision
0092     double base() const { return base_; }
0093     // covered range
0094     double range() const { return range_; }
0095 
0096   protected:
0097     // true if twos'complement or false if binary representation is chosen
0098     bool twos_;
0099     // number of used bits
0100     int width_;
0101     // precision
0102     double base_;
0103     // covered range
0104     double range_;
0105   };
0106 
0107   // function template for DataFormat generation
0108   template <Variable v, Process p>
0109   DataFormat makeDataFormat(const tt::Setup* setup);
0110 
0111   // specializations
0112 
0113   template <>
0114   DataFormat makeDataFormat<Variable::inv2R, Process::tfp>(const tt::Setup* setup);
0115   template <>
0116   DataFormat makeDataFormat<Variable::phiT, Process::tfp>(const tt::Setup* setup);
0117   template <>
0118   DataFormat makeDataFormat<Variable::cot, Process::tfp>(const tt::Setup* setup);
0119   template <>
0120   DataFormat makeDataFormat<Variable::zT, Process::tfp>(const tt::Setup* setup);
0121 
0122   template <>
0123   DataFormat makeDataFormat<Variable::r, Process::dtc>(const tt::Setup* setup);
0124   template <>
0125   DataFormat makeDataFormat<Variable::phi, Process::dtc>(const tt::Setup* setup);
0126   template <>
0127   DataFormat makeDataFormat<Variable::z, Process::dtc>(const tt::Setup* setup);
0128   template <>
0129   DataFormat makeDataFormat<Variable::layer, Process::dtc>(const tt::Setup* setup);
0130 
0131   template <>
0132   DataFormat makeDataFormat<Variable::phi, Process::gp>(const tt::Setup* setup);
0133   template <>
0134   DataFormat makeDataFormat<Variable::z, Process::gp>(const tt::Setup* setup);
0135   template <>
0136   DataFormat makeDataFormat<Variable::phiT, Process::gp>(const tt::Setup* setup);
0137   template <>
0138   DataFormat makeDataFormat<Variable::zT, Process::gp>(const tt::Setup* setup);
0139   template <>
0140   DataFormat makeDataFormat<Variable::cot, Process::gp>(const tt::Setup* setup);
0141   template <>
0142   DataFormat makeDataFormat<Variable::layer, Process::gp>(const tt::Setup* setup);
0143 
0144   template <>
0145   DataFormat makeDataFormat<Variable::phi, Process::ht>(const tt::Setup* setup);
0146   template <>
0147   DataFormat makeDataFormat<Variable::inv2R, Process::ht>(const tt::Setup* setup);
0148   template <>
0149   DataFormat makeDataFormat<Variable::phiT, Process::ht>(const tt::Setup* setup);
0150 
0151   template <>
0152   DataFormat makeDataFormat<Variable::dPhi, Process::ctb>(const tt::Setup* setup);
0153   template <>
0154   DataFormat makeDataFormat<Variable::dZ, Process::ctb>(const tt::Setup* setup);
0155   template <>
0156   DataFormat makeDataFormat<Variable::layer, Process::ctb>(const tt::Setup* setup);
0157 
0158   template <>
0159   DataFormat makeDataFormat<Variable::inv2R, Process::kf>(const tt::Setup* setup);
0160   template <>
0161   DataFormat makeDataFormat<Variable::phiT, Process::kf>(const tt::Setup* setup);
0162   template <>
0163   DataFormat makeDataFormat<Variable::cot, Process::kf>(const tt::Setup* setup);
0164   template <>
0165   DataFormat makeDataFormat<Variable::zT, Process::kf>(const tt::Setup* setup);
0166   template <>
0167   DataFormat makeDataFormat<Variable::phi, Process::kf>(const tt::Setup* setup);
0168   template <>
0169   DataFormat makeDataFormat<Variable::match, Process::kf>(const tt::Setup* setup);
0170 
0171   template <>
0172   DataFormat makeDataFormat<Variable::cot, Process::dr>(const tt::Setup* setup);
0173 
0174   /*! \class  trackerTFP::DataFormats
0175    *  \brief  Class to calculate and provide dataformats used by Track Trigger emulator
0176    *  \author Thomas Schuh
0177    *  \date   2020, June
0178    */
0179   class DataFormats {
0180   private:
0181     // variable flavour mapping, Each row below declares which processing steps use the variable named in the comment at the end of the row
0182     static constexpr std::array<std::array<Process, +Process::end>, +Variable::end> config_ = {{
0183         //  Process::dtc  Process::pp   Process::gp   Process::ht   Process::ctb  Process::kf   Process::dr,  Process::tfp
0184         {{Process::dtc,
0185           Process::dtc,
0186           Process::dtc,
0187           Process::dtc,
0188           Process::dtc,
0189           Process::dtc,
0190           Process::dtc,
0191           Process::x}},  // Variable::r
0192         {{Process::dtc,
0193           Process::dtc,
0194           Process::gp,
0195           Process::ht,
0196           Process::ht,
0197           Process::kf,
0198           Process::kf,
0199           Process::x}},  // Variable::phi
0200         {{Process::dtc,
0201           Process::dtc,
0202           Process::gp,
0203           Process::gp,
0204           Process::gp,
0205           Process::gp,
0206           Process::gp,
0207           Process::x}},  // Variable::z
0208         {{Process::x,
0209           Process::x,
0210           Process::x,
0211           Process::x,
0212           Process::ctb,
0213           Process::ctb,
0214           Process::ctb,
0215           Process::x}},  // Variable::dPhi
0216         {{Process::x,
0217           Process::x,
0218           Process::x,
0219           Process::x,
0220           Process::ctb,
0221           Process::ctb,
0222           Process::ctb,
0223           Process::x}},  // Variable::dZ
0224         {{Process::ht,
0225           Process::ht,
0226           Process::ht,
0227           Process::ht,
0228           Process::ht,
0229           Process::kf,
0230           Process::kf,
0231           Process::tfp}},  // Variable::inv2R
0232         {{Process::gp,
0233           Process::gp,
0234           Process::gp,
0235           Process::ht,
0236           Process::ht,
0237           Process::kf,
0238           Process::kf,
0239           Process::tfp}},  // Variable::phiT
0240         {{Process::x,
0241           Process::x,
0242           Process::gp,
0243           Process::x,
0244           Process::gp,
0245           Process::kf,
0246           Process::dr,
0247           Process::tfp}},  // Variable::cot
0248         {{Process::gp,
0249           Process::gp,
0250           Process::gp,
0251           Process::gp,
0252           Process::gp,
0253           Process::kf,
0254           Process::kf,
0255           Process::tfp}},  // Variable::zT
0256         {{Process::dtc,
0257           Process::dtc,
0258           Process::gp,
0259           Process::gp,
0260           Process::ctb,
0261           Process::x,
0262           Process::x,
0263           Process::x}},  // Variable::layer
0264         {{Process::x, Process::x, Process::x, Process::x, Process::x, Process::kf, Process::x, Process::x}}  // Variable::match
0265     }};
0266     // stub word assembly, shows which stub variables are used by each process
0267     static constexpr std::array<std::initializer_list<Variable>, +Process::end> stubs_ = {{
0268         {Variable::r,
0269          Variable::phi,
0270          Variable::z,
0271          Variable::layer,
0272          Variable::phiT,
0273          Variable::phiT,
0274          Variable::zT,
0275          Variable::zT,
0276          Variable::inv2R,
0277          Variable::inv2R},  // Process::dtc
0278         {Variable::r,
0279          Variable::phi,
0280          Variable::z,
0281          Variable::layer,
0282          Variable::phiT,
0283          Variable::phiT,
0284          Variable::zT,
0285          Variable::zT,
0286          Variable::inv2R,
0287          Variable::inv2R},                                                                             // Process::pp
0288         {Variable::r, Variable::phi, Variable::z, Variable::layer, Variable::inv2R, Variable::inv2R},  // Process::gp
0289         {Variable::r, Variable::phi, Variable::z, Variable::layer, Variable::phiT, Variable::zT},      // Process::ht
0290         {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ},                       // Process::ctb
0291         {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ},                       // Process::kf
0292         {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ},                       // Process::dr
0293         {}                                                                                             // Process::tfp
0294     }};
0295     // track word assembly, shows which track variables are used by each process
0296     static constexpr std::array<std::initializer_list<Variable>, +Process::end> tracks_ = {{
0297         {},                                                                               // Process::dtc
0298         {},                                                                               // Process::pp
0299         {},                                                                               // Process::gp
0300         {},                                                                               // Process::ht
0301         {Variable::inv2R, Variable::phiT, Variable::zT},                                  // Process::ctb
0302         {Variable::inv2R, Variable::phiT, Variable::cot, Variable::zT, Variable::match},  // Process::kf
0303         {Variable::inv2R, Variable::phiT, Variable::cot, Variable::zT},                   // Process::dr
0304         {}                                                                                // Process::tfp
0305     }};
0306 
0307   public:
0308     DataFormats();
0309     DataFormats(const tt::Setup* setup);
0310     ~DataFormats() = default;
0311     // converts bits to ntuple of variables
0312     template <typename... Ts>
0313     void convertStub(Process p, const tt::Frame& bv, std::tuple<Ts...>& data) const {
0314       TTBV ttBV(bv);
0315       extractStub(p, ttBV, data);
0316     }
0317     // converts ntuple of variables to bits
0318     template <typename... Ts>
0319     void convertStub(Process p, const std::tuple<Ts...>& data, tt::Frame& bv) const {
0320       TTBV ttBV(1, 1 + numUnusedBitsStubs_[+p]);
0321       attachStub(p, data, ttBV);
0322       bv = ttBV.bs();
0323     }
0324     // converts bits to ntuple of variables
0325     template <typename... Ts>
0326     void convertTrack(Process p, const tt::Frame& bv, std::tuple<Ts...>& data) const {
0327       TTBV ttBV(bv);
0328       extractTrack(p, ttBV, data);
0329     }
0330     // converts ntuple of variables to bits
0331     template <typename... Ts>
0332     void convertTrack(Process p, const std::tuple<Ts...>& data, tt::Frame& bv) const {
0333       TTBV ttBV(1, 1 + numUnusedBitsTracks_[+p]);
0334       attachTrack(p, data, ttBV);
0335       bv = ttBV.bs();
0336     }
0337     // access to run-time constants
0338     const tt::Setup* setup() const { return setup_; }
0339     // number of bits being used for specific variable flavour
0340     int width(Variable v, Process p) const { return formats_[+v][+p]->width(); }
0341     // precision being used for specific variable flavour
0342     double base(Variable v, Process p) const { return formats_[+v][+p]->base(); }
0343     // covered range for specific variable flavour
0344     double range(Variable v, Process p) const { return formats_[+v][+p]->range(); }
0345     // number of unused frame bits for a given Stub flavour
0346     int numUnusedBitsStubs(Process p) const { return numUnusedBitsStubs_[+p]; }
0347     // number of unused frame bits for a given Track flavour
0348     int numUnusedBitsTracks(Process p) const { return numUnusedBitsTracks_[+p]; }
0349     // number of channels of a given process on a TFP
0350     int numChannel(Process p) const { return numChannel_[+p]; }
0351     // number of stub channels of a given process for whole system
0352     int numStreamsStubs(Process p) const { return numStreamsStubs_[+p]; }
0353     // number of track channels of a given process for whole system
0354     int numStreamsTracks(Process p) const { return numStreamsTracks_[+p]; }
0355     // access to spedific format
0356     const DataFormat& format(Variable v, Process p) const { return *formats_[+v][+p]; }
0357 
0358   private:
0359     // number of unique data formats
0360     int numDataFormats_;
0361     // method to count number of unique data formats
0362     template <Variable v = Variable::begin, Process p = Process::begin>
0363     void countFormats();
0364     // constructs data formats of all unique used variables and flavours
0365     template <Variable v = Variable::begin, Process p = Process::begin>
0366     void fillDataFormats();
0367     // helper (loop) data formats of all unique used variables and flavours
0368     template <Variable v, Process p, Process it = Process::begin>
0369     void fillFormats();
0370     // helper (loop) to convert bits to ntuple of variables
0371     template <int it = 0, typename... Ts>
0372     void extractStub(Process p, TTBV& ttBV, std::tuple<Ts...>& data) const {
0373       Variable v = *std::next(stubs_[+p].begin(), sizeof...(Ts) - 1 - it);
0374       formats_[+v][+p]->extract(ttBV, std::get<sizeof...(Ts) - 1 - it>(data));
0375       if constexpr (it + 1 != sizeof...(Ts))
0376         extractStub<it + 1>(p, ttBV, data);
0377     }
0378     // helper (loop) to convert bits to ntuple of variables
0379     template <int it = 0, typename... Ts>
0380     void extractTrack(Process p, TTBV& ttBV, std::tuple<Ts...>& data) const {
0381       Variable v = *std::next(tracks_[+p].begin(), sizeof...(Ts) - 1 - it);
0382       formats_[+v][+p]->extract(ttBV, std::get<sizeof...(Ts) - 1 - it>(data));
0383       if constexpr (it + 1 != sizeof...(Ts))
0384         extractTrack<it + 1>(p, ttBV, data);
0385     }
0386     // helper (loop) to convert ntuple of variables to bits
0387     template <int it = 0, typename... Ts>
0388     void attachStub(Process p, const std::tuple<Ts...>& data, TTBV& ttBV) const {
0389       Variable v = *std::next(stubs_[+p].begin(), it);
0390       formats_[+v][+p]->attach(std::get<it>(data), ttBV);
0391       if constexpr (it + 1 != sizeof...(Ts))
0392         attachStub<it + 1>(p, data, ttBV);
0393     }
0394     // helper (loop) to convert ntuple of variables to bits
0395     template <int it = 0, typename... Ts>
0396     void attachTrack(Process p, const std::tuple<Ts...>& data, TTBV& ttBV) const {
0397       Variable v = *std::next(tracks_[+p].begin(), it);
0398       formats_[+v][+p]->attach(std::get<it>(data), ttBV);
0399       if constexpr (it + 1 != sizeof...(Ts))
0400         attachTrack<it + 1>(p, data, ttBV);
0401     }
0402     // stored run-time constants
0403     const tt::Setup* setup_;
0404     // collection of unique formats
0405     std::vector<DataFormat> dataFormats_;
0406     // variable flavour mapping
0407     std::vector<std::vector<DataFormat*>> formats_;
0408     // number of unused frame bits for a all Stub flavours
0409     std::vector<int> numUnusedBitsStubs_;
0410     // number of unused frame bits for a all Track flavours
0411     std::vector<int> numUnusedBitsTracks_;
0412     // number of channels of all processes on a TFP
0413     std::vector<int> numChannel_;
0414     // number of stub channels of all processes for whole system
0415     std::vector<int> numStreamsStubs_;
0416     // number of track channels of all processes for whole system
0417     std::vector<int> numStreamsTracks_;
0418   };
0419 
0420   // base class to represent stubs
0421   template <typename... Ts>
0422   class Stub {
0423   public:
0424     // construct Stub from Frame
0425     Stub(const tt::FrameStub& fs, const DataFormats* df, Process p) : dataFormats_(df), p_(p), frame_(fs) {
0426       dataFormats_->convertStub(p_, frame_.second, data_);
0427     }
0428     template <typename... Others>
0429     // construct Stub from other Stub
0430     Stub(const Stub<Others...>& stub, Ts... data)
0431         : dataFormats_(stub.dataFormats()), p_(stub.p() + 1), frame_(stub.frame()), data_(data...) {
0432       dataFormats_->convertStub(p_, data_, frame_.second);
0433     }
0434     // construct Stub from TTStubRef
0435     Stub(const TTStubRef& ttStubRef, const DataFormats* df, Process p, Ts... data)
0436         : dataFormats_(df), p_(p), frame_(ttStubRef, tt::Frame()), data_(data...) {
0437       dataFormats_->convertStub(p_, data_, frame_.second);
0438     }
0439     Stub() {}
0440     virtual ~Stub() = default;
0441     // true if frame valid, false if gap in data stream
0442     explicit operator bool() const { return frame_.first.isNonnull(); }
0443     // access to DataFormats
0444     const DataFormats* dataFormats() const { return dataFormats_; }
0445     // stub flavour
0446     Process p() const { return p_; }
0447     // acess to frame
0448     const tt::FrameStub& frame() const { return frame_; }
0449 
0450   protected:
0451     // all dataformats
0452     const DataFormats* dataFormats_;
0453     // stub flavour
0454     Process p_;
0455     // underlying TTStubRef and bitvector
0456     tt::FrameStub frame_;
0457     // ntuple of variables this stub is assemled of
0458     std::tuple<Ts...> data_;
0459   };
0460 
0461   // class to represent stubs generated by process DTC
0462   class StubDTC : public Stub<double, double, double, TTBV, int, int, int, int, int, int> {
0463   public:
0464     // construct StubDTC from TTStubRef
0465     StubDTC(const TTStubRef& ttStubRef,
0466             const DataFormats* df,
0467             double r,
0468             double phi,
0469             double z,
0470             const TTBV& layer,
0471             int phiTMin,
0472             int phiTMax,
0473             int zTMin,
0474             int zTMax,
0475             int inv2RMin,
0476             int inv2RMax)
0477         : Stub(ttStubRef, df, Process::dtc, r, phi, z, layer, phiTMin, phiTMax, zTMin, zTMax, inv2RMin, inv2RMax) {}
0478     ~StubDTC() override = default;
0479     // stub radius wrt chosenRofPhi
0480     double r() const { return std::get<0>(data_); }
0481     // stub phi wrt processing nonant centre
0482     double phi() const { return std::get<1>(data_); }
0483     // stub z
0484     double z() const { return std::get<2>(data_); }
0485     // enhanced layer id
0486     TTBV layer() const { return std::get<3>(data_); }
0487     // first phi sector this stub belongs to
0488     int phiTMin() const { return std::get<4>(data_); }
0489     // last phi sector this stub belongs to
0490     int phiTMax() const { return std::get<5>(data_); }
0491     // first eta sector this stub belongs to
0492     int zTMin() const { return std::get<6>(data_); }
0493     // last eta sector this stub belongs to
0494     int zTMax() const { return std::get<7>(data_); }
0495     // first inv2R bin this stub belongs to
0496     int inv2RMin() const { return std::get<8>(data_); }
0497     // last inv2R bin this stub belongs to
0498     int inv2RMax() const { return std::get<9>(data_); }
0499   };
0500 
0501   // class to represent stubs generated by process patch pannel
0502   class StubPP : public Stub<double, double, double, TTBV, int, int, int, int, int, int> {
0503   public:
0504     // construct StubPP from Frame
0505     StubPP(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::pp) {}
0506     ~StubPP() override = default;
0507     // stub radius wrt chosenRofPhi
0508     double r() const { return std::get<0>(data_); }
0509     // stub phi wrt processing nonant centre
0510     double phi() const { return std::get<1>(data_); }
0511     // stub z
0512     double z() const { return std::get<2>(data_); }
0513     // enhanced layer id
0514     const TTBV& layer() const { return std::get<3>(data_); }
0515     // first phi sector this stub belongs to
0516     int phiTMin() const { return std::get<4>(data_); }
0517     // last phi sector this stub belongs to
0518     int phiTMax() const { return std::get<5>(data_); }
0519     // first eta sector this stub belongs to
0520     int zTMin() const { return std::get<6>(data_); }
0521     // last eta sector this stub belongs to
0522     int zTMax() const { return std::get<7>(data_); }
0523     // first inv2R bin this stub belongs to
0524     int inv2RMin() const { return std::get<8>(data_); }
0525     // last inv2R bin this stub belongs to
0526     int inv2RMax() const { return std::get<9>(data_); }
0527   };
0528 
0529   // class to represent stubs generated by process geometric processor
0530   class StubGP : public Stub<double, double, double, TTBV, int, int> {
0531   public:
0532     // construct StubGP from Frame
0533     StubGP(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::gp) {}
0534     // construct StubGP from StubPP
0535     StubGP(const StubPP& stub, double r, double phi, double z, const TTBV& layer, int inv2RMin, int inv2RMax)
0536         : Stub(stub, r, phi, z, layer, inv2RMin, inv2RMax) {}
0537     ~StubGP() override = default;
0538     // stub radius wrt chosenRofPhi
0539     double r() const { return std::get<0>(data_); }
0540     // stub phi wrt phi sector centre
0541     double phi() const { return std::get<1>(data_); }
0542     // stub z residual wrt eta sector
0543     double z() const { return std::get<2>(data_); }
0544     // enhanced layer id
0545     const TTBV& layer() const { return std::get<3>(data_); }
0546     // first inv2R bin this stub belongs to
0547     int inv2RMin() const { return std::get<4>(data_); }
0548     // last inv2R bin this stub belongs to
0549     int inv2RMax() const { return std::get<5>(data_); }
0550   };
0551 
0552   // class to represent stubs generated by process hough transform
0553   class StubHT : public Stub<double, double, double, TTBV, int, int> {
0554   public:
0555     // construct StubHT from Frame
0556     StubHT(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::ht) {}
0557     // construct StubHT from StubGP
0558     StubHT(const StubGP& stub, double r, double phi, double z, const TTBV& layer, int phiT, int zT)
0559         : Stub(stub, r, phi, z, layer, phiT, zT) {}
0560     ~StubHT() override = default;
0561     // stub radius wrt chosenRofPhi
0562     double r() const { return std::get<0>(data_); };
0563     // stub phi residual wrt track parameter
0564     double phi() const { return std::get<1>(data_); };
0565     // stub z residual wrt eta sector
0566     double z() const { return std::get<2>(data_); };
0567     // enhanced layer id
0568     const TTBV& layer() const { return std::get<3>(data_); }
0569     // stub phi at radius chosenRofPhi wrt processing nonant centre
0570     int phiT() const { return std::get<4>(data_); };
0571     // eta sector
0572     int zT() const { return std::get<5>(data_); };
0573   };
0574 
0575   // class to represent stubs generated by process CTB
0576   class StubCTB : public Stub<double, double, double, double, double> {
0577   public:
0578     // construct StubTB from Frame
0579     StubCTB(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::ctb) {}
0580     // construct StubTB from StubZHT
0581     StubCTB(const StubHT& stub, double r, double phi, double z, double dPhi, double dZ)
0582         : Stub(stub, r, phi, z, dPhi, dZ) {}
0583     ~StubCTB() override = default;
0584     // stub radius wrt chosenRofPhi
0585     double r() const { return std::get<0>(data_); }
0586     // stub phi residual wrt finer track parameter
0587     double phi() const { return std::get<1>(data_); }
0588     // stub z residual wrt track parameter
0589     double z() const { return std::get<2>(data_); }
0590     // stub phi uncertainty
0591     double dPhi() const { return std::get<3>(data_); }
0592     // stub z uncertainty
0593     double dZ() const { return std::get<4>(data_); }
0594   };
0595 
0596   // class to represent stubs generated by process kalman filter
0597   class StubKF : public Stub<double, double, double, double, double> {
0598   public:
0599     // construct StubKF from Frame
0600     StubKF(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::kf) {}
0601     // construct StubKF from StubCTB
0602     StubKF(const StubCTB& stub, double r, double phi, double z, double dPhi, double dZ)
0603         : Stub(stub, r, phi, z, dPhi, dZ) {}
0604     ~StubKF() override = default;
0605     // stub radius wrt choenRofPhi
0606     double r() const { return std::get<0>(data_); }
0607     // stub phi residual wrt fitted parameter
0608     double phi() const { return std::get<1>(data_); }
0609     // stub z residual wrt fitted parameter
0610     double z() const { return std::get<2>(data_); }
0611     // stub phi uncertainty
0612     double dPhi() const { return std::get<3>(data_); }
0613     // stub z uncertainty
0614     double dZ() const { return std::get<4>(data_); }
0615   };
0616 
0617   // class to represent stubs generated by process duplicate removal
0618   class StubDR : public Stub<double, double, double, double, double> {
0619   public:
0620     // construct StubDR from Frame
0621     StubDR(const tt::FrameStub& fs, const DataFormats* df) : Stub(fs, df, Process::dr) {}
0622     // construct StubDR from StubKF
0623     StubDR(const StubKF& stub, double r, double phi, double z, double dPhi, double dZ)
0624         : Stub(stub, r, phi, z, dPhi, dZ) {}
0625     ~StubDR() override = default;
0626     // stub radius wrt choenRofPhi
0627     double r() const { return std::get<0>(data_); }
0628     // stub phi residual wrt fitted parameter
0629     double phi() const { return std::get<1>(data_); }
0630     // stub z residual wrt fitted parameter
0631     double z() const { return std::get<2>(data_); }
0632     // stub phi uncertainty
0633     double dPhi() const { return std::get<3>(data_); }
0634     // stub z uncertainty
0635     double dZ() const { return std::get<4>(data_); }
0636   };
0637 
0638   // base class to represent tracks
0639   template <typename... Ts>
0640   class Track {
0641   public:
0642     // construct Track from Frame
0643     Track(const tt::FrameTrack& ft, const DataFormats* df, Process p) : dataFormats_(df), p_(p), frame_(ft) {
0644       dataFormats_->convertTrack(p_, frame_.second, data_);
0645     }
0646     // construct Track from TTTrackRef
0647     Track(const TTTrackRef& ttTrackRef, const DataFormats* df, Process p, Ts... data)
0648         : dataFormats_(df), p_(p), frame_(ttTrackRef, tt::Frame()), data_(data...) {
0649       dataFormats_->convertTrack(p_, data_, frame_.second);
0650     }
0651     // construct Track from other Track
0652     template <typename... Others>
0653     Track(const Track<Others...>& track, Ts... data)
0654         : dataFormats_(track.dataFormats()), p_(track.p() + 1), frame_(track.frame()), data_(data...) {
0655       dataFormats_->convertTrack(p_, data_, frame_.second);
0656     }
0657     virtual ~Track() = default;
0658     // true if frame valid, false if gap in data stream
0659     explicit operator bool() const { return frame_.first.isNonnull(); }
0660     // access to DataFormats
0661     const DataFormats* dataFormats() const { return dataFormats_; }
0662     // track flavour
0663     Process p() const { return p_; }
0664     // acces to frame
0665     const tt::FrameTrack& frame() const { return frame_; }
0666 
0667   protected:
0668     // all data formats
0669     const DataFormats* dataFormats_;
0670     // track flavour
0671     Process p_;
0672     // underlying TTTrackRef and bitvector
0673     tt::FrameTrack frame_;
0674     // ntuple of variables this track is assemled of
0675     std::tuple<Ts...> data_;
0676   };
0677 
0678   // class to represent tracks generated by process Clean Track Builder
0679   class TrackCTB : public Track<double, double, double> {
0680   public:
0681     // construct TrackTB from Frame
0682     TrackCTB(const tt::FrameTrack& ft, const DataFormats* df) : Track(ft, df, Process::ctb) {}
0683     // construct TrackTB from StubsCTB
0684     TrackCTB(const TTTrackRef& tTTrackRef, const DataFormats* df, double inv2R, double phiT, double zT)
0685         : Track(tTTrackRef, df, Process::ctb, inv2R, phiT, zT) {}
0686     ~TrackCTB() override = default;
0687     // track inv2R
0688     double inv2R() const { return std::get<0>(data_); }
0689     // track phi at radius chosenRofPhi wrt pprocessing centre
0690     double phiT() const { return std::get<1>(data_); }
0691     // track z at radius chosenRofZ
0692     double zT() const { return std::get<2>(data_); }
0693   };
0694 
0695   // class to represent tracks generated by process kalman filter
0696   class TrackKF : public Track<double, double, double, double, TTBV> {
0697   public:
0698     // construct TrackKF from Frame
0699     TrackKF(const tt::FrameTrack& ft, const DataFormats* df) : Track(ft, df, Process::kf) {}
0700     // construct TrackKF from TrackCTB
0701     TrackKF(const TrackCTB& track, double inv2R, double phiT, double cot, double zT, const TTBV& match)
0702         : Track(track, inv2R, phiT, cot, zT, match) {}
0703     ~TrackKF() override = default;
0704     // track qOver pt
0705     double inv2R() const { return std::get<0>(data_); }
0706     // track phi at radius chosenRofPhi wrt processing nonant centre
0707     double phiT() const { return std::get<1>(data_); }
0708     // track cotTheta wrt eta sector cotTheta
0709     double cot() const { return std::get<2>(data_); }
0710     // track z at radius chosenRofZ
0711     double zT() const { return std::get<3>(data_); }
0712     // true if kf prameter consistent with mht parameter
0713     const TTBV& match() const { return std::get<4>(data_); }
0714   };
0715 
0716   // class to represent tracks generated by process duplicate removal
0717   class TrackDR : public Track<double, double, double, double> {
0718   public:
0719     // construct TrackDR from Frame
0720     TrackDR(const tt::FrameTrack& ft, const DataFormats* df) : Track(ft, df, Process::dr) {}
0721     // construct TrackDR from TrackKF
0722     TrackDR(const TrackKF& track, double inv2R, double phiT, double cot, double zT)
0723         : Track(track, inv2R, phiT, cot, zT) {}
0724     ~TrackDR() override = default;
0725     // track inv2R
0726     double inv2R() const { return std::get<0>(data_); }
0727     // track phi at radius 0 wrt processing nonant centre
0728     double phiT() const { return std::get<1>(data_); }
0729     // track cotThea
0730     double cot() const { return std::get<2>(data_); }
0731     // track z at radius 0
0732     double zT() const { return std::get<3>(data_); }
0733   };
0734 
0735 }  // namespace trackerTFP
0736 
0737 EVENTSETUP_DATA_DEFAULT_RECORD(trackerTFP::DataFormats, trackerTFP::DataFormatsRcd);
0738 
0739 #endif