Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-15 23:40:43

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 "FWCore/ParameterSet/interface/ParameterSet.h"
0014 #include "L1Trigger/TrackerTFP/interface/DataFormatsRcd.h"
0015 #include "L1Trigger/TrackTrigger/interface/Setup.h"
0016 #include "DataFormats/L1TrackTrigger/interface/TTBV.h"
0017 
0018 #include <vector>
0019 #include <cmath>
0020 #include <initializer_list>
0021 #include <tuple>
0022 #include <iostream>
0023 #include <string>
0024 
0025 namespace trackerTFP {
0026 
0027   // track trigger processes
0028   enum class Process { begin, fe = begin, dtc, pp, gp, ht, mht, zht, kfin, kf, dr, end, x };
0029   // track trigger variables
0030   enum class Variable {
0031     begin,
0032     r = begin,
0033     phi,
0034     z,
0035     layer,
0036     sectorsPhi,
0037     sectorEta,
0038     sectorPhi,
0039     phiT,
0040     inv2R,
0041     zT,
0042     cot,
0043     dPhi,
0044     dZ,
0045     match,
0046     hitPattern,
0047     phi0,
0048     z0,
0049     end,
0050     x
0051   };
0052   // track trigger process order
0053   constexpr std::initializer_list<Process> Processes = {Process::fe,
0054                                                         Process::dtc,
0055                                                         Process::pp,
0056                                                         Process::gp,
0057                                                         Process::ht,
0058                                                         Process::mht,
0059                                                         Process::zht,
0060                                                         Process::kfin,
0061                                                         Process::kf,
0062                                                         Process::dr};
0063   // conversion: Process to int
0064   inline constexpr int operator+(Process p) { return static_cast<int>(p); }
0065   // conversion: Variable to int
0066   inline constexpr int operator+(Variable v) { return static_cast<int>(v); }
0067   // increment of Process
0068   inline constexpr Process operator++(Process p) { return Process(+p + 1); }
0069   // increment of Variable
0070   inline constexpr Variable operator++(Variable v) { return Variable(+v + 1); }
0071 
0072   //Base class representing format of a variable
0073   class DataFormat {
0074   public:
0075     DataFormat(bool twos) : twos_(twos), width_(0), base_(1.), range_(0.) {}
0076     ~DataFormat() {}
0077     // converts int to bitvector
0078     TTBV ttBV(int i) const { return TTBV(i, width_, twos_); }
0079     // converts double to bitvector
0080     TTBV ttBV(double d) const { return TTBV(d, base_, width_, twos_); }
0081     // extracts int from bitvector, removing these bits from bitvector
0082     void extract(TTBV& in, int& out) const { out = in.extract(width_, twos_); }
0083     // extracts double from bitvector, removing these bits from bitvector
0084     void extract(TTBV& in, double& out) const { out = in.extract(base_, width_, twos_); }
0085     // extracts double from bitvector, removing these bits from bitvector
0086     void extract(TTBV& in, TTBV& out) const { out = in.slice(width_, twos_); }
0087     // attaches integer to bitvector
0088     void attach(const int i, TTBV& ttBV) const { ttBV += TTBV(i, width_, twos_); }
0089     // attaches double to bitvector
0090     void attach(const double d, TTBV& ttBV) const { ttBV += TTBV(d, base_, width_, twos_); }
0091     // attaches bitvector to bitvector
0092     void attach(const TTBV bv, TTBV& ttBV) const { ttBV += bv; }
0093     // converts int to double
0094     double floating(int i) const { return (i + .5) * base_; }
0095     // converts double to int
0096     int integer(double d) const { return std::floor(d / base_ + 1.e-12); }
0097     // converts double to int and back to double
0098     double digi(double d) const { return floating(integer(d)); }
0099     // converts binary integer value to twos complement integer value
0100     int toSigned(int i) const { return i - std::pow(2, width_) / 2; }
0101     // converts twos complement integer value to binary integer value
0102     int toUnsigned(int i) const { return i + std::pow(2, width_) / 2; }
0103     // converts floating point value to binary integer value
0104     int toUnsigned(double d) const { return this->integer(d) + std::pow(2, width_) / 2; }
0105     // returns false if data format would oferflow for this double value
0106     bool inRange(double d, bool digi = false) const {
0107       const double range = digi ? base_ * pow(2, width_) : range_;
0108       return d >= -range / 2. && d < range / 2.;
0109     }
0110     // returns false if data format would oferflow for this int value
0111     bool inRange(int i) const { return inRange(floating(i)); }
0112     // true if twos'complement or false if binary representation is chosen
0113     bool twos() const { return twos_; }
0114     // number of used bits
0115     int width() const { return width_; }
0116     // precision
0117     double base() const { return base_; }
0118     // covered range
0119     double range() const { return range_; }
0120 
0121   protected:
0122     // true if twos'complement or false if binary representation is chosen
0123     bool twos_;
0124     // number of used bits
0125     int width_;
0126     // precision
0127     double base_;
0128     // covered range
0129     double range_;
0130   };
0131 
0132   // class representing format of a specific variable
0133   template <Variable v, Process p>
0134   class Format : public DataFormat {
0135   public:
0136     Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0137     ~Format() {}
0138   };
0139 
0140   template <>
0141   Format<Variable::phiT, Process::ht>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0142   template <>
0143   Format<Variable::phiT, Process::mht>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0144   template <>
0145   Format<Variable::inv2R, Process::ht>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0146   template <>
0147   Format<Variable::inv2R, Process::mht>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0148   template <>
0149   Format<Variable::r, Process::ht>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0150   template <>
0151   Format<Variable::phi, Process::ht>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0152   template <>
0153   Format<Variable::phi, Process::mht>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0154   template <>
0155   Format<Variable::phi, Process::zht>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0156   template <>
0157   Format<Variable::phi, Process::kfin>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0158   template <>
0159   Format<Variable::phi, Process::kf>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0160   template <>
0161   Format<Variable::phi, Process::gp>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0162   template <>
0163   Format<Variable::phi, Process::dtc>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0164   template <>
0165   Format<Variable::z, Process::dtc>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0166   template <>
0167   Format<Variable::z, Process::gp>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0168   template <>
0169   Format<Variable::z, Process::zht>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0170   template <>
0171   Format<Variable::z, Process::kfin>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0172   template <>
0173   Format<Variable::z, Process::kf>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0174   template <>
0175   Format<Variable::zT, Process::zht>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0176   template <>
0177   Format<Variable::cot, Process::zht>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0178   template <>
0179   Format<Variable::layer, Process::ht>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0180   template <>
0181   Format<Variable::sectorEta, Process::gp>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0182   template <>
0183   Format<Variable::sectorPhi, Process::gp>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0184   template <>
0185   Format<Variable::sectorsPhi, Process::gp>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0186   template <>
0187   Format<Variable::match, Process::kf>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0188   template <>
0189   Format<Variable::hitPattern, Process::kfin>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0190   template <>
0191   Format<Variable::phi0, Process::dr>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0192   template <>
0193   Format<Variable::inv2R, Process::dr>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0194   template <>
0195   Format<Variable::z0, Process::dr>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0196   template <>
0197   Format<Variable::cot, Process::dr>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0198   template <>
0199   Format<Variable::phiT, Process::kf>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0200   template <>
0201   Format<Variable::inv2R, Process::kf>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0202   template <>
0203   Format<Variable::zT, Process::kf>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0204   template <>
0205   Format<Variable::cot, Process::kf>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0206   template <>
0207   Format<Variable::dPhi, Process::kfin>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0208   template <>
0209   Format<Variable::dZ, Process::kfin>::Format(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0210 
0211   /*! \class  trackerTFP::DataFormats
0212    *  \brief  Class to calculate and provide dataformats used by Track Trigger emulator
0213    *  \author Thomas Schuh
0214    *  \date   2020, June
0215    */
0216   class DataFormats {
0217   private:
0218     // variable flavour mapping, Each row below declares which processing steps use the variable named in the comment at the end of the row
0219     static constexpr std::array<std::array<Process, +Process::end>, +Variable::end> config_ = {{
0220         //  Process::fe  Process::dtc  Process::pp   Process::gp  Process::ht  Process::mht  Process::zht  Process::kfin  Process::kf    Process::dr
0221         {{Process::x,
0222           Process::ht,
0223           Process::ht,
0224           Process::ht,
0225           Process::ht,
0226           Process::ht,
0227           Process::ht,
0228           Process::ht,
0229           Process::ht,
0230           Process::x}},  // Variable::r
0231         {{Process::x,
0232           Process::dtc,
0233           Process::dtc,
0234           Process::gp,
0235           Process::ht,
0236           Process::mht,
0237           Process::zht,
0238           Process::kfin,
0239           Process::kfin,
0240           Process::x}},  // Variable::phi
0241         {{Process::x,
0242           Process::dtc,
0243           Process::dtc,
0244           Process::gp,
0245           Process::gp,
0246           Process::gp,
0247           Process::zht,
0248           Process::kfin,
0249           Process::kfin,
0250           Process::x}},  // Variable::z
0251         {{Process::x,
0252           Process::ht,
0253           Process::ht,
0254           Process::ht,
0255           Process::ht,
0256           Process::ht,
0257           Process::ht,
0258           Process::x,
0259           Process::x,
0260           Process::x}},  // Variable::layer
0261         {{Process::x,
0262           Process::dtc,
0263           Process::dtc,
0264           Process::x,
0265           Process::x,
0266           Process::x,
0267           Process::x,
0268           Process::x,
0269           Process::x,
0270           Process::x}},  // Variable::sectorsPhi
0271         {{Process::x,
0272           Process::gp,
0273           Process::gp,
0274           Process::gp,
0275           Process::gp,
0276           Process::gp,
0277           Process::gp,
0278           Process::gp,
0279           Process::gp,
0280           Process::x}},  // Variable::sectorEta
0281         {{Process::x,
0282           Process::x,
0283           Process::x,
0284           Process::gp,
0285           Process::gp,
0286           Process::gp,
0287           Process::gp,
0288           Process::gp,
0289           Process::gp,
0290           Process::x}},  // Variable::sectorPhi
0291         {{Process::x,
0292           Process::ht,
0293           Process::ht,
0294           Process::ht,
0295           Process::ht,
0296           Process::mht,
0297           Process::mht,
0298           Process::mht,
0299           Process::kf,
0300           Process::x}},  // Variable::phiT
0301         {{Process::x,
0302           Process::ht,
0303           Process::ht,
0304           Process::ht,
0305           Process::ht,
0306           Process::mht,
0307           Process::mht,
0308           Process::mht,
0309           Process::kf,
0310           Process::dr}},  // Variable::inv2R
0311         {{Process::x,
0312           Process::x,
0313           Process::x,
0314           Process::x,
0315           Process::x,
0316           Process::x,
0317           Process::zht,
0318           Process::zht,
0319           Process::kf,
0320           Process::x}},  // Variable::zT
0321         {{Process::x,
0322           Process::x,
0323           Process::x,
0324           Process::x,
0325           Process::x,
0326           Process::x,
0327           Process::zht,
0328           Process::zht,
0329           Process::kf,
0330           Process::dr}},  // Variable::cot
0331         {{Process::x,
0332           Process::x,
0333           Process::x,
0334           Process::x,
0335           Process::x,
0336           Process::x,
0337           Process::x,
0338           Process::kfin,
0339           Process::kfin,
0340           Process::x}},  // Variable::dPhi
0341         {{Process::x,
0342           Process::x,
0343           Process::x,
0344           Process::x,
0345           Process::x,
0346           Process::x,
0347           Process::x,
0348           Process::kfin,
0349           Process::kfin,
0350           Process::x}},  // Variable::dZ
0351         {{Process::x,
0352           Process::x,
0353           Process::x,
0354           Process::x,
0355           Process::x,
0356           Process::x,
0357           Process::x,
0358           Process::x,
0359           Process::kf,
0360           Process::x}},  // Variable::match
0361         {{Process::x,
0362           Process::x,
0363           Process::x,
0364           Process::x,
0365           Process::x,
0366           Process::x,
0367           Process::x,
0368           Process::kfin,
0369           Process::x,
0370           Process::x}},  // Variable::hitPattern
0371         {{Process::x,
0372           Process::x,
0373           Process::x,
0374           Process::x,
0375           Process::x,
0376           Process::x,
0377           Process::x,
0378           Process::x,
0379           Process::x,
0380           Process::dr}},  // Variable::phi0
0381         {{Process::x,
0382           Process::x,
0383           Process::x,
0384           Process::x,
0385           Process::x,
0386           Process::x,
0387           Process::x,
0388           Process::x,
0389           Process::x,
0390           Process::dr}}  // Variable::z0
0391     }};
0392     // stub word assembly, shows which stub variables are used by each process
0393     static constexpr std::array<std::initializer_list<Variable>, +Process::end> stubs_ = {{
0394         {},  // Process::fe
0395         {Variable::r,
0396          Variable::phi,
0397          Variable::z,
0398          Variable::layer,
0399          Variable::sectorsPhi,
0400          Variable::sectorEta,
0401          Variable::sectorEta,
0402          Variable::inv2R,
0403          Variable::inv2R},  // Process::dtc
0404         {Variable::r,
0405          Variable::phi,
0406          Variable::z,
0407          Variable::layer,
0408          Variable::sectorsPhi,
0409          Variable::sectorEta,
0410          Variable::sectorEta,
0411          Variable::inv2R,
0412          Variable::inv2R},                                                                             // Process::pp
0413         {Variable::r, Variable::phi, Variable::z, Variable::layer, Variable::inv2R, Variable::inv2R},  // Process::gp
0414         {Variable::r,
0415          Variable::phi,
0416          Variable::z,
0417          Variable::layer,
0418          Variable::sectorPhi,
0419          Variable::sectorEta,
0420          Variable::phiT},  // Process::ht
0421         {Variable::r,
0422          Variable::phi,
0423          Variable::z,
0424          Variable::layer,
0425          Variable::sectorPhi,
0426          Variable::sectorEta,
0427          Variable::phiT,
0428          Variable::inv2R},  // Process::mht
0429         {Variable::r,
0430          Variable::phi,
0431          Variable::z,
0432          Variable::layer,
0433          Variable::sectorPhi,
0434          Variable::sectorEta,
0435          Variable::phiT,
0436          Variable::inv2R,
0437          Variable::zT,
0438          Variable::cot},                                                          // Process::zht
0439         {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ},  // Process::kfin
0440         {Variable::r, Variable::phi, Variable::z, Variable::dPhi, Variable::dZ},  // Process::kf
0441         {}                                                                        // Process::dr
0442     }};
0443     // track word assembly, shows which track variables are used by each process
0444     static constexpr std::array<std::initializer_list<Variable>, +Process::end> tracks_ = {{
0445         {},  // Process::fe
0446         {},  // Process::dtc
0447         {},  // Process::pp
0448         {},  // Process::gp
0449         {},  // Process::ht
0450         {},  // Process::mht
0451         {},  // Process::zht
0452         {Variable::hitPattern,
0453          Variable::sectorPhi,
0454          Variable::sectorEta,
0455          Variable::phiT,
0456          Variable::inv2R,
0457          Variable::zT,
0458          Variable::cot},  // Process::kfin
0459         {Variable::match,
0460          Variable::sectorPhi,
0461          Variable::sectorEta,
0462          Variable::phiT,
0463          Variable::inv2R,
0464          Variable::cot,
0465          Variable::zT},                                                 // Process::kf
0466         {Variable::phi0, Variable::inv2R, Variable::z0, Variable::cot}  // Process::dr
0467     }};
0468 
0469   public:
0470     DataFormats();
0471     DataFormats(const edm::ParameterSet& iConfig, const tt::Setup* setup);
0472     ~DataFormats() {}
0473     // bool indicating if hybrid or tmtt being used
0474     bool hybrid() const { return iConfig_.getParameter<bool>("UseHybrid"); }
0475     // converts bits to ntuple of variables
0476     template <typename... Ts>
0477     void convertStub(Process p, const tt::Frame& bv, std::tuple<Ts...>& data) const;
0478     // converts ntuple of variables to bits
0479     template <typename... Ts>
0480     void convertStub(Process p, const std::tuple<Ts...>& data, tt::Frame& bv) const;
0481     // converts bits to ntuple of variables
0482     template <typename... Ts>
0483     void convertTrack(Process p, const tt::Frame& bv, std::tuple<Ts...>& data) const;
0484     // converts ntuple of variables to bits
0485     template <typename... Ts>
0486     void convertTrack(Process p, const std::tuple<Ts...>& data, tt::Frame& bv) const;
0487     // access to run-time constants
0488     const tt::Setup* setup() const { return setup_; }
0489     // number of bits being used for specific variable flavour
0490     int width(Variable v, Process p) const { return formats_[+v][+p]->width(); }
0491     // precision being used for specific variable flavour
0492     double base(Variable v, Process p) const { return formats_[+v][+p]->base(); }
0493     // number of unused frame bits for a given Stub flavour
0494     int numUnusedBitsStubs(Process p) const { return numUnusedBitsStubs_[+p]; }
0495     // number of unused frame bits for a given Track flavour
0496     int numUnusedBitsTracks(Process p) const { return numUnusedBitsTracks_[+p]; }
0497     // number of channels of a given process on a TFP
0498     int numChannel(Process p) const { return numChannel_[+p]; }
0499     // number of channels of a given process for whole system
0500     int numStreams(Process p) const { return numStreams_[+p]; }
0501     //
0502     int numStreamsStubs(Process p) const { return numStreamsStubs_[+p]; }
0503     //
0504     int numStreamsTracks(Process p) const { return numStreamsTracks_[+p]; }
0505     // access to spedific format
0506     const DataFormat& format(Variable v, Process p) const { return *formats_[+v][+p]; }
0507     // critical radius defining region overlap shape in cm
0508     double chosenRofPhi() const { return hybrid() ? setup_->hybridChosenRofPhi() : setup_->chosenRofPhi(); }
0509 
0510   private:
0511     // number of unique data formats
0512     int numDataFormats_;
0513     // method to count number of unique data formats
0514     template <Variable v = Variable::begin, Process p = Process::begin>
0515     void countFormats();
0516     // constructs data formats of all unique used variables and flavours
0517     template <Variable v = Variable::begin, Process p = Process::begin>
0518     void fillDataFormats();
0519     // helper (loop) data formats of all unique used variables and flavours
0520     template <Variable v, Process p, Process it = Process::begin>
0521     void fillFormats();
0522     // helper (loop) to convert bits to ntuple of variables
0523     template <int it = 0, typename... Ts>
0524     void extractStub(Process p, TTBV& ttBV, std::tuple<Ts...>& data) const;
0525     // helper (loop) to convert bits to ntuple of variables
0526     template <int it = 0, typename... Ts>
0527     void extractTrack(Process p, TTBV& ttBV, std::tuple<Ts...>& data) const;
0528     // helper (loop) to convert ntuple of variables to bits
0529     template <int it = 0, typename... Ts>
0530     void attachStub(Process p, const std::tuple<Ts...>& data, TTBV& ttBV) const;
0531     // helper (loop) to convert ntuple of variables to bits
0532     template <int it = 0, typename... Ts>
0533     void attachTrack(Process p, const std::tuple<Ts...>& data, TTBV& ttBV) const;
0534     // configuration during construction
0535     edm::ParameterSet iConfig_;
0536     // stored run-time constants
0537     const tt::Setup* setup_;
0538     // collection of unique formats
0539     std::vector<DataFormat> dataFormats_;
0540     // variable flavour mapping
0541     std::vector<std::vector<DataFormat*>> formats_;
0542     // number of unused frame bits for a all Stub flavours
0543     std::vector<int> numUnusedBitsStubs_;
0544     // number of unused frame bits for a all Track flavours
0545     std::vector<int> numUnusedBitsTracks_;
0546     // number of channels of all processes on a TFP
0547     std::vector<int> numChannel_;
0548     // number of channels of all processes for whole system
0549     std::vector<int> numStreams_;
0550     //
0551     std::vector<int> numStreamsStubs_;
0552     //
0553     std::vector<int> numStreamsTracks_;
0554   };
0555 
0556   // base class to represent stubs
0557   template <typename... Ts>
0558   class Stub {
0559   public:
0560     // construct Stub from Frame
0561     Stub(const tt::FrameStub& frame, const DataFormats* dataFormats, Process p);
0562     template <typename... Others>
0563     // construct Stub from other Stub
0564     Stub(const Stub<Others...>& stub, Ts... data);
0565     // construct Stub from TTStubRef
0566     Stub(const TTStubRef& ttStubRef, const DataFormats* dataFormats, Process p, Ts... data);
0567     Stub() {}
0568     ~Stub() {}
0569     // true if frame valid, false if gap in data stream
0570     explicit operator bool() const { return frame_.first.isNonnull(); }
0571     // access to DataFormats
0572     const DataFormats* dataFormats() const { return dataFormats_; }
0573     // stub flavour
0574     Process p() const { return p_; }
0575     // acess to frame
0576     tt::FrameStub frame() const { return frame_; }
0577     // access to TTStubRef
0578     TTStubRef ttStubRef() const { return frame_.first; }
0579     // access to bitvector
0580     tt::Frame bv() const { return frame_.second; }
0581     // id of collection this stub belongs to
0582     int trackId() const { return trackId_; }
0583 
0584   protected:
0585     // number of used bits for given variable
0586     int width(Variable v) const { return dataFormats_->width(v, p_); }
0587     // precision of given variable
0588     double base(Variable v) const { return dataFormats_->base(v, p_); }
0589     // format of given variable
0590     DataFormat format(Variable v) const { return dataFormats_->format(v, p_); }
0591     // all dataformats
0592     const DataFormats* dataFormats_;
0593     // stub flavour
0594     Process p_;
0595     // underlying TTStubRef and bitvector
0596     tt::FrameStub frame_;
0597     // ntuple of variables this stub is assemled of
0598     std::tuple<Ts...> data_;
0599     // id of collection this stub belongs to
0600     int trackId_;
0601   };
0602 
0603   // class to represent stubs generated by process patch pannel
0604   class StubPP : public Stub<double, double, double, int, TTBV, int, int, int, int> {
0605   public:
0606     // construct StubPP from Frame
0607     StubPP(const tt::FrameStub& frame, const DataFormats* dataFormats);
0608     ~StubPP() {}
0609     // true if stub belongs to given sector
0610     bool inSector(int sector) const { return sectors_[sector]; }
0611     // sectors this stub belongs to
0612     std::vector<int> sectors() const { return sectors_.ids(); }
0613     // stub radius wrt chosenRofPhi
0614     double r() const { return std::get<0>(data_); }
0615     // stub phi wrt processing nonant centre
0616     double phi() const { return std::get<1>(data_); }
0617     // stub z
0618     double z() const { return std::get<2>(data_); }
0619     // reduced layer id
0620     int layer() const { return std::get<3>(data_); }
0621     // phi sector map to which this stub belongs to
0622     TTBV sectorsPhi() const { return std::get<4>(data_); }
0623     // first eta sector this stub belongs to
0624     int sectorEtaMin() const { return std::get<5>(data_); }
0625     // last eta sector this stub belongs to
0626     int sectorEtaMax() const { return std::get<6>(data_); }
0627     // first inv2R bin this stub belongs to
0628     int inv2RMin() const { return std::get<7>(data_); }
0629     // last inv2R bin this stub belongs to
0630     int inv2RMax() const { return std::get<8>(data_); }
0631 
0632   private:
0633     // sectors this stub belongs to
0634     TTBV sectors_;
0635   };
0636 
0637   // class to represent stubs generated by process geometric processor
0638   class StubGP : public Stub<double, double, double, int, int, int> {
0639   public:
0640     // construct StubGP from Frame
0641     StubGP(const tt::FrameStub& frame, const DataFormats* dataFormats, int sectorPhi, int sectorEta);
0642     // construct StubGO from StubPP
0643     StubGP(const StubPP& stub, int sectorPhi, int sectorEta);
0644     ~StubGP() {}
0645     // true if stub belongs to given inv2R bin
0646     bool inInv2RBin(int inv2RBin) const { return inv2RBins_[inv2RBin]; }
0647     // inv2R bins  this stub belongs to
0648     std::vector<int> inv2RBins() const { return inv2RBins_.ids(); }
0649     // stub phi sector
0650     int sectorPhi() const { return sectorPhi_; }
0651     // stub eta sector
0652     int sectorEta() const { return sectorEta_; }
0653     // stub radius wrt chosenRofPhi
0654     double r() const { return std::get<0>(data_); }
0655     // stub phi wrt phi sector centre
0656     double phi() const { return std::get<1>(data_); }
0657     // stub z residual wrt eta sector
0658     double z() const { return std::get<2>(data_); }
0659     // reduced layer id
0660     int layer() const { return std::get<3>(data_); }
0661     // first inv2R bin this stub belongs to
0662     int inv2RMin() const { return std::get<4>(data_); }
0663     // last inv2R bin this stub belongs to
0664     int inv2RMax() const { return std::get<5>(data_); }
0665 
0666   private:
0667     // inv2R bins this stub belongs to
0668     TTBV inv2RBins_;
0669     // stub phi sector
0670     int sectorPhi_;
0671     // stub eta sector
0672     int sectorEta_;
0673   };
0674 
0675   // class to represent stubs generated by process hough transform
0676   class StubHT : public Stub<double, double, double, int, int, int, int> {
0677   public:
0678     // construct StubHT from Frame
0679     StubHT(const tt::FrameStub& frame, const DataFormats* dataFormats, int inv2R);
0680     // construct StubHT from StubGP and HT cell assignment
0681     StubHT(const StubGP& stub, int phiT, int inv2R);
0682     ~StubHT() {}
0683     // stub qOver pt
0684     int inv2R() const { return inv2R_; }
0685     // stub radius wrt chosenRofPhi
0686     double r() const { return std::get<0>(data_); };
0687     // stub phi residual wrt track parameter
0688     double phi() const { return std::get<1>(data_); };
0689     // stub z residual wrt eta sector
0690     double z() const { return std::get<2>(data_); };
0691     // reduced layer id
0692     int layer() const { return std::get<3>(data_); };
0693     // phi sector
0694     int sectorPhi() const { return std::get<4>(data_); };
0695     // eta sector
0696     int sectorEta() const { return std::get<5>(data_); };
0697     // stub phi at radius chosenRofPhi wrt phi sector centre
0698     int phiT() const { return std::get<6>(data_); };
0699 
0700   private:
0701     // fills track id
0702     void fillTrackId();
0703     // stub qOver pt
0704     int inv2R_;
0705   };
0706 
0707   // class to represent stubs generated by process mini hough transform
0708   class StubMHT : public Stub<double, double, double, int, int, int, int, int> {
0709   public:
0710     // construct StubMHT from Frame
0711     StubMHT(const tt::FrameStub& frame, const DataFormats* dataFormats);
0712     // construct StubMHT from StubHT and MHT cell assignment
0713     StubMHT(const StubHT& stub, int phiT, int inv2R);
0714     ~StubMHT() {}
0715     // stub radius wrt choenRofPhi
0716     double r() const { return std::get<0>(data_); }
0717     // stub phi residual wrt finer track parameter
0718     double phi() const { return std::get<1>(data_); }
0719     // stub z rsidual wrt eta sector
0720     double z() const { return std::get<2>(data_); }
0721     // reduced layer id
0722     int layer() const { return std::get<3>(data_); }
0723     // phi sector
0724     int sectorPhi() const { return std::get<4>(data_); }
0725     // eta sector
0726     int sectorEta() const { return std::get<5>(data_); }
0727     // stub phi at radius chosenRofPhi wrt phi sector centre
0728     int phiT() const { return std::get<6>(data_); }
0729     // stub inv2R
0730     int inv2R() const { return std::get<7>(data_); }
0731 
0732   private:
0733     // fills track id
0734     void fillTrackId();
0735   };
0736 
0737   // class to represent stubs generated by process z hough transform
0738   class StubZHT : public Stub<double, double, double, int, int, int, int, int, int, int> {
0739   public:
0740     // construct StubZHT from Frame
0741     StubZHT(const tt::FrameStub& frame, const DataFormats* dataFormats);
0742     // construct StubZHT from StubMHT
0743     StubZHT(const StubMHT& stub);
0744     //
0745     StubZHT(const StubZHT& stub, double zT, double cot, int id);
0746     //
0747     StubZHT(const StubZHT& stub, int cot, int zT);
0748     ~StubZHT() {}
0749     // stub radius wrt chonseRofPhi
0750     double r() const { return std::get<0>(data_); }
0751     // stub phiresiudal wrt finer track parameter
0752     double phi() const { return std::get<1>(data_); }
0753     // stub z residual to track parameter
0754     double z() const { return std::get<2>(data_); }
0755     // reduced layer id
0756     int layer() const { return std::get<3>(data_); }
0757     // phi sector
0758     int sectorPhi() const { return std::get<4>(data_); }
0759     // eta sector
0760     int sectorEta() const { return std::get<5>(data_); }
0761     // stub phi at radius chosenRofPhi wrt phi sector centre
0762     int phiT() const { return std::get<6>(data_); }
0763     // stub inv2R
0764     int inv2R() const { return std::get<7>(data_); }
0765     // stub z at radius chosenRofZ wrt eta sector centre
0766     int zT() const { return std::get<8>(data_); }
0767     // stub cotTheta wrt eta sector cotTheta
0768     int cot() const { return std::get<9>(data_); }
0769     double cotf() const { return cot_; }
0770     double ztf() const { return zT_; }
0771     double chi() const { return chi_; }
0772 
0773   private:
0774     // fills track id
0775     void fillTrackId();
0776     double r_;
0777     double chi_;
0778     double cot_;
0779     double zT_;
0780   };
0781 
0782   // class to represent stubs generated by process kfin
0783   class StubKFin : public Stub<double, double, double, double, double> {
0784   public:
0785     // construct StubKFin from Frame
0786     StubKFin(const tt::FrameStub& frame, const DataFormats* dataFormats, int layer);
0787     // construct StubKFin from StubZHT
0788     StubKFin(const StubZHT& stub, double dPhi, double dZ, int layer);
0789     // construct StubKFin from TTStubRef
0790     StubKFin(const TTStubRef& ttStubRef,
0791              const DataFormats* dataFormats,
0792              double r,
0793              double phi,
0794              double z,
0795              double dPhi,
0796              double dZ,
0797              int layer);
0798     ~StubKFin() {}
0799     // kf layer id
0800     int layer() const { return layer_; }
0801     // stub radius wrt chosenRofPhi
0802     double r() const { return std::get<0>(data_); }
0803     // stub phi residual wrt finer track parameter
0804     double phi() const { return std::get<1>(data_); }
0805     // stub z residual wrt track parameter
0806     double z() const { return std::get<2>(data_); }
0807     // stub phi uncertainty
0808     double dPhi() const { return std::get<3>(data_); }
0809     // stub z uncertainty
0810     double dZ() const { return std::get<4>(data_); }
0811 
0812   private:
0813     // kf layer id
0814     int layer_;
0815   };
0816 
0817   // class to represent stubs generated by process kalman filter
0818   class StubKF : public Stub<double, double, double, double, double> {
0819   public:
0820     // construct StubKF from Frame
0821     StubKF(const tt::FrameStub& frame, const DataFormats* dataFormats, int layer);
0822     // construct StubKF from StubKFin
0823     StubKF(const StubKFin& stub, double inv2R, double phiT, double cot, double zT);
0824     ~StubKF() {}
0825     // kf layer id
0826     int layer() const { return layer_; }
0827     // stub radius wrt choenRofPhi
0828     double r() const { return std::get<0>(data_); }
0829     // stub phi residual wrt fitted parameter
0830     double phi() const { return std::get<1>(data_); }
0831     // stub z residual wrt fitted parameter
0832     double z() const { return std::get<2>(data_); }
0833     // stub phi uncertainty
0834     double dPhi() const { return std::get<3>(data_); }
0835     // stub z uncertainty
0836     double dZ() const { return std::get<4>(data_); }
0837 
0838   private:
0839     // kf layer id
0840     int layer_;
0841   };
0842 
0843   // base class to represent tracks
0844   template <typename... Ts>
0845   class Track {
0846   public:
0847     // construct Track from Frame
0848     Track(const tt::FrameTrack& frame, const DataFormats* dataFormats, Process p);
0849     // construct Track from other Track
0850     template <typename... Others>
0851     Track(const Track<Others...>& track, Ts... data);
0852     // construct Track from Stub
0853     template <typename... Others>
0854     Track(const Stub<Others...>& stub, const TTTrackRef& ttTrackRef, Ts... data);
0855     // construct Track from TTTrackRef
0856     Track(const TTTrackRef& ttTrackRef, const DataFormats* dataFormats, Process p, Ts... data);
0857     ~Track() {}
0858     // true if frame valid, false if gap in data stream
0859     explicit operator bool() const { return frame_.first.isNonnull(); }
0860     // access to DataFormats
0861     const DataFormats* dataFormats() const { return dataFormats_; }
0862     // track flavour
0863     Process p() const { return p_; }
0864     // acces to frame
0865     tt::FrameTrack frame() const { return frame_; }
0866     // access to TTTrackRef
0867     TTTrackRef ttTrackRef() const { return frame_.first; }
0868     // access to bitvector
0869     tt::Frame bv() const { return frame_.second; }
0870     // access to ntuple of variables this track is assemled of
0871     std::tuple<Ts...> data() const { return data_; }
0872 
0873   protected:
0874     //number of bits uesd of given variable
0875     int width(Variable v) const { return dataFormats_->width(v, p_); }
0876     // precision of given variable
0877     double base(Variable v) const { return dataFormats_->base(v, p_); }
0878     // access to run-time constants
0879     const tt::Setup* setup() const { return dataFormats_->setup(); }
0880     // format of given variable
0881     DataFormat format(Variable v) const { return dataFormats_->format(v, p_); }
0882     // format of given variable and process
0883     DataFormat format(Variable v, Process p) const { return dataFormats_->format(v, p); }
0884     // all data formats
0885     const DataFormats* dataFormats_;
0886     // track flavour
0887     Process p_;
0888     // underlying TTTrackRef and bitvector
0889     tt::FrameTrack frame_;
0890     // ntuple of variables this track is assemled of
0891     std::tuple<Ts...> data_;
0892   };
0893 
0894   class TrackKFin : public Track<TTBV, int, int, double, double, double, double> {
0895   public:
0896     // construct TrackKFin from Frame
0897     TrackKFin(const tt::FrameTrack& frame, const DataFormats* dataFormats, const std::vector<StubKFin*>& stubs);
0898     // construct TrackKFin from StubKFin
0899     TrackKFin(const StubZHT& stub, const TTTrackRef& ttTrackRef, const TTBV& maybePattern);
0900     // construct TrackKFin from TTTrackRef
0901     TrackKFin(const TTTrackRef& ttTrackRef,
0902               const DataFormats* dataFormats,
0903               const TTBV& maybePattern,
0904               double phiT,
0905               double qOverPt,
0906               double zT,
0907               double cot,
0908               int sectorPhi,
0909               int sectorEta);
0910     ~TrackKFin() {}
0911     // pattern of layers which are only maybe crossed by found candidate
0912     const TTBV& maybePattern() const { return std::get<0>(data_); }
0913     // phi sector
0914     int sectorPhi() const { return std::get<1>(data_); }
0915     // eta sector
0916     int sectorEta() const { return std::get<2>(data_); }
0917     // track phi at radius chosenRofPhi wrt phi sector centre
0918     double phiT() const { return std::get<3>(data_); }
0919     // track inv2R
0920     double inv2R() const { return std::get<4>(data_); }
0921     // track z at radius chosenRofZ wrt eta sector centre
0922     double zT() const { return std::get<5>(data_); }
0923     // track cotTheta wrt seta sector cotTheta
0924     double cot() const { return std::get<6>(data_); }
0925     //
0926     TTBV hitPattern() const { return hitPattern_; }
0927     // true if given layer has a hit
0928     bool hitPattern(int index) const { return hitPattern_[index]; }
0929     // true if given layer has a hit or is a maybe layer
0930     bool maybePattern(int index) const { return hitPattern_[index] || maybePattern()[index]; }
0931     // stubs on a given layer
0932     std::vector<StubKFin*> layerStubs(int layer) const { return stubs_[layer]; }
0933     // firts stub on a given layer
0934     StubKFin* layerStub(int layer) const { return stubs_[layer].front(); }
0935     // selection of ttStubRefs for given hit ids on given layers
0936     std::vector<TTStubRef> ttStubRefs(const TTBV& hitPattern, const std::vector<int>& layerMap) const;
0937     // stubs organized in layer
0938     std::vector<std::vector<StubKFin*>> stubs() const { return stubs_; }
0939     // global cotTheta
0940     double cotGlobal() const { return cot() + setup()->sectorCot(sectorEta()); }
0941 
0942   private:
0943     // stubs organized in layer
0944     std::vector<std::vector<StubKFin*>> stubs_;
0945     //
0946     TTBV hitPattern_;
0947   };
0948 
0949   // class to represent tracks generated by process kalman filter
0950   class TrackKF : public Track<int, int, int, double, double, double, double> {
0951   public:
0952     // construct TrackKF from Frame
0953     TrackKF(const tt::FrameTrack& frame, const DataFormats* dataFormats);
0954     // construct TrackKF from TrackKFKFin
0955     TrackKF(const TrackKFin& track, double phiT, double inv2R, double zT, double cot);
0956     ~TrackKF() {}
0957     // true if kf prameter consistent with mht parameter
0958     bool match() const { return std::get<0>(data_); }
0959     // phi sector
0960     int sectorPhi() const { return std::get<1>(data_); }
0961     // eta sector
0962     int sectorEta() const { return std::get<2>(data_); }
0963     // track phi at radius chosenRofPhi wrt phi sector centre
0964     double phiT() const { return std::get<3>(data_); }
0965     // track qOver pt
0966     double inv2R() const { return std::get<4>(data_); }
0967     // track cotTheta wrt eta sector cotTheta
0968     double cot() const { return std::get<5>(data_); }
0969     // track z at radius chosenRofZ wrt eta sector centre
0970     double zT() const { return std::get<6>(data_); }
0971     // global cotTheta
0972     double cotGlobal() const { return cot() + setup()->sectorCot(sectorEta()); }
0973     // conversion to TTTrack with given stubs
0974     TTTrack<Ref_Phase2TrackerDigi_> ttTrack(const std::vector<StubKF>& stubs) const;
0975 
0976   private:
0977   };
0978 
0979   //Class to represent KFout 96-bit track for use in distribution server
0980   class TrackKFOut {
0981   public:
0982     TrackKFOut() : TrackKFOut(0, 0, 0, 0, 0, tt::FrameTrack(), 0, 0, false) {}
0983     // construct TrackKF from Partial Tracks
0984     TrackKFOut(TTBV PartialTrack1,
0985                TTBV PartialTrack2,
0986                TTBV PartialTrack3,
0987                int sortKey,
0988                int nonantId,
0989                const tt::FrameTrack& track,
0990                int trackID,
0991                int linkID,
0992                bool valid)
0993         : PartialTrack1_(PartialTrack1),
0994           PartialTrack2_(PartialTrack2),
0995           PartialTrack3_(PartialTrack3),
0996           sortKey_(sortKey),
0997           nonantId_(nonantId),
0998           track_(track),
0999           trackID_(trackID),
1000           linkID_(linkID),
1001           valid_(valid) {}
1002 
1003     ~TrackKFOut() {}
1004 
1005     int sortKey() const { return sortKey_; }
1006     int nonantId() const { return nonantId_; }
1007 
1008     bool dataValid() const { return valid_; }
1009 
1010     int trackID() const { return trackID_; }
1011     int linkID() const { return linkID_; }
1012 
1013     TTBV PartialTrack1() const { return PartialTrack1_; }
1014     TTBV PartialTrack2() const { return PartialTrack2_; }
1015     TTBV PartialTrack3() const { return PartialTrack3_; }
1016 
1017     tt::FrameTrack track() const { return track_; }
1018 
1019   private:
1020     TTBV PartialTrack1_;
1021     TTBV PartialTrack2_;
1022     TTBV PartialTrack3_;
1023     int sortKey_;
1024     int nonantId_;
1025     tt::FrameTrack track_;
1026     int trackID_;
1027     int linkID_;
1028     bool valid_;
1029   };
1030 
1031   typedef std::vector<TrackKFOut> TrackKFOutSACollection;
1032   typedef std::shared_ptr<TrackKFOut> TrackKFOutSAPtr;
1033   typedef std::vector<TrackKFOutSAPtr> TrackKFOutSAPtrCollection;
1034   typedef std::vector<std::vector<std::shared_ptr<TrackKFOut>>> TrackKFOutSAPtrCollections;
1035   typedef std::vector<std::vector<std::vector<std::shared_ptr<TrackKFOut>>>> TrackKFOutSAPtrCollectionss;
1036   // class to represent tracks generated by process duplicate removal
1037   class TrackDR : public Track<double, double, double, double> {
1038   public:
1039     // construct TrackDR from Frame
1040     TrackDR(const tt::FrameTrack& frame, const DataFormats* dataFormats);
1041     // construct TrackDR from TrackKF
1042     TrackDR(const TrackKF& track);
1043     ~TrackDR() {}
1044     // track phi at radius 0 wrt processing nonant centre
1045     double phi0() const { return std::get<0>(data_); }
1046     // track inv2R
1047     double inv2R() const { return std::get<1>(data_); }
1048     // track z at radius 0
1049     double z0() const { return std::get<2>(data_); }
1050     // track cotThea
1051     double cot() const { return std::get<3>(data_); }
1052     // conversion to TTTrack
1053     TTTrack<Ref_Phase2TrackerDigi_> ttTrack() const;
1054 
1055   private:
1056   };
1057 
1058 }  // namespace trackerTFP
1059 
1060 EVENTSETUP_DATA_DEFAULT_RECORD(trackerTFP::DataFormats, trackerTFP::DataFormatsRcd);
1061 
1062 #endif