Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-10-14 01:43:53

0001 #include "L1Trigger/TrackerTFP/interface/DataFormats.h"
0002 #include "L1Trigger/TrackTrigger/interface/StubPtConsistency.h"
0003 
0004 #include <vector>
0005 #include <deque>
0006 #include <cmath>
0007 #include <tuple>
0008 #include <iterator>
0009 #include <algorithm>
0010 #include <string>
0011 #include <iostream>
0012 
0013 using namespace std;
0014 using namespace edm;
0015 using namespace tt;
0016 
0017 namespace trackerTFP {
0018 
0019   // default constructor, trying to needs space as proper constructed object
0020   DataFormats::DataFormats()
0021       : numDataFormats_(0),
0022         formats_(+Variable::end, std::vector<DataFormat*>(+Process::end, nullptr)),
0023         numUnusedBitsStubs_(+Process::end, TTBV::S_),
0024         numUnusedBitsTracks_(+Process::end, TTBV::S_),
0025         numChannel_(+Process::end, 0) {
0026     setup_ = nullptr;
0027     countFormats();
0028     dataFormats_.reserve(numDataFormats_);
0029     numStreams_.reserve(+Process::end);
0030     numStreamsStubs_.reserve(+Process::end);
0031     numStreamsTracks_.reserve(+Process::end);
0032   }
0033 
0034   // method to count number of unique data formats
0035   template <Variable v, Process p>
0036   void DataFormats::countFormats() {
0037     if constexpr (config_[+v][+p] == p)
0038       numDataFormats_++;
0039     if constexpr (++p != Process::end)
0040       countFormats<v, ++p>();
0041     else if constexpr (++v != Variable::end)
0042       countFormats<++v>();
0043   }
0044 
0045   // proper constructor
0046   DataFormats::DataFormats(const ParameterSet& iConfig, const Setup* setup) : DataFormats() {
0047     iConfig_ = iConfig;
0048     setup_ = setup;
0049     fillDataFormats();
0050     for (const Process p : Processes)
0051       for (const Variable v : stubs_[+p])
0052         numUnusedBitsStubs_[+p] -= formats_[+v][+p] ? formats_[+v][+p]->width() : 0;
0053     for (const Process p : Processes)
0054       for (const Variable v : tracks_[+p])
0055         numUnusedBitsTracks_[+p] -= formats_[+v][+p] ? formats_[+v][+p]->width() : 0;
0056     numChannel_[+Process::dtc] = setup_->numDTCsPerRegion();
0057     numChannel_[+Process::pp] = setup_->numDTCsPerTFP();
0058     numChannel_[+Process::gp] = setup_->numSectors();
0059     numChannel_[+Process::ht] = setup_->htNumBinsInv2R();
0060     numChannel_[+Process::mht] = setup_->htNumBinsInv2R();
0061     numChannel_[+Process::zht] = setup_->htNumBinsInv2R();
0062     numChannel_[+Process::kfin] = setup_->kfNumWorker() * setup_->numLayers();
0063     numChannel_[+Process::kf] = setup_->kfNumWorker();
0064     transform(numChannel_.begin(), numChannel_.end(), back_inserter(numStreams_), [this](int channel) {
0065       return channel * setup_->numRegions();
0066     });
0067     numStreamsStubs_ = numStreams_;
0068     numStreamsStubs_[+Process::kf] = numStreams_[+Process::kfin];
0069     numStreamsTracks_ = vector<int>(+Process::end, 0);
0070     numStreamsTracks_[+Process::kfin] = numStreams_[+Process::kf];
0071     numStreamsTracks_[+Process::kf] = numStreams_[+Process::kf];
0072   }
0073 
0074   // constructs data formats of all unique used variables and flavours
0075   template <Variable v, Process p>
0076   void DataFormats::fillDataFormats() {
0077     if constexpr (config_[+v][+p] == p) {
0078       dataFormats_.emplace_back(Format<v, p>(iConfig_, setup_));
0079       fillFormats<v, p>();
0080     }
0081     if constexpr (++p != Process::end)
0082       fillDataFormats<v, ++p>();
0083     else if constexpr (++v != Variable::end)
0084       fillDataFormats<++v>();
0085   }
0086 
0087   // helper (loop) data formats of all unique used variables and flavours
0088   template <Variable v, Process p, Process it>
0089   void DataFormats::fillFormats() {
0090     if (config_[+v][+it] == p) {
0091       formats_[+v][+it] = &dataFormats_.back();
0092     }
0093     if constexpr (++it != Process::end)
0094       fillFormats<v, p, ++it>();
0095   }
0096 
0097   // converts bits to ntuple of variables
0098   template <typename... Ts>
0099   void DataFormats::convertStub(Process p, const Frame& bv, tuple<Ts...>& data) const {
0100     TTBV ttBV(bv);
0101     extractStub(p, ttBV, data);
0102   }
0103 
0104   // helper (loop) to convert bits to ntuple of variables
0105   template <int it, typename... Ts>
0106   void DataFormats::extractStub(Process p, TTBV& ttBV, std::tuple<Ts...>& data) const {
0107     Variable v = *next(stubs_[+p].begin(), sizeof...(Ts) - 1 - it);
0108     formats_[+v][+p]->extract(ttBV, get<sizeof...(Ts) - 1 - it>(data));
0109     if constexpr (it + 1 != sizeof...(Ts))
0110       extractStub<it + 1>(p, ttBV, data);
0111   }
0112 
0113   // converts ntuple of variables to bits
0114   template <typename... Ts>
0115   void DataFormats::convertStub(Process p, const std::tuple<Ts...>& data, Frame& bv) const {
0116     TTBV ttBV(1, numUnusedBitsStubs_[+p]);
0117     attachStub(p, data, ttBV);
0118     bv = ttBV.bs();
0119   }
0120 
0121   // helper (loop) to convert ntuple of variables to bits
0122   template <int it, typename... Ts>
0123   void DataFormats::attachStub(Process p, const tuple<Ts...>& data, TTBV& ttBV) const {
0124     Variable v = *next(stubs_[+p].begin(), it);
0125     formats_[+v][+p]->attach(get<it>(data), ttBV);
0126     if constexpr (it + 1 != sizeof...(Ts))
0127       attachStub<it + 1>(p, data, ttBV);
0128   }
0129 
0130   // converts bits to ntuple of variables
0131   template <typename... Ts>
0132   void DataFormats::convertTrack(Process p, const Frame& bv, tuple<Ts...>& data) const {
0133     TTBV ttBV(bv);
0134     extractTrack(p, ttBV, data);
0135   }
0136 
0137   // helper (loop) to convert bits to ntuple of variables
0138   template <int it, typename... Ts>
0139   void DataFormats::extractTrack(Process p, TTBV& ttBV, std::tuple<Ts...>& data) const {
0140     Variable v = *next(tracks_[+p].begin(), sizeof...(Ts) - 1 - it);
0141     formats_[+v][+p]->extract(ttBV, get<sizeof...(Ts) - 1 - it>(data));
0142     if constexpr (it + 1 != sizeof...(Ts))
0143       extractTrack<it + 1>(p, ttBV, data);
0144   }
0145 
0146   // converts ntuple of variables to bits
0147   template <typename... Ts>
0148   void DataFormats::convertTrack(Process p, const std::tuple<Ts...>& data, Frame& bv) const {
0149     TTBV ttBV(1, numUnusedBitsTracks_[+p]);
0150     attachTrack(p, data, ttBV);
0151     bv = ttBV.bs();
0152   }
0153 
0154   // helper (loop) to convert ntuple of variables to bits
0155   template <int it, typename... Ts>
0156   void DataFormats::attachTrack(Process p, const tuple<Ts...>& data, TTBV& ttBV) const {
0157     Variable v = *next(tracks_[+p].begin(), it);
0158     formats_[+v][+p]->attach(get<it>(data), ttBV);
0159     if constexpr (it + 1 != sizeof...(Ts))
0160       attachTrack<it + 1>(p, data, ttBV);
0161   }
0162 
0163   // construct Stub from Frame
0164   template <typename... Ts>
0165   Stub<Ts...>::Stub(const FrameStub& frame, const DataFormats* dataFormats, Process p)
0166       : dataFormats_(dataFormats), p_(p), frame_(frame), trackId_(0) {
0167     dataFormats_->convertStub(p, frame.second, data_);
0168   }
0169 
0170   // construct Stub from other Stub
0171   template <typename... Ts>
0172   template <typename... Others>
0173   Stub<Ts...>::Stub(const Stub<Others...>& stub, Ts... data)
0174       : dataFormats_(stub.dataFormats()),
0175         p_(++stub.p()),
0176         frame_(stub.frame().first, Frame()),
0177         data_(data...),
0178         trackId_(0) {}
0179 
0180   // construct Stub from TTStubRef
0181   template <typename... Ts>
0182   Stub<Ts...>::Stub(const TTStubRef& ttStubRef, const DataFormats* dataFormats, Process p, Ts... data)
0183       : dataFormats_(dataFormats), p_(p), frame_(ttStubRef, Frame()), data_(data...), trackId_(0) {}
0184 
0185   // construct StubPP from Frame
0186   StubPP::StubPP(const FrameStub& frame, const DataFormats* formats) : Stub(frame, formats, Process::pp) {
0187     for (int sectorEta = sectorEtaMin(); sectorEta <= sectorEtaMax(); sectorEta++)
0188       for (int sectorPhi = 0; sectorPhi < width(Variable::sectorsPhi); sectorPhi++)
0189         sectors_[sectorEta * width(Variable::sectorsPhi) + sectorPhi] = sectorsPhi()[sectorPhi];
0190   }
0191 
0192   // construct StubGP from Frame
0193   StubGP::StubGP(const FrameStub& frame, const DataFormats* formats, int sectorPhi, int sectorEta)
0194       : Stub(frame, formats, Process::gp), sectorPhi_(sectorPhi), sectorEta_(sectorEta) {
0195     const Setup* setup = dataFormats_->setup();
0196     inv2RBins_ = TTBV(0, setup->htNumBinsInv2R());
0197     for (int inv2R = inv2RMin(); inv2R <= inv2RMax(); inv2R++)
0198       inv2RBins_.set(inv2R + inv2RBins_.size() / 2);
0199   }
0200 
0201   // construct StubGP from StubPP
0202   StubGP::StubGP(const StubPP& stub, int sectorPhi, int sectorEta)
0203       : Stub(stub, stub.r(), stub.phi(), stub.z(), stub.layer(), stub.inv2RMin(), stub.inv2RMax()),
0204         sectorPhi_(sectorPhi),
0205         sectorEta_(sectorEta) {
0206     const Setup* setup = dataFormats_->setup();
0207     get<1>(data_) -= (sectorPhi_ - .5) * setup->baseSector();
0208     get<2>(data_) -= (r() + dataFormats_->chosenRofPhi()) * setup->sectorCot(sectorEta_);
0209     dataFormats_->convertStub(p_, data_, frame_.second);
0210   }
0211 
0212   // construct StubHT from Frame
0213   StubHT::StubHT(const FrameStub& frame, const DataFormats* formats, int inv2R)
0214       : Stub(frame, formats, Process::ht), inv2R_(inv2R) {
0215     fillTrackId();
0216   }
0217 
0218   // construct StubHT from StubGP and HT cell assignment
0219   StubHT::StubHT(const StubGP& stub, int phiT, int inv2R)
0220       : Stub(stub, stub.r(), stub.phi(), stub.z(), stub.layer(), stub.sectorPhi(), stub.sectorEta(), phiT),
0221         inv2R_(inv2R) {
0222     get<1>(data_) -=
0223         format(Variable::inv2R).floating(this->inv2R()) * r() + format(Variable::phiT).floating(this->phiT());
0224     fillTrackId();
0225     dataFormats_->convertStub(p_, data_, frame_.second);
0226   }
0227 
0228   void StubHT::fillTrackId() {
0229     TTBV ttBV(bv());
0230     trackId_ = ttBV.extract(width(Variable::sectorPhi) + width(Variable::sectorEta) + width(Variable::phiT));
0231   }
0232 
0233   // construct StubMHT from Frame
0234   StubMHT::StubMHT(const FrameStub& frame, const DataFormats* formats) : Stub(frame, formats, Process::mht) {
0235     fillTrackId();
0236   }
0237 
0238   // construct StubMHT from StubHT and MHT cell assignment
0239   StubMHT::StubMHT(const StubHT& stub, int phiT, int inv2R)
0240       : Stub(stub,
0241              stub.r(),
0242              stub.phi(),
0243              stub.z(),
0244              stub.layer(),
0245              stub.sectorPhi(),
0246              stub.sectorEta(),
0247              stub.phiT(),
0248              stub.inv2R()) {
0249     const Setup* setup = dataFormats_->setup();
0250     // update track (phIT, inv2R), and phi residuals w.r.t. track, to reflect MHT cell assignment.
0251     get<6>(data_) = this->phiT() * setup->mhtNumBinsPhiT() + phiT;
0252     get<7>(data_) = this->inv2R() * setup->mhtNumBinsInv2R() + inv2R;
0253     get<1>(data_) -= base(Variable::inv2R) * (inv2R - .5) * r() + base(Variable::phiT) * (phiT - .5);
0254     dataFormats_->convertStub(p_, data_, frame_.second);
0255     fillTrackId();
0256   }
0257 
0258   // fills track id
0259   void StubMHT::fillTrackId() {
0260     TTBV ttBV(bv());
0261     trackId_ = ttBV.extract(width(Variable::sectorPhi) + width(Variable::sectorEta) + width(Variable::phiT) +
0262                             width(Variable::inv2R));
0263   }
0264 
0265   // construct StubZHT from Frame
0266   StubZHT::StubZHT(const FrameStub& frame, const DataFormats* formats) : Stub(frame, formats, Process::zht) {
0267     cot_ = 0.;
0268     zT_ = 0.;
0269     fillTrackId();
0270   }
0271 
0272   // construct StubZHT from StubMHT
0273   StubZHT::StubZHT(const StubMHT& stub)
0274       : Stub(stub,
0275              stub.r(),
0276              stub.phi(),
0277              stub.z(),
0278              stub.layer(),
0279              stub.sectorPhi(),
0280              stub.sectorEta(),
0281              stub.phiT(),
0282              stub.inv2R(),
0283              0,
0284              0) {
0285     cot_ = 0.;
0286     zT_ = 0.;
0287     r_ = format(Variable::r).digi(this->r() + dataFormats_->chosenRofPhi() - dataFormats_->setup()->chosenRofZ());
0288     chi_ = stub.z();
0289     trackId_ = stub.trackId();
0290   }
0291 
0292   //
0293   StubZHT::StubZHT(const StubZHT& stub, double zT, double cot, int id)
0294       : Stub(stub.frame().first,
0295              stub.dataFormats(),
0296              Process::zht,
0297              stub.r(),
0298              stub.phi(),
0299              stub.z(),
0300              stub.layer(),
0301              stub.sectorPhi(),
0302              stub.sectorEta(),
0303              stub.phiT(),
0304              stub.inv2R(),
0305              stub.zT(),
0306              stub.cot()) {
0307     // update track (zT, cot), and phi residuals w.r.t. track, to reflect ZHT cell assignment.
0308     r_ = stub.r_;
0309     cot_ = stub.cotf() + cot;
0310     zT_ = stub.ztf() + zT;
0311     chi_ = stub.z() - zT_ + r_ * cot_;
0312     get<8>(data_) = format(Variable::zT).integer(zT_);
0313     get<9>(data_) = format(Variable::cot).integer(cot_);
0314     dataFormats_->convertStub(p_, data_, frame_.second);
0315     trackId_ = stub.trackId() * 4 + id;
0316   }
0317 
0318   //
0319   StubZHT::StubZHT(const StubZHT& stub, int cot, int zT)
0320       : Stub(stub.frame().first,
0321              stub.dataFormats(),
0322              Process::zht,
0323              stub.r(),
0324              stub.phi(),
0325              0.,
0326              stub.layer(),
0327              stub.sectorPhi(),
0328              stub.sectorEta(),
0329              stub.phiT(),
0330              stub.inv2R(),
0331              zT,
0332              cot) {
0333     get<2>(data_) =
0334         format(Variable::z)
0335             .digi(stub.z() - (format(Variable::zT).floating(zT) - stub.r_ * format(Variable::cot).floating(cot)));
0336     dataFormats_->convertStub(p_, data_, frame_.second);
0337     fillTrackId();
0338   }
0339 
0340   // fills track id
0341   void StubZHT::fillTrackId() {
0342     TTBV ttBV(bv());
0343     trackId_ = ttBV.extract(width(Variable::sectorPhi) + width(Variable::sectorEta) + width(Variable::phiT) +
0344                             width(Variable::inv2R) + width(Variable::zT) + width(Variable::cot));
0345   }
0346 
0347   // construct StubKFin from Frame
0348   StubKFin::StubKFin(const FrameStub& frame, const DataFormats* formats, int layer)
0349       : Stub(frame, formats, Process::kfin), layer_(layer) {}
0350 
0351   // construct StubKFin from StubZHT
0352   StubKFin::StubKFin(const StubZHT& stub, double dPhi, double dZ, int layer)
0353       : Stub(stub, stub.r(), stub.phi(), stub.z(), dPhi, dZ), layer_(layer) {
0354     dataFormats_->convertStub(p_, data_, frame_.second);
0355   }
0356 
0357   // construct StubKFin from TTStubRef
0358   StubKFin::StubKFin(const TTStubRef& ttStubRef,
0359                      const DataFormats* dataFormats,
0360                      double r,
0361                      double phi,
0362                      double z,
0363                      double dPhi,
0364                      double dZ,
0365                      int layer)
0366       : Stub(ttStubRef, dataFormats, Process::kfin, r, phi, z, dPhi, dZ), layer_(layer) {
0367     dataFormats_->convertStub(p_, data_, frame_.second);
0368   }
0369 
0370   // construct StubKF from Frame
0371   StubKF::StubKF(const FrameStub& frame, const DataFormats* formats, int layer)
0372       : Stub(frame, formats, Process::kf), layer_(layer) {}
0373 
0374   // construct StubKF from StubKFin
0375   StubKF::StubKF(const StubKFin& stub, double inv2R, double phiT, double cot, double zT)
0376       : Stub(stub, stub.r(), 0., 0., stub.dPhi(), stub.dZ()), layer_(stub.layer()) {
0377     const Setup* setup = dataFormats_->setup();
0378     get<1>(data_) = format(Variable::phi).digi(stub.phi() - (phiT + this->r() * inv2R));
0379     const double d =
0380         (dataFormats_->hybrid() ? setup->hybridChosenRofPhi() : setup->chosenRofPhi()) - setup->chosenRofZ();
0381     const double rz = format(Variable::r).digi(this->r() + d);
0382     get<2>(data_) = format(Variable::z).digi(stub.z() - (zT + rz * cot));
0383     dataFormats_->convertStub(p_, data_, frame_.second);
0384   }
0385 
0386   // construct Track from Frame
0387   template <typename... Ts>
0388   Track<Ts...>::Track(const FrameTrack& frame, const DataFormats* dataFormats, Process p)
0389       : dataFormats_(dataFormats), p_(p), frame_(frame) {
0390     dataFormats_->convertTrack(p_, frame.second, data_);
0391   }
0392 
0393   // construct Track from other Track
0394   template <typename... Ts>
0395   template <typename... Others>
0396   Track<Ts...>::Track(const Track<Others...>& track, Ts... data)
0397       : dataFormats_(track.dataFormats()), p_(++track.p()), frame_(track.frame().first, Frame()), data_(data...) {}
0398 
0399   // construct Track from Stub
0400   template <typename... Ts>
0401   template <typename... Others>
0402   Track<Ts...>::Track(const Stub<Others...>& stub, const TTTrackRef& ttTrackRef, Ts... data)
0403       : dataFormats_(stub.dataFormats()), p_(++stub.p()), frame_(ttTrackRef, Frame()), data_(data...) {}
0404 
0405   // construct Track from TTTrackRef
0406   template <typename... Ts>
0407   Track<Ts...>::Track(const TTTrackRef& ttTrackRef, const DataFormats* dataFormats, Process p, Ts... data)
0408       : dataFormats_(dataFormats), p_(p), frame_(ttTrackRef, Frame()), data_(data...) {}
0409 
0410   // construct TrackKFin from Frame
0411   TrackKFin::TrackKFin(const FrameTrack& frame, const DataFormats* dataFormats, const vector<StubKFin*>& stubs)
0412       : Track(frame, dataFormats, Process::kfin), stubs_(setup()->numLayers()), hitPattern_(0, setup()->numLayers()) {
0413     vector<int> nStubs(stubs_.size(), 0);
0414     for (StubKFin* stub : stubs)
0415       nStubs[stub->layer()]++;
0416     for (int layer = 0; layer < dataFormats->setup()->numLayers(); layer++)
0417       stubs_[layer].reserve(nStubs[layer]);
0418     for (StubKFin* stub : stubs) {
0419       const int layer = stub->layer();
0420       stubs_[layer].push_back(stub);
0421       hitPattern_.set(layer);
0422     }
0423   }
0424 
0425   // construct TrackKFin from StubZHT
0426   TrackKFin::TrackKFin(const StubZHT& stub, const TTTrackRef& ttTrackRef, const TTBV& maybePattern)
0427       : Track(stub, ttTrackRef, maybePattern, stub.sectorPhi(), stub.sectorEta(), 0., 0., 0., 0.),
0428         stubs_(setup()->numLayers()),
0429         hitPattern_(0, setup()->numLayers()) {
0430     get<3>(data_) = format(Variable::phiT, Process::mht).floating(stub.phiT());
0431     get<4>(data_) = format(Variable::inv2R, Process::mht).floating(stub.inv2R());
0432     get<5>(data_) = format(Variable::zT, Process::zht).floating(stub.zT());
0433     get<6>(data_) = format(Variable::cot, Process::zht).floating(stub.cot());
0434     dataFormats_->convertTrack(p_, data_, frame_.second);
0435   }
0436 
0437   // construct TrackKFin from TTTrackRef
0438   TrackKFin::TrackKFin(const TTTrackRef& ttTrackRef,
0439                        const DataFormats* dataFormats,
0440                        const TTBV& maybePattern,
0441                        double phiT,
0442                        double inv2R,
0443                        double zT,
0444                        double cot,
0445                        int sectorPhi,
0446                        int sectorEta)
0447       : Track(ttTrackRef, dataFormats, Process::kfin, maybePattern, sectorPhi, sectorEta, phiT, inv2R, zT, cot),
0448         stubs_(setup()->numLayers()),
0449         hitPattern_(0, setup()->numLayers()) {
0450     dataFormats_->convertTrack(p_, data_, frame_.second);
0451   }
0452 
0453   vector<TTStubRef> TrackKFin::ttStubRefs(const TTBV& hitPattern, const vector<int>& layerMap) const {
0454     vector<TTStubRef> stubs;
0455     stubs.reserve(hitPattern.count());
0456     for (int layer = 0; layer < setup()->numLayers(); layer++)
0457       if (hitPattern[layer])
0458         stubs.push_back(stubs_[layer][layerMap[layer]]->ttStubRef());
0459     return stubs;
0460   }
0461 
0462   // construct TrackKF from Frame
0463   TrackKF::TrackKF(const FrameTrack& frame, const DataFormats* dataFormats) : Track(frame, dataFormats, Process::kf) {}
0464 
0465   // construct TrackKF from TrackKfin
0466   TrackKF::TrackKF(const TrackKFin& track, double phiT, double inv2R, double zT, double cot)
0467       : Track(
0468             track, false, track.sectorPhi(), track.sectorEta(), track.phiT(), track.inv2R(), track.cot(), track.zT()) {
0469     get<0>(data_) = abs(inv2R) < dataFormats_->format(Variable::inv2R, Process::zht).base() / 2. &&
0470                     abs(phiT) < dataFormats_->format(Variable::phiT, Process::zht).base() / 2.;
0471     get<3>(data_) += phiT;
0472     get<4>(data_) += inv2R;
0473     get<5>(data_) += cot;
0474     get<6>(data_) += zT;
0475     dataFormats_->convertTrack(p_, data_, frame_.second);
0476   }
0477 
0478   // conversion to TTTrack with given stubs
0479   TTTrack<Ref_Phase2TrackerDigi_> TrackKF::ttTrack(const vector<StubKF>& stubs) const {
0480     const double invR = -this->inv2R() * 2.;
0481     const double phi0 =
0482         deltaPhi(this->phiT() - this->inv2R() * dataFormats_->chosenRofPhi() +
0483                  setup()->baseSector() * (this->sectorPhi() - .5) + setup()->baseRegion() * frame_.first->phiSector());
0484     const double cot = this->cot() + setup()->sectorCot(this->sectorEta());
0485     const double z0 = this->zT() - this->cot() * setup()->chosenRofZ();
0486     TTBV hitVector(0, setup()->numLayers());
0487     double chi2phi(0.);
0488     double chi2z(0.);
0489     vector<TTStubRef> ttStubRefs;
0490     const int nLayer = stubs.size();
0491     ttStubRefs.reserve(nLayer);
0492     for (const StubKF& stub : stubs) {
0493       hitVector.set(stub.layer());
0494       const TTStubRef& ttStubRef = stub.ttStubRef();
0495       chi2phi += pow(stub.phi(), 2) / setup()->v0(ttStubRef, this->inv2R());
0496       chi2z += pow(stub.z(), 2) / setup()->v1(ttStubRef, cot);
0497       ttStubRefs.push_back(ttStubRef);
0498     }
0499     static constexpr int nPar = 4;
0500     static constexpr double d0 = 0.;
0501     static constexpr double trkMVA1 = 0.;
0502     static constexpr double trkMVA2 = 0.;
0503     static constexpr double trkMVA3 = 0.;
0504     const int hitPattern = hitVector.val();
0505     const double bField = setup()->bField();
0506     TTTrack<Ref_Phase2TrackerDigi_> ttTrack(
0507         invR, phi0, cot, z0, d0, chi2phi, chi2z, trkMVA1, trkMVA2, trkMVA3, hitPattern, nPar, bField);
0508     ttTrack.setStubRefs(ttStubRefs);
0509     ttTrack.setPhiSector(frame_.first->phiSector());
0510     ttTrack.setEtaSector(this->sectorEta());
0511     ttTrack.setTrackSeedType(frame_.first->trackSeedType());
0512     ttTrack.setStubPtConsistency(StubPtConsistency::getConsistency(
0513         ttTrack, setup()->trackerGeometry(), setup()->trackerTopology(), bField, nPar));
0514     return ttTrack;
0515   }
0516 
0517   // construct TrackDR from Frame
0518   TrackDR::TrackDR(const FrameTrack& frame, const DataFormats* dataFormats) : Track(frame, dataFormats, Process::dr) {}
0519 
0520   // construct TrackDR from TrackKF
0521   TrackDR::TrackDR(const TrackKF& track) : Track(track, 0., 0., 0., 0.) {
0522     get<0>(data_) = track.phiT() + track.inv2R() * dataFormats_->chosenRofPhi() +
0523                     dataFormats_->format(Variable::phi, Process::gp).range() * (track.sectorPhi() - .5);
0524     get<1>(data_) = track.inv2R();
0525     get<2>(data_) = track.zT() - track.cot() * setup()->chosenRofZ();
0526     get<3>(data_) = track.cot() + setup()->sectorCot(track.sectorEta());
0527     dataFormats_->convertTrack(p_, data_, frame_.second);
0528   }
0529 
0530   // conversion to TTTrack
0531   TTTrack<Ref_Phase2TrackerDigi_> TrackDR::ttTrack() const {
0532     const double inv2R = this->inv2R();
0533     const double phi0 = this->phi0();
0534     const double cot = this->cot();
0535     const double z0 = this->z0();
0536     static constexpr double d0 = 0.;
0537     static constexpr double chi2phi = 0.;
0538     static constexpr double chi2z = 0;
0539     static constexpr double trkMVA1 = 0.;
0540     static constexpr double trkMVA2 = 0.;
0541     static constexpr double trkMVA3 = 0.;
0542     static constexpr int hitPattern = 0.;
0543     static constexpr int nPar = 4;
0544     static constexpr double bField = 0.;
0545     const int sectorPhi = frame_.first->phiSector();
0546     const int sectorEta = frame_.first->etaSector();
0547     TTTrack<Ref_Phase2TrackerDigi_> ttTrack(
0548         inv2R, phi0, cot, z0, d0, chi2phi, chi2z, trkMVA1, trkMVA2, trkMVA3, hitPattern, nPar, bField);
0549     ttTrack.setPhiSector(sectorPhi);
0550     ttTrack.setEtaSector(sectorEta);
0551     return ttTrack;
0552   }
0553 
0554   template <>
0555   Format<Variable::phiT, Process::ht>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0556     range_ = 2. * M_PI / (double)(setup->numRegions() * setup->numSectorsPhi());
0557     base_ = range_ / (double)setup->htNumBinsPhiT();
0558     width_ = ceil(log2(setup->htNumBinsPhiT()));
0559   }
0560 
0561   template <>
0562   Format<Variable::phiT, Process::mht>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0563     const Format<Variable::phiT, Process::ht> ht(iConfig, setup);
0564     range_ = ht.range();
0565     base_ = ht.base() / setup->mhtNumBinsPhiT();
0566     width_ = ceil(log2(setup->htNumBinsPhiT() * setup->mhtNumBinsPhiT()));
0567   }
0568 
0569   template <>
0570   Format<Variable::inv2R, Process::ht>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0571     const double mintPt = iConfig.getParameter<bool>("UseHybrid") ? setup->hybridMinPtCand() : setup->minPt();
0572     range_ = 2. * setup->invPtToDphi() / mintPt;
0573     base_ = range_ / (double)setup->htNumBinsInv2R();
0574     width_ = ceil(log2(setup->htNumBinsInv2R()));
0575   }
0576 
0577   template <>
0578   Format<Variable::inv2R, Process::mht>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0579     const Format<Variable::inv2R, Process::ht> ht(iConfig, setup);
0580     range_ = ht.range();
0581     base_ = ht.base() / setup->mhtNumBinsInv2R();
0582     width_ = ceil(log2(setup->htNumBinsInv2R() * setup->mhtNumBinsInv2R()));
0583   }
0584 
0585   template <>
0586   Format<Variable::r, Process::ht>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0587     const double chosenRofPhi =
0588         iConfig.getParameter<bool>("UseHybrid") ? setup->hybridChosenRofPhi() : setup->chosenRofPhi();
0589     width_ = setup->tmttWidthR();
0590     range_ = 2. * max(abs(setup->outerRadius() - chosenRofPhi), abs(setup->innerRadius() - chosenRofPhi));
0591     const Format<Variable::phiT, Process::ht> phiT(iConfig, setup);
0592     const Format<Variable::inv2R, Process::ht> inv2R(iConfig, setup);
0593     base_ = phiT.base() / inv2R.base();
0594     const int shift = ceil(log2(range_ / base_ / pow(2., width_)));
0595     base_ *= pow(2., shift);
0596   }
0597 
0598   template <>
0599   Format<Variable::phi, Process::gp>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0600     const Format<Variable::phiT, Process::ht> phiT(iConfig, setup);
0601     const Format<Variable::inv2R, Process::ht> inv2R(iConfig, setup);
0602     const Format<Variable::r, Process::ht> r(iConfig, setup);
0603     range_ = phiT.range() + inv2R.range() * r.base() * pow(2., r.width()) / 4.;
0604     const Format<Variable::phi, Process::dtc> dtc(iConfig, setup);
0605     base_ = dtc.base();
0606     width_ = ceil(log2(range_ / base_));
0607   }
0608 
0609   template <>
0610   Format<Variable::phi, Process::dtc>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0611     width_ = setup->tmttWidthPhi();
0612     const Format<Variable::phiT, Process::ht> phiT(iConfig, setup);
0613     const Format<Variable::inv2R, Process::ht> inv2R(iConfig, setup);
0614     const Format<Variable::r, Process::ht> r(iConfig, setup);
0615     range_ = 2. * M_PI / (double)setup->numRegions() + inv2R.range() * r.base() * pow(2., r.width()) / 4.;
0616     const int shift = ceil(log2(range_ / phiT.base() / pow(2., width_)));
0617     base_ = phiT.base() * pow(2., shift);
0618   }
0619 
0620   template <>
0621   Format<Variable::phi, Process::ht>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0622     const Format<Variable::phiT, Process::ht> phiT(iConfig, setup);
0623     range_ = 2. * phiT.base();
0624     const Format<Variable::phi, Process::gp> gp(iConfig, setup);
0625     base_ = gp.base();
0626     width_ = ceil(log2(range_ / base_));
0627   }
0628 
0629   template <>
0630   Format<Variable::phi, Process::mht>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0631     const Format<Variable::phiT, Process::mht> phiT(iConfig, setup);
0632     range_ = 2. * phiT.base();
0633     const Format<Variable::phi, Process::ht> ht(iConfig, setup);
0634     base_ = ht.base();
0635     width_ = ceil(log2(range_ / base_));
0636   }
0637 
0638   template <>
0639   Format<Variable::phi, Process::kf>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0640     const Format<Variable::phi, Process::zht> phi(iConfig, setup);
0641     const double rangeFactor = iConfig.getParameter<ParameterSet>("KalmanFilter").getParameter<double>("RangeFactor");
0642     range_ = rangeFactor * phi.range();
0643     base_ = phi.base();
0644     width_ = ceil(log2(range_ / base_));
0645   }
0646 
0647   template <>
0648   Format<Variable::z, Process::dtc>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0649     width_ = setup->tmttWidthZ();
0650     range_ = 2. * setup->halfLength();
0651     const Format<Variable::r, Process::ht> r(iConfig, setup);
0652     const int shift = ceil(log2(range_ / r.base())) - width_;
0653     base_ = r.base() * pow(2., shift);
0654   }
0655 
0656   template <>
0657   Format<Variable::z, Process::gp>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0658     range_ = setup->neededRangeChiZ();
0659     const Format<Variable::z, Process::dtc> dtc(iConfig, setup);
0660     base_ = dtc.base();
0661     width_ = ceil(log2(range_ / base_));
0662   }
0663 
0664   template <>
0665   Format<Variable::zT, Process::zht>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0666     const int numBinsZT = iConfig.getParameter<ParameterSet>("ZHoughTransform").getParameter<int>("NumBinsZT");
0667     const int numStages = iConfig.getParameter<ParameterSet>("ZHoughTransform").getParameter<int>("NumStages");
0668     width_ = ceil(log2(pow(numBinsZT, numStages)));
0669     const Format<Variable::z, Process::dtc> z(iConfig, setup);
0670     range_ = -1.;
0671     for (int eta = 0; eta < setup->numSectorsEta(); eta++)
0672       range_ = max(range_, (sinh(setup->boundarieEta(eta + 1)) - sinh(setup->boundarieEta(eta))));
0673     range_ *= setup->chosenRofZ();
0674     const int shift = ceil(log2(range_ / z.base() / pow(2., width_)));
0675     base_ = z.base() * pow(2., shift);
0676   }
0677 
0678   template <>
0679   Format<Variable::cot, Process::zht>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0680     const int numBinsCot = iConfig.getParameter<ParameterSet>("ZHoughTransform").getParameter<int>("NumBinsCot");
0681     const int numStages = iConfig.getParameter<ParameterSet>("ZHoughTransform").getParameter<int>("NumStages");
0682     width_ = ceil(log2(pow(numBinsCot, numStages)));
0683     const Format<Variable::zT, Process::zht> zT(iConfig, setup);
0684     range_ = (zT.range() + 2. * setup->beamWindowZ()) / setup->chosenRofZ();
0685     const int shift = ceil(log2(range_)) - width_;
0686     base_ = pow(2., shift);
0687   }
0688 
0689   template <>
0690   Format<Variable::z, Process::zht>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0691     const Format<Variable::zT, Process::zht> zT(iConfig, setup);
0692     const Format<Variable::cot, Process::zht> cot(iConfig, setup);
0693     const double rangeR =
0694         2. * max(abs(setup->outerRadius() - setup->chosenRofZ()), abs(setup->innerRadius() - setup->chosenRofZ()));
0695     range_ = zT.base() + cot.base() * rangeR + setup->maxdZ();
0696     const Format<Variable::z, Process::dtc> dtc(iConfig, setup);
0697     base_ = dtc.base();
0698     width_ = ceil(log2(range_ / base_));
0699     /*const Format<Variable::z, Process::gp> z(iConfig, setup);
0700     width_ = z.width();
0701     range_ = z.range();
0702     base_ = z.base();*/
0703   }
0704 
0705   template <>
0706   Format<Variable::z, Process::kfin>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0707     const Format<Variable::z, Process::zht> zht(iConfig, setup);
0708     range_ = zht.range() * pow(2, setup->kfinShiftRangeZ());
0709     base_ = zht.base();
0710     width_ = ceil(log2(range_ / base_));
0711   }
0712 
0713   template <>
0714   Format<Variable::phi, Process::zht>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0715     const Format<Variable::phiT, Process::mht> phiT(iConfig, setup);
0716     const Format<Variable::inv2R, Process::mht> inv2R(iConfig, setup);
0717     const double chosenRofPhi =
0718         iConfig.getParameter<bool>("UseHybrid") ? setup->hybridChosenRofPhi() : setup->chosenRofPhi();
0719     const double rangeR = 2. * max(abs(setup->outerRadius() - chosenRofPhi), abs(setup->innerRadius() - chosenRofPhi));
0720     range_ = phiT.base() + inv2R.base() * rangeR + setup->maxdPhi();
0721     const Format<Variable::phi, Process::dtc> dtc(iConfig, setup);
0722     base_ = dtc.base();
0723     width_ = ceil(log2(range_ / base_));
0724   }
0725 
0726   template <>
0727   Format<Variable::phi, Process::kfin>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0728     const Format<Variable::phi, Process::zht> zht(iConfig, setup);
0729     range_ = zht.range() * pow(2, setup->kfinShiftRangePhi());
0730     base_ = zht.base();
0731     width_ = ceil(log2(range_ / base_));
0732   }
0733 
0734   template <>
0735   Format<Variable::z, Process::kf>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0736     /*const Format<Variable::z, Process::zht> z(iConfig, setup);
0737     const double rangeFactor = iConfig.getParameter<ParameterSet>("KalmanFilter").getParameter<double>("RangeFactor");
0738     range_ = rangeFactor * z.range();
0739     base_ = z.base();
0740     width_ = ceil(log2(range_ / base_));*/
0741     const Format<Variable::zT, Process::zht> zT(iConfig, setup);
0742     const Format<Variable::cot, Process::zht> cot(iConfig, setup);
0743     const double rangeR =
0744         2. * max(abs(setup->outerRadius() - setup->chosenRofZ()), abs(setup->innerRadius() - setup->chosenRofZ()));
0745     range_ = zT.base() + cot.base() * rangeR + setup->maxdZ();
0746     const Format<Variable::z, Process::dtc> dtc(iConfig, setup);
0747     base_ = dtc.base();
0748     const double rangeFactor = iConfig.getParameter<ParameterSet>("KalmanFilter").getParameter<double>("RangeFactor");
0749     range_ *= rangeFactor;
0750     width_ = ceil(log2(range_ / base_));
0751   }
0752 
0753   template <>
0754   Format<Variable::layer, Process::ht>::Format(const ParameterSet& iConfig, const Setup* setup) : DataFormat(false) {
0755     range_ = setup->numLayers();
0756     width_ = ceil(log2(range_));
0757   }
0758 
0759   template <>
0760   Format<Variable::sectorEta, Process::gp>::Format(const ParameterSet& iConfig, const Setup* setup)
0761       : DataFormat(false) {
0762     range_ = setup->numSectorsEta();
0763     width_ = ceil(log2(range_));
0764   }
0765 
0766   template <>
0767   Format<Variable::sectorPhi, Process::gp>::Format(const ParameterSet& iConfig, const Setup* setup)
0768       : DataFormat(false) {
0769     range_ = setup->numSectorsPhi();
0770     width_ = ceil(log2(range_));
0771   }
0772 
0773   template <>
0774   Format<Variable::sectorsPhi, Process::dtc>::Format(const ParameterSet& iConfig, const Setup* setup)
0775       : DataFormat(false) {
0776     range_ = setup->numSectorsPhi();
0777     width_ = setup->numSectorsPhi();
0778   }
0779 
0780   template <>
0781   Format<Variable::match, Process::kf>::Format(const edm::ParameterSet& iConfig, const Setup* setup)
0782       : DataFormat(false) {
0783     width_ = 1;
0784     range_ = 1.;
0785   }
0786 
0787   template <>
0788   Format<Variable::hitPattern, Process::kfin>::Format(const edm::ParameterSet& iConfig, const Setup* setup)
0789       : DataFormat(false) {
0790     width_ = setup->numLayers();
0791   }
0792 
0793   template <>
0794   Format<Variable::phi0, Process::dr>::Format(const edm::ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0795     const Format<Variable::inv2R, Process::ht> inv2R(iConfig, setup);
0796     const Format<Variable::phiT, Process::ht> phiT(iConfig, setup);
0797     const double chosenRofPhi =
0798         iConfig.getParameter<bool>("UseHybrid") ? setup->hybridChosenRofPhi() : setup->chosenRofPhi();
0799     width_ = setup->tfpWidthPhi0();
0800     range_ = 2. * M_PI / (double)setup->numRegions() + inv2R.range() * chosenRofPhi;
0801     base_ = phiT.base();
0802     const int shift = ceil(log2(range_ / base_ / pow(2., width_)));
0803     base_ *= pow(2., shift);
0804   }
0805 
0806   template <>
0807   Format<Variable::inv2R, Process::dr>::Format(const edm::ParameterSet& iConfig, const Setup* setup)
0808       : DataFormat(true) {
0809     const Format<Variable::inv2R, Process::ht> inv2R(iConfig, setup);
0810     width_ = setup->tfpWidthInv2R();
0811     range_ = inv2R.range();
0812     base_ = inv2R.base();
0813     const int shift = ceil(log2(range_ / base_ / pow(2., width_)));
0814     base_ *= pow(2., shift);
0815   }
0816 
0817   template <>
0818   Format<Variable::z0, Process::dr>::Format(const edm::ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0819     const Format<Variable::zT, Process::zht> zT(iConfig, setup);
0820     width_ = setup->tfpWidthZ0();
0821     range_ = 2. * setup->beamWindowZ();
0822     base_ = zT.base();
0823     const int shift = ceil(log2(range_ / base_ / pow(2., width_)));
0824     base_ *= pow(2., shift);
0825   }
0826 
0827   template <>
0828   Format<Variable::cot, Process::dr>::Format(const edm::ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0829     const Format<Variable::cot, Process::zht> cot(iConfig, setup);
0830     width_ = setup->tfpWidthCot();
0831     range_ = 2. * setup->maxCot();
0832     base_ = cot.base();
0833     const int shift = ceil(log2(range_ / base_ / pow(2., width_)));
0834     base_ *= pow(2., shift);
0835   }
0836 
0837   template <>
0838   Format<Variable::phiT, Process::kf>::Format(const edm::ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0839     const Format<Variable::phi0, Process::dr> phi0(iConfig, setup);
0840     const Format<Variable::phiT, Process::ht> phiT(iConfig, setup);
0841     const double rangeFactor = iConfig.getParameter<ParameterSet>("KalmanFilter").getParameter<double>("RangeFactor");
0842     range_ = rangeFactor * phiT.range();
0843     base_ = phi0.base();
0844     width_ = ceil(log2(range_ / base_));
0845   }
0846 
0847   template <>
0848   Format<Variable::inv2R, Process::kf>::Format(const edm::ParameterSet& iConfig, const Setup* setup)
0849       : DataFormat(true) {
0850     const Format<Variable::inv2R, Process::dr> dr(iConfig, setup);
0851     const Format<Variable::inv2R, Process::mht> mht(iConfig, setup);
0852     const double rangeFactor = iConfig.getParameter<ParameterSet>("KalmanFilter").getParameter<double>("RangeFactor");
0853     range_ = mht.range() + rangeFactor * mht.base();
0854     base_ = dr.base();
0855     width_ = ceil(log2(range_ / base_));
0856   }
0857 
0858   template <>
0859   Format<Variable::zT, Process::kf>::Format(const edm::ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0860     const Format<Variable::z0, Process::dr> z0(iConfig, setup);
0861     const Format<Variable::zT, Process::zht> zT(iConfig, setup);
0862     const double rangeFactor = iConfig.getParameter<ParameterSet>("KalmanFilter").getParameter<double>("RangeFactor");
0863     range_ = zT.range() + rangeFactor * zT.base();
0864     base_ = z0.base();
0865     width_ = ceil(log2(range_ / base_));
0866   }
0867 
0868   template <>
0869   Format<Variable::cot, Process::kf>::Format(const edm::ParameterSet& iConfig, const Setup* setup) : DataFormat(true) {
0870     const Format<Variable::cot, Process::dr> dr(iConfig, setup);
0871     const Format<Variable::cot, Process::zht> zht(iConfig, setup);
0872     const double rangeFactor = iConfig.getParameter<ParameterSet>("KalmanFilter").getParameter<double>("RangeFactor");
0873     range_ = zht.range() + rangeFactor * zht.base();
0874     base_ = dr.base();
0875     width_ = ceil(log2(range_ / base_));
0876   }
0877 
0878   template <>
0879   Format<Variable::dPhi, Process::kfin>::Format(const edm::ParameterSet& iConfig, const Setup* setup)
0880       : DataFormat(false) {
0881     const Format<Variable::phi, Process::kfin> phi(iConfig, setup);
0882     range_ = setup->maxdPhi();
0883     base_ = phi.base();
0884     width_ = ceil(log2(range_ / base_));
0885   }
0886 
0887   template <>
0888   Format<Variable::dZ, Process::kfin>::Format(const edm::ParameterSet& iConfig, const Setup* setup)
0889       : DataFormat(false) {
0890     const Format<Variable::z, Process::kfin> z(iConfig, setup);
0891     range_ = setup->maxdZ();
0892     base_ = z.base();
0893     width_ = ceil(log2(range_ / base_));
0894   }
0895 
0896 }  // namespace trackerTFP