diff --git a/DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThContainer.h b/DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThContainer.h new file mode 100644 index 0000000000000..ca044f03a70e7 --- /dev/null +++ b/DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThContainer.h @@ -0,0 +1,50 @@ +//------------------------------------------------- +// +// Class L1Phase2MuDTPhContainer +// +// Description: trigger primtive data for the +// muon barrel Phase2 trigger +// +// +// Author List: Federica Primavera Bologna INFN +// +// +//-------------------------------------------------- +#ifndef L1Phase2MuDTThContainer_H +#define L1Phase2MuDTThContainer_H + +//------------------------------------ +// Collaborating Class Declarations -- +//------------------------------------ +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThDigi.h" + +//---------------------- +// Base Class Headers -- +//---------------------- +#include + +//--------------- +// C++ Headers -- +//--------------- + +// --------------------- +// -- Class Interface -- +// --------------------- + +class L1Phase2MuDTThContainer { +public: + typedef std::vector Segment_Container; + typedef Segment_Container::const_iterator Segment_iterator; + + // Constructor + L1Phase2MuDTThContainer(); + + void setContainer(const Segment_Container& inputSegments); + + Segment_Container const* getContainer() const; + +private: + Segment_Container m_segments; +}; + +#endif diff --git a/DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThDigi.h b/DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThDigi.h new file mode 100644 index 0000000000000..4e726f8bc420c --- /dev/null +++ b/DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThDigi.h @@ -0,0 +1,47 @@ +#ifndef L1Phase2MuDTThDigi_H +#define L1Phase2MuDTThDigi_H + +class L1Phase2MuDTThDigi { +public: + // Constructors + L1Phase2MuDTThDigi(); + + L1Phase2MuDTThDigi(int bx, int wh, int sc, int st, int z, int k, int qual, int idx, int t0, int chi2, int rpc = -10); + + // Operations + int bxNum() const; + + int whNum() const; + int scNum() const; + int stNum() const; + + int z() const; + int k() const; + + int quality() const; + int index() const; + + int t0() const; + int chi2() const; + + int rpcFlag() const; + +private: + int m_bx; + int m_wheel; + int m_sector; + int m_station; + + int m_zGlobal; + int m_kSlope; + + int m_qualityCode; + int m_index; + + int m_t0; + int m_chi2; + + int m_rpcFlag; +}; + +#endif diff --git a/DataFormats/L1DTTrackFinder/src/L1Phase2MuDTThContainer.cc b/DataFormats/L1DTTrackFinder/src/L1Phase2MuDTThContainer.cc new file mode 100644 index 0000000000000..d7c37dc0f440e --- /dev/null +++ b/DataFormats/L1DTTrackFinder/src/L1Phase2MuDTThContainer.cc @@ -0,0 +1,7 @@ +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThContainer.h" + +L1Phase2MuDTThContainer::L1Phase2MuDTThContainer() {} + +void L1Phase2MuDTThContainer::setContainer(const Segment_Container& inputSegments) { m_segments = inputSegments; } + +L1Phase2MuDTThContainer::Segment_Container const* L1Phase2MuDTThContainer::getContainer() const { return &m_segments; } diff --git a/DataFormats/L1DTTrackFinder/src/L1Phase2MuDTThDigi.cc b/DataFormats/L1DTTrackFinder/src/L1Phase2MuDTThDigi.cc new file mode 100644 index 0000000000000..e035e5274a231 --- /dev/null +++ b/DataFormats/L1DTTrackFinder/src/L1Phase2MuDTThDigi.cc @@ -0,0 +1,50 @@ +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThDigi.h" + +L1Phase2MuDTThDigi::L1Phase2MuDTThDigi() + : m_bx(-100), + m_wheel(0), + m_sector(0), + m_station(0), + m_zGlobal(0), + m_kSlope(0), + m_qualityCode(-1), + m_index(0), + m_t0(0), + m_chi2(0), + m_rpcFlag(-10) {} + +L1Phase2MuDTThDigi::L1Phase2MuDTThDigi( + int bx, int wh, int sc, int st, int z, int k, int qual, int idx, int t0, int chi2, int rpc) + : m_bx(bx), + m_wheel(wh), + m_sector(sc), + m_station(st), + m_zGlobal(z), + m_kSlope(k), + m_qualityCode(qual), + m_index(idx), + m_t0(t0), + m_chi2(chi2), + m_rpcFlag(rpc) {} + +int L1Phase2MuDTThDigi::bxNum() const { return m_bx; } + +int L1Phase2MuDTThDigi::whNum() const { return m_wheel; } + +int L1Phase2MuDTThDigi::scNum() const { return m_sector; } + +int L1Phase2MuDTThDigi::stNum() const { return m_station; } + +int L1Phase2MuDTThDigi::z() const { return m_zGlobal; } + +int L1Phase2MuDTThDigi::k() const { return m_kSlope; } + +int L1Phase2MuDTThDigi::quality() const { return m_qualityCode; } + +int L1Phase2MuDTThDigi::index() const { return m_index; } + +int L1Phase2MuDTThDigi::t0() const { return m_t0; } + +int L1Phase2MuDTThDigi::chi2() const { return m_chi2; } + +int L1Phase2MuDTThDigi::rpcFlag() const { return m_rpcFlag; } diff --git a/L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h b/L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h new file mode 100644 index 0000000000000..af9d789c3d56f --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h @@ -0,0 +1,80 @@ +#ifndef L1Trigger_DTTriggerPhase2_GlobalCoordsObtainer_h +#define L1Trigger_DTTriggerPhase2_GlobalCoordsObtainer_h + +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/Framework/interface/FrameworkfwdMostUsed.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "DataFormats/MuonDetId/interface/DTChamberId.h" + +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" + +#include +#include +#include + +// =============================================================================== +// Previous definitions and declarations +// =============================================================================== + +struct lut_value { + long int a; + long int b; +}; + +struct lut_group { + std::map phic; + std::map phi1; + std::map phi3; + std::map phib; +}; + +struct global_constant_per_sl { + double perp; + double x_phi0; +}; + +struct global_constant { + uint32_t chid; + global_constant_per_sl sl1; + global_constant_per_sl sl3; +}; + +// =============================================================================== +// Class declarations +// =============================================================================== + +class GlobalCoordsObtainer { +public: + GlobalCoordsObtainer(const edm::ParameterSet& pset); + ~GlobalCoordsObtainer(); + + void generate_luts(); + std::vector get_global_coordinates(uint32_t, int, int, int); + +private: + std::map calc_atan_lut(int, int, double, double, double, int, int, int, int, int); + // utilities to go to and from 2 complement + int to_two_comp(int val, int size) { + if (val >= 0) + return val; + return std::pow(2, size) + val; + } + + int from_two_comp(int val, int size) { return val - ((2 * val) & (1 << size)); } + + // attributes + bool cmssw_for_global_; + edm::FileInPath global_coords_filename_; + std::vector global_constants; + std::map luts; +}; + +#endif \ No newline at end of file diff --git a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyticAnalyzer.h b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyticAnalyzer.h new file mode 100644 index 0000000000000..c7624d7834326 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyticAnalyzer.h @@ -0,0 +1,118 @@ +#ifndef L1Trigger_DTTriggerPhase2_MuonPathAnalyticAnalyzer_h +#define L1Trigger_DTTriggerPhase2_MuonPathAnalyticAnalyzer_h + +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h" + +// =============================================================================== +// Previous definitions and declarations +// =============================================================================== + +struct MAGNITUDE { + int add; + int coeff[4]; + int mult; +}; + +struct CONSTANTS { + MAGNITUDE pos; + MAGNITUDE slope; + MAGNITUDE slope_xhh; + MAGNITUDE t0; +}; + +struct LATCOMB_CONSTANTS { + int latcomb; + CONSTANTS constants; +}; + +struct CELL_VALID_LAYOUT { + int cell_horiz_layout[4]; + int valid[4]; +}; + +struct CELL_VALID_LAYOUT_CONSTANTS { + CELL_VALID_LAYOUT cell_valid_layout; + LATCOMB_CONSTANTS latcomb_constants[6]; +}; + +// =============================================================================== +// Class declarations +// =============================================================================== + +class MuonPathAnalyticAnalyzer : public MuonPathAnalyzer { +public: + // Constructors and destructor + MuonPathAnalyticAnalyzer(const edm::ParameterSet &pset, + edm::ConsumesCollector &iC, + std::shared_ptr &globalcoordsobtainer); + ~MuonPathAnalyticAnalyzer() override; + + // Main methods + void initialise(const edm::EventSetup &iEventSetup) override; + void run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + MuonPathPtrs &inMpath, + std::vector &metaPrimitives) override; + void run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + MuonPathPtrs &inMpath, + MuonPathPtrs &outMPath) override{}; + + void finish() override; + + // Other public methods + + bool hasPosRF(int wh, int sec) { return wh > 0 || (wh == 0 && sec % 4 > 1); }; + + // Public attributes + DTGeometry const *dtGeo_; + edm::ESGetToken dtGeomH; + + //shift + edm::FileInPath shift_filename_; + std::map shiftinfo_; + + //shift theta + edm::FileInPath shift_theta_filename_; + std::map shiftthetainfo_; + + int chosen_sl_; + +private: + // Private methods + void analyze(MuonPathPtr &inMPath, std::vector &metaPrimitives); + void fillLAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER(); + void segment_fitter(DTSuperLayerId MuonPathSLId, + int wires[4], + int t0s[4], + int valid[4], + int reduced_times[4], + int cell_horiz_layout[4], + LATCOMB_CONSTANTS latcomb_consts, + int xwire_mm[4], + int coarse_pos, + int coarse_offset, + std::vector &metaPrimitives); + int compute_parameter(MAGNITUDE constants, int t0s[4], int DIV_SHR_BITS, int INCREASED_RES); + std::vector getLateralityCombination(int latcomb); + + // Private attributes + + bool debug_; + double chi2Th_; + double tanPhiTh_; + double tanPhiThw2max_; + double tanPhiThw2min_; + double tanPhiThw1max_; + double tanPhiThw1min_; + double tanPhiThw0_; + int cellLayout_[cmsdt::NUM_LAYERS]; + bool cmssw_for_global_; + std::string geometry_tag_; + std::vector LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER; + + // global coordinates + std::shared_ptr globalcoordsobtainer_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h index 159a6289273e0..470b276708a8a 100644 --- a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h +++ b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h @@ -19,6 +19,7 @@ #include "L1Trigger/DTTriggerPhase2/interface/MuonPath.h" #include "L1Trigger/DTTriggerPhase2/interface/constants.h" +#include "L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h" #include "Geometry/Records/interface/MuonGeometryRecord.h" #include "Geometry/DTGeometry/interface/DTGeometry.h" diff --git a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h index 3baf7556d7309..05fdf8ed6d33b 100644 --- a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h +++ b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h @@ -25,7 +25,7 @@ class MuonPathAnalyzerInChamber : public MuonPathAnalyzer { void run(edm::Event &iEvent, const edm::EventSetup &iEventSetup, MuonPathPtrs &inMpath, - std::vector &metaPrimitives) override {} + std::vector &metaPrimitives) override{}; void run(edm::Event &iEvent, const edm::EventSetup &iEventSetup, MuonPathPtrs &inMpath, @@ -38,7 +38,7 @@ class MuonPathAnalyzerInChamber : public MuonPathAnalyzer { void setMinHits4Fit(int h) { minHits4Fit_ = h; }; void setChiSquareThreshold(float ch2Thr) { chiSquareThreshold_ = ch2Thr; }; void setMinimumQuality(cmsdt::MP_QUALITY q) { - if (minQuality_ >= cmsdt::LOWQGHOST) + if (minQuality_ >= cmsdt::LOWQ) minQuality_ = q; }; diff --git a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerPerSL.h b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerPerSL.h deleted file mode 100644 index 7352ea9677bdd..0000000000000 --- a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerPerSL.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef L1Trigger_DTTriggerPhase2_MuonPathAnalyzerPerSL_h -#define L1Trigger_DTTriggerPhase2_MuonPathAnalyzerPerSL_h - -#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h" - -// =============================================================================== -// Class declarations -// =============================================================================== - -class MuonPathAnalyzerPerSL : public MuonPathAnalyzer { -public: - // Constructors and destructor - MuonPathAnalyzerPerSL(const edm::ParameterSet &pset, edm::ConsumesCollector &iC); - ~MuonPathAnalyzerPerSL() override; - - // Main methods - void initialise(const edm::EventSetup &iEventSetup) override; - void run(edm::Event &iEvent, - const edm::EventSetup &iEventSetup, - MuonPathPtrs &inMpath, - std::vector &metaPrimitives) override; - void run(edm::Event &iEvent, - const edm::EventSetup &iEventSetup, - MuonPathPtrs &inMpath, - MuonPathPtrs &outMPath) override{}; - - void finish() override; - - // Other public methods - void setBXTolerance(int t) { bxTolerance_ = t; }; - int bxTolerance(void) { return bxTolerance_; }; - - void setChiSquareThreshold(float ch2Thr) { chiSquareThreshold_ = ch2Thr; }; - - void setMinQuality(cmsdt::MP_QUALITY q) { - if (minQuality_ >= cmsdt::LOWQGHOST) - minQuality_ = q; - }; - cmsdt::MP_QUALITY minQuality(void) { return minQuality_; }; - - bool hasPosRF(int wh, int sec) { return wh > 0 || (wh == 0 && sec % 4 > 1); }; - - // Public attributes - DTGeometry const *dtGeo_; - edm::ESGetToken dtGeomH; - - //shift - edm::FileInPath shift_filename_; - std::map shiftinfo_; - - int chosen_sl_; - -private: - // Private methods - void analyze(MuonPathPtr &inMPath, std::vector &metaPrimitives); - - void setCellLayout(const int layout[cmsdt::NUM_LAYERS]); - void buildLateralities(void); - bool isStraightPath(cmsdt::LATERAL_CASES sideComb[cmsdt::NUM_LAYERS]); - - void evaluatePathQuality(MuonPathPtr &mPath); - void evaluateLateralQuality(int latIdx, MuonPathPtr &mPath, cmsdt::LATQ_TYPE *latQuality); - void validate(cmsdt::LATERAL_CASES sideComb[3], int layerIndex[3], MuonPathPtr &mPath, cmsdt::PARTIAL_LATQ_TYPE *latq); - - int eqMainBXTerm(cmsdt::LATERAL_CASES sideComb[2], int layerIdx[2], MuonPathPtr &mPath); - - int eqMainTerm(cmsdt::LATERAL_CASES sideComb[2], int layerIdx[2], MuonPathPtr &mPath, int bxValue); - - void lateralCoeficients(cmsdt::LATERAL_CASES sideComb[2], int *coefs); - bool sameBXValue(cmsdt::PARTIAL_LATQ_TYPE *latq); - - void calculatePathParameters(MuonPathPtr &mPath); - void calcTanPhiXPosChamber(MuonPathPtr &mPath); - void calcCellDriftAndXcoor(MuonPathPtr &mPath); - void calcChiSquare(MuonPathPtr &mPath); - - void calcTanPhiXPosChamber3Hits(MuonPathPtr &mPath); - void calcTanPhiXPosChamber4Hits(MuonPathPtr &mPath); - - int omittedHit(int idx); - - // Private attributes - - static const int LAYER_ARRANGEMENTS_[cmsdt::NUM_LAYERS][cmsdt::NUM_CELL_COMB]; - cmsdt::LATERAL_CASES lateralities_[cmsdt::NUM_LATERALITIES][cmsdt::NUM_LAYERS]; - cmsdt::LATQ_TYPE latQuality_[cmsdt::NUM_LATERALITIES]; - - int totalNumValLateralities_; - - int bxTolerance_; - cmsdt::MP_QUALITY minQuality_; - float chiSquareThreshold_; - bool debug_; - double chi2Th_; - double chi2corTh_; - double tanPhiTh_; - int cellLayout_[cmsdt::NUM_LAYERS]; - bool use_LSB_; - double tanPsi_precision_; - double x_precision_; -}; - -#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MuonPathAssociator.h b/L1Trigger/DTTriggerPhase2/interface/MuonPathAssociator.h index 8586f54f3b96b..06b2246eb5637 100644 --- a/L1Trigger/DTTriggerPhase2/interface/MuonPathAssociator.h +++ b/L1Trigger/DTTriggerPhase2/interface/MuonPathAssociator.h @@ -15,6 +15,7 @@ #include "L1Trigger/DTTriggerPhase2/interface/MuonPath.h" #include "L1Trigger/DTTriggerPhase2/interface/constants.h" +#include "L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h" #include "Geometry/Records/interface/MuonGeometryRecord.h" #include "Geometry/DTGeometry/interface/DTGeometry.h" @@ -34,7 +35,9 @@ class MuonPathAssociator { public: // Constructors and destructor - MuonPathAssociator(const edm::ParameterSet &pset, edm::ConsumesCollector &iC); + MuonPathAssociator(const edm::ParameterSet &pset, + edm::ConsumesCollector &iC, + std::shared_ptr &globalcoordsobtainer); ~MuonPathAssociator(); // Main methods @@ -80,13 +83,15 @@ class MuonPathAssociator { double dTanPsi_correlate_TP_; double minx_match_2digis_; double chi2corTh_; - bool use_LSB_; - double tanPsi_precision_; - double x_precision_; + bool cmssw_for_global_; + std::string geometry_tag_; //shift edm::FileInPath shift_filename_; std::map shiftinfo_; + + // global coordinates + std::shared_ptr globalcoordsobtainer_; }; #endif diff --git a/L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h b/L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h index 0e7b1ba0e9dc3..e4b6852844425 100644 --- a/L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h +++ b/L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h @@ -16,6 +16,8 @@ #include "DataFormats/DTDigi/interface/DTDigiCollection.h" #include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhContainer.h" #include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhDigi.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThContainer.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThDigi.h" #include "DataFormats/RPCRecHit/interface/RPCRecHitCollection.h" #include diff --git a/L1Trigger/DTTriggerPhase2/interface/constants.h b/L1Trigger/DTTriggerPhase2/interface/constants.h index 3c7e1b7756f78..d73a078811b2f 100644 --- a/L1Trigger/DTTriggerPhase2/interface/constants.h +++ b/L1Trigger/DTTriggerPhase2/interface/constants.h @@ -38,7 +38,8 @@ */ namespace cmsdt { - enum MP_QUALITY { NOPATH = 0, LOWQGHOST, LOWQ, HIGHQGHOST, HIGHQ, CLOWQ, LOWLOWQ, CHIGHQ, HIGHLOWQ, HIGHHIGHQ }; + // enum MP_QUALITY { NOPATH = 0, LOWQGHOST, LOWQ, HIGHQGHOST, HIGHQ, CLOWQ, LOWLOWQ, CHIGHQ, HIGHLOWQ, HIGHHIGHQ }; + enum MP_QUALITY { NOPATH = 0, LOWQ = 1, CLOWQ = 2, HIGHQ = 3, CHIGHQ = 4, LOWLOWQ = 6, HIGHLOWQ = 7, HIGHHIGHQ = 8 }; // Tipos de lateralidad de traza de partícula al pasar por una celda enum LATERAL_CASES { LEFT = 0, RIGHT, NONE }; @@ -171,15 +172,27 @@ namespace cmsdt { /* Adimensional */ constexpr int MAX_BX_IDX = 3564; - // En nanosegundos (tiempo de deriva en la celda) - constexpr float MAXDRIFT = 386.75; - // En milímetros (dimensiones de la celda) + // In ns (maximum drift time inside the cell) + constexpr float MAXDRIFT = 387; + // In mm (cell dimmensions) constexpr int CELL_HEIGHT = 13; constexpr float CELL_SEMIHEIGHT = 6.5; constexpr int CELL_LENGTH = 42; constexpr int CELL_SEMILENGTH = 21; - // En milímetros / nanosegundo (velocidad de deriva) + // In mm / ns (velocidad de deriva) constexpr float DRIFT_SPEED = 0.0542; + // With 4 bits for the decimal part + constexpr int DRIFT_SPEED_X4 = 889; // 55.5 * 2 ** 4 + + // distance between SLs, cm + constexpr float VERT_PHI1_PHI3 = 23.5; + + // inverse of the distance between SLs, FW units + constexpr int VERT_PHI1_PHI3_INV = 558; + + // distance between center of the chamber and each SL in mm, 2 bit precision for the decimal part + constexpr int CH_CENTER_TO_MID_SL_X2 = 470; // 117.5 * 2 ** 2 + /* This is the maximum value than internal time can take. This is because internal time is cyclical due to the limited size of the time counters and @@ -202,17 +215,13 @@ namespace cmsdt { constexpr int NUM_CELL_COMB = 3; constexpr int TOTAL_CHANNELS = (NUM_LAYERS * NUM_CH_PER_LAYER); constexpr int NUM_SUPERLAYERS = 3; - constexpr float PHIRES_CONV = 65536. / 0.8; - constexpr float PHIBRES_CONV = 2048. / 1.4; + constexpr float PHIRES_CONV = 65536. / 0.5; // 17 bits, [-0.5, 0.5] + constexpr float PHIBRES_CONV = 4096. / 2.; // 13 bits, [-2, 2] constexpr int CHI2RES_CONV = 1000000; + constexpr int TDCTIME_REDUCED_SIZE = 10; + constexpr float ZRES_CONV = 65536. / 1500; + constexpr float KRES_CONV = 65536. / 2; - constexpr int DIVISION_HELPER1 = 43691; - constexpr int DIVISION_HELPER2 = 65536; - constexpr int DIVISION_HELPER3 = 131072; - constexpr int DENOM_TYPE1 = 6; - constexpr int DENOM_TYPE2 = 4; - constexpr int DENOM_TYPE3 = 2; - constexpr int NBITS = 18; /* * Size of pre-mixer buffers for DTPrimitives * @@ -245,9 +254,49 @@ namespace cmsdt { constexpr double X_POS_L3 = 0.65; constexpr double X_POS_L4 = 1.95; - constexpr int MEANTIME_2LAT = 16384; - constexpr int MEANTIME_3LAT = 10923; - constexpr int MEANTIME_4LAT = 8192; + /* + * Analyzer precision constants + */ + constexpr int DIV_SHR_BITS_T0 = 16; + constexpr int DIV_SHR_BITS_POS = 21; + constexpr int DIV_SHR_BITS_SLOPE = 21; + constexpr int DIV_SHR_BITS_SLOPE_XHH = 18; + + constexpr int INCREASED_RES_T0 = 0; + constexpr int INCREASED_RES_POS = 4; + constexpr int INCREASED_RES_SLOPE = 12; + constexpr int INCREASED_RES_SLOPE_XHH = 4; + + constexpr int INCREASED_RES_POS_POW = 16; + constexpr int INCREASED_RES_SLOPE_POW = 4096; + + // Values to compute drift distances from drift times + constexpr int DTDD_PREADD = 9; + constexpr int DTDD_MULT = 445; + constexpr int DTDD_SHIFTR_BITS = 13; + + /* + * Local to global coordinates transformation + */ + + constexpr int X_SIZE = 18; + constexpr int TANPSI_SIZE = 15; + constexpr int PHI_SIZE = 17; // (1 / 2 ** 17) + constexpr int PHIB_SIZE = 11; // (2 ** 2) / (2 ** 13) + + constexpr int PHI_LUT_ADDR_WIDTH = 12; + constexpr int PHI_B_SHL_BITS = 7; + constexpr int PHI_MULT_SHR_BITS = 10; + constexpr int PHI_LUT_A_BITS = 12; + constexpr int PHI_LUT_B_BITS = 20; + + constexpr int PHIB_LUT_ADDR_WIDTH = 9; + constexpr int PHIB_B_SHL_BITS = 7; + constexpr int PHIB_MULT_SHR_BITS = 10; + constexpr int PHIB_LUT_A_BITS = 10; + constexpr int PHIB_LUT_B_BITS = 16; + + constexpr int PHI_PHIB_RES_DIFF_BITS = 6; } // namespace cmsdt diff --git a/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc b/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc index 0d9925a8cd08c..73a4a84895f29 100644 --- a/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc +++ b/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc @@ -27,12 +27,13 @@ #include "L1Trigger/DTTriggerPhase2/interface/HoughGrouping.h" #include "L1Trigger/DTTriggerPhase2/interface/PseudoBayesGrouping.h" #include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h" -#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerPerSL.h" +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyticAnalyzer.h" #include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h" #include "L1Trigger/DTTriggerPhase2/interface/MuonPathAssociator.h" #include "L1Trigger/DTTriggerPhase2/interface/MPFilter.h" #include "L1Trigger/DTTriggerPhase2/interface/MPQualityEnhancerFilter.h" #include "L1Trigger/DTTriggerPhase2/interface/MPRedundantFilter.h" +#include "L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h" #include "DataFormats/MuonDetId/interface/DTChamberId.h" #include "DataFormats/MuonDetId/interface/DTSuperLayerId.h" @@ -41,6 +42,8 @@ #include "DataFormats/DTDigi/interface/DTDigiCollection.h" #include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhContainer.h" #include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhDigi.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThContainer.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThDigi.h" // DT trigger GeomUtils #include "DQM/DTMonitorModule/interface/DTTrigGeomUtils.h" @@ -114,10 +117,8 @@ class DTTrigPhase2Prod : public edm::stream::EDProducer<> { double dT0_correlate_TP_; bool do_correlation_; int scenario_; - - // shift - edm::FileInPath shift_filename_; - std::map shiftinfo_; + bool cmssw_for_global_; + std::string geometry_tag_; // ParameterSet edm::EDGetTokenT dtDigisToken_; @@ -130,6 +131,7 @@ class DTTrigPhase2Prod : public edm::stream::EDProducer<> { std::unique_ptr mpathqualityenhancer_; std::unique_ptr mpathredundantfilter_; std::unique_ptr mpathassociator_; + std::shared_ptr globalcoordsobtainer_; // Buffering bool activateBuffer_; @@ -161,6 +163,7 @@ namespace { DTTrigPhase2Prod::DTTrigPhase2Prod(const ParameterSet& pset) : qmap_({{9, 9}, {8, 8}, {7, 6}, {6, 7}, {5, 3}, {4, 5}, {3, 4}, {2, 2}, {1, 1}}) { produces(); + produces(); debug_ = pset.getUntrackedParameter("debug"); dump_ = pset.getUntrackedParameter("dump"); @@ -176,7 +179,14 @@ DTTrigPhase2Prod::DTTrigPhase2Prod(const ParameterSet& pset) // Choosing grouping scheme: algo_ = pset.getParameter("algo"); + // Local to global coordinates approach + cmssw_for_global_ = pset.getUntrackedParameter("cmssw_for_global", true); + geometry_tag_ = pset.getUntrackedParameter("geometry_tag", ""); + edm::ConsumesCollector consumesColl(consumesCollector()); + globalcoordsobtainer_ = std::make_shared(pset); + if (!cmssw_for_global_) + globalcoordsobtainer_->generate_luts(); if (algo_ == PseudoBayes) { grouping_obj_ = @@ -191,7 +201,7 @@ DTTrigPhase2Prod::DTTrigPhase2Prod(const ParameterSet& pset) if (algo_ == Standard) { if (debug_) LogDebug("DTTrigPhase2Prod") << "DTp2:constructor: JM analyzer"; - mpathanalyzer_ = std::make_unique(pset, consumesColl); + mpathanalyzer_ = std::make_unique(pset, consumesColl, globalcoordsobtainer_); } else { if (debug_) LogDebug("DTTrigPhase2Prod") << "DTp2:constructor: Full chamber analyzer"; @@ -205,7 +215,7 @@ DTTrigPhase2Prod::DTTrigPhase2Prod(const ParameterSet& pset) mpathqualityenhancer_ = std::make_unique(pset); mpathredundantfilter_ = std::make_unique(pset); - mpathassociator_ = std::make_unique(pset, consumesColl); + mpathassociator_ = std::make_unique(pset, consumesColl, globalcoordsobtainer_); rpc_integrator_ = std::make_unique(pset, consumesColl); dtGeomH = esConsumes(); @@ -228,8 +238,9 @@ void DTTrigPhase2Prod::beginRun(edm::Run const& iRun, const edm::EventSetup& iEv mpathredundantfilter_->initialise(iEventSetup); // Filter object initialisation mpathassociator_->initialise(iEventSetup); // Associator object initialisation - const MuonGeometryRecord& geom = iEventSetup.get(); - dtGeo_ = &geom.get(dtGeomH); + edm::ESHandle geom; + iEventSetup.get().get(geometry_tag_, geom); + dtGeo_ = &(*geom); } void DTTrigPhase2Prod::produce(Event& iEvent, const EventSetup& iEventSetup) { @@ -475,7 +486,7 @@ void DTTrigPhase2Prod::produce(Event& iEvent, const EventSetup& iEventSetup) { else if (scenario_ == DATA) //scope for data shift_back = 0; else if (scenario_ == SLICE_TEST) //scope for slice test - shift_back = 0; + shift_back = 400; // RPC integration if (useRPC_) { @@ -489,11 +500,13 @@ void DTTrigPhase2Prod::produce(Event& iEvent, const EventSetup& iEventSetup) { /// STORING RESULTs vector outP2Ph; + vector outP2Th; // Assigning index value assignIndex(correlatedMetaPrimitives); for (const auto& metaPrimitiveIt : correlatedMetaPrimitives) { DTChamberId chId(metaPrimitiveIt.rawId); + DTSuperLayerId slId(metaPrimitiveIt.rawId); if (debug_) LogDebug("DTTrigPhase2Prod") << "looping in final vector: SuperLayerId" << chId << " x=" << metaPrimitiveIt.x << " quality=" << metaPrimitiveIt.quality @@ -517,20 +530,39 @@ void DTTrigPhase2Prod::produce(Event& iEvent, const EventSetup& iEventSetup) { if (debug_) LogDebug("DTTrigPhase2Prod") << "pushing back phase-2 dataformat carlo-federica dataformat"; - outP2Ph.push_back(L1Phase2MuDTPhDigi( - (int)round(metaPrimitiveIt.t0 / (float)LHC_CLK_FREQ) - shift_back, - chId.wheel(), // uwh (m_wheel) - sectorTP, // usc (m_sector) - chId.station(), // ust (m_station) - sl, // ust (m_station) - (int)round(metaPrimitiveIt.phi * PHIRES_CONV), // uphi (_phiAngle) - (int)round(metaPrimitiveIt.phiB * PHIBRES_CONV), // uphib (m_phiBending) - metaPrimitiveIt.quality, // uqua (m_qualityCode) - metaPrimitiveIt.index, // uind (m_segmentIndex) - (int)round(metaPrimitiveIt.t0) - shift_back * LHC_CLK_FREQ, // ut0 (m_t0Segment) - (int)round(metaPrimitiveIt.chi2 * CHI2RES_CONV), // uchi2 (m_chi2Segment) - metaPrimitiveIt.rpcFlag // urpc (m_rpcFlag) - )); + + if (slId.superLayer() != 2) { + //phiTP + outP2Ph.push_back(L1Phase2MuDTPhDigi( + (int)round(metaPrimitiveIt.t0 / (float)LHC_CLK_FREQ) - shift_back, + chId.wheel(), // uwh (m_wheel) + sectorTP, // usc (m_sector) + chId.station(), // ust (m_station) + sl, // ust (m_station) + (int)round(metaPrimitiveIt.phi * PHIRES_CONV), // uphi (_phiAngle) + (int)round(metaPrimitiveIt.phiB * PHIBRES_CONV), // uphib (m_phiBending) + metaPrimitiveIt.quality, // uqua (m_qualityCode) + metaPrimitiveIt.index, // uind (m_segmentIndex) + (int)round(metaPrimitiveIt.t0) - shift_back * LHC_CLK_FREQ, // ut0 (m_t0Segment) + (int)round(metaPrimitiveIt.chi2 * CHI2RES_CONV), // uchi2 (m_chi2Segment) + metaPrimitiveIt.rpcFlag // urpc (m_rpcFlag) + )); + } else { + //thTP + outP2Th.push_back(L1Phase2MuDTThDigi( + (int)round(metaPrimitiveIt.t0 / (float)LHC_CLK_FREQ) - shift_back, + chId.wheel(), // uwh (m_wheel) + sectorTP, // usc (m_sector) + chId.station(), // ust (m_station) + (int)round(metaPrimitiveIt.phi * ZRES_CONV), // uz (m_zGlobal) + (int)round(metaPrimitiveIt.phiB * KRES_CONV), // uk (m_kSlope) + metaPrimitiveIt.quality, // uqua (m_qualityCode) + metaPrimitiveIt.index, // uind (m_segmentIndex) + (int)round(metaPrimitiveIt.t0) - shift_back * LHC_CLK_FREQ, // ut0 (m_t0Segment) + (int)round(metaPrimitiveIt.chi2 * CHI2RES_CONV), // uchi2 (m_chi2Segment) + metaPrimitiveIt.rpcFlag // urpc (m_rpcFlag) + )); + } } // Storing RPC hits that were not used elsewhere @@ -547,6 +579,12 @@ void DTTrigPhase2Prod::produce(Event& iEvent, const EventSetup& iEventSetup) { iEvent.put(std::move(resultP2Ph)); outP2Ph.clear(); outP2Ph.erase(outP2Ph.begin(), outP2Ph.end()); + + std::unique_ptr resultP2Th(new L1Phase2MuDTThContainer); + resultP2Th->setContainer(outP2Th); + iEvent.put(std::move(resultP2Th)); + outP2Th.clear(); + outP2Th.erase(outP2Th.begin(), outP2Th.end()); } void DTTrigPhase2Prod::endRun(edm::Run const& iRun, const edm::EventSetup& iEventSetup) { diff --git a/L1Trigger/DTTriggerPhase2/python/dtTriggerPhase2PrimitiveDigis_cfi.py b/L1Trigger/DTTriggerPhase2/python/dtTriggerPhase2PrimitiveDigis_cfi.py index f1c65d71868e2..63be80ade8ac9 100644 --- a/L1Trigger/DTTriggerPhase2/python/dtTriggerPhase2PrimitiveDigis_cfi.py +++ b/L1Trigger/DTTriggerPhase2/python/dtTriggerPhase2PrimitiveDigis_cfi.py @@ -6,8 +6,14 @@ dtTriggerPhase2PrimitiveDigis = cms.EDProducer("DTTrigPhase2Prod", digiTag = cms.InputTag("CalibratedDigis"), + geometry_tag = cms.untracked.string(""), trigger_with_sl = cms.untracked.int32(4), - tanPhiTh = cms.untracked.double(1.), + tanPhiTh = cms.untracked.double(1.), + tanPhiThw2max = cms.untracked.double(1.3), + tanPhiThw2min = cms.untracked.double(0.5), + tanPhiThw1max = cms.untracked.double(0.9), + tanPhiThw1min = cms.untracked.double(0.2), + tanPhiThw0 = cms.untracked.double(0.5), chi2Th = cms.untracked.double(0.01), #in cm^2 chi2corTh = cms.untracked.double(0.1), #in cm^2 do_correlation = cms.bool(True), @@ -17,9 +23,6 @@ dTanPsi_correlate_TP = cms.untracked.double(99999.), clean_chi2_correlation = cms.untracked.bool(True), allow_confirmation = cms.untracked.bool(True), - use_LSB = cms.untracked.bool(True), - tanPsi_precision = cms.untracked.double(1./4096.), - x_precision = cms.untracked.double(1./160.), minx_match_2digis = cms.untracked.double(1.), scenario = cms.int32(0), #0 for mc, 1 for data, 2 for slice test filter_cousins = cms.untracked.bool(True), @@ -27,6 +30,9 @@ ttrig_filename = cms.FileInPath('L1Trigger/DTTriggerPhase2/data/wire_rawId_ttrig.txt'), z_filename = cms.FileInPath('L1Trigger/DTTriggerPhase2/data/wire_rawId_z.txt'), shift_filename = cms.FileInPath('L1Trigger/DTTriggerPhase2/data/wire_rawId_x.txt'), + shift_theta_filename = cms.FileInPath('L1Trigger/DTTriggerPhase2/data/theta_shift.txt'), + global_coords_filename = cms.FileInPath('L1Trigger/DTTriggerPhase2/data/global_coord_perp_x_phi0.txt'), + cmssw_for_global = cms.untracked.bool(False), algo = cms.int32(0), # 0 = STD gr., 2 = Hough transform, 1 = PseudoBayes Approach minHits4Fit = cms.untracked.int32(4), @@ -34,7 +40,7 @@ #debugging debug = cms.untracked.bool(False), dump = cms.untracked.bool(False), - + #RPC rpcRecHits = cms.InputTag("rpcRecHits"), useRPC = cms.bool(False), diff --git a/L1Trigger/DTTriggerPhase2/src/GlobalCoordsObtainer.cc b/L1Trigger/DTTriggerPhase2/src/GlobalCoordsObtainer.cc new file mode 100644 index 0000000000000..1376d4c6e40c0 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/GlobalCoordsObtainer.cc @@ -0,0 +1,264 @@ +#include "L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h" + +using namespace edm; +using namespace cmsdt; + +// ============================================================================ +// Constructors and destructor +// ============================================================================ +GlobalCoordsObtainer::GlobalCoordsObtainer(const ParameterSet& pset) { + global_coords_filename_ = pset.getParameter("global_coords_filename"); + std::ifstream ifin3(global_coords_filename_.fullPath()); + + if (ifin3.fail()) { + throw cms::Exception("Missing Input File") + << "GlobalCoordsObtainer::GlobalCoordsObtainer() - Cannot find " << global_coords_filename_.fullPath(); + } + + int wh, st, se, sl; + double perp, x_phi0; + std::string line; + + global_constant_per_sl sl1_constants; + global_constant_per_sl sl3_constants; + + while (ifin3.good()) { + ifin3 >> wh >> st >> se >> sl >> perp >> x_phi0; + + if (sl == 1) { + sl1_constants.perp = perp; + sl1_constants.x_phi0 = x_phi0; + } else { + sl3_constants.perp = perp; + sl3_constants.x_phi0 = x_phi0; + + DTChamberId ChId(wh, st, se); + global_constants.push_back({ChId.rawId(), sl1_constants, sl3_constants}); + } + } +} + +GlobalCoordsObtainer::~GlobalCoordsObtainer() {} + +void GlobalCoordsObtainer::generate_luts() { + for (auto& global_constant : global_constants) { + int sgn = 1; + DTChamberId ChId(global_constant.chid); + // typical hasPosRF function + if (ChId.wheel() > 0 || (ChId.wheel() == 0 && ChId.sector() % 4 > 1)) { + sgn = -1; + } + + auto phi1 = calc_atan_lut(12, + 6, + (1. / 16) / (global_constant.sl1.perp * 10), + global_constant.sl1.x_phi0 / global_constant.sl1.perp, + 1. / std::pow(2, 17), + 10, + 3, + 12, + 20, + sgn); + + auto phi3 = calc_atan_lut(12, + 6, + (1. / 16) / (global_constant.sl3.perp * 10), + global_constant.sl3.x_phi0 / global_constant.sl3.perp, + 1. / std::pow(2, 17), + 10, + 3, + 12, + 20, + sgn); + + double max_x_phi0 = global_constant.sl1.x_phi0; + if (global_constant.sl3.x_phi0 > max_x_phi0) { + max_x_phi0 = global_constant.sl3.x_phi0; + } + + auto phic = calc_atan_lut(12, + 6, + (1. / 16) / ((global_constant.sl1.perp + global_constant.sl3.perp) / .2), + max_x_phi0 / ((global_constant.sl1.perp + global_constant.sl3.perp) / 2), + 1. / std::pow(2, 17), + 10, + 3, + 12, + 20, + sgn); + + auto phib = calc_atan_lut(9, 6, 1. / 4096, 0., 4. / std::pow(2, 13), 10, 3, 10, 16, sgn); + + luts[global_constant.chid] = {phic, phi1, phi3, phib}; + } +} + +std::map GlobalCoordsObtainer::calc_atan_lut(int msb_num, + int lsb_num, + double in_res, + double abscissa_0, + double out_res, + int a_extra_bits, + int b_extra_bits, + int a_size, + int b_size, + int sgn) { + // Calculates the coefficients needed to calculate the arc-tan function in fw + // by doing a piece-wise linear approximation. + // In fw, input (x) and output (y) are integers, these conversions are needed + // t = x*in_res - abscissa_0 + // phi = arctan(t) + // y = phi/out_res + // => y = arctan(x*in_res - abcissa_0)/out_res + // The linear function is approximated as + // y = a*x_lsb + b + // Where a, b = func(x_msb) are the coefficients stored in the lut + + // a is stored as unsigned, b as signed, with their respective sizes a_size, b_size, + // previously shifted left by a_extra_bits and b_extra_bits, respectively + + long int a_min = -std::pow(2, (a_size - 1)); + long int a_max = std::pow(2, (a_size - 1)) - 1; + long int b_min = -std::pow(2, (b_size - 1)); + long int b_max = std::pow(2, (b_size - 1)) - 1; + + std::map lut; + + for (long int x_msb = -(long int)std::pow(2, msb_num - 1); x_msb < (long int)std::pow(2, msb_num - 1); x_msb++) { + int x1 = ((x_msb) << lsb_num); + int x2 = ((x_msb + 1) << lsb_num) - 1; + + double t1 = x1 * in_res - abscissa_0; + double t2 = x2 * in_res - abscissa_0; + + double phi1 = sgn * atan(t1); + double phi2 = sgn * atan(t2); + + double y1 = phi1 / out_res; + double y2 = phi2 / out_res; + + // we want to find a, b so that the error in the extremes is the same as the error in the center + // so the error in the extremes will be the same, so the "a" is determined by those points + double a = (y2 - y1) / (x2 - x1); + + // by derivating the error function and equaling to 0, you get this is the point + // towards the interval center with the highest error + // err_f = y - (a*x+b) = sgn*arctan(x*in_res - abcissa_0)/out_res - (a*x+b) + // d(err_f)/dx = sgn*(1/(1+(x*in_res - abcissa_0)^2))*in_res/out_res - a + // d(err_f)/dx = 0 => x_max_err = (sqrt(in_res/out_res/a-1) + abscissa_0)/in_res + // There is sign ambiguity in the sqrt operation. The sqrt has units of t (adimensional). + // It is resolved by setting the sqrt to have the same sign as (t1+t2)/2 + + double t_max_err = sqrt(sgn * in_res / out_res / a - 1); + if ((t1 + t2) < 0) { + t_max_err *= -1; + } + + double x_max_err = (t_max_err + abscissa_0) / in_res; + double phi_max_err = sgn * atan(t_max_err); + double y_max_err = phi_max_err / out_res; + + // once you have the point of max error, the "b" parameter is chosen as the average between + // those two numbers, which makes the error at the center be equal in absolute value + // to the error in the extremes + // units: rad + + double b = (y1 + y_max_err - a * (x_max_err - x1)) / 2; + + // increase b in 1/2 of y_lsb, so that fw truncate operation on the of the result + // is equivalent to a round function instead of a floor function + b += 0.5; + + // shift left and round + long int a_int = (long int)(round(a * (pow(2, a_extra_bits)))); + long int b_int = (long int)(round(b * (pow(2, b_extra_bits)))); + + // tuck a, b constants into the bit size of the output (un)signed integer + std::vector as = {a_min, a_int, a_max}; + std::vector bs = {b_min, b_int, b_max}; + + std::sort(as.begin(), as.end()); + std::sort(bs.begin(), bs.end()); + + a_int = as.at(1); + b_int = bs.at(1); + + // // convert a, b to two's complement + // auto a_signed = a_int % (long int) (pow(2, a_size)); + // auto b_signed = b_int % (long int) (pow(2, b_size)); + + // convert x_msb to two's complement signed + int index = to_two_comp(x_msb, msb_num); + lut[index] = {a_int, b_int}; + } + return lut; +} + +std::vector GlobalCoordsObtainer::get_global_coordinates(uint32_t chid, int sl, int x, int tanpsi) { + // Depending on the type of primitive (SL1, SL3 or correlated), choose the + // appropriate input data (x, tanpsi) from the input primitive data structure + // and the corresponding phi-lut from the 3 available options + auto phi_lut = &luts[chid].phic; + if (sl == 1) { + phi_lut = &luts[chid].phi1; + } else if (sl == 3) { + phi_lut = &luts[chid].phi3; + } + + auto phib_lut = &luts[chid].phib; + + // x and slope are given in two's complement in fw + x = to_two_comp(x, X_SIZE); + tanpsi = to_two_comp(tanpsi, TANPSI_SIZE); + + // Slice x and tanpsi + // Both x and tanpsi are represented in vhdl as signed, this means their values + // are stored as two's complement. + + // The MSB part is going to be used to index the luts and obtain a and b parameters + // Converting the upper part of the signed to an integer (with sign). + + int x_msb = x >> (X_SIZE - PHI_LUT_ADDR_WIDTH); + x_msb = from_two_comp(x_msb, PHI_LUT_ADDR_WIDTH); + + int tanpsi_msb = tanpsi >> (TANPSI_SIZE - PHIB_LUT_ADDR_WIDTH); + tanpsi_msb = from_two_comp(tanpsi_msb, PHIB_LUT_ADDR_WIDTH); + + x_msb = x >> (X_SIZE - PHI_LUT_ADDR_WIDTH); + x_msb = from_two_comp(x_msb, PHI_LUT_ADDR_WIDTH); + + tanpsi_msb = tanpsi >> (TANPSI_SIZE - PHIB_LUT_ADDR_WIDTH); + tanpsi_msb = from_two_comp(tanpsi_msb, PHIB_LUT_ADDR_WIDTH); + + // The LSB part can be sliced right away because it must yield a positive integer + int x_lsb = x & (int)(std::pow(2, (X_SIZE - PHI_LUT_ADDR_WIDTH)) - 1); + int tanpsi_lsb = tanpsi & (int)(std::pow(2, (TANPSI_SIZE - PHIB_LUT_ADDR_WIDTH)) - 1); + + // Index the luts wiht the MSB parts already calculated + auto phi_lut_q = phi_lut->at(to_two_comp(x_msb, PHI_LUT_ADDR_WIDTH)); + auto phib_lut_q = phib_lut->at(to_two_comp(tanpsi_msb, PHIB_LUT_ADDR_WIDTH)); + + // Separate this data into the coefficients a and b + auto phi_lut_a = phi_lut_q.a; + auto phi_lut_b = phi_lut_q.b; + auto phib_lut_a = phib_lut_q.a; + auto phib_lut_b = phib_lut_q.b; + + // Do the linear piece-wise operations + // At this point all variables that can be negative have already been converted + // so will yield negative values when necessary + int phi_uncut = (phi_lut_b << PHI_B_SHL_BITS) + x_lsb * phi_lut_a; + int psi_uncut = (phib_lut_b << PHIB_B_SHL_BITS) + tanpsi_lsb * phib_lut_a; + + // Trim phi to its final size + int phi = (phi_uncut >> PHI_MULT_SHR_BITS); + + // Calculate phi_bending from the uncut version of phi and psi, and the trim it to size + int phib_uncut = psi_uncut - (phi_uncut >> (PHI_PHIB_RES_DIFF_BITS + PHI_MULT_SHR_BITS - PHIB_MULT_SHR_BITS)); + int phib = (phib_uncut >> PHIB_MULT_SHR_BITS); + + double phi_f = (double)phi / pow(2, PHI_SIZE); + double phib_f = (double)phib / pow(2, PHIB_SIZE); + + return std::vector({phi_f, phib_f}); +} \ No newline at end of file diff --git a/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyticAnalyzer.cc b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyticAnalyzer.cc new file mode 100644 index 0000000000000..92d8f9750c7ae --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyticAnalyzer.cc @@ -0,0 +1,2253 @@ +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyticAnalyzer.h" +#include +#include + +using namespace edm; +using namespace std; +using namespace cmsdt; +// ============================================================================ +// Constructors and destructor +// ============================================================================ +MuonPathAnalyticAnalyzer::MuonPathAnalyticAnalyzer(const ParameterSet &pset, + edm::ConsumesCollector &iC, + std::shared_ptr &globalcoordsobtainer) + : MuonPathAnalyzer(pset, iC), + debug_(pset.getUntrackedParameter("debug")), + chi2Th_(pset.getUntrackedParameter("chi2Th")), + tanPhiTh_(pset.getUntrackedParameter("tanPhiTh")), + tanPhiThw2max_(pset.getUntrackedParameter("tanPhiThw2max")), + tanPhiThw2min_(pset.getUntrackedParameter("tanPhiThw2min")), + tanPhiThw1max_(pset.getUntrackedParameter("tanPhiThw1max")), + tanPhiThw1min_(pset.getUntrackedParameter("tanPhiThw1min")), + tanPhiThw0_(pset.getUntrackedParameter("tanPhiThw0")), + cmssw_for_global_(pset.getUntrackedParameter("cmssw_for_global")), + geometry_tag_(pset.getUntrackedParameter("geometry_tag")) { + if (debug_) + LogDebug("MuonPathAnalyticAnalyzer") << "MuonPathAnalyzer: constructor"; + + fillLAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER(); + + //shift phi + int rawId; + shift_filename_ = pset.getParameter("shift_filename"); + std::ifstream ifin3(shift_filename_.fullPath()); + double shift; + if (ifin3.fail()) { + throw cms::Exception("Missing Input File") + << "MuonPathAnalyticAnalyzer::MuonPathAnalyticAnalyzer() - Cannot find " << shift_filename_.fullPath(); + } + while (ifin3.good()) { + ifin3 >> rawId >> shift; + shiftinfo_[rawId] = shift; + } + + //shift theta + + shift_theta_filename_ = pset.getParameter("shift_theta_filename"); + std::ifstream ifin4(shift_theta_filename_.fullPath()); + if (ifin4.fail()) { + throw cms::Exception("Missing Input File") + << "MuonPathAnalyzerPerSL::MuonPathAnalyzerPerSL() - Cannot find " << shift_theta_filename_.fullPath(); + } + + while (ifin4.good()) { + ifin4 >> rawId >> shift; + shiftthetainfo_[rawId] = shift; + } + + chosen_sl_ = pset.getUntrackedParameter("trigger_with_sl"); + + if (chosen_sl_ != 1 && chosen_sl_ != 3 && chosen_sl_ != 4) { + LogDebug("MuonPathAnalyticAnalyzer") << "chosen sl must be 1,3 or 4(both superlayers)"; + assert(chosen_sl_ != 1 && chosen_sl_ != 3 && chosen_sl_ != 4); //4 means run using the two superlayers + } + + dtGeomH = iC.esConsumes(); + globalcoordsobtainer_ = globalcoordsobtainer; +} + +MuonPathAnalyticAnalyzer::~MuonPathAnalyticAnalyzer() { + if (debug_) + LogDebug("MuonPathAnalyticAnalyzer") << "MuonPathAnalyzer: destructor"; +} + +// ============================================================================ +// Main methods (initialise, run, finish) +// ============================================================================ +void MuonPathAnalyticAnalyzer::initialise(const edm::EventSetup &iEventSetup) { + if (debug_) + LogDebug("MuonPathAnalyticAnalyzer") << "MuonPathAnalyticAnalyzer::initialiase"; + + edm::ESHandle geom; + iEventSetup.get().get(geometry_tag_, geom); + dtGeo_ = &(*geom); +} + +void MuonPathAnalyticAnalyzer::run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + MuonPathPtrs &muonpaths, + std::vector &metaPrimitives) { + if (debug_) + LogDebug("MuonPathAnalyticAnalyzer") << "MuonPathAnalyticAnalyzer: run"; + + // fit per SL (need to allow for multiple outputs for a single mpath) + for (auto &muonpath : muonpaths) { + analyze(muonpath, metaPrimitives); + } +} + +void MuonPathAnalyticAnalyzer::finish() { + if (debug_) + LogDebug("MuonPathAnalyticAnalyzer") << "MuonPathAnalyzer: finish"; +}; + +//------------------------------------------------------------------ +//--- Métodos privados +//------------------------------------------------------------------ + +void MuonPathAnalyticAnalyzer::analyze(MuonPathPtr &inMPath, std::vector &metaPrimitives) { + if (debug_) + LogDebug("MuonPathAnalyticAnalyzer") << "DTp2:analyze \t\t\t\t starts"; + // LOCATE MPATH + int selected_Id = 0; + if (inMPath->primitive(0)->tdcTimeStamp() != -1) + selected_Id = inMPath->primitive(0)->cameraId(); + else if (inMPath->primitive(1)->tdcTimeStamp() != -1) + selected_Id = inMPath->primitive(1)->cameraId(); + else if (inMPath->primitive(2)->tdcTimeStamp() != -1) + selected_Id = inMPath->primitive(2)->cameraId(); + else if (inMPath->primitive(3)->tdcTimeStamp() != -1) + selected_Id = inMPath->primitive(3)->cameraId(); + + DTLayerId thisLId(selected_Id); + if (debug_) + LogDebug("MuonPathAnalyticAnalyzer") << "Building up MuonPathSLId from rawId in the Primitive"; + DTSuperLayerId MuonPathSLId(thisLId.wheel(), thisLId.station(), thisLId.sector(), thisLId.superLayer()); + if (debug_) + LogDebug("MuonPathAnalyticAnalyzer") << "The MuonPathSLId is" << MuonPathSLId; + + if (debug_) + LogDebug("MuonPathAnalyticAnalyzer") + << "DTp2:analyze \t\t\t\t In analyze function checking if inMPath->isAnalyzable() " << inMPath->isAnalyzable(); + + if (chosen_sl_ < 4 && thisLId.superLayer() != chosen_sl_) + return; // avoid running when mpath not in chosen SL (for 1SL fitting) + + auto mPath = std::make_shared(inMPath); + mPath->setQuality(NOPATH); + + int wi[4], wires[4], t0s[4], valids[4]; + // bool is_four_hit = true; + for (int j = 0; j < NUM_LAYERS; j++) { + if (mPath->primitive(j)->isValidTime()) { + wi[j] = mPath->primitive(j)->channelId(); + wires[j] = mPath->primitive(j)->channelId(); + t0s[j] = mPath->primitive(j)->tdcTimeStamp(); + valids[j] = 1; + } else { + wi[j] = -1; + wires[j] = -1; + t0s[j] = -1; + valids[j] = 0; + // is_four_hit = false; + } + } + + if (wi[0] < 0) + wi[0] = wi[1]; + else if (wi[1] < 0) + wi[1] = wi[0]; + else if (wi[2] < 0) + wi[2] = wi[1] - 1; + else if (wi[3] < 0) + wi[3] = wi[2]; + + int cell_horiz_layout[4]; + for (int lay = 0; lay < NUM_LAYERS; lay++) { + cell_horiz_layout[lay] = (wi[lay] - wi[0]) * 2; + if (lay % 2 != 0) + cell_horiz_layout[lay]--; + } + + // calculate the coarse offset position + int tmp = 1; + if (valids[1] == 0) + tmp = 3; + int coarse_pos = (wi[tmp] * 2 - cell_horiz_layout[tmp]) * 21 * std::pow(2, 4); + + //calculate the relative position of wires in mm wrt layer 0's cell wire + int xwire_mm[4]; + for (int lay = 0; lay < NUM_LAYERS; lay++) { + xwire_mm[lay] = 21 * cell_horiz_layout[lay]; + } + + // divide the timestamps in coarse + reduced part + int valid_coarse_times[4], min_coarse_time = 999999, max_coarse_time = -999999; + for (int lay = 0; lay < NUM_LAYERS; lay++) { + if (valids[lay] == 1) { + valid_coarse_times[lay] = (t0s[lay] >> (TDCTIME_REDUCED_SIZE - 1)); + if (valid_coarse_times[lay] < min_coarse_time) { + min_coarse_time = valid_coarse_times[lay]; + } + if (valid_coarse_times[lay] > max_coarse_time) { + max_coarse_time = valid_coarse_times[lay]; + } + } else { + valid_coarse_times[lay] = -1; + } + } + + // if (!is_four_hit) cout << "Found a 3!" << endl; + + if (max_coarse_time - min_coarse_time >= 2) + return; + int coarse_offset = max_coarse_time - 1; + + int reduced_times[4]; + for (int lay = 0; lay < NUM_LAYERS; lay++) { + reduced_times[lay] = + ((1 - ((max_coarse_time & 1) ^ ((t0s[lay] >> (TDCTIME_REDUCED_SIZE - 1)) & 1))) << (TDCTIME_REDUCED_SIZE - 1)); + reduced_times[lay] += (t0s[lay] & std::stoi(std::string(TDCTIME_REDUCED_SIZE - 1, '1'), nullptr, 2)); + } + std::vector latcomb_consts_arr; + for (auto &elem : LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER) + if (elem.cell_valid_layout.valid[0] == valids[0] && elem.cell_valid_layout.valid[1] == valids[1] && + elem.cell_valid_layout.valid[2] == valids[2] && elem.cell_valid_layout.valid[3] == valids[3] && + elem.cell_valid_layout.cell_horiz_layout[0] == cell_horiz_layout[0] && + elem.cell_valid_layout.cell_horiz_layout[1] == cell_horiz_layout[1] && + elem.cell_valid_layout.cell_horiz_layout[2] == cell_horiz_layout[2] && + elem.cell_valid_layout.cell_horiz_layout[3] == cell_horiz_layout[3]) + for (auto &ind_latcomb_consts : elem.latcomb_constants) + latcomb_consts_arr.push_back(ind_latcomb_consts); + for (auto &latcomb_consts : latcomb_consts_arr) { + segment_fitter(MuonPathSLId, + wires, + t0s, + valids, + reduced_times, + cell_horiz_layout, + latcomb_consts, + xwire_mm, + coarse_pos, + coarse_offset, + metaPrimitives); + } +} + +int MuonPathAnalyticAnalyzer::compute_parameter(MAGNITUDE constants, int t0s[4], int DIV_SHR_BITS, int INCREASED_RES) { + long int result = 0; + for (int lay = 0; lay < NUM_LAYERS; lay++) { + result += constants.coeff[lay] * t0s[lay]; + } + result = ((result * int(std::pow(2, INCREASED_RES)) + constants.add) * constants.mult) >> DIV_SHR_BITS; + + return result; +} + +void MuonPathAnalyticAnalyzer::segment_fitter(DTSuperLayerId MuonPathSLId, + int wires[4], + int t0s[4], + int valid[4], + int reduced_times[4], + int cell_horiz_layout[4], + LATCOMB_CONSTANTS latcomb_consts, + int xwire_mm[4], + int coarse_pos, + int coarse_offset, + std::vector &metaPrimitives) { + auto latcomb = latcomb_consts.latcomb; + auto constants = latcomb_consts.constants; + bool is_four_hit = true; + + if (latcomb == 0) + return; + + int lat_array[4]; + for (int lay = 0; lay < NUM_LAYERS; lay++) { + if (((latcomb >> lay) & 1) != 0) { + lat_array[lay] = 1; + } else + lat_array[lay] = -1; + } + + int time = compute_parameter(constants.t0, reduced_times, DIV_SHR_BITS_T0, INCREASED_RES_T0); + int pos = compute_parameter(constants.pos, reduced_times, DIV_SHR_BITS_POS, INCREASED_RES_POS); + int slope = compute_parameter(constants.slope, reduced_times, DIV_SHR_BITS_SLOPE, INCREASED_RES_SLOPE); + int slope_xhh = + compute_parameter(constants.slope_xhh, reduced_times, DIV_SHR_BITS_SLOPE_XHH, INCREASED_RES_SLOPE_XHH); + + int bx_time = time + (coarse_offset << (TDCTIME_REDUCED_SIZE - 1)); + + pos += coarse_pos; + + int chi2_mm2_p = 0; + for (int lay = 0; lay < NUM_LAYERS; lay++) { + int drift_time = reduced_times[lay] - time; + if (valid[lay] == 1 && (drift_time < 0 || drift_time > MAXDRIFT)) + return; + + int drift_dist = ((((drift_time * INCREASED_RES_POS_POW) + DTDD_PREADD) * DTDD_MULT) >> DTDD_SHIFTR_BITS); + int xdist = xwire_mm[lay] * pow(2, 4) - (pos - coarse_pos) + lat_array[lay] * drift_dist; + xdist -= (3 - 2 * (3 - lay)) * slope_xhh; + int res = xdist; + if (valid[lay] == 0) { + res = 0; + is_four_hit = false; + } + chi2_mm2_p += res * res * 4; + } + + int quality = HIGHQ; + if (!is_four_hit) + quality = LOWQ; + + // Obtain coordinate values in floating point + double pos_f, slope_f, chi2_f; + DTWireId wireId(MuonPathSLId, 2, 1); + + pos_f = double(pos) + + int(10 * shiftinfo_[wireId.rawId()] * INCREASED_RES_POS_POW); // position in mm * precision in JM RF + pos_f /= (10. * INCREASED_RES_POS_POW); // position in cm w.r.t center of the chamber + slope_f = -(double(slope) / INCREASED_RES_SLOPE_POW); + chi2_f = double(chi2_mm2_p) / (16. * 64. * 100.); + + // Impose the thresholds + if (MuonPathSLId.superLayer() != 2) + if (std::abs(slope_f) > tanPhiTh_) + return; + if (chi2_f > (chi2Th_)) + return; + + // Compute phi and phib + // Implemented using cmssw geometry as of now, will implemented fw-like in the near future + DTChamberId ChId(MuonPathSLId.wheel(), MuonPathSLId.station(), MuonPathSLId.sector()); + double phi = -999.; + double phiB = -999.; + if (cmssw_for_global_ && MuonPathSLId.superLayer() != 2) { + double z = 0; + double z1 = Z_POS_SL; + double z3 = -1. * z1; + if (ChId.station() == 3 or ChId.station() == 4) { + z1 = z1 + Z_SHIFT_MB4; + z3 = z3 + Z_SHIFT_MB4; + } + if (MuonPathSLId.superLayer() == 1) + z = z1; + else if (MuonPathSLId.superLayer() == 3) + z = z3; + + GlobalPoint jm_x_cmssw_global = dtGeo_->chamber(ChId)->toGlobal(LocalPoint(pos_f, 0., z)); + int thisec = MuonPathSLId.sector(); + if (thisec == 13) + thisec = 4; + if (thisec == 14) + thisec = 10; + phi = jm_x_cmssw_global.phi() - PHI_CONV * (thisec - 1); + double psi = atan(slope_f); + phiB = hasPosRF(MuonPathSLId.wheel(), MuonPathSLId.sector()) ? psi - phi : -psi - phi; + + } else if (MuonPathSLId.superLayer() != 2) { + auto global_coords = + globalcoordsobtainer_->get_global_coordinates(ChId.rawId(), MuonPathSLId.superLayer(), pos, slope); + phi = global_coords[0]; + phiB = global_coords[1]; + + } else { + DTLayerId SL2_layer2Id(MuonPathSLId, 2); + double z_shift = shiftthetainfo_[SL2_layer2Id.rawId()]; + double jm_y = hasPosRF(MuonPathSLId.wheel(), MuonPathSLId.sector()) ? z_shift - pos_f : z_shift + pos_f; + phi = jm_y; + phiB = slope_f; // + } + + // get the lateralities (in reverse order) in order to fill the metaprimitive + std::vector lateralities = getLateralityCombination(latcomb); + for (int lay = 0; lay < NUM_LAYERS; lay++) { + if (valid[lay] == 0) + lateralities[lay] = -1; + } + + if (MuonPathSLId.superLayer() == 2) { + // Impose the thresholds + if (std::abs(MuonPathSLId.wheel()) == 2) { + if (slope_f > tanPhiThw2max_ or slope_f < tanPhiThw2min_) + return; + } + + if (std::abs(MuonPathSLId.wheel()) == 1) { + if (slope_f > tanPhiThw1max_ or slope_f < tanPhiThw1min_) + return; + } + + if (MuonPathSLId.wheel() == 0) { + if (std::abs(slope_f) > tanPhiThw0_) + return; + } + + DTLayerId SL2_layer2Id(MuonPathSLId, 2); + double z_shift = shiftthetainfo_[SL2_layer2Id.rawId()]; + double jm_y = hasPosRF(MuonPathSLId.wheel(), MuonPathSLId.sector()) ? z_shift - pos_f : z_shift + pos_f; + if (cmssw_for_global_) { + LocalPoint wire1_in_layer(dtGeo_->layer(SL2_layer2Id)->specificTopology().wirePosition(1), 0, -0.65); + GlobalPoint wire1_in_global = dtGeo_->layer(SL2_layer2Id)->toGlobal(wire1_in_layer); + LocalPoint wire1_in_sl = dtGeo_->superLayer(MuonPathSLId)->toLocal(wire1_in_global); + double x_shift = wire1_in_sl.x(); + jm_y = (dtGeo_->superLayer(MuonPathSLId) + ->toGlobal(LocalPoint(double(pos) / (10 * pow(2, INCREASED_RES_POS)) + x_shift, 0., 0))) + .z(); + } + phi = jm_y; + phiB = slope_f; + } + + metaPrimitives.emplace_back(metaPrimitive({MuonPathSLId.rawId(), + double(bx_time), + pos_f, + slope_f, + phi, + phiB, + chi2_f, + quality, + wires[0], + t0s[0], + lateralities[0], + wires[1], + t0s[1], + lateralities[1], + wires[2], + t0s[2], + lateralities[2], + wires[3], + t0s[3], + lateralities[3], + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1})); +} + +std::vector MuonPathAnalyticAnalyzer::getLateralityCombination(int latcomb) { + // returns the latcomb as a binary number represented in a vector of integers + // careful, the output is in reverse order + std::vector binaryNum = {}; + while (latcomb > 1) { + binaryNum.push_back(latcomb % 2); + latcomb = latcomb / 2; + } + binaryNum.push_back(latcomb); + while (binaryNum.size() < 4) + binaryNum.push_back(0); + return binaryNum; +} + +void MuonPathAnalyticAnalyzer::fillLAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER() { + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, 0, -1}, {1, 1, 0, 1}}, + { + {1, + { + {-6170, {1, 0, 0, -1}, 56936}, + {239, {0, 1, 0, -1}, 4380}, + {37, {0, 1, 0, -1}, 3559}, + {776, {2, 3, 0, -1}, 16384}, + }}, + {2, + { + {-30885, {-1, 3, 0, -2}, 18979}, + {-1583769, {1, 0, 0, -1}, 2920}, + {-6133, {1, 0, 0, -1}, 2372}, + {-771, {2, 3, 0, 1}, 10923}, + }}, + {3, + { + {-6170, {1, 0, 0, -1}, 56936}, + {-1584008, {-1, 1, 0, 0}, 8759}, + {-6170, {-1, 1, 0, 0}, 7117}, + {-773, {-2, 3, 0, 1}, 32768}, + }}, + {8, + { + {-6170, {-1, 0, 0, 1}, 56936}, + {-1584008, {1, -1, 0, 0}, 8759}, + {-6170, {1, -1, 0, 0}, 7117}, + {775, {-2, 3, 0, 1}, 32768}, + }}, + {9, + { + {-30885, {1, -3, 0, 2}, 18979}, + {-1583769, {-1, 0, 0, 1}, 2920}, + {-6133, {-1, 0, 0, 1}, 2372}, + {777, {2, 3, 0, 1}, 10923}, + }}, + {10, + { + {-6170, {-1, 0, 0, 1}, 56936}, + {239, {0, -1, 0, 1}, 4380}, + {37, {0, -1, 0, 1}, 3559}, + {-772, {2, 3, 0, -1}, 16384}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, 0, 1}, {0, 1, 1, 1}}, + { + {2, + { + {-6170, {0, 1, -1, 0}, 56936}, + {1584248, {0, 0, 1, -1}, 8759}, + {6206, {0, 0, 1, -1}, 7117}, + {1, {0, 1, 2, -1}, 32768}, + }}, + {4, + { + {-6170, {0, -1, 1, 0}, 56936}, + {3168495, {0, 1, 0, -1}, 4380}, + {12413, {0, 1, 0, -1}, 3559}, + {2, {0, 1, 2, 1}, 16384}, + }}, + {6, + { + {-6170, {0, 2, -1, -1}, 56936}, + {1584248, {0, -1, 1, 0}, 8759}, + {6206, {0, -1, 1, 0}, 7117}, + {1, {0, -1, 2, 1}, 32768}, + }}, + {8, + { + {-6170, {0, -2, 1, 1}, 56936}, + {1584248, {0, 1, -1, 0}, 8759}, + {6206, {0, 1, -1, 0}, 7117}, + {1, {0, -1, 2, 1}, 32768}, + }}, + {10, + { + {-6170, {0, 1, -1, 0}, 56936}, + {3168495, {0, -1, 0, 1}, 4380}, + {12413, {0, -1, 0, 1}, 3559}, + {2, {0, 1, 2, 1}, 16384}, + }}, + {12, + { + {-6170, {0, -1, 1, 0}, 56936}, + {1584248, {0, 0, -1, 1}, 8759}, + {6206, {0, 0, -1, 1}, 7117}, + {1, {0, 1, 2, -1}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, -2, -3}, {1, 1, 0, 1}}, + { + {1, + { + {-18546, {1, 0, 0, -1}, 56936}, + {-3168017, {0, 1, 0, -1}, 4380}, + {-12339, {0, 1, 0, -1}, 3559}, + {2, {2, 3, 0, -1}, 16384}, + }}, + {2, + { + {-55637, {-1, 3, 0, -2}, 18979}, + {-4752025, {1, 0, 0, -1}, 2920}, + {-18509, {1, 0, 0, -1}, 2372}, + {3, {2, 3, 0, 1}, 10923}, + }}, + {3, + { + {-18546, {1, 0, 0, -1}, 56936}, + {-1584008, {-1, 1, 0, 0}, 8759}, + {-6170, {-1, 1, 0, 0}, 7117}, + {1, {-2, 3, 0, 1}, 32768}, + }}, + {8, + { + {-18546, {-1, 0, 0, 1}, 56936}, + {-1584008, {1, -1, 0, 0}, 8759}, + {-6170, {1, -1, 0, 0}, 7117}, + {1, {-2, 3, 0, 1}, 32768}, + }}, + {9, + { + {-55637, {1, -3, 0, 2}, 18979}, + {-4752025, {-1, 0, 0, 1}, 2920}, + {-18509, {-1, 0, 0, 1}, 2372}, + {3, {2, 3, 0, 1}, 10923}, + }}, + {10, + { + {-18546, {-1, 0, 0, 1}, 56936}, + {-3168017, {0, -1, 0, 1}, 4380}, + {-12339, {0, -1, 0, 1}, 3559}, + {2, {2, 3, 0, -1}, 16384}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 0, 1}, {0, 1, 1, 1}}, + { + {2, + { + {6206, {0, 1, -1, 0}, 56936}, + {1584248, {0, 0, 1, -1}, 8759}, + {6206, {0, 0, 1, -1}, 7117}, + {775, {0, 1, 2, -1}, 32768}, + }}, + {4, + { + {6206, {0, -1, 1, 0}, 56936}, + {239, {0, 1, 0, -1}, 4380}, + {37, {0, 1, 0, -1}, 3559}, + {-772, {0, 1, 2, 1}, 16384}, + }}, + {6, + { + {18582, {0, 2, -1, -1}, 56936}, + {-1584008, {0, -1, 1, 0}, 8759}, + {-6170, {0, -1, 1, 0}, 7117}, + {-773, {0, -1, 2, 1}, 32768}, + }}, + {8, + { + {18582, {0, -2, 1, 1}, 56936}, + {-1584008, {0, 1, -1, 0}, 8759}, + {-6170, {0, 1, -1, 0}, 7117}, + {775, {0, -1, 2, 1}, 32768}, + }}, + {10, + { + {6206, {0, 1, -1, 0}, 56936}, + {239, {0, -1, 0, 1}, 4380}, + {37, {0, -1, 0, 1}, 3559}, + {776, {0, 1, 2, 1}, 16384}, + }}, + {12, + { + {6206, {0, -1, 1, 0}, 56936}, + {1584248, {0, 0, -1, 1}, 8759}, + {6206, {0, 0, -1, 1}, 7117}, + {-773, {0, 1, 2, -1}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 2, 1}, {1, 1, 1, 0}}, + { + {1, + { + {18582, {1, 1, -2, 0}, 56936}, + {1584248, {0, 1, -1, 0}, 8759}, + {6206, {0, 1, -1, 0}, 7117}, + {1, {1, 2, -1, 0}, 32768}, + }}, + {2, + { + {18582, {0, 1, -1, 0}, 56936}, + {3168495, {1, 0, -1, 0}, 4380}, + {12413, {1, 0, -1, 0}, 3559}, + {2, {1, 2, 1, 0}, 16384}, + }}, + {3, + { + {18582, {0, 1, -1, 0}, 56936}, + {1584248, {-1, 1, 0, 0}, 8759}, + {6206, {-1, 1, 0, 0}, 7117}, + {1, {-1, 2, 1, 0}, 32768}, + }}, + {4, + { + {18582, {0, -1, 1, 0}, 56936}, + {1584248, {1, -1, 0, 0}, 8759}, + {6206, {1, -1, 0, 0}, 7117}, + {1, {-1, 2, 1, 0}, 32768}, + }}, + {5, + { + {18582, {0, -1, 1, 0}, 56936}, + {3168495, {-1, 0, 1, 0}, 4380}, + {12413, {-1, 0, 1, 0}, 3559}, + {2, {1, 2, 1, 0}, 16384}, + }}, + {6, + { + {18582, {-1, -1, 2, 0}, 56936}, + {1584248, {0, -1, 1, 0}, 8759}, + {6206, {0, -1, 1, 0}, 7117}, + {1, {1, 2, -1, 0}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 0, -1}, {1, 0, 1, 1}}, + { + {1, + { + {-6170, {1, 0, 0, -1}, 56936}, + {-1584008, {0, 0, 1, -1}, 8759}, + {-6170, {0, 0, 1, -1}, 7117}, + {-773, {1, 0, 3, -2}, 32768}, + }}, + {4, + { + {-6133, {-2, 0, 3, -1}, 18979}, + {-1583769, {1, 0, 0, -1}, 2920}, + {-6133, {1, 0, 0, -1}, 2372}, + {777, {1, 0, 3, 2}, 10923}, + }}, + {5, + { + {-6170, {1, 0, 0, -1}, 56936}, + {239, {-1, 0, 1, 0}, 4380}, + {37, {-1, 0, 1, 0}, 3559}, + {776, {-1, 0, 3, 2}, 16384}, + }}, + {8, + { + {-6170, {-1, 0, 0, 1}, 56936}, + {239, {1, 0, -1, 0}, 4380}, + {37, {1, 0, -1, 0}, 3559}, + {-772, {-1, 0, 3, 2}, 16384}, + }}, + {9, + { + {-6133, {2, 0, -3, 1}, 18979}, + {-1583769, {-1, 0, 0, 1}, 2920}, + {-6133, {-1, 0, 0, 1}, 2372}, + {-771, {1, 0, 3, 2}, 10923}, + }}, + {12, + { + {-6170, {-1, 0, 0, 1}, 56936}, + {-1584008, {0, 0, -1, 1}, 8759}, + {-6170, {0, 0, -1, 1}, 7117}, + {775, {1, 0, 3, -2}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, -2, -1}, {1, 1, 1, 0}}, + { + {1, + { + {-18546, {1, 1, -2, 0}, 56936}, + {-1584008, {0, 1, -1, 0}, 8759}, + {-6170, {0, 1, -1, 0}, 7117}, + {1, {1, 2, -1, 0}, 32768}, + }}, + {2, + { + {-18546, {0, 1, -1, 0}, 56936}, + {-3168017, {1, 0, -1, 0}, 4380}, + {-12339, {1, 0, -1, 0}, 3559}, + {2, {1, 2, 1, 0}, 16384}, + }}, + {3, + { + {-18546, {0, 1, -1, 0}, 56936}, + {-1584008, {-1, 1, 0, 0}, 8759}, + {-6170, {-1, 1, 0, 0}, 7117}, + {1, {-1, 2, 1, 0}, 32768}, + }}, + {4, + { + {-18546, {0, -1, 1, 0}, 56936}, + {-1584008, {1, -1, 0, 0}, 8759}, + {-6170, {1, -1, 0, 0}, 7117}, + {1, {-1, 2, 1, 0}, 32768}, + }}, + {5, + { + {-18546, {0, -1, 1, 0}, 56936}, + {-3168017, {-1, 0, 1, 0}, 4380}, + {-12339, {-1, 0, 1, 0}, 3559}, + {2, {1, 2, 1, 0}, 16384}, + }}, + {6, + { + {-18546, {-1, -1, 2, 0}, 56936}, + {-1584008, {0, -1, 1, 0}, 8759}, + {-6170, {0, -1, 1, 0}, 7117}, + {1, {1, 2, -1, 0}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, -2, -3}, {0, 1, 1, 1}}, + { + {2, + { + {-18546, {0, 1, -1, 0}, 56936}, + {-1584008, {0, 0, 1, -1}, 8759}, + {-6170, {0, 0, 1, -1}, 7117}, + {1, {0, 1, 2, -1}, 32768}, + }}, + {4, + { + {-18546, {0, -1, 1, 0}, 56936}, + {-3168017, {0, 1, 0, -1}, 4380}, + {-12339, {0, 1, 0, -1}, 3559}, + {2, {0, 1, 2, 1}, 16384}, + }}, + {6, + { + {-18546, {0, 2, -1, -1}, 56936}, + {-1584008, {0, -1, 1, 0}, 8759}, + {-6170, {0, -1, 1, 0}, 7117}, + {1, {0, -1, 2, 1}, 32768}, + }}, + {8, + { + {-18546, {0, -2, 1, 1}, 56936}, + {-1584008, {0, 1, -1, 0}, 8759}, + {-6170, {0, 1, -1, 0}, 7117}, + {1, {0, -1, 2, 1}, 32768}, + }}, + {10, + { + {-18546, {0, 1, -1, 0}, 56936}, + {-3168017, {0, -1, 0, 1}, 4380}, + {-12339, {0, -1, 0, 1}, 3559}, + {2, {0, 1, 2, 1}, 16384}, + }}, + {12, + { + {-18546, {0, -1, 1, 0}, 56936}, + {-1584008, {0, 0, -1, 1}, 8759}, + {-6170, {0, 0, -1, 1}, 7117}, + {1, {0, 1, 2, -1}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, -2, -1}, {0, 1, 1, 1}}, + { + {2, + { + {-18546, {0, 1, -1, 0}, 56936}, + {1584248, {0, 0, 1, -1}, 8759}, + {6206, {0, 0, 1, -1}, 7117}, + {775, {0, 1, 2, -1}, 32768}, + }}, + {4, + { + {-18546, {0, -1, 1, 0}, 56936}, + {239, {0, 1, 0, -1}, 4380}, + {37, {0, 1, 0, -1}, 3559}, + {-772, {0, 1, 2, 1}, 16384}, + }}, + {6, + { + {-6170, {0, 2, -1, -1}, 56936}, + {-1584008, {0, -1, 1, 0}, 8759}, + {-6170, {0, -1, 1, 0}, 7117}, + {-773, {0, -1, 2, 1}, 32768}, + }}, + {8, + { + {-6170, {0, -2, 1, 1}, 56936}, + {-1584008, {0, 1, -1, 0}, 8759}, + {-6170, {0, 1, -1, 0}, 7117}, + {775, {0, -1, 2, 1}, 32768}, + }}, + {10, + { + {-18546, {0, 1, -1, 0}, 56936}, + {239, {0, -1, 0, 1}, 4380}, + {37, {0, -1, 0, 1}, 3559}, + {776, {0, 1, 2, 1}, 16384}, + }}, + {12, + { + {-18546, {0, -1, 1, 0}, 56936}, + {1584248, {0, 0, -1, 1}, 8759}, + {6206, {0, 0, -1, 1}, 7117}, + {-773, {0, 1, 2, -1}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, -2, -3}, {1, 1, 1, 0}}, + { + {1, + { + {-18546, {1, 1, -2, 0}, 56936}, + {-1584008, {0, 1, -1, 0}, 8759}, + {-6170, {0, 1, -1, 0}, 7117}, + {1, {1, 2, -1, 0}, 32768}, + }}, + {2, + { + {-18546, {0, 1, -1, 0}, 56936}, + {-3168017, {1, 0, -1, 0}, 4380}, + {-12339, {1, 0, -1, 0}, 3559}, + {2, {1, 2, 1, 0}, 16384}, + }}, + {3, + { + {-18546, {0, 1, -1, 0}, 56936}, + {-1584008, {-1, 1, 0, 0}, 8759}, + {-6170, {-1, 1, 0, 0}, 7117}, + {1, {-1, 2, 1, 0}, 32768}, + }}, + {4, + { + {-18546, {0, -1, 1, 0}, 56936}, + {-1584008, {1, -1, 0, 0}, 8759}, + {-6170, {1, -1, 0, 0}, 7117}, + {1, {-1, 2, 1, 0}, 32768}, + }}, + {5, + { + {-18546, {0, -1, 1, 0}, 56936}, + {-3168017, {-1, 0, 1, 0}, 4380}, + {-12339, {-1, 0, 1, 0}, 3559}, + {2, {1, 2, 1, 0}, 16384}, + }}, + {6, + { + {-18546, {-1, -1, 2, 0}, 56936}, + {-1584008, {0, -1, 1, 0}, 8759}, + {-6170, {0, -1, 1, 0}, 7117}, + {1, {1, 2, -1, 0}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 2, 1}, {0, 1, 1, 1}}, + { + {2, + { + {18582, {0, 1, -1, 0}, 56936}, + {-1584008, {0, 0, 1, -1}, 8759}, + {-6170, {0, 0, 1, -1}, 7117}, + {-773, {0, 1, 2, -1}, 32768}, + }}, + {4, + { + {18582, {0, -1, 1, 0}, 56936}, + {239, {0, 1, 0, -1}, 4380}, + {37, {0, 1, 0, -1}, 3559}, + {776, {0, 1, 2, 1}, 16384}, + }}, + {6, + { + {6206, {0, 2, -1, -1}, 56936}, + {1584248, {0, -1, 1, 0}, 8759}, + {6206, {0, -1, 1, 0}, 7117}, + {775, {0, -1, 2, 1}, 32768}, + }}, + {8, + { + {6206, {0, -2, 1, 1}, 56936}, + {1584248, {0, 1, -1, 0}, 8759}, + {6206, {0, 1, -1, 0}, 7117}, + {-773, {0, -1, 2, 1}, 32768}, + }}, + {10, + { + {18582, {0, 1, -1, 0}, 56936}, + {239, {0, -1, 0, 1}, 4380}, + {37, {0, -1, 0, 1}, 3559}, + {-772, {0, 1, 2, 1}, 16384}, + }}, + {12, + { + {18582, {0, -1, 1, 0}, 56936}, + {-1584008, {0, 0, -1, 1}, 8759}, + {-6170, {0, 0, -1, 1}, 7117}, + {775, {0, 1, 2, -1}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, -2, -1}, {1, 1, 1, 1}}, + { + {4, + { + {-222510, {-6, -5, 14, -3}, 4067}, + {-6334836, {4, 1, 0, -5}, 626}, + {-24494, {4, 1, 0, -5}, 508}, + {-3087, {1, 2, 7, 4}, 4681}, + }}, + {6, + { + {-24715, {-1, 1, 1, -1}, 28468}, + {-6335315, {3, -1, 1, -3}, 876}, + {-24568, {3, -1, 1, -3}, 712}, + {-772, {1, 1, 1, 1}, 16384}, + }}, + {7, + { + {-37018, {5, 2, -1, -6}, 9489}, + {-3168017, {-1, 0, 1, 0}, 4380}, + {-12339, {-1, 0, 1, 0}, 3559}, + {-2318, {-2, 1, 4, 3}, 10923}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 2, 3}, {0, 1, 1, 1}}, + { + {2, + { + {18582, {0, 1, -1, 0}, 56936}, + {1584248, {0, 0, 1, -1}, 8759}, + {6206, {0, 0, 1, -1}, 7117}, + {1, {0, 1, 2, -1}, 32768}, + }}, + {4, + { + {18582, {0, -1, 1, 0}, 56936}, + {3168495, {0, 1, 0, -1}, 4380}, + {12413, {0, 1, 0, -1}, 3559}, + {2, {0, 1, 2, 1}, 16384}, + }}, + {6, + { + {18582, {0, 2, -1, -1}, 56936}, + {1584248, {0, -1, 1, 0}, 8759}, + {6206, {0, -1, 1, 0}, 7117}, + {1, {0, -1, 2, 1}, 32768}, + }}, + {8, + { + {18582, {0, -2, 1, 1}, 56936}, + {1584248, {0, 1, -1, 0}, 8759}, + {6206, {0, 1, -1, 0}, 7117}, + {1, {0, -1, 2, 1}, 32768}, + }}, + {10, + { + {18582, {0, 1, -1, 0}, 56936}, + {3168495, {0, -1, 0, 1}, 4380}, + {12413, {0, -1, 0, 1}, 3559}, + {2, {0, 1, 2, 1}, 16384}, + }}, + {12, + { + {18582, {0, -1, 1, 0}, 56936}, + {1584248, {0, 0, -1, 1}, 8759}, + {6206, {0, 0, -1, 1}, 7117}, + {1, {0, 1, 2, -1}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 0, -1}, {1, 1, 1, 1}}, + { + {1, + { + {-37018, {6, 1, -2, -5}, 9489}, + {-3168017, {0, 1, 0, -1}, 4380}, + {-12339, {0, 1, 0, -1}, 3559}, + {-2318, {3, 4, 1, -2}, 10923}, + }}, + {9, + { + {37, {1, -1, -1, 1}, 28468}, + {-6335315, {-3, 1, -1, 3}, 876}, + {-24568, {-3, 1, -1, 3}, 712}, + {-772, {1, 1, 1, 1}, 16384}, + }}, + {13, + { + {49762, {3, -14, 5, 6}, 4067}, + {-6334836, {-5, 0, 1, 4}, 626}, + {-24494, {-5, 0, 1, 4}, 508}, + {-3087, {4, 7, 2, 1}, 4681}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, -2, -1}, {1, 1, 0, 1}}, + { + {1, + { + {-6170, {1, 0, 0, -1}, 56936}, + {239, {0, 1, 0, -1}, 4380}, + {37, {0, 1, 0, -1}, 3559}, + {776, {2, 3, 0, -1}, 16384}, + }}, + {2, + { + {-30885, {-1, 3, 0, -2}, 18979}, + {-1583769, {1, 0, 0, -1}, 2920}, + {-6133, {1, 0, 0, -1}, 2372}, + {-771, {2, 3, 0, 1}, 10923}, + }}, + {3, + { + {-6170, {1, 0, 0, -1}, 56936}, + {-1584008, {-1, 1, 0, 0}, 8759}, + {-6170, {-1, 1, 0, 0}, 7117}, + {-773, {-2, 3, 0, 1}, 32768}, + }}, + {8, + { + {-6170, {-1, 0, 0, 1}, 56936}, + {-1584008, {1, -1, 0, 0}, 8759}, + {-6170, {1, -1, 0, 0}, 7117}, + {775, {-2, 3, 0, 1}, 32768}, + }}, + {9, + { + {-30885, {1, -3, 0, 2}, 18979}, + {-1583769, {-1, 0, 0, 1}, 2920}, + {-6133, {-1, 0, 0, 1}, 2372}, + {777, {2, 3, 0, 1}, 10923}, + }}, + {10, + { + {-6170, {-1, 0, 0, 1}, 56936}, + {239, {0, -1, 0, 1}, 4380}, + {37, {0, -1, 0, 1}, 3559}, + {-772, {2, 3, 0, -1}, 16384}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 2, 3}, {1, 1, 0, 1}}, + { + {1, + { + {18582, {1, 0, 0, -1}, 56936}, + {3168495, {0, 1, 0, -1}, 4380}, + {12413, {0, 1, 0, -1}, 3559}, + {2, {2, 3, 0, -1}, 16384}, + }}, + {2, + { + {55747, {-1, 3, 0, -2}, 18979}, + {4752743, {1, 0, 0, -1}, 2920}, + {18619, {1, 0, 0, -1}, 2372}, + {3, {2, 3, 0, 1}, 10923}, + }}, + {3, + { + {18582, {1, 0, 0, -1}, 56936}, + {1584248, {-1, 1, 0, 0}, 8759}, + {6206, {-1, 1, 0, 0}, 7117}, + {1, {-2, 3, 0, 1}, 32768}, + }}, + {8, + { + {18582, {-1, 0, 0, 1}, 56936}, + {1584248, {1, -1, 0, 0}, 8759}, + {6206, {1, -1, 0, 0}, 7117}, + {1, {-2, 3, 0, 1}, 32768}, + }}, + {9, + { + {55747, {1, -3, 0, 2}, 18979}, + {4752743, {-1, 0, 0, 1}, 2920}, + {18619, {-1, 0, 0, 1}, 2372}, + {3, {2, 3, 0, 1}, 10923}, + }}, + {10, + { + {18582, {-1, 0, 0, 1}, 56936}, + {3168495, {0, -1, 0, 1}, 4380}, + {12413, {0, -1, 0, 1}, 3559}, + {2, {2, 3, 0, -1}, 16384}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, 0, 1}, {1, 1, 1, 0}}, + { + {1, + { + {6206, {1, 1, -2, 0}, 56936}, + {1584248, {0, 1, -1, 0}, 8759}, + {6206, {0, 1, -1, 0}, 7117}, + {775, {1, 2, -1, 0}, 32768}, + }}, + {2, + { + {-6170, {0, 1, -1, 0}, 56936}, + {239, {1, 0, -1, 0}, 4380}, + {37, {1, 0, -1, 0}, 3559}, + {-772, {1, 2, 1, 0}, 16384}, + }}, + {3, + { + {-6170, {0, 1, -1, 0}, 56936}, + {-1584008, {-1, 1, 0, 0}, 8759}, + {-6170, {-1, 1, 0, 0}, 7117}, + {-773, {-1, 2, 1, 0}, 32768}, + }}, + {4, + { + {-6170, {0, -1, 1, 0}, 56936}, + {-1584008, {1, -1, 0, 0}, 8759}, + {-6170, {1, -1, 0, 0}, 7117}, + {775, {-1, 2, 1, 0}, 32768}, + }}, + {5, + { + {-6170, {0, -1, 1, 0}, 56936}, + {239, {-1, 0, 1, 0}, 4380}, + {37, {-1, 0, 1, 0}, 3559}, + {776, {1, 2, 1, 0}, 16384}, + }}, + {6, + { + {6206, {-1, -1, 2, 0}, 56936}, + {1584248, {0, -1, 1, 0}, 8759}, + {6206, {0, -1, 1, 0}, 7117}, + {-773, {1, 2, -1, 0}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 0, -1}, {0, 1, 1, 1}}, + { + {2, + { + {6206, {0, 1, -1, 0}, 56936}, + {-1584008, {0, 0, 1, -1}, 8759}, + {-6170, {0, 0, 1, -1}, 7117}, + {1, {0, 1, 2, -1}, 32768}, + }}, + {4, + { + {6206, {0, -1, 1, 0}, 56936}, + {-3168017, {0, 1, 0, -1}, 4380}, + {-12339, {0, 1, 0, -1}, 3559}, + {2, {0, 1, 2, 1}, 16384}, + }}, + {6, + { + {6206, {0, 2, -1, -1}, 56936}, + {-1584008, {0, -1, 1, 0}, 8759}, + {-6170, {0, -1, 1, 0}, 7117}, + {1, {0, -1, 2, 1}, 32768}, + }}, + {8, + { + {6206, {0, -2, 1, 1}, 56936}, + {-1584008, {0, 1, -1, 0}, 8759}, + {-6170, {0, 1, -1, 0}, 7117}, + {1, {0, -1, 2, 1}, 32768}, + }}, + {10, + { + {6206, {0, 1, -1, 0}, 56936}, + {-3168017, {0, -1, 0, 1}, 4380}, + {-12339, {0, -1, 0, 1}, 3559}, + {2, {0, 1, 2, 1}, 16384}, + }}, + {12, + { + {6206, {0, -1, 1, 0}, 56936}, + {-1584008, {0, 0, -1, 1}, 8759}, + {-6170, {0, 0, -1, 1}, 7117}, + {1, {0, 1, 2, -1}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, 0, -1}, {1, 1, 1, 1}}, + { + {2, + { + {-123502, {-3, 14, -5, -6}, 4067}, + {-6334836, {5, 0, -1, -4}, 626}, + {-24494, {5, 0, -1, -4}, 508}, + {-2314, {4, 7, 2, 1}, 4681}, + }}, + {10, + { + {-12339, {-1, 1, -1, 1}, 28468}, + {479, {1, -1, -1, 1}, 2190}, + {74, {1, -1, -1, 1}, 1779}, + {-1543, {1, 3, 3, 1}, 8192}, + }}, + {3, + { + {-12339, {1, 1, -1, -1}, 28468}, + {-3168017, {-1, 1, 1, -1}, 4380}, + {-12339, {-1, 1, 1, -1}, 3559}, + {-1545, {-1, 3, 3, -1}, 16384}, + }}, + {11, + { + {-49246, {6, 5, -14, 3}, 4067}, + {-6334836, {-4, -1, 0, 5}, 626}, + {-24494, {-4, -1, 0, 5}, 508}, + {-2314, {1, 2, 7, 4}, 4681}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, 0, -1}, {0, 1, 1, 1}}, + { + {2, + { + {-6170, {0, 1, -1, 0}, 56936}, + {-1584008, {0, 0, 1, -1}, 8759}, + {-6170, {0, 0, 1, -1}, 7117}, + {-773, {0, 1, 2, -1}, 32768}, + }}, + {4, + { + {-6170, {0, -1, 1, 0}, 56936}, + {239, {0, 1, 0, -1}, 4380}, + {37, {0, 1, 0, -1}, 3559}, + {776, {0, 1, 2, 1}, 16384}, + }}, + {6, + { + {-18546, {0, 2, -1, -1}, 56936}, + {1584248, {0, -1, 1, 0}, 8759}, + {6206, {0, -1, 1, 0}, 7117}, + {775, {0, -1, 2, 1}, 32768}, + }}, + {8, + { + {-18546, {0, -2, 1, 1}, 56936}, + {1584248, {0, 1, -1, 0}, 8759}, + {6206, {0, 1, -1, 0}, 7117}, + {-773, {0, -1, 2, 1}, 32768}, + }}, + {10, + { + {-6170, {0, 1, -1, 0}, 56936}, + {239, {0, -1, 0, 1}, 4380}, + {37, {0, -1, 0, 1}, 3559}, + {-772, {0, 1, 2, 1}, 16384}, + }}, + {12, + { + {-6170, {0, -1, 1, 0}, 56936}, + {-1584008, {0, 0, -1, 1}, 8759}, + {-6170, {0, 0, -1, 1}, 7117}, + {775, {0, 1, 2, -1}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 2, 3}, {1, 1, 1, 1}}, + { + {8, + { + {111495, {-5, -2, 1, 6}, 9489}, + {3168495, {1, 0, -1, 0}, 4380}, + {12413, {1, 0, -1, 0}, 3559}, + {3, {-2, 1, 4, 3}, 10923}, + }}, + {12, + { + {37165, {-1, -1, 1, 1}, 28468}, + {3168495, {1, -1, -1, 1}, 4380}, + {12413, {1, -1, -1, 1}, 3559}, + {2, {-1, 3, 3, -1}, 16384}, + }}, + {14, + { + {111495, {-6, -1, 2, 5}, 9489}, + {3168495, {0, -1, 0, 1}, 4380}, + {12413, {0, -1, 0, 1}, 3559}, + {3, {3, 4, 1, -2}, 10923}, + }}, + {1, + { + {111495, {6, 1, -2, -5}, 9489}, + {3168495, {0, 1, 0, -1}, 4380}, + {12413, {0, 1, 0, -1}, 3559}, + {3, {3, 4, 1, -2}, 10923}, + }}, + {3, + { + {37165, {1, 1, -1, -1}, 28468}, + {3168495, {-1, 1, 1, -1}, 4380}, + {12413, {-1, 1, 1, -1}, 3559}, + {2, {-1, 3, 3, -1}, 16384}, + }}, + {7, + { + {111495, {5, 2, -1, -6}, 9489}, + {3168495, {-1, 0, 1, 0}, 4380}, + {12413, {-1, 0, 1, 0}, 3559}, + {3, {-2, 1, 4, 3}, 10923}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 0, 1}, {1, 0, 1, 1}}, + { + {1, + { + {6206, {1, 0, 0, -1}, 56936}, + {1584248, {0, 0, 1, -1}, 8759}, + {6206, {0, 0, 1, -1}, 7117}, + {775, {1, 0, 3, -2}, 32768}, + }}, + {4, + { + {6243, {-2, 0, 3, -1}, 18979}, + {1584487, {1, 0, 0, -1}, 2920}, + {6243, {1, 0, 0, -1}, 2372}, + {-771, {1, 0, 3, 2}, 10923}, + }}, + {5, + { + {6206, {1, 0, 0, -1}, 56936}, + {239, {-1, 0, 1, 0}, 4380}, + {37, {-1, 0, 1, 0}, 3559}, + {-772, {-1, 0, 3, 2}, 16384}, + }}, + {8, + { + {6206, {-1, 0, 0, 1}, 56936}, + {239, {1, 0, -1, 0}, 4380}, + {37, {1, 0, -1, 0}, 3559}, + {776, {-1, 0, 3, 2}, 16384}, + }}, + {9, + { + {6243, {2, 0, -3, 1}, 18979}, + {1584487, {-1, 0, 0, 1}, 2920}, + {6243, {-1, 0, 0, 1}, 2372}, + {777, {1, 0, 3, 2}, 10923}, + }}, + {12, + { + {6206, {-1, 0, 0, 1}, 56936}, + {1584248, {0, 0, -1, 1}, 8759}, + {6206, {0, 0, -1, 1}, 7117}, + {-773, {1, 0, 3, -2}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 2, 1}, {1, 1, 0, 1}}, + { + {1, + { + {6206, {1, 0, 0, -1}, 56936}, + {239, {0, 1, 0, -1}, 4380}, + {37, {0, 1, 0, -1}, 3559}, + {-772, {2, 3, 0, -1}, 16384}, + }}, + {2, + { + {30995, {-1, 3, 0, -2}, 18979}, + {1584487, {1, 0, 0, -1}, 2920}, + {6243, {1, 0, 0, -1}, 2372}, + {777, {2, 3, 0, 1}, 10923}, + }}, + {3, + { + {6206, {1, 0, 0, -1}, 56936}, + {1584248, {-1, 1, 0, 0}, 8759}, + {6206, {-1, 1, 0, 0}, 7117}, + {775, {-2, 3, 0, 1}, 32768}, + }}, + {8, + { + {6206, {-1, 0, 0, 1}, 56936}, + {1584248, {1, -1, 0, 0}, 8759}, + {6206, {1, -1, 0, 0}, 7117}, + {-773, {-2, 3, 0, 1}, 32768}, + }}, + {9, + { + {30995, {1, -3, 0, 2}, 18979}, + {1584487, {-1, 0, 0, 1}, 2920}, + {6243, {-1, 0, 0, 1}, 2372}, + {-771, {2, 3, 0, 1}, 10923}, + }}, + {10, + { + {6206, {-1, 0, 0, 1}, 56936}, + {239, {0, -1, 0, 1}, 4380}, + {37, {0, -1, 0, 1}, 3559}, + {776, {2, 3, 0, -1}, 16384}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, 0, -1}, {1, 1, 1, 0}}, + { + {1, + { + {6206, {1, 1, -2, 0}, 56936}, + {1584248, {0, 1, -1, 0}, 8759}, + {6206, {0, 1, -1, 0}, 7117}, + {775, {1, 2, -1, 0}, 32768}, + }}, + {2, + { + {-6170, {0, 1, -1, 0}, 56936}, + {239, {1, 0, -1, 0}, 4380}, + {37, {1, 0, -1, 0}, 3559}, + {-772, {1, 2, 1, 0}, 16384}, + }}, + {3, + { + {-6170, {0, 1, -1, 0}, 56936}, + {-1584008, {-1, 1, 0, 0}, 8759}, + {-6170, {-1, 1, 0, 0}, 7117}, + {-773, {-1, 2, 1, 0}, 32768}, + }}, + {4, + { + {-6170, {0, -1, 1, 0}, 56936}, + {-1584008, {1, -1, 0, 0}, 8759}, + {-6170, {1, -1, 0, 0}, 7117}, + {775, {-1, 2, 1, 0}, 32768}, + }}, + {5, + { + {-6170, {0, -1, 1, 0}, 56936}, + {239, {-1, 0, 1, 0}, 4380}, + {37, {-1, 0, 1, 0}, 3559}, + {776, {1, 2, 1, 0}, 16384}, + }}, + {6, + { + {6206, {-1, -1, 2, 0}, 56936}, + {1584248, {0, -1, 1, 0}, 8759}, + {6206, {0, -1, 1, 0}, 7117}, + {-773, {1, 2, -1, 0}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 2, 1}, {1, 0, 1, 1}}, + { + {1, + { + {6206, {1, 0, 0, -1}, 56936}, + {-1584008, {0, 0, 1, -1}, 8759}, + {-6170, {0, 0, 1, -1}, 7117}, + {-1546, {1, 0, 3, -2}, 32768}, + }}, + {4, + { + {43371, {-2, 0, 3, -1}, 18979}, + {1584487, {1, 0, 0, -1}, 2920}, + {6243, {1, 0, 0, -1}, 2372}, + {1550, {1, 0, 3, 2}, 10923}, + }}, + {5, + { + {6206, {1, 0, 0, -1}, 56936}, + {3168495, {-1, 0, 1, 0}, 4380}, + {12413, {-1, 0, 1, 0}, 3559}, + {1549, {-1, 0, 3, 2}, 16384}, + }}, + {8, + { + {6206, {-1, 0, 0, 1}, 56936}, + {3168495, {1, 0, -1, 0}, 4380}, + {12413, {1, 0, -1, 0}, 3559}, + {-1545, {-1, 0, 3, 2}, 16384}, + }}, + {9, + { + {43371, {2, 0, -3, 1}, 18979}, + {1584487, {-1, 0, 0, 1}, 2920}, + {6243, {-1, 0, 0, 1}, 2372}, + {-1544, {1, 0, 3, 2}, 10923}, + }}, + {12, + { + {6206, {-1, 0, 0, 1}, 56936}, + {-1584008, {0, 0, -1, 1}, 8759}, + {-6170, {0, 0, -1, 1}, 7117}, + {1548, {1, 0, 3, -2}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 0, -1}, {1, 1, 1, 0}}, + { + {1, + { + {-6170, {1, 1, -2, 0}, 56936}, + {-1584008, {0, 1, -1, 0}, 8759}, + {-6170, {0, 1, -1, 0}, 7117}, + {-773, {1, 2, -1, 0}, 32768}, + }}, + {2, + { + {6206, {0, 1, -1, 0}, 56936}, + {239, {1, 0, -1, 0}, 4380}, + {37, {1, 0, -1, 0}, 3559}, + {776, {1, 2, 1, 0}, 16384}, + }}, + {3, + { + {6206, {0, 1, -1, 0}, 56936}, + {1584248, {-1, 1, 0, 0}, 8759}, + {6206, {-1, 1, 0, 0}, 7117}, + {775, {-1, 2, 1, 0}, 32768}, + }}, + {4, + { + {6206, {0, -1, 1, 0}, 56936}, + {1584248, {1, -1, 0, 0}, 8759}, + {6206, {1, -1, 0, 0}, 7117}, + {-773, {-1, 2, 1, 0}, 32768}, + }}, + {5, + { + {6206, {0, -1, 1, 0}, 56936}, + {239, {-1, 0, 1, 0}, 4380}, + {37, {-1, 0, 1, 0}, 3559}, + {-772, {1, 2, 1, 0}, 16384}, + }}, + {6, + { + {-6170, {-1, -1, 2, 0}, 56936}, + {-1584008, {0, -1, 1, 0}, 8759}, + {-6170, {0, -1, 1, 0}, 7117}, + {775, {1, 2, -1, 0}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 2, 3}, {1, 1, 1, 0}}, + { + {1, + { + {18582, {1, 1, -2, 0}, 56936}, + {1584248, {0, 1, -1, 0}, 8759}, + {6206, {0, 1, -1, 0}, 7117}, + {1, {1, 2, -1, 0}, 32768}, + }}, + {2, + { + {18582, {0, 1, -1, 0}, 56936}, + {3168495, {1, 0, -1, 0}, 4380}, + {12413, {1, 0, -1, 0}, 3559}, + {2, {1, 2, 1, 0}, 16384}, + }}, + {3, + { + {18582, {0, 1, -1, 0}, 56936}, + {1584248, {-1, 1, 0, 0}, 8759}, + {6206, {-1, 1, 0, 0}, 7117}, + {1, {-1, 2, 1, 0}, 32768}, + }}, + {4, + { + {18582, {0, -1, 1, 0}, 56936}, + {1584248, {1, -1, 0, 0}, 8759}, + {6206, {1, -1, 0, 0}, 7117}, + {1, {-1, 2, 1, 0}, 32768}, + }}, + {5, + { + {18582, {0, -1, 1, 0}, 56936}, + {3168495, {-1, 0, 1, 0}, 4380}, + {12413, {-1, 0, 1, 0}, 3559}, + {2, {1, 2, 1, 0}, 16384}, + }}, + {6, + { + {18582, {-1, -1, 2, 0}, 56936}, + {1584248, {0, -1, 1, 0}, 8759}, + {6206, {0, -1, 1, 0}, 7117}, + {1, {1, 2, -1, 0}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 0, 1}, {1, 1, 1, 0}}, + { + {1, + { + {-6170, {1, 1, -2, 0}, 56936}, + {-1584008, {0, 1, -1, 0}, 8759}, + {-6170, {0, 1, -1, 0}, 7117}, + {-773, {1, 2, -1, 0}, 32768}, + }}, + {2, + { + {6206, {0, 1, -1, 0}, 56936}, + {239, {1, 0, -1, 0}, 4380}, + {37, {1, 0, -1, 0}, 3559}, + {776, {1, 2, 1, 0}, 16384}, + }}, + {3, + { + {6206, {0, 1, -1, 0}, 56936}, + {1584248, {-1, 1, 0, 0}, 8759}, + {6206, {-1, 1, 0, 0}, 7117}, + {775, {-1, 2, 1, 0}, 32768}, + }}, + {4, + { + {6206, {0, -1, 1, 0}, 56936}, + {1584248, {1, -1, 0, 0}, 8759}, + {6206, {1, -1, 0, 0}, 7117}, + {-773, {-1, 2, 1, 0}, 32768}, + }}, + {5, + { + {6206, {0, -1, 1, 0}, 56936}, + {239, {-1, 0, 1, 0}, 4380}, + {37, {-1, 0, 1, 0}, 3559}, + {-772, {1, 2, 1, 0}, 16384}, + }}, + {6, + { + {-6170, {-1, -1, 2, 0}, 56936}, + {-1584008, {0, -1, 1, 0}, 8759}, + {-6170, {0, -1, 1, 0}, 7117}, + {775, {1, 2, -1, 0}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, 0, 1}, {1, 1, 1, 1}}, + { + {2, + { + {-49246, {-3, 14, -5, -6}, 4067}, + {6338188, {5, 0, -1, -4}, 626}, + {25010, {5, 0, -1, -4}, 508}, + {-3087, {4, 7, 2, 1}, 4681}, + }}, + {6, + { + {37, {-1, 1, 1, -1}, 28468}, + {6337709, {3, -1, 1, -3}, 876}, + {24936, {3, -1, 1, -3}, 712}, + {-772, {1, 1, 1, 1}, 16384}, + }}, + {14, + { + {37239, {-6, -1, 2, 5}, 9489}, + {3168495, {0, -1, 0, 1}, 4380}, + {12413, {0, -1, 0, 1}, 3559}, + {-2318, {3, 4, 1, -2}, 10923}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, -2, -3}, {1, 0, 1, 1}}, + { + {1, + { + {-18546, {1, 0, 0, -1}, 56936}, + {-1584008, {0, 0, 1, -1}, 8759}, + {-6170, {0, 0, 1, -1}, 7117}, + {1, {1, 0, 3, -2}, 32768}, + }}, + {4, + { + {-55637, {-2, 0, 3, -1}, 18979}, + {-4752025, {1, 0, 0, -1}, 2920}, + {-18509, {1, 0, 0, -1}, 2372}, + {3, {1, 0, 3, 2}, 10923}, + }}, + {5, + { + {-18546, {1, 0, 0, -1}, 56936}, + {-3168017, {-1, 0, 1, 0}, 4380}, + {-12339, {-1, 0, 1, 0}, 3559}, + {2, {-1, 0, 3, 2}, 16384}, + }}, + {8, + { + {-18546, {-1, 0, 0, 1}, 56936}, + {-3168017, {1, 0, -1, 0}, 4380}, + {-12339, {1, 0, -1, 0}, 3559}, + {2, {-1, 0, 3, 2}, 16384}, + }}, + {9, + { + {-55637, {2, 0, -3, 1}, 18979}, + {-4752025, {-1, 0, 0, 1}, 2920}, + {-18509, {-1, 0, 0, 1}, 2372}, + {3, {1, 0, 3, 2}, 10923}, + }}, + {12, + { + {-18546, {-1, 0, 0, 1}, 56936}, + {-1584008, {0, 0, -1, 1}, 8759}, + {-6170, {0, 0, -1, 1}, 7117}, + {1, {1, 0, 3, -2}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 0, 1}, {1, 1, 1, 1}}, + { + {4, + { + {49762, {-6, -5, 14, -3}, 4067}, + {6338188, {4, 1, 0, -5}, 626}, + {25010, {4, 1, 0, -5}, 508}, + {-2314, {1, 2, 7, 4}, 4681}, + }}, + {12, + { + {12413, {-1, -1, 1, 1}, 28468}, + {3168495, {1, -1, -1, 1}, 4380}, + {12413, {1, -1, -1, 1}, 3559}, + {-1545, {-1, 3, 3, -1}, 16384}, + }}, + {5, + { + {12413, {1, -1, 1, -1}, 28468}, + {479, {-1, 1, 1, -1}, 2190}, + {74, {-1, 1, 1, -1}, 1779}, + {-1543, {1, 3, 3, 1}, 8192}, + }}, + {13, + { + {124018, {3, -14, 5, 6}, 4067}, + {6338188, {-5, 0, 1, 4}, 626}, + {25010, {-5, 0, 1, 4}, 508}, + {-2314, {4, 7, 2, 1}, 4681}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, 0, 1}, {1, 0, 1, 1}}, + { + {1, + { + {6206, {1, 0, 0, -1}, 56936}, + {1584248, {0, 0, 1, -1}, 8759}, + {6206, {0, 0, 1, -1}, 7117}, + {775, {1, 0, 3, -2}, 32768}, + }}, + {4, + { + {6243, {-2, 0, 3, -1}, 18979}, + {1584487, {1, 0, 0, -1}, 2920}, + {6243, {1, 0, 0, -1}, 2372}, + {-771, {1, 0, 3, 2}, 10923}, + }}, + {5, + { + {6206, {1, 0, 0, -1}, 56936}, + {239, {-1, 0, 1, 0}, 4380}, + {37, {-1, 0, 1, 0}, 3559}, + {-772, {-1, 0, 3, 2}, 16384}, + }}, + {8, + { + {6206, {-1, 0, 0, 1}, 56936}, + {239, {1, 0, -1, 0}, 4380}, + {37, {1, 0, -1, 0}, 3559}, + {776, {-1, 0, 3, 2}, 16384}, + }}, + {9, + { + {6243, {2, 0, -3, 1}, 18979}, + {1584487, {-1, 0, 0, 1}, 2920}, + {6243, {-1, 0, 0, 1}, 2372}, + {777, {1, 0, 3, 2}, 10923}, + }}, + {12, + { + {6206, {-1, 0, 0, 1}, 56936}, + {1584248, {0, 0, -1, 1}, 8759}, + {6206, {0, 0, -1, 1}, 7117}, + {-773, {1, 0, 3, -2}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, 0, -1}, {1, 0, 1, 1}}, + { + {1, + { + {-6170, {1, 0, 0, -1}, 56936}, + {-1584008, {0, 0, 1, -1}, 8759}, + {-6170, {0, 0, 1, -1}, 7117}, + {-773, {1, 0, 3, -2}, 32768}, + }}, + {4, + { + {-6133, {-2, 0, 3, -1}, 18979}, + {-1583769, {1, 0, 0, -1}, 2920}, + {-6133, {1, 0, 0, -1}, 2372}, + {777, {1, 0, 3, 2}, 10923}, + }}, + {5, + { + {-6170, {1, 0, 0, -1}, 56936}, + {239, {-1, 0, 1, 0}, 4380}, + {37, {-1, 0, 1, 0}, 3559}, + {776, {-1, 0, 3, 2}, 16384}, + }}, + {8, + { + {-6170, {-1, 0, 0, 1}, 56936}, + {239, {1, 0, -1, 0}, 4380}, + {37, {1, 0, -1, 0}, 3559}, + {-772, {-1, 0, 3, 2}, 16384}, + }}, + {9, + { + {-6133, {2, 0, -3, 1}, 18979}, + {-1583769, {-1, 0, 0, 1}, 2920}, + {-6133, {-1, 0, 0, 1}, 2372}, + {-771, {1, 0, 3, 2}, 10923}, + }}, + {12, + { + {-6170, {-1, 0, 0, 1}, 56936}, + {-1584008, {0, 0, -1, 1}, 8759}, + {-6170, {0, 0, -1, 1}, 7117}, + {775, {1, 0, 3, -2}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 2, 1}, {1, 1, 1, 1}}, + { + {8, + { + {37239, {-5, -2, 1, 6}, 9489}, + {3168495, {1, 0, -1, 0}, 4380}, + {12413, {1, 0, -1, 0}, 3559}, + {-2318, {-2, 1, 4, 3}, 10923}, + }}, + {9, + { + {24789, {1, -1, -1, 1}, 28468}, + {6337709, {-3, 1, -1, 3}, 876}, + {24936, {-3, 1, -1, 3}, 712}, + {-772, {1, 1, 1, 1}, 16384}, + }}, + {11, + { + {223026, {6, 5, -14, 3}, 4067}, + {6338188, {-4, -1, 0, 5}, 626}, + {25010, {-4, -1, 0, 5}, 508}, + {-3087, {1, 2, 7, 4}, 4681}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + {0, + { + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + {0, {0, 0, 0, 0}, 0}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, -2, -1}, {1, 0, 1, 1}}, + { + {1, + { + {-6170, {1, 0, 0, -1}, 56936}, + {1584248, {0, 0, 1, -1}, 8759}, + {6206, {0, 0, 1, -1}, 7117}, + {1548, {1, 0, 3, -2}, 32768}, + }}, + {4, + { + {-43261, {-2, 0, 3, -1}, 18979}, + {-1583769, {1, 0, 0, -1}, 2920}, + {-6133, {1, 0, 0, -1}, 2372}, + {-1544, {1, 0, 3, 2}, 10923}, + }}, + {5, + { + {-6170, {1, 0, 0, -1}, 56936}, + {-3168017, {-1, 0, 1, 0}, 4380}, + {-12339, {-1, 0, 1, 0}, 3559}, + {-1545, {-1, 0, 3, 2}, 16384}, + }}, + {8, + { + {-6170, {-1, 0, 0, 1}, 56936}, + {-3168017, {1, 0, -1, 0}, 4380}, + {-12339, {1, 0, -1, 0}, 3559}, + {1549, {-1, 0, 3, 2}, 16384}, + }}, + {9, + { + {-43261, {2, 0, -3, 1}, 18979}, + {-1583769, {-1, 0, 0, 1}, 2920}, + {-6133, {-1, 0, 0, 1}, 2372}, + {1550, {1, 0, 3, 2}, 10923}, + }}, + {12, + { + {-6170, {-1, 0, 0, 1}, 56936}, + {1584248, {0, 0, -1, 1}, 8759}, + {6206, {0, 0, -1, 1}, 7117}, + {-1546, {1, 0, 3, -2}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 0, -1}, {1, 1, 0, 1}}, + { + {1, + { + {-6170, {1, 0, 0, -1}, 56936}, + {-3168017, {0, 1, 0, -1}, 4380}, + {-12339, {0, 1, 0, -1}, 3559}, + {-1545, {2, 3, 0, -1}, 16384}, + }}, + {2, + { + {6243, {-1, 3, 0, -2}, 18979}, + {-1583769, {1, 0, 0, -1}, 2920}, + {-6133, {1, 0, 0, -1}, 2372}, + {1550, {2, 3, 0, 1}, 10923}, + }}, + {3, + { + {-6170, {1, 0, 0, -1}, 56936}, + {1584248, {-1, 1, 0, 0}, 8759}, + {6206, {-1, 1, 0, 0}, 7117}, + {1548, {-2, 3, 0, 1}, 32768}, + }}, + {8, + { + {-6170, {-1, 0, 0, 1}, 56936}, + {1584248, {1, -1, 0, 0}, 8759}, + {6206, {1, -1, 0, 0}, 7117}, + {-1546, {-2, 3, 0, 1}, 32768}, + }}, + {9, + { + {6243, {1, -3, 0, 2}, 18979}, + {-1583769, {-1, 0, 0, 1}, 2920}, + {-6133, {-1, 0, 0, 1}, 2372}, + {-1544, {2, 3, 0, 1}, 10923}, + }}, + {10, + { + {-6170, {-1, 0, 0, 1}, 56936}, + {-3168017, {0, -1, 0, 1}, 4380}, + {-12339, {0, -1, 0, 1}, 3559}, + {1549, {2, 3, 0, -1}, 16384}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, -2, -3}, {1, 1, 1, 1}}, + { + {8, + { + {-111274, {-5, -2, 1, 6}, 9489}, + {-3168017, {1, 0, -1, 0}, 4380}, + {-12339, {1, 0, -1, 0}, 3559}, + {3, {-2, 1, 4, 3}, 10923}, + }}, + {12, + { + {-37091, {-1, -1, 1, 1}, 28468}, + {-3168017, {1, -1, -1, 1}, 4380}, + {-12339, {1, -1, -1, 1}, 3559}, + {2, {-1, 3, 3, -1}, 16384}, + }}, + {14, + { + {-111274, {-6, -1, 2, 5}, 9489}, + {-3168017, {0, -1, 0, 1}, 4380}, + {-12339, {0, -1, 0, 1}, 3559}, + {3, {3, 4, 1, -2}, 10923}, + }}, + {1, + { + {-111274, {6, 1, -2, -5}, 9489}, + {-3168017, {0, 1, 0, -1}, 4380}, + {-12339, {0, 1, 0, -1}, 3559}, + {3, {3, 4, 1, -2}, 10923}, + }}, + {3, + { + {-37091, {1, 1, -1, -1}, 28468}, + {-3168017, {-1, 1, 1, -1}, 4380}, + {-12339, {-1, 1, 1, -1}, 3559}, + {2, {-1, 3, 3, -1}, 16384}, + }}, + {7, + { + {-111274, {5, 2, -1, -6}, 9489}, + {-3168017, {-1, 0, 1, 0}, 4380}, + {-12339, {-1, 0, 1, 0}, 3559}, + {3, {-2, 1, 4, 3}, 10923}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 0, 1}, {1, 1, 0, 1}}, + { + {1, + { + {6206, {1, 0, 0, -1}, 56936}, + {239, {0, 1, 0, -1}, 4380}, + {37, {0, 1, 0, -1}, 3559}, + {-772, {2, 3, 0, -1}, 16384}, + }}, + {2, + { + {30995, {-1, 3, 0, -2}, 18979}, + {1584487, {1, 0, 0, -1}, 2920}, + {6243, {1, 0, 0, -1}, 2372}, + {777, {2, 3, 0, 1}, 10923}, + }}, + {3, + { + {6206, {1, 0, 0, -1}, 56936}, + {1584248, {-1, 1, 0, 0}, 8759}, + {6206, {-1, 1, 0, 0}, 7117}, + {775, {-2, 3, 0, 1}, 32768}, + }}, + {8, + { + {6206, {-1, 0, 0, 1}, 56936}, + {1584248, {1, -1, 0, 0}, 8759}, + {6206, {1, -1, 0, 0}, 7117}, + {-773, {-2, 3, 0, 1}, 32768}, + }}, + {9, + { + {30995, {1, -3, 0, 2}, 18979}, + {1584487, {-1, 0, 0, 1}, 2920}, + {6243, {-1, 0, 0, 1}, 2372}, + {-771, {2, 3, 0, 1}, 10923}, + }}, + {10, + { + {6206, {-1, 0, 0, 1}, 56936}, + {239, {0, -1, 0, 1}, 4380}, + {37, {0, -1, 0, 1}, 3559}, + {776, {2, 3, 0, -1}, 16384}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, 1, 2, 3}, {1, 0, 1, 1}}, + { + {1, + { + {18582, {1, 0, 0, -1}, 56936}, + {1584248, {0, 0, 1, -1}, 8759}, + {6206, {0, 0, 1, -1}, 7117}, + {1, {1, 0, 3, -2}, 32768}, + }}, + {4, + { + {55747, {-2, 0, 3, -1}, 18979}, + {4752743, {1, 0, 0, -1}, 2920}, + {18619, {1, 0, 0, -1}, 2372}, + {3, {1, 0, 3, 2}, 10923}, + }}, + {5, + { + {18582, {1, 0, 0, -1}, 56936}, + {3168495, {-1, 0, 1, 0}, 4380}, + {12413, {-1, 0, 1, 0}, 3559}, + {2, {-1, 0, 3, 2}, 16384}, + }}, + {8, + { + {18582, {-1, 0, 0, 1}, 56936}, + {3168495, {1, 0, -1, 0}, 4380}, + {12413, {1, 0, -1, 0}, 3559}, + {2, {-1, 0, 3, 2}, 16384}, + }}, + {9, + { + {55747, {2, 0, -3, 1}, 18979}, + {4752743, {-1, 0, 0, 1}, 2920}, + {18619, {-1, 0, 0, 1}, 2372}, + {3, {1, 0, 3, 2}, 10923}, + }}, + {12, + { + {18582, {-1, 0, 0, 1}, 56936}, + {1584248, {0, 0, -1, 1}, 8759}, + {6206, {0, 0, -1, 1}, 7117}, + {1, {1, 0, 3, -2}, 32768}, + }}, + }}); + LAYOUT_VALID_TO_LATCOMB_CONSTS_ENCODER.push_back({{{0, -1, 0, 1}, {1, 1, 0, 1}}, + { + {1, + { + {6206, {1, 0, 0, -1}, 56936}, + {3168495, {0, 1, 0, -1}, 4380}, + {12413, {0, 1, 0, -1}, 3559}, + {1549, {2, 3, 0, -1}, 16384}, + }}, + {2, + { + {-6133, {-1, 3, 0, -2}, 18979}, + {1584487, {1, 0, 0, -1}, 2920}, + {6243, {1, 0, 0, -1}, 2372}, + {-1544, {2, 3, 0, 1}, 10923}, + }}, + {3, + { + {6206, {1, 0, 0, -1}, 56936}, + {-1584008, {-1, 1, 0, 0}, 8759}, + {-6170, {-1, 1, 0, 0}, 7117}, + {-1546, {-2, 3, 0, 1}, 32768}, + }}, + {8, + { + {6206, {-1, 0, 0, 1}, 56936}, + {-1584008, {1, -1, 0, 0}, 8759}, + {-6170, {1, -1, 0, 0}, 7117}, + {1548, {-2, 3, 0, 1}, 32768}, + }}, + {9, + { + {-6133, {1, -3, 0, 2}, 18979}, + {1584487, {-1, 0, 0, 1}, 2920}, + {6243, {-1, 0, 0, 1}, 2372}, + {1550, {2, 3, 0, 1}, 10923}, + }}, + {10, + { + {6206, {-1, 0, 0, 1}, 56936}, + {3168495, {0, -1, 0, 1}, 4380}, + {12413, {0, -1, 0, 1}, 3559}, + {-1545, {2, 3, 0, -1}, 16384}, + }}, + }}); +} diff --git a/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerInChamber.cc b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerInChamber.cc index 42a0aadd2144e..a634baabd7632 100644 --- a/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerInChamber.cc +++ b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerInChamber.cc @@ -14,7 +14,7 @@ MuonPathAnalyzerInChamber::MuonPathAnalyzerInChamber(const ParameterSet &pset, e chi2Th_(pset.getUntrackedParameter("chi2Th")), shift_filename_(pset.getParameter("shift_filename")), bxTolerance_(30), - minQuality_(LOWQGHOST), + minQuality_(LOWQ), chiSquareThreshold_(50), minHits4Fit_(pset.getUntrackedParameter("minHits4Fit")) { // Obtention of parameters diff --git a/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerPerSL.cc b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerPerSL.cc deleted file mode 100644 index 3fa3436fe06b4..0000000000000 --- a/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerPerSL.cc +++ /dev/null @@ -1,1076 +0,0 @@ -#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerPerSL.h" -#include -#include - -using namespace edm; -using namespace std; -using namespace cmsdt; -// ============================================================================ -// Constructors and destructor -// ============================================================================ -MuonPathAnalyzerPerSL::MuonPathAnalyzerPerSL(const ParameterSet &pset, edm::ConsumesCollector &iC) - : MuonPathAnalyzer(pset, iC), - bxTolerance_(30), - minQuality_(LOWQGHOST), - chiSquareThreshold_(50), - debug_(pset.getUntrackedParameter("debug")), - chi2Th_(pset.getUntrackedParameter("chi2Th")), - tanPhiTh_(pset.getUntrackedParameter("tanPhiTh")), - use_LSB_(pset.getUntrackedParameter("use_LSB")), - tanPsi_precision_(pset.getUntrackedParameter("tanPsi_precision")), - x_precision_(pset.getUntrackedParameter("x_precision")) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "MuonPathAnalyzer: constructor"; - - setChiSquareThreshold(chi2Th_ * 100.); - - //shift - int rawId; - shift_filename_ = pset.getParameter("shift_filename"); - std::ifstream ifin3(shift_filename_.fullPath()); - double shift; - if (ifin3.fail()) { - throw cms::Exception("Missing Input File") - << "MuonPathAnalyzerPerSL::MuonPathAnalyzerPerSL() - Cannot find " << shift_filename_.fullPath(); - } - while (ifin3.good()) { - ifin3 >> rawId >> shift; - shiftinfo_[rawId] = shift; - } - - chosen_sl_ = pset.getUntrackedParameter("trigger_with_sl"); - - if (chosen_sl_ != 1 && chosen_sl_ != 3 && chosen_sl_ != 4) { - LogDebug("MuonPathAnalyzerPerSL") << "chosen sl must be 1,3 or 4(both superlayers)"; - assert(chosen_sl_ != 1 && chosen_sl_ != 3 && chosen_sl_ != 4); //4 means run using the two superlayers - } - - dtGeomH = iC.esConsumes(); -} - -MuonPathAnalyzerPerSL::~MuonPathAnalyzerPerSL() { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "MuonPathAnalyzer: destructor"; -} - -// ============================================================================ -// Main methods (initialise, run, finish) -// ============================================================================ -void MuonPathAnalyzerPerSL::initialise(const edm::EventSetup &iEventSetup) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "MuonPathAnalyzerPerSL::initialiase"; - - const MuonGeometryRecord &geom = iEventSetup.get(); - dtGeo_ = &geom.get(dtGeomH); -} - -void MuonPathAnalyzerPerSL::run(edm::Event &iEvent, - const edm::EventSetup &iEventSetup, - MuonPathPtrs &muonpaths, - std::vector &metaPrimitives) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "MuonPathAnalyzerPerSL: run"; - - // fit per SL (need to allow for multiple outputs for a single mpath) - for (auto &muonpath : muonpaths) { - analyze(muonpath, metaPrimitives); - } -} - -void MuonPathAnalyzerPerSL::finish() { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "MuonPathAnalyzer: finish"; -}; - -constexpr int MuonPathAnalyzerPerSL::LAYER_ARRANGEMENTS_[NUM_LAYERS][NUM_CELL_COMB] = { - {0, 1, 2}, - {1, 2, 3}, // Consecutive groups - {0, 1, 3}, - {0, 2, 3} // Non-consecutive groups -}; - -//------------------------------------------------------------------ -//--- Métodos privados -//------------------------------------------------------------------ - -void MuonPathAnalyzerPerSL::analyze(MuonPathPtr &inMPath, std::vector &metaPrimitives) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t starts"; - - // LOCATE MPATH - int selected_Id = 0; - if (inMPath->primitive(0)->tdcTimeStamp() != -1) - selected_Id = inMPath->primitive(0)->cameraId(); - else if (inMPath->primitive(1)->tdcTimeStamp() != -1) - selected_Id = inMPath->primitive(1)->cameraId(); - else if (inMPath->primitive(2)->tdcTimeStamp() != -1) - selected_Id = inMPath->primitive(2)->cameraId(); - else if (inMPath->primitive(3)->tdcTimeStamp() != -1) - selected_Id = inMPath->primitive(3)->cameraId(); - - DTLayerId thisLId(selected_Id); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "Building up MuonPathSLId from rawId in the Primitive"; - DTSuperLayerId MuonPathSLId(thisLId.wheel(), thisLId.station(), thisLId.sector(), thisLId.superLayer()); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "The MuonPathSLId is" << MuonPathSLId; - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:analyze \t\t\t\t In analyze function checking if inMPath->isAnalyzable() " << inMPath->isAnalyzable(); - - if (chosen_sl_ < 4 && thisLId.superLayer() != chosen_sl_) - return; // avoid running when mpath not in chosen SL (for 1SL fitting) - - auto mPath = std::make_shared(inMPath); - - if (mPath->isAnalyzable()) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t yes it is analyzable " << mPath->isAnalyzable(); - setCellLayout(mPath->cellLayout()); - evaluatePathQuality(mPath); - } else { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t no it is NOT analyzable " << mPath->isAnalyzable(); - return; - } - - int wi[8], tdc[8], lat[8]; - DTPrimitivePtr Prim0(mPath->primitive(0)); - wi[0] = Prim0->channelId(); - tdc[0] = Prim0->tdcTimeStamp(); - DTPrimitivePtr Prim1(mPath->primitive(1)); - wi[1] = Prim1->channelId(); - tdc[1] = Prim1->tdcTimeStamp(); - DTPrimitivePtr Prim2(mPath->primitive(2)); - wi[2] = Prim2->channelId(); - tdc[2] = Prim2->tdcTimeStamp(); - DTPrimitivePtr Prim3(mPath->primitive(3)); - wi[3] = Prim3->channelId(); - tdc[3] = Prim3->tdcTimeStamp(); - for (int i = 4; i < 8; i++) { - wi[i] = -1; - tdc[i] = -1; - lat[i] = -1; - } - - DTWireId wireId(MuonPathSLId, 2, 1); - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t checking if it passes the min quality cut " - << mPath->quality() << ">" << minQuality_; - if (mPath->quality() >= minQuality_) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t min quality achievedCalidad: " << mPath->quality(); - for (int i = 0; i <= 3; i++) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:analyze \t\t\t\t Capa: " << mPath->primitive(i)->layerId() - << " Canal: " << mPath->primitive(i)->channelId() << " TDCTime: " << mPath->primitive(i)->tdcTimeStamp(); - } - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t Starting lateralities loop, totalNumValLateralities: " - << totalNumValLateralities_; - - double best_chi2 = 99999.; - double chi2_jm_tanPhi = 999; - double chi2_jm_x = -1; - double chi2_jm_t0 = -1; - double chi2_phi = -1; - double chi2_phiB = -1; - double chi2_chi2 = -1; - int chi2_quality = -1; - int bestLat[8]; - for (int i = 0; i < 8; i++) { - bestLat[i] = -1; - } - - for (int i = 0; i < totalNumValLateralities_; i++) { //here - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t laterality #- " << i; - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " checking quality:"; - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " checking mPath Quality=" << mPath->quality(); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " latQuality_[i].val=" << latQuality_[i].valid; - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " before if:"; - - if (latQuality_[i].valid and - (((mPath->quality() == HIGHQ or mPath->quality() == HIGHQGHOST) and latQuality_[i].quality == HIGHQ) or - ((mPath->quality() == LOWQ or mPath->quality() == LOWQGHOST) and latQuality_[i].quality == LOWQ))) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " inside if"; - mPath->setBxTimeValue(latQuality_[i].bxValue); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " settingLateralCombination"; - mPath->setLateralComb(lateralities_[i]); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " done settingLateralCombination"; - - // Clonamos el objeto analizado. - auto mpAux = std::make_shared(mPath); - lat[0] = mpAux->lateralComb()[0]; - lat[1] = mpAux->lateralComb()[1]; - lat[2] = mpAux->lateralComb()[2]; - lat[3] = mpAux->lateralComb()[3]; - - int wiOk[NUM_LAYERS], tdcOk[NUM_LAYERS], latOk[NUM_LAYERS]; - for (int lay = 0; lay < 4; lay++) { - if (latQuality_[i].invalidateHitIdx == lay) { - wiOk[lay] = -1; - tdcOk[lay] = -1; - latOk[lay] = -1; - } else { - wiOk[lay] = wi[lay]; - tdcOk[lay] = tdc[lay]; - latOk[lay] = lat[lay]; - } - } - - int idxHitNotValid = latQuality_[i].invalidateHitIdx; - if (idxHitNotValid >= 0) { - auto dtpAux = std::make_shared(); - mpAux->setPrimitive(dtpAux, idxHitNotValid); - } - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t calculating parameters "; - calculatePathParameters(mpAux); - /* - * After calculating the parameters, and if it is a 4-hit fit, - * if the resultant chi2 is higher than the programmed threshold, - * the mpath is eliminated and we go to the next element - */ - if ((mpAux->quality() == HIGHQ or mpAux->quality() == HIGHQGHOST) && - mpAux->chiSquare() > chiSquareThreshold_) { //check this if!!! - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:analyze \t\t\t\t\t HIGHQ or HIGHQGHOST but min chi2 or Q test not satisfied "; - } else { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t inside else, returning values: "; - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t BX Time = " << mpAux->bxTimeValue(); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t BX Id = " << mpAux->bxNumId(); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t XCoor = " << mpAux->horizPos(); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t tan(Phi)= " << mpAux->tanPhi(); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t chi2= " << mpAux->chiSquare(); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t lateralities = " - << " " << mpAux->lateralComb()[0] << " " << mpAux->lateralComb()[1] << " " - << mpAux->lateralComb()[2] << " " << mpAux->lateralComb()[3]; - - DTChamberId ChId(MuonPathSLId.wheel(), MuonPathSLId.station(), MuonPathSLId.sector()); - - double jm_tanPhi = -1. * mpAux->tanPhi(); //testing with this line - if (use_LSB_) - jm_tanPhi = floor(jm_tanPhi / tanPsi_precision_) * tanPsi_precision_; - double jm_x = - (((double)mpAux->horizPos()) / 10.) + x_precision_ * (round(shiftinfo_[wireId.rawId()] / x_precision_)); - if (use_LSB_) - jm_x = ((double)round(((double)jm_x) / x_precision_)) * x_precision_; - //changing to chamber frame or reference: - double jm_t0 = mpAux->bxTimeValue(); - int quality = mpAux->quality(); - - //computing phi and phiB - double z = 0; - double z1 = Z_POS_SL; - double z3 = -1. * z1; - if (ChId.station() == 3 or ChId.station() == 4) { - z1 = z1 + Z_SHIFT_MB4; - z3 = z3 + Z_SHIFT_MB4; - } else if (MuonPathSLId.superLayer() == 1) - z = z1; - else if (MuonPathSLId.superLayer() == 3) - z = z3; - - GlobalPoint jm_x_cmssw_global = dtGeo_->chamber(ChId)->toGlobal(LocalPoint(jm_x, 0., z)); - int thisec = MuonPathSLId.sector(); - if (thisec == 13) - thisec = 4; - if (thisec == 14) - thisec = 10; - double phi = jm_x_cmssw_global.phi() - PHI_CONV * (thisec - 1); - double psi = atan(jm_tanPhi); - double phiB = hasPosRF(MuonPathSLId.wheel(), MuonPathSLId.sector()) ? psi - phi : -psi - phi; - double chi2 = mpAux->chiSquare() * 0.01; //in cmssw we need cm, 1 cm^2 = 100 mm^2 - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:analyze \t\t\t\t\t\t\t\t pushing back metaPrimitive at x=" << jm_x << " tanPhi:" << jm_tanPhi - << " t0:" << jm_t0; - - if (mpAux->quality() == HIGHQ or - mpAux->quality() == HIGHQGHOST) { //keep only the values with the best chi2 among lateralities - if ((chi2 < best_chi2) && (std::abs(jm_tanPhi) <= tanPhiTh_)) { - chi2_jm_tanPhi = jm_tanPhi; - chi2_jm_x = (mpAux->horizPos() / 10.) + shiftinfo_[wireId.rawId()]; - chi2_jm_t0 = mpAux->bxTimeValue(); - chi2_phi = phi; - chi2_phiB = phiB; - chi2_chi2 = chi2; - best_chi2 = chi2; - chi2_quality = mpAux->quality(); - for (int i = 0; i < 4; i++) { - bestLat[i] = lat[i]; - } - } - } else if (std::abs(jm_tanPhi) <= - tanPhiTh_) { //write the metaprimitive in case no HIGHQ or HIGHQGHOST and tanPhi range - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:analyze \t\t\t\t\t\t\t\t pushing back metaprimitive no HIGHQ or HIGHQGHOST"; - metaPrimitives.emplace_back(metaPrimitive({MuonPathSLId.rawId(), - jm_t0, - jm_x, - jm_tanPhi, - phi, - phiB, - chi2, - quality, - wiOk[0], - tdcOk[0], - latOk[0], - wiOk[1], - tdcOk[1], - latOk[1], - wiOk[2], - tdcOk[2], - latOk[2], - wiOk[3], - tdcOk[3], - latOk[3], - wi[4], - tdc[4], - lat[4], - wi[5], - tdc[5], - lat[5], - wi[6], - tdc[6], - lat[6], - wi[7], - tdc[7], - lat[7], - -1})); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:analyze \t\t\t\t\t\t\t\t done pushing back metaprimitive no HIGHQ or HIGHQGHOST"; - } - } - } else { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:analyze \t\t\t\t\t\t\t\t latQuality_[i].valid and (((mPath->quality()==HIGHQ or " - "mPath->quality()==HIGHQGHOST) and latQuality_[i].quality==HIGHQ) or ((mPath->quality() " - "== LOWQ or mPath->quality()==LOWQGHOST) and latQuality_[i].quality==LOWQ)) not passed"; - } - } - if (chi2_jm_tanPhi != 999 and std::abs(chi2_jm_tanPhi) < tanPhiTh_) { // - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t\t\t\t pushing back best chi2 metaPrimitive"; - metaPrimitives.emplace_back(metaPrimitive({MuonPathSLId.rawId(), - chi2_jm_t0, - chi2_jm_x, - chi2_jm_tanPhi, - chi2_phi, - chi2_phiB, - chi2_chi2, - chi2_quality, - wi[0], - tdc[0], - bestLat[0], - wi[1], - tdc[1], - bestLat[1], - wi[2], - tdc[2], - bestLat[2], - wi[3], - tdc[3], - bestLat[3], - wi[4], - tdc[4], - bestLat[4], - wi[5], - tdc[5], - bestLat[5], - wi[6], - tdc[6], - bestLat[6], - wi[7], - tdc[7], - bestLat[7], - -1})); - } - } - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t finishes"; -} - -void MuonPathAnalyzerPerSL::setCellLayout(const int layout[NUM_LAYERS]) { - memcpy(cellLayout_, layout, 4 * sizeof(int)); - - buildLateralities(); -} - -/** - * For a given 4-cell combination (one per layer), all the possible lateralities - * combinations that are compatible with a straight line are generated. - */ -void MuonPathAnalyzerPerSL::buildLateralities(void) { - LATERAL_CASES(*validCase)[NUM_LAYERS], sideComb[NUM_LAYERS]; - - totalNumValLateralities_ = 0; - /* We generate all the possible lateralities combination for a given group - of cells */ - for (int lowLay = LEFT; lowLay <= RIGHT; lowLay++) - for (int midLowLay = LEFT; midLowLay <= RIGHT; midLowLay++) - for (int midHigLay = LEFT; midHigLay <= RIGHT; midHigLay++) - for (int higLay = LEFT; higLay <= RIGHT; higLay++) { - sideComb[0] = static_cast(lowLay); - sideComb[1] = static_cast(midLowLay); - sideComb[2] = static_cast(midHigLay); - sideComb[3] = static_cast(higLay); - - /* If a laterality combination is valid, we store it */ - if (isStraightPath(sideComb)) { - validCase = lateralities_ + totalNumValLateralities_; - memcpy(validCase, sideComb, 4 * sizeof(LATERAL_CASES)); - - latQuality_[totalNumValLateralities_].valid = false; - latQuality_[totalNumValLateralities_].bxValue = 0; - latQuality_[totalNumValLateralities_].quality = NOPATH; - latQuality_[totalNumValLateralities_].invalidateHitIdx = -1; - - totalNumValLateralities_++; - } - } -} - -/** - * This method checks whether a given combination conform a straight line or not - */ -bool MuonPathAnalyzerPerSL::isStraightPath(LATERAL_CASES sideComb[NUM_LAYERS]) { - return true; //trying with all lateralities to be confirmed - - int i, ajustedLayout[NUM_LAYERS], pairDiff[3], desfase[3]; - - for (i = 0; i <= 3; i++) - ajustedLayout[i] = cellLayout_[i] + sideComb[i]; - for (i = 0; i <= 2; i++) - pairDiff[i] = ajustedLayout[i + 1] - ajustedLayout[i]; - for (i = 0; i <= 1; i++) - desfase[i] = abs(pairDiff[i + 1] - pairDiff[i]); - desfase[2] = abs(pairDiff[2] - pairDiff[0]); - bool resultado = (desfase[0] > 1 or desfase[1] > 1 or desfase[2] > 1); - - return (!resultado); -} -void MuonPathAnalyzerPerSL::evaluatePathQuality(MuonPathPtr &mPath) { - int totalHighQ = 0, totalLowQ = 0; - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:evaluatePathQuality \t\t\t\t\t En evaluatePathQuality Evaluando PathQ. Celda base: " - << mPath->baseChannelId(); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluatePathQuality \t\t\t\t\t Total lateralidades: " - << totalNumValLateralities_; - - mPath->setQuality(NOPATH); - - for (int latIdx = 0; latIdx < totalNumValLateralities_; latIdx++) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluatePathQuality \t\t\t\t\t Analizando combinacion de lateralidad: " - << lateralities_[latIdx][0] << " " << lateralities_[latIdx][1] << " " - << lateralities_[latIdx][2] << " " << lateralities_[latIdx][3]; - - evaluateLateralQuality(latIdx, mPath, &(latQuality_[latIdx])); - - if (latQuality_[latIdx].quality == HIGHQ) { - totalHighQ++; - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluatePathQuality \t\t\t\t\t\t Lateralidad HIGHQ"; - } - if (latQuality_[latIdx].quality == LOWQ) { - totalLowQ++; - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluatePathQuality \t\t\t\t\t\t Lateralidad LOWQ"; - } - } - /* - * Quality stablishment - */ - if (totalHighQ == 1) { - mPath->setQuality(HIGHQ); - } else if (totalHighQ > 1) { - mPath->setQuality(HIGHQGHOST); - } else if (totalLowQ == 1) { - mPath->setQuality(LOWQ); - } else if (totalLowQ > 1) { - mPath->setQuality(LOWQGHOST); - } -} - -void MuonPathAnalyzerPerSL::evaluateLateralQuality(int latIdx, MuonPathPtr &mPath, LATQ_TYPE *latQuality) { - int layerGroup[3]; - LATERAL_CASES sideComb[3]; - PARTIAL_LATQ_TYPE latQResult[NUM_LAYERS] = {{false, 0}, {false, 0}, {false, 0}, {false, 0}}; - - // Default values. - latQuality->valid = false; - latQuality->bxValue = 0; - latQuality->quality = NOPATH; - latQuality->invalidateHitIdx = -1; - - /* If, for a given laterality combination, the two consecutive 3-layer combinations - were a valid track, we will have found a right high-quality track, hence - it will be unnecessary to check the remaining 2 combinations. - In order to mimic the FPGA behaviour, we build a code that analyzes the 4 combinations - with an additional logic to discriminate the final quality of the track - */ - for (int i = 0; i <= 3; i++) { - memcpy(layerGroup, LAYER_ARRANGEMENTS_[i], 3 * sizeof(int)); - - // Pick the laterality combination for each cell - for (int j = 0; j < 3; j++) - sideComb[j] = lateralities_[latIdx][layerGroup[j]]; - - validate(sideComb, layerGroup, mPath, &(latQResult[i])); - } - /* - Impose the condition for a complete laterality combination, that all combinations - should give the same BX vale to give a consistent track. - */ - if (!sameBXValue(latQResult)) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:evaluateLateralQuality \t\t\t\t\t Lateralidad DESCARTADA. Tolerancia de BX excedida"; - return; - } - - // two complementary valid tracks => full muon track. - if ((latQResult[0].latQValid && latQResult[1].latQValid) or (latQResult[0].latQValid && latQResult[2].latQValid) or - (latQResult[0].latQValid && latQResult[3].latQValid) or (latQResult[1].latQValid && latQResult[2].latQValid) or - (latQResult[1].latQValid && latQResult[3].latQValid) or (latQResult[2].latQValid && latQResult[3].latQValid)) { - latQuality->valid = true; - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t\t Valid BXs"; - long int sumBX = 0, numValid = 0; - for (int i = 0; i <= 3; i++) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t\t " - << "[" << latQResult[i].bxValue << "," << latQResult[i].latQValid << "]"; - if (latQResult[i].latQValid) { - sumBX += latQResult[i].bxValue; - numValid++; - } - } - - // mean time of all lateralities. - if (numValid == 1) - latQuality->bxValue = sumBX; - else if (numValid == 2) - latQuality->bxValue = (sumBX * (MEANTIME_2LAT)) / std::pow(2, 15); - else if (numValid == 3) - latQuality->bxValue = (sumBX * (MEANTIME_3LAT)) / std::pow(2, 15); - else if (numValid == 4) - latQuality->bxValue = (sumBX * (MEANTIME_4LAT)) / std::pow(2, 15); - - latQuality->quality = HIGHQ; - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluateLateralQuality \t\t\t\t\t Lateralidad ACEPTADA. HIGHQ."; - } else { - if (latQResult[0].latQValid or latQResult[1].latQValid or latQResult[2].latQValid or latQResult[3].latQValid) { - latQuality->valid = true; - latQuality->quality = LOWQ; - for (int i = 0; i < 4; i++) - if (latQResult[i].latQValid) { - latQuality->bxValue = latQResult[i].bxValue; - latQuality->invalidateHitIdx = omittedHit(i); - break; - } - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluateLateralQuality \t\t\t\t\t Lateralidad ACEPTADA. LOWQ."; - } else { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluateLateralQuality \t\t\t\t\t Lateralidad DESCARTADA. NOPATH."; - } - } -} - -/** - * Validate, for a layer combination (3), cells and lateralities, if the temporal values - * fullfill the mean-timer criteria. - */ -void MuonPathAnalyzerPerSL::validate(LATERAL_CASES sideComb[3], - int layerIndex[3], - MuonPathPtr &mPath, - PARTIAL_LATQ_TYPE *latq) { - // Valor por defecto. - latq->bxValue = 0; - latq->latQValid = false; - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t In validate, checking muon path for layers: " - << layerIndex[0] << "/" << layerIndex[1] << "/" << layerIndex[2]; - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t Partial lateralities: " << sideComb[0] << "/" - << sideComb[1] << "/" << sideComb[2]; - - int validCells = 0; - for (int j = 0; j < 3; j++) - if (mPath->primitive(layerIndex[j])->isValidTime()) - validCells++; - - if (validCells != 3) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t There is no valid cells."; - return; - } - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t TDC values: " - << mPath->primitive(layerIndex[0])->tdcTimeStamp() << "/" - << mPath->primitive(layerIndex[1])->tdcTimeStamp() << "/" - << mPath->primitive(layerIndex[2])->tdcTimeStamp() << "."; - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t Valid TIMES: " - << mPath->primitive(layerIndex[0])->isValidTime() << "/" - << mPath->primitive(layerIndex[1])->isValidTime() << "/" - << mPath->primitive(layerIndex[2])->isValidTime() << "."; - - /* Vertical distances */ - int dVertMI = layerIndex[1] - layerIndex[0]; - int dVertSM = layerIndex[2] - layerIndex[1]; - - /* Horizontal distances between lower/middle and middle/upper cells */ - int dHorzMI = cellLayout_[layerIndex[1]] - cellLayout_[layerIndex[0]]; - int dHorzSM = cellLayout_[layerIndex[2]] - cellLayout_[layerIndex[1]]; - - /* Pair index of layers that we are using - SM => Upper + Middle - MI => Middle + Lower - We use pointers to simplify the code */ - int *layPairSM = &layerIndex[1]; - int *layPairMI = &layerIndex[0]; - - /* Pair combination of cells to compose the equation. */ - LATERAL_CASES smSides[2], miSides[2]; - - /* Considering the index 0 of "sideComb" the laterality of the lower cells is stored, - we extract the laterality combiantion for SM and MI pairs */ - - memcpy(smSides, &sideComb[1], 2 * sizeof(LATERAL_CASES)); - - memcpy(miSides, &sideComb[0], 2 * sizeof(LATERAL_CASES)); - - long int bxValue = 0; - int coefsAB[2] = {0, 0}, coefsCD[2] = {0, 0}; - /* It's neccesary to be careful with that pointer's indirection. We need to - retrieve the lateral coeficientes (+-1) from the lower/middle and - middle/upper cell's lateral combinations. They are needed to evaluate the - existance of a possible BX value, following it's calculation equation */ - lateralCoeficients(miSides, coefsAB); - lateralCoeficients(smSides, coefsCD); - - /* Each of the summs of the 'coefsCD' & 'coefsAB' give always as results 0, +-2 - */ - - int denominator = dVertMI * (coefsCD[1] + coefsCD[0]) - dVertSM * (coefsAB[1] + coefsAB[0]); - - if (denominator == 0) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t Imposible to calculate BX."; - return; - } - - long int sumA = (long int)floor(MAXDRIFT * (dVertMI * dHorzSM - dVertSM * dHorzMI)); - long int numerator = - (sumA + dVertMI * eqMainBXTerm(smSides, layPairSM, mPath) - dVertSM * eqMainBXTerm(miSides, layPairMI, mPath)); - - // These magic numbers are for doing divisions in the FW. - // These divisions are done with a precision of 18bits. - if (denominator == -1 * DENOM_TYPE1) - bxValue = (numerator * (-1 * DIVISION_HELPER1)) / std::pow(2, NBITS); - else if (denominator == -1 * DENOM_TYPE2) - bxValue = (numerator * (-1 * DIVISION_HELPER2)) / std::pow(2, NBITS); - else if (denominator == -1 * DENOM_TYPE3) - bxValue = (numerator * (-1 * DIVISION_HELPER3)) / std::pow(2, NBITS); - else if (denominator == DENOM_TYPE3) - bxValue = (numerator * (DIVISION_HELPER3)) / std::pow(2, NBITS); - else if (denominator == DENOM_TYPE2) - bxValue = (numerator * (DIVISION_HELPER2)) / std::pow(2, NBITS); - else if (denominator == DENOM_TYPE1) - bxValue = (numerator * (DIVISION_HELPER1)) / std::pow(2, NBITS); - else - LogDebug("MuonPathAnalyzerPerSL") << "Different!"; - if (bxValue < 0) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t No-valid combination. Negative BX."; - return; - } - - for (int i = 0; i < 3; i++) - if (mPath->primitive(layerIndex[i])->isValidTime()) { - int diffTime = mPath->primitive(layerIndex[i])->tdcTimeStampNoOffset() - bxValue; - - if (diffTime <= 0 or diffTime > round(MAXDRIFT)) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:validate \t\t\t\t\t\t\t Invalid BX value. at least one crazt TDC time"; - return; - } - } - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t BX: " << bxValue; - - /* If you reach here, the BX and partial laterality are considered are valid - */ - latq->bxValue = bxValue; - latq->latQValid = true; -} -int MuonPathAnalyzerPerSL::eqMainBXTerm(LATERAL_CASES sideComb[2], int layerIdx[2], MuonPathPtr &mPath) { - int eqTerm = 0, coefs[2]; - - lateralCoeficients(sideComb, coefs); - - eqTerm = coefs[0] * mPath->primitive(layerIdx[0])->tdcTimeStampNoOffset() + - coefs[1] * mPath->primitive(layerIdx[1])->tdcTimeStampNoOffset(); - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:eqMainBXTerm \t\t\t\t\t In eqMainBXTerm EQTerm(BX): " << eqTerm; - - return (eqTerm); -} -int MuonPathAnalyzerPerSL::eqMainTerm(LATERAL_CASES sideComb[2], int layerIdx[2], MuonPathPtr &mPath, int bxValue) { - int eqTerm = 0, coefs[2]; - - lateralCoeficients(sideComb, coefs); - - if (!use_LSB_) - eqTerm = coefs[0] * (mPath->primitive(layerIdx[0])->tdcTimeStampNoOffset() - bxValue) + - coefs[1] * (mPath->primitive(layerIdx[1])->tdcTimeStampNoOffset() - bxValue); - else - eqTerm = coefs[0] * floor((DRIFT_SPEED / (10 * x_precision_)) * - (mPath->primitive(layerIdx[0])->tdcTimeStampNoOffset() - bxValue)) + - coefs[1] * floor((DRIFT_SPEED / (10 * x_precision_)) * - (mPath->primitive(layerIdx[1])->tdcTimeStampNoOffset() - bxValue)); - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:\t\t\t\t\t EQTerm(Main): " << eqTerm; - - return (eqTerm); -} - -void MuonPathAnalyzerPerSL::lateralCoeficients(LATERAL_CASES sideComb[2], int *coefs) { - if ((sideComb[0] == LEFT) && (sideComb[1] == LEFT)) { - *(coefs) = +1; - *(coefs + 1) = -1; - } else if ((sideComb[0] == LEFT) && (sideComb[1] == RIGHT)) { - *(coefs) = +1; - *(coefs + 1) = +1; - } else if ((sideComb[0] == RIGHT) && (sideComb[1] == LEFT)) { - *(coefs) = -1; - *(coefs + 1) = -1; - } else if ((sideComb[0] == RIGHT) && (sideComb[1] == RIGHT)) { - *(coefs) = -1; - *(coefs + 1) = +1; - } -} - -/** - * Determines if all valid partial lateral combinations share the same value - * of 'bxValue'. - */ -bool MuonPathAnalyzerPerSL::sameBXValue(PARTIAL_LATQ_TYPE *latq) { - bool result = true; - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue bxTolerance_: " << bxTolerance_; - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue \t\t\t\t\t\t d01:" << abs(latq[0].bxValue - latq[1].bxValue); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue \t\t\t\t\t\t d02:" << abs(latq[0].bxValue - latq[2].bxValue); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue \t\t\t\t\t\t d03:" << abs(latq[0].bxValue - latq[3].bxValue); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue \t\t\t\t\t\t d12:" << abs(latq[1].bxValue - latq[2].bxValue); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue \t\t\t\t\t\t d13:" << abs(latq[1].bxValue - latq[3].bxValue); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue \t\t\t\t\t\t d23:" << abs(latq[2].bxValue - latq[3].bxValue); - - bool d01, d02, d03, d12, d13, d23; - d01 = (abs(latq[0].bxValue - latq[1].bxValue) <= bxTolerance_) ? true : false; - d02 = (abs(latq[0].bxValue - latq[2].bxValue) <= bxTolerance_) ? true : false; - d03 = (abs(latq[0].bxValue - latq[3].bxValue) <= bxTolerance_) ? true : false; - d12 = (abs(latq[1].bxValue - latq[2].bxValue) <= bxTolerance_) ? true : false; - d13 = (abs(latq[1].bxValue - latq[3].bxValue) <= bxTolerance_) ? true : false; - d23 = (abs(latq[2].bxValue - latq[3].bxValue) <= bxTolerance_) ? true : false; - - /* 4 groups of partial combination of valid lateralities */ - if ((latq[0].latQValid && latq[1].latQValid && latq[2].latQValid && latq[3].latQValid) && !(d01 && d12 && d23)) - result = false; - else - /* 4 posible cases of 3 groups of valid partial lateralities */ - if (((latq[0].latQValid && latq[1].latQValid && latq[2].latQValid) && !(d01 && d12)) or - ((latq[0].latQValid && latq[1].latQValid && latq[3].latQValid) && !(d01 && d13)) or - ((latq[0].latQValid && latq[2].latQValid && latq[3].latQValid) && !(d02 && d23)) or - ((latq[1].latQValid && latq[2].latQValid && latq[3].latQValid) && !(d12 && d23))) - result = false; - else - /* Lastly, the 4 possible cases of partial valid lateralities */ - - if (((latq[0].latQValid && latq[1].latQValid) && !d01) or ((latq[0].latQValid && latq[2].latQValid) && !d02) or - ((latq[0].latQValid && latq[3].latQValid) && !d03) or ((latq[1].latQValid && latq[2].latQValid) && !d12) or - ((latq[1].latQValid && latq[3].latQValid) && !d13) or ((latq[2].latQValid && latq[3].latQValid) && !d23)) - result = false; - - return result; -} - -/** Calculate the parameters of the detected trayectories */ -void MuonPathAnalyzerPerSL::calculatePathParameters(MuonPathPtr &mPath) { - // The order is important. - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:calculatePathParameters \t\t\t\t\t\t calculating calcCellDriftAndXcoor(mPath) "; - calcCellDriftAndXcoor(mPath); - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:calculatePathParameters \t\t\t\t\t\t checking mPath->quality() " - << mPath->quality(); - if (mPath->quality() == HIGHQ or mPath->quality() == HIGHQGHOST) { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:calculatePathParameters \t\t\t\t\t\t\t Quality test passed, now calcTanPhiXPosChamber4Hits(mPath) "; - calcTanPhiXPosChamber4Hits(mPath); - } else { - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") - << "DTp2:calculatePathParameters \t\t\t\t\t\t\t Quality test NOT passed calcTanPhiXPosChamber3Hits(mPath) "; - calcTanPhiXPosChamber3Hits(mPath); - } - - if (debug_) - LogDebug("MuonPathAnalyzerPerSL") << "DTp2:calculatePathParameters \t\t\t\t\t\t calcChiSquare(mPath) "; - calcChiSquare(mPath); -} - -void MuonPathAnalyzerPerSL::calcTanPhiXPosChamber(MuonPathPtr &mPath) { - int layerIdx[2]; - /* - To calculate path's angle are only necessary two valid primitives. - This method should be called only when a 'MuonPath' is determined as valid, - so, at least, three of its primitives must have a valid time. - With this two comparitions (which can be implemented easily as multiplexors - in the FPGA) this method ensures to catch two of those valid primitives to - evaluate the angle. - - The first one is below the middle line of the superlayer, while the other - one is above this line - */ - if (mPath->primitive(0)->isValidTime()) - layerIdx[0] = 0; - else - layerIdx[0] = 1; - - if (mPath->primitive(3)->isValidTime()) - layerIdx[1] = 3; - else - layerIdx[1] = 2; - - /* We identify along which cells' sides the muon travels */ - LATERAL_CASES sideComb[2]; - sideComb[0] = (mPath->lateralComb())[layerIdx[0]]; - sideComb[1] = (mPath->lateralComb())[layerIdx[1]]; - - /* Horizontal gap between cells in cell's semi-length units */ - int dHoriz = (mPath->cellLayout())[layerIdx[1]] - (mPath->cellLayout())[layerIdx[0]]; - - /* Vertical gap between cells in cell's height units */ - int dVert = layerIdx[1] - layerIdx[0]; - - /*-----------------------------------------------------------------*/ - /*--------------------- Phi angle calculation ---------------------*/ - /*-----------------------------------------------------------------*/ - float num = CELL_SEMILENGTH * dHoriz + DRIFT_SPEED * eqMainTerm(sideComb, layerIdx, mPath, mPath->bxTimeValue()); - - float denom = CELL_HEIGHT * dVert; - float tanPhi = num / denom; - - mPath->setTanPhi(tanPhi); - - /*-----------------------------------------------------------------*/ - /*----------------- Horizontal coord. calculation -----------------*/ - /*-----------------------------------------------------------------*/ - - /* - Using known coordinates, relative to superlayer axis reference, (left most - superlayer side, and middle line between 2nd and 3rd layers), calculating - horizontal coordinate implies using a basic line equation: - (y - y0) = (x - x0) * cotg(Phi) - This horizontal coordinate can be obtained setting y = 0 on last equation, - and also setting y0 and x0 with the values of a known muon's path cell - position hit. - It's enough to use the lower cell (layerIdx[0]) coordinates. So: - xC = x0 - y0 * tan(Phi) - */ - float lowerXPHorizPos = mPath->xCoorCell(layerIdx[0]); - - float lowerXPVertPos = 0; // This is only the absolute value distance. - if (layerIdx[0] == 0) - lowerXPVertPos = CELL_HEIGHT + CELL_SEMIHEIGHT; - else - lowerXPVertPos = CELL_SEMIHEIGHT; - - mPath->setHorizPos(lowerXPHorizPos + lowerXPVertPos * tanPhi); -} - -/** - * Coordinate and angle calculations for a 4 HITS cases - */ -void MuonPathAnalyzerPerSL::calcTanPhiXPosChamber4Hits(MuonPathPtr &mPath) { - int x_prec_inv = (int)(1. / (10. * x_precision_)); - int numberOfBits = (int)(round(std::log(x_prec_inv) / std::log(2.))); - int numerator = 3 * (int)round(mPath->xCoorCell(3) / (10 * x_precision_)) + - (int)round(mPath->xCoorCell(2) / (10 * x_precision_)) - - (int)round(mPath->xCoorCell(1) / (10 * x_precision_)) - - 3 * (int)round(mPath->xCoorCell(0) / (10 * x_precision_)); - int CELL_HEIGHT_JM = pow(2, 15) / ((int)(10 * CELL_HEIGHT)); - int tanPhi_x4096 = (numerator * CELL_HEIGHT_JM) >> (3 + numberOfBits); - mPath->setTanPhi(tanPhi_x4096 * tanPsi_precision_); - - float XPos = (mPath->xCoorCell(0) + mPath->xCoorCell(1) + mPath->xCoorCell(2) + mPath->xCoorCell(3)) / 4; - mPath->setHorizPos(floor(XPos / (10 * x_precision_)) * 10 * x_precision_); -} - -/** - * 3 HITS cases - */ -void MuonPathAnalyzerPerSL::calcTanPhiXPosChamber3Hits(MuonPathPtr &mPath) { - int layerIdx[2]; - int x_prec_inv = (int)(1. / (10. * x_precision_)); - int numberOfBits = (int)(round(std::log(x_prec_inv) / std::log(2.))); - - if (mPath->primitive(0)->isValidTime()) - layerIdx[0] = 0; - else - layerIdx[0] = 1; - - if (mPath->primitive(3)->isValidTime()) - layerIdx[1] = 3; - else - layerIdx[1] = 2; - - /*-----------------------------------------------------------------*/ - /*--------------------- Phi angle calculation ---------------------*/ - /*-----------------------------------------------------------------*/ - - int tan_division_denominator_bits = 16; - - int num = - ((int)((int)(x_prec_inv * mPath->xCoorCell(layerIdx[1])) - (int)(x_prec_inv * mPath->xCoorCell(layerIdx[0]))) - << (12 - numberOfBits)); - int denominator = (layerIdx[1] - layerIdx[0]) * CELL_HEIGHT; - int denominator_inv = ((int)(0.5 + pow(2, tan_division_denominator_bits) / float(denominator))); - - float tanPhi = ((num * denominator_inv) >> tan_division_denominator_bits) / ((1. / tanPsi_precision_)); - - mPath->setTanPhi(tanPhi); - - /*-----------------------------------------------------------------*/ - /*----------------- Horizontal coord. calculation -----------------*/ - /*-----------------------------------------------------------------*/ - float XPos = 0; - if (mPath->primitive(0)->isValidTime() and mPath->primitive(3)->isValidTime()) - XPos = (mPath->xCoorCell(0) + mPath->xCoorCell(3)) / 2; - else - XPos = (mPath->xCoorCell(1) + mPath->xCoorCell(2)) / 2; - - mPath->setHorizPos(floor(XPos / (10 * x_precision_)) * 10 * x_precision_); -} - -/** - * Calculate the drift distances of each wire and the horizontal position - */ -void MuonPathAnalyzerPerSL::calcCellDriftAndXcoor(MuonPathPtr &mPath) { - long int drift_speed_new = 889; - long int drift_dist_um_x4; - long int wireHorizPos_x4; - long int pos_mm_x4; - int x_prec_inv = (int)(1. / (10. * x_precision_)); - - for (int i = 0; i <= 3; i++) - if (mPath->primitive(i)->isValidTime()) { - drift_dist_um_x4 = - drift_speed_new * ((long int)mPath->primitive(i)->tdcTimeStampNoOffset() - (long int)mPath->bxTimeValue()); - wireHorizPos_x4 = (long)(mPath->primitive(i)->wireHorizPos() * x_prec_inv); - - if ((mPath->lateralComb())[i] == LEFT) - pos_mm_x4 = wireHorizPos_x4 - (drift_dist_um_x4 >> 10); - else - pos_mm_x4 = wireHorizPos_x4 + (drift_dist_um_x4 >> 10); - - mPath->setXCoorCell(pos_mm_x4 * (10 * x_precision_), i); - mPath->setDriftDistance(((float)(drift_dist_um_x4 >> 10)) * (10 * x_precision_), i); - } -} - -/** - * Calculate the quality estimator of each trayectory. - */ -void MuonPathAnalyzerPerSL::calcChiSquare(MuonPathPtr &mPath) { - int x_prec_inv = (int)(1. / (10. * x_precision_)); - int numberOfBits = (int)(round(std::log(x_prec_inv) / std::log(2.))); - long int Z_FACTOR[NUM_LAYERS] = {-6, -2, 2, 6}; - for (int i = 0; i < 4; i++) { - Z_FACTOR[i] = Z_FACTOR[i] * (long int)CELL_HEIGHT; - } - long int sum_A = 0, sum_B = 0; - long int chi2_mm2_x1024 = 0; - for (int i = 0; i < 4; i++) { - if (mPath->primitive(i)->isValidTime()) { - sum_A = (((int)(mPath->xCoorCell(i) / (10 * x_precision_))) - ((int)(mPath->horizPos() / (10 * x_precision_)))) - << (14 - numberOfBits); - sum_B = Z_FACTOR[i] * ((int)(mPath->tanPhi() / tanPsi_precision_)); - chi2_mm2_x1024 += (sum_A - sum_B) * (sum_A - sum_B); - } - } - chi2_mm2_x1024 = chi2_mm2_x1024 >> 18; - - mPath->setChiSquare(((double)chi2_mm2_x1024 / 1024.)); -} - -int MuonPathAnalyzerPerSL::omittedHit(int idx) { - switch (idx) { - case 0: - return 3; - case 1: - return 0; - case 2: - return 2; - case 3: - return 1; - } - - return -1; -} diff --git a/L1Trigger/DTTriggerPhase2/src/MuonPathAssociator.cc b/L1Trigger/DTTriggerPhase2/src/MuonPathAssociator.cc index b1150be0cc92d..00476899a4d75 100644 --- a/L1Trigger/DTTriggerPhase2/src/MuonPathAssociator.cc +++ b/L1Trigger/DTTriggerPhase2/src/MuonPathAssociator.cc @@ -1,5 +1,5 @@ #include "L1Trigger/DTTriggerPhase2/interface/MuonPathAssociator.h" -#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerPerSL.h" +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyticAnalyzer.h" #include "L1Trigger/DTTriggerPhase2/interface/constants.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" @@ -10,13 +10,12 @@ using namespace cmsdt; // ============================================================================ // Constructors and destructor // ============================================================================ -MuonPathAssociator::MuonPathAssociator(const ParameterSet &pset, edm::ConsumesCollector &iC) { +MuonPathAssociator::MuonPathAssociator(const ParameterSet &pset, + edm::ConsumesCollector &iC, + std::shared_ptr &globalcoordsobtainer) { // Obtention of parameters debug_ = pset.getUntrackedParameter("debug"); clean_chi2_correlation_ = pset.getUntrackedParameter("clean_chi2_correlation"); - use_LSB_ = pset.getUntrackedParameter("use_LSB"); - tanPsi_precision_ = pset.getUntrackedParameter("tanPsi_precision"); - x_precision_ = pset.getUntrackedParameter("x_precision"); useBX_correlation_ = pset.getUntrackedParameter("useBX_correlation"); allow_confirmation_ = pset.getUntrackedParameter("allow_confirmation"); dT0_correlate_TP_ = pset.getUntrackedParameter("dT0_correlate_TP"); @@ -24,6 +23,8 @@ MuonPathAssociator::MuonPathAssociator(const ParameterSet &pset, edm::ConsumesCo dTanPsi_correlate_TP_ = pset.getUntrackedParameter("dTanPsi_correlate_TP"); minx_match_2digis_ = pset.getUntrackedParameter("minx_match_2digis"); chi2corTh_ = pset.getUntrackedParameter("chi2corTh"); + cmssw_for_global_ = pset.getUntrackedParameter("cmssw_for_global"); + geometry_tag_ = pset.getUntrackedParameter("geometry_tag"); if (debug_) LogDebug("MuonPathAssociator") << "MuonPathAssociator: constructor"; @@ -43,6 +44,7 @@ MuonPathAssociator::MuonPathAssociator(const ParameterSet &pset, edm::ConsumesCo } dtGeomH_ = iC.esConsumes(); + globalcoordsobtainer_ = globalcoordsobtainer; } MuonPathAssociator::~MuonPathAssociator() { @@ -57,8 +59,9 @@ void MuonPathAssociator::initialise(const edm::EventSetup &iEventSetup) { if (debug_) LogDebug("MuonPathAssociator") << "MuonPathAssociator::initialiase"; - const MuonGeometryRecord &geom = iEventSetup.get(); - dtGeo_ = &geom.get(dtGeomH_); + edm::ESHandle geom; + iEventSetup.get().get(geometry_tag_, geom); + dtGeo_ = &(*geom); } void MuonPathAssociator::run(edm::Event &iEvent, @@ -81,11 +84,6 @@ void MuonPathAssociator::finish() { void MuonPathAssociator::correlateMPaths(edm::Handle dtdigis, std::vector &inMPaths, std::vector &outMPaths) { - int x_prec_inv = (int)(1. / (10. * x_precision_)); - int numberOfBits = (int)(round(std::log(x_prec_inv) / std::log(2.))); - - //Silvia's code for correlationg filteredMetaPrimitives - if (debug_) LogDebug("MuonPathAssociator") << "starting correlation"; @@ -153,29 +151,38 @@ void MuonPathAssociator::correlateMPaths(edm::Handle dtdigis, if (std::abs(SL1metaPrimitive->t0 - SL3metaPrimitive->t0) >= dT0_correlate_TP_) continue; //time match } - long int PosSL1 = (int)round(10 * SL1metaPrimitive->x / (10 * x_precision_)); - long int PosSL3 = (int)round(10 * SL3metaPrimitive->x / (10 * x_precision_)); + long int PosSL1 = (int)round(INCREASED_RES_POS_POW * 10 * SL1metaPrimitive->x); + long int PosSL3 = (int)round(INCREASED_RES_POS_POW * 10 * SL3metaPrimitive->x); double NewSlope = -999.; - if (use_LSB_) { - long int newConstant = (int)(139.5 * 4); - long int difPos_mm_x4 = PosSL3 - PosSL1; - long int tanPsi_x4096_x128 = (difPos_mm_x4)*newConstant; - long int tanPsi_x4096 = tanPsi_x4096_x128 / ((long int)pow(2, 5 + numberOfBits)); - if (tanPsi_x4096 < 0 && tanPsi_x4096_x128 % ((long int)pow(2, 5 + numberOfBits)) != 0) - tanPsi_x4096--; - NewSlope = -tanPsi_x4096 * tanPsi_precision_; + + long int pos = (PosSL3 + PosSL1) / 2; + // FW always rounds down (e.g 29.5 -> 29, -29.5 -> -30). For negative numbers, we don't do the same. + // Let's fix it (this also happens for the slope) + if (((PosSL3 + PosSL1) % 2 != 0) && (pos < 0)) { + pos--; } + + long int difPos_mm_x4 = PosSL3 - PosSL1; + long int tanPsi_x4096_x128 = (difPos_mm_x4)*VERT_PHI1_PHI3_INV; + long int tanpsi = tanPsi_x4096_x128 / ((long int)pow(2, 5 + INCREASED_RES_POS)); + if (tanpsi < 0 && tanPsi_x4096_x128 % ((long int)pow(2, 5 + INCREASED_RES_POS)) != 0) + tanpsi--; + NewSlope = -tanpsi / (double)INCREASED_RES_SLOPE_POW; double MeanT0 = (SL1metaPrimitive->t0 + SL3metaPrimitive->t0) / 2; - double MeanPos = (PosSL3 + PosSL1) / (2. / (x_precision_)); - if (use_LSB_) { - MeanPos = floor(round(10. * (MeanPos / x_precision_)) * 0.1) * x_precision_; - } + double MeanPos = (PosSL3 + PosSL1) / (2. * INCREASED_RES_POS_POW * 10); DTSuperLayerId SLId1(SL1metaPrimitive->rawId); DTSuperLayerId SLId3(SL3metaPrimitive->rawId); DTWireId wireId1(SLId1, 2, 1); DTWireId wireId3(SLId3, 2, 1); + int shift_sl1 = int(round(shiftinfo_[wireId1.rawId()] * INCREASED_RES_POS_POW * 10)); + int shift_sl3 = int(round(shiftinfo_[wireId3.rawId()] * INCREASED_RES_POS_POW * 10)); + if (shift_sl1 < shift_sl3) { + pos -= shift_sl1; + } else + pos -= shift_sl3; + int wi[8], tdc[8], lat[8]; wi[0] = SL1metaPrimitive->wi1; tdc[0] = SL1metaPrimitive->tdc1; @@ -204,27 +211,26 @@ void MuonPathAssociator::correlateMPaths(edm::Handle dtdigis, long int chi2 = 0; - long int CH_CENTER_TO_MID_SL_P = (long int)(117.5 * 4); long int Z_FACTOR_CORR[8] = {-6, -2, 2, 6, -6, -2, 2, 6}; for (int i = 0; i < 8; i++) { int sign = 2 * (i / 4) - 1; - Z_FACTOR_CORR[i] = Z_FACTOR_CORR[i] * CELL_HEIGHT + CH_CENTER_TO_MID_SL_P * sign; + Z_FACTOR_CORR[i] = Z_FACTOR_CORR[i] * CELL_HEIGHT + CH_CENTER_TO_MID_SL_X2 * sign; } long int sum_A, sum_B; - for (int i = 0; i < 8; i++) { + for (int i = 0; i < NUM_LAYERS_2SL; i++) { long int shift, slTime; - if (i / 4 == 0) { - shift = round(shiftinfo_[wireId1.rawId()] / x_precision_); + if (i / NUM_LAYERS == 0) { // layers 0 - 3 -> SL1 + shift = shift_sl1; slTime = SL1metaPrimitive->t0; - } else { - shift = round(shiftinfo_[wireId3.rawId()] / x_precision_); + } else { // layers 4 - 7 -> SL3 + shift = shift_sl3; slTime = SL3metaPrimitive->t0; } if (wi[i] != -1) { - long int drift_speed_new = 889; - long int drift_dist_um_x4 = drift_speed_new * (((long int)tdc[i]) - slTime); - long int wireHorizPos_x4 = (42 * wi[i] + ((i + 1) % 2) * 21) / (10 * x_precision_); + long int drift_dist_um_x4 = DRIFT_SPEED_X4 * (((long int)tdc[i]) - slTime); + long int wireHorizPos_x4 = + (CELL_LENGTH * wi[i] + ((i + 1) % 2) * CELL_SEMILENGTH) * INCREASED_RES_POS_POW; long int pos_mm_x4; if (lat[i] == 0) { @@ -232,14 +238,14 @@ void MuonPathAssociator::correlateMPaths(edm::Handle dtdigis, } else { pos_mm_x4 = wireHorizPos_x4 + (drift_dist_um_x4 >> 10); } - sum_A = shift + pos_mm_x4 - (long int)round(MeanPos / x_precision_); - sum_A = sum_A << (14 - numberOfBits); - sum_B = Z_FACTOR_CORR[i] * (long int)round(-NewSlope / tanPsi_precision_); + sum_A = shift + pos_mm_x4 - (long int)round(MeanPos * 10 * INCREASED_RES_POS_POW); + sum_A = sum_A << (14 - INCREASED_RES_POS); + sum_B = Z_FACTOR_CORR[i] * (long int)round(-NewSlope * INCREASED_RES_SLOPE_POW); chi2 += ((sum_A - sum_B) * (sum_A - sum_B)) >> 2; } } - double newChi2 = (double)(chi2 >> 16) / (1024. * 100.); + double newChi2 = (double)(chi2 >> INCREASED_RES_POS_POW) / (1024. * 100.); if (newChi2 > chi2corTh_) continue; @@ -249,29 +255,38 @@ void MuonPathAssociator::correlateMPaths(edm::Handle dtdigis, useFitSL3[sl3] = true; int quality = 0; - if (SL3metaPrimitive->quality <= 2 and SL1metaPrimitive->quality <= 2) - quality = 6; - - if ((SL3metaPrimitive->quality >= 3 && SL1metaPrimitive->quality <= 2) or - (SL1metaPrimitive->quality >= 3 && SL3metaPrimitive->quality <= 2)) - quality = 8; - - if (SL3metaPrimitive->quality >= 3 && SL1metaPrimitive->quality >= 3) - quality = 9; - - double z = 0; - if (ChId.station() >= 3) - z = -1.8; - GlobalPoint jm_x_cmssw_global = dtGeo_->chamber(ChId)->toGlobal( - LocalPoint(MeanPos, 0., z)); //Jm_x is already extrapolated to the middle of the SL - int thisec = ChId.sector(); - if (se == 13) - thisec = 4; - if (se == 14) - thisec = 10; - double phi = jm_x_cmssw_global.phi() - 0.5235988 * (thisec - 1); - double psi = atan(NewSlope); - double phiB = hasPosRF(ChId.wheel(), ChId.sector()) ? psi - phi : -psi - phi; + if (SL3metaPrimitive->quality == LOWQ and SL1metaPrimitive->quality == LOWQ) + quality = LOWLOWQ; + + if ((SL3metaPrimitive->quality == HIGHQ && SL1metaPrimitive->quality == LOWQ) or + (SL1metaPrimitive->quality == HIGHQ && SL3metaPrimitive->quality == LOWQ)) + quality = HIGHLOWQ; + + if (SL3metaPrimitive->quality == HIGHQ && SL1metaPrimitive->quality == HIGHQ) + quality = HIGHHIGHQ; + + double phi = -999.; + double phiB = -999.; + if (cmssw_for_global_) { + double z = 0; + if (ChId.station() >= 3) + z = Z_SHIFT_MB4; + GlobalPoint jm_x_cmssw_global = dtGeo_->chamber(ChId)->toGlobal( + LocalPoint(MeanPos, 0., z)); //Jm_x is already extrapolated to the middle of the SL + int thisec = ChId.sector(); + if (se == 13) + thisec = 4; + if (se == 14) + thisec = 10; + phi = jm_x_cmssw_global.phi() - PHI_CONV * (thisec - 1); + double psi = atan(NewSlope); + phiB = hasPosRF(ChId.wheel(), ChId.sector()) ? psi - phi : -psi - phi; + } else { + auto global_coords = globalcoordsobtainer_->get_global_coordinates(ChId.rawId(), 0, pos, tanpsi); + + phi = global_coords[0]; + phiB = global_coords[1]; + } if (!clean_chi2_correlation_) outMPaths.emplace_back(ChId.rawId(), @@ -357,10 +372,10 @@ void MuonPathAssociator::correlateMPaths(edm::Handle dtdigis, int best_lat = -1; int next_lat = -1; int lat = -1; - for (const auto &dtLayerId_It : *dtdigis) { const DTLayerId dtLId = dtLayerId_It.first; - const DTSuperLayerId &dtSLId(dtLId); + // creating a new DTSuperLayerId object to compare with the required SL id + const DTSuperLayerId dtSLId(dtLId.wheel(), dtLId.station(), dtLId.sector(), 3); if (dtSLId.rawId() != sl3Id.rawId()) continue; double l_shift = 0; @@ -372,17 +387,20 @@ void MuonPathAssociator::correlateMPaths(edm::Handle dtdigis, l_shift = -1 * X_POS_L3; else if (dtLId.layer() == 1) l_shift = -1 * X_POS_L4; - double x_inSL3 = SL1metaPrimitive->x - SL1metaPrimitive->tanPhi * (23.5 + l_shift); + double x_inSL3 = SL1metaPrimitive->x - SL1metaPrimitive->tanPhi * (VERT_PHI1_PHI3 + l_shift); for (auto digiIt = (dtLayerId_It.second).first; digiIt != (dtLayerId_It.second).second; ++digiIt) { DTWireId wireId(dtLId, (*digiIt).wire()); - int x_wire = shiftinfo_[wireId.rawId()] + ((*digiIt).time() - SL1metaPrimitive->t0) * 0.00543; - int x_wire_left = shiftinfo_[wireId.rawId()] - ((*digiIt).time() - SL1metaPrimitive->t0) * 0.00543; + double x_wire = + shiftinfo_[wireId.rawId()] + ((*digiIt).time() - SL1metaPrimitive->t0) * DRIFT_SPEED / 10.; + double x_wire_left = + shiftinfo_[wireId.rawId()] - ((*digiIt).time() - SL1metaPrimitive->t0) * DRIFT_SPEED / 10.; lat = 1; if (std::abs(x_inSL3 - x_wire) > std::abs(x_inSL3 - x_wire_left)) { x_wire = x_wire_left; //choose the closest laterality lat = 0; } if (std::abs(x_inSL3 - x_wire) < minx) { + min2x = minx; minx = std::abs(x_inSL3 - x_wire); next_wire = best_wire; next_tdc = best_tdc; @@ -405,9 +423,9 @@ void MuonPathAssociator::correlateMPaths(edm::Handle dtdigis, } } if (matched_digis >= 2 and best_layer != -1 and next_layer != -1) { - int new_quality = 7; - if (SL1metaPrimitive->quality <= 2) - new_quality = 5; + int new_quality = CHIGHQ; + if (SL1metaPrimitive->quality == LOWQ) + new_quality = CLOWQ; int wi1 = -1; int tdc1 = -1; @@ -564,23 +582,26 @@ void MuonPathAssociator::correlateMPaths(edm::Handle dtdigis, for (const auto &dtLayerId_It : *dtdigis) { const DTLayerId dtLId = dtLayerId_It.first; - const DTSuperLayerId &dtSLId(dtLId); + // creating a new DTSuperLayerId object to compare with the required SL id + const DTSuperLayerId dtSLId(dtLId.wheel(), dtLId.station(), dtLId.sector(), 1); if (dtSLId.rawId() != sl1Id.rawId()) continue; double l_shift = 0; if (dtLId.layer() == 4) - l_shift = 1.95; + l_shift = X_POS_L4; if (dtLId.layer() == 3) - l_shift = 0.65; + l_shift = X_POS_L3; if (dtLId.layer() == 2) - l_shift = -0.65; + l_shift = -1 * X_POS_L3; if (dtLId.layer() == 1) - l_shift = -1.95; - double x_inSL1 = SL3metaPrimitive->x + SL3metaPrimitive->tanPhi * (23.5 - l_shift); + l_shift = -1 * X_POS_L4; + double x_inSL1 = SL3metaPrimitive->x + SL3metaPrimitive->tanPhi * (VERT_PHI1_PHI3 - l_shift); for (auto digiIt = (dtLayerId_It.second).first; digiIt != (dtLayerId_It.second).second; ++digiIt) { DTWireId wireId(dtLId, (*digiIt).wire()); - int x_wire = shiftinfo_[wireId.rawId()] + ((*digiIt).time() - SL3metaPrimitive->t0) * 0.00543; - int x_wire_left = shiftinfo_[wireId.rawId()] - ((*digiIt).time() - SL3metaPrimitive->t0) * 0.00543; + double x_wire = + shiftinfo_[wireId.rawId()] + ((*digiIt).time() - SL3metaPrimitive->t0) * DRIFT_SPEED / 10.; + double x_wire_left = + shiftinfo_[wireId.rawId()] - ((*digiIt).time() - SL3metaPrimitive->t0) * DRIFT_SPEED / 10.; lat = 1; if (std::abs(x_inSL1 - x_wire) > std::abs(x_inSL1 - x_wire_left)) { x_wire = x_wire_left; //choose the closest laterality @@ -609,9 +630,9 @@ void MuonPathAssociator::correlateMPaths(edm::Handle dtdigis, } } if (matched_digis >= 2 and best_layer != -1 and next_layer != -1) { - int new_quality = 7; - if (SL3metaPrimitive->quality <= 2) - new_quality = 5; + int new_quality = CHIGHQ; + if (SL3metaPrimitive->quality == LOWQ) + new_quality = CLOWQ; int wi1 = -1; int tdc1 = -1; @@ -889,6 +910,35 @@ void MuonPathAssociator::correlateMPaths(edm::Handle dtdigis, } } } + + //eta TP we do not correlate with other superlayer in the same chamber so we forward them all + std::vector SL2metaPrimitives; + + for (int wh = -2; wh <= 2; wh++) { + for (int st = 1; st <= 4; st++) { + for (int se = 1; se <= 14; se++) { + if (se >= 13 && st != 4) + continue; + + DTChamberId ChId(wh, st, se); + DTSuperLayerId sl2Id(wh, st, se, 2); + + //filterSL2 etaTP + for (auto metaprimitiveIt = inMPaths.begin(); metaprimitiveIt != inMPaths.end(); ++metaprimitiveIt) + if (metaprimitiveIt->rawId == sl2Id.rawId()) { + SL2metaPrimitives.push_back(*metaprimitiveIt); + //std::cout<<"pushing back eta metaprimitive: "; + printmPC(*metaprimitiveIt); + outMPaths.push_back(*metaprimitiveIt); + } + } + } + } + + LogDebug("MuonPathAssociator") << "\t etaTP: added " << SL2metaPrimitives.size() << "to outMPaths" << std::endl; + + SL2metaPrimitives.clear(); + SL2metaPrimitives.erase(SL2metaPrimitives.begin(), SL2metaPrimitives.end()); } void MuonPathAssociator::removeSharingFits(vector &chamberMPaths, vector &allMPaths) {