diff --git a/DataFormats/L1DTTrackFinder/BuildFile.xml b/DataFormats/L1DTTrackFinder/BuildFile.xml index bd2a1d535a5e3..54b1c2a65f97d 100644 --- a/DataFormats/L1DTTrackFinder/BuildFile.xml +++ b/DataFormats/L1DTTrackFinder/BuildFile.xml @@ -3,4 +3,5 @@ + diff --git a/DataFormats/L1TMuonPhase2/interface/KMTFTrack.h b/DataFormats/L1TMuonPhase2/interface/KMTFTrack.h index 7e6197eea6d9e..a414b3458e169 100644 --- a/DataFormats/L1TMuonPhase2/interface/KMTFTrack.h +++ b/DataFormats/L1TMuonPhase2/interface/KMTFTrack.h @@ -10,30 +10,40 @@ namespace l1t { class KMTFTrack; typedef std::vector KMTFTrackCollection; typedef BXVector KMTFTrackBxCollection; + typedef math::Error<5>::type CovarianceMatrix5dim; + typedef math::Error<2>::type CovarianceMatrix2dim; class KMTFTrack : public reco::LeafCandidate { public: KMTFTrack() : reco::LeafCandidate(-1, reco::LeafCandidate::PolarLorentzVector(0.1, 0.0, 0.0, 0.105)), unconstrainedP4_(reco::LeafCandidate::PolarLorentzVector(0.1, 0.0, 0.0, 0.105)), - covariance_(std::vector(6, 0.0)), + covariance_(std::vector(15, 0.0)), + covarianceNB_(std::vector(3, 0.0)), curvVertex_(0), ptC_(0), phiVertex_(0), dxy_(0), + zVertex_(0), + kSlopeVertex_(0), curvMuon_(0), ptU_(0), phiMuon_(0), phiBMuon_(0), + zMuon_(0), + kSlopeMuon_(0), curv_(0), phi_(0), phiB_(0), + z_(0), + kSlope_(0), coarseEta_(0), approxPromptChi2_(0), approxPromptErrChi2_(0), approxDispChi2_(0), approxDispErrChi2_(0), hitPattern_(0), + thetaDigiPattern_(0), step_(1), sector_(0), wheel_(0), @@ -46,27 +56,35 @@ namespace l1t { ~KMTFTrack() override = default; - KMTFTrack(const l1t::MuonStubRef& seed, int phi, int phiB) + KMTFTrack(const l1t::MuonStubRef& seed, int phi, int phiB, int z, int kSlope) : reco::LeafCandidate(-1, reco::LeafCandidate::PolarLorentzVector(0.1, 0.0, 0.0, 0.105)), unconstrainedP4_(reco::LeafCandidate::PolarLorentzVector(0.1, 0.0, 0.0, 0.105)), - covariance_(std::vector(6, 0.0)), + covariance_(std::vector(15, 0.0)), + covarianceNB_(std::vector(3, 0.0)), curvVertex_(0), ptC_(0), phiVertex_(0), dxy_(0), + zVertex_(0), + kSlopeVertex_(0), curvMuon_(0), ptU_(0), phiMuon_(0), phiBMuon_(0), + zMuon_(0), + kSlopeMuon_(0), curv_(0), phi_(phi), phiB_(phiB), + z_(z), + kSlope_(kSlope), coarseEta_(0), approxPromptChi2_(0), approxPromptErrChi2_(0), approxDispChi2_(0), approxDispErrChi2_(0), hitPattern_(0), + thetaDigiPattern_(0), step_(seed->depthRegion()), sector_(seed->phiRegion()), wheel_(seed->etaRegion()), @@ -80,6 +98,7 @@ namespace l1t { residuals_.push_back(0); residuals_.push_back(0); residuals_.push_back(0); + residuals_.push_back(0); } reco::LeafCandidate::PolarLorentzVector displacedP4() const { return unconstrainedP4_; } @@ -92,6 +111,10 @@ namespace l1t { int phiAtMuon() const { return phiMuon_; } //unconstrained phiB at station 1 int phiBAtMuon() const { return phiBMuon_; } + //unconstrained z at station 1 + int zAtMuon() const { return zMuon_; } + //unconstrained kSLope at station 1 + int kSlopeAtMuon() const { return kSlopeMuon_; } //constrained pt int ptPrompt() const { return ptC_; } @@ -99,6 +122,10 @@ namespace l1t { int curvatureAtVertex() const { return curvVertex_; } //constrained phi at the vertex int phiAtVertex() const { return phiVertex_; } + //constrained z at the vertex + int zAtVertex() const { return zVertex_; } + //constrained kSlope at the vertex + int kSlopeAtVertex() const { return kSlopeVertex_; } //Impact parameter as calculated from the muon track int dxy() const { return dxy_; } //Unconstrained curvature at the Muon systen @@ -107,6 +134,10 @@ namespace l1t { int positionAngle() const { return phi_; } //Unconstrained bending angle at the Muon systen int bendingAngle() const { return phiB_; } + + //global z and slope of stub + int zPosition() const { return z_; } + int kSlope() const { return kSlope_; } //Coarse eta caluclated only using phi segments int coarseEta() const { return coarseEta_; } //Approximate Chi2 metrics @@ -116,6 +147,7 @@ namespace l1t { int approxDispErrChi2() const { return approxDispErrChi2_; } int hitPattern() const { return hitPattern_; } + int thetaDigiPattern() const { return thetaDigiPattern_; } //step; int step() const { return step_; } //sector; @@ -156,8 +188,37 @@ namespace l1t { return kalmanGain0_; } + const std::vector& ThetaGain1D(unsigned int step) const { + switch (step) { + case 3: + return ThetaGain1D3_; + case 2: + return ThetaGain1D2_; + case 1: + return ThetaGain1D1_; + case 0: + return ThetaGain1D0_; + } + return ThetaGain1D0_; + } + + const std::vector& ThetaGain(unsigned int step) const { + switch (step) { + case 3: + return ThetaGain3_; + case 2: + return ThetaGain2_; + case 1: + return ThetaGain1_; + case 0: + return ThetaGain0_; + } + return ThetaGain0_; + } + //get covariance const std::vector& covariance() const { return covariance_; } + const std::vector& covarianceNB() const { return covarianceNB_; } //get residual int residual(uint i) const { return residuals_[i]; } @@ -188,23 +249,29 @@ namespace l1t { } //Set coordinates general - void setCoordinates(int step, int curv, int phi, int phiB) { + void setCoordinates(int step, int curv, int phi, int phiB, int z, int kSlope) { step_ = step; curv_ = curv; phiB_ = phiB; phi_ = phi; + z_ = z; + kSlope_ = kSlope; } - void setCoordinatesAtVertex(int curv, int phi, int dxy) { + void setCoordinatesAtVertex(int curv, int phi, int dxy, int z, int kSlope) { curvVertex_ = curv; phiVertex_ = phi; dxy_ = dxy; + zVertex_ = z; + kSlopeVertex_ = kSlope; } - void setCoordinatesAtMuon(int curv, int phi, int phiB) { + void setCoordinatesAtMuon(int curv, int phi, int phiB, int z, int kSlope) { curvMuon_ = curv; phiMuon_ = phi; phiBMuon_ = phiB; + zMuon_ = z; + kSlopeMuon_ = kSlope; } void setPt(int ptC, int ptU) { @@ -215,6 +282,7 @@ namespace l1t { void setCoarseEta(int eta) { coarseEta_ = eta; } void setHitPattern(int pattern) { hitPattern_ = pattern; } + void setThetaDigiPattern(int theta_pattern) { thetaDigiPattern_ = theta_pattern; } void setApproxChi2(int chi, int chiErr, bool prompt) { if (prompt) { @@ -305,14 +373,101 @@ namespace l1t { } } + void setThetaGain1D(unsigned int step, + unsigned int K, + int priorThetaPattern, + int seedStation, + int priorPhiPattern, + float G31, + float G32, + float G41, + float G42) { + std::vector* v1 = nullptr; + switch (step) { + case 3: + v1 = &ThetaGain1D3_; + break; + case 2: + v1 = &ThetaGain1D2_; + break; + case 1: + v1 = &ThetaGain1D1_; + break; + case 0: + v1 = &ThetaGain1D0_; + break; + default: + throw cms::Exception("WrongCondition") << "1D: Critical ERROR on setting the Theta gain\n"; + } + v1->push_back(static_cast(K)); + v1->push_back(static_cast(priorThetaPattern)); + v1->push_back(static_cast(seedStation)); + v1->push_back(static_cast(priorPhiPattern)); + v1->push_back(G31); + v1->push_back(G32); + v1->push_back(G41); + v1->push_back(G42); + } + + void setThetaGain(unsigned int step, + unsigned int K, + int priorThetaPattern, + int seedStation, + int priorPhiPattern, + float G32, + float G33, + float G42, + float G43) { + std::vector* v2 = nullptr; + switch (step) { + case 3: + v2 = &ThetaGain3_; + break; + case 2: + v2 = &ThetaGain2_; + break; + case 1: + v2 = &ThetaGain1_; + break; + case 0: + v2 = &ThetaGain0_; + break; + default: + throw cms::Exception("WrongCondition") << "Critical ERROR on setting the Theta gain\n"; + } + v2->push_back(static_cast(K)); + v2->push_back(static_cast(priorThetaPattern)); + v2->push_back(static_cast(seedStation)); + v2->push_back(static_cast(priorPhiPattern)); + v2->push_back(G32); + v2->push_back(G33); + v2->push_back(G42); + v2->push_back(G43); + } + //set covariance - void setCovariance(const CovarianceMatrix& c) { + void setCovariance(const CovarianceMatrix5dim& c) { covariance_[0] = c(0, 0); covariance_[1] = c(0, 1); covariance_[2] = c(1, 1); covariance_[3] = c(0, 2); covariance_[4] = c(1, 2); covariance_[5] = c(2, 2); + covariance_[6] = c(0, 3); + covariance_[7] = c(1, 3); + covariance_[8] = c(2, 3); + covariance_[9] = c(3, 3); + covariance_[10] = c(0, 4); + covariance_[11] = c(1, 4); + covariance_[12] = c(2, 4); + covariance_[13] = c(3, 4); + covariance_[14] = c(4, 4); + } + + void setCovarianceNB(const CovarianceMatrix2dim& c) { + covarianceNB_[0] = c(0, 0); + covarianceNB_[1] = c(0, 1); + covarianceNB_[2] = c(1, 1); } //set fine eta @@ -329,6 +484,7 @@ namespace l1t { //Covariance matrix for studies std::vector covariance_; + std::vector covarianceNB_; l1t::MuonStubRefVector stubs_; //vertex coordinates @@ -336,17 +492,23 @@ namespace l1t { int ptC_; int phiVertex_; int dxy_; + int zVertex_; + int kSlopeVertex_; //muon coordinates int curvMuon_; int ptU_; int phiMuon_; int phiBMuon_; + int zMuon_; + int kSlopeMuon_; //generic coordinates int curv_; int phi_; int phiB_; + int z_; + int kSlope_; //common coordinates int coarseEta_; @@ -358,6 +520,8 @@ namespace l1t { //phi bitmask int hitPattern_; + //bitmask pattern based on theta digi presence + int thetaDigiPattern_; //propagation step int step_; @@ -393,6 +557,16 @@ namespace l1t { std::vector kalmanGain3_; std::vector residuals_; + + std::vector ThetaGain1D0_; + std::vector ThetaGain1D1_; + std::vector ThetaGain1D2_; + std::vector ThetaGain1D3_; + + std::vector ThetaGain0_; + std::vector ThetaGain1_; + std::vector ThetaGain2_; + std::vector ThetaGain3_; }; } // namespace l1t diff --git a/DataFormats/L1TMuonPhase2/src/classes_def.xml b/DataFormats/L1TMuonPhase2/src/classes_def.xml index 4c34f5483adcf..8fda3dd87d504 100644 --- a/DataFormats/L1TMuonPhase2/src/classes_def.xml +++ b/DataFormats/L1TMuonPhase2/src/classes_def.xml @@ -22,7 +22,8 @@ - + + diff --git a/L1Trigger/Phase2L1GMT/interface/KMTFCore.h b/L1Trigger/Phase2L1GMT/interface/KMTFCore.h index 19291d1f53031..99cb6553f3522 100644 --- a/L1Trigger/Phase2L1GMT/interface/KMTFCore.h +++ b/L1Trigger/Phase2L1GMT/interface/KMTFCore.h @@ -2,6 +2,8 @@ Kalman Filter L1 Muon algorithm Tyler Lam (UCLA) Sep. 2021 +Delano Campos (UCLA) +Feb. 2026 */ #ifndef L1Trigger_Phase2L1GMT_KMTFCore_h #define L1Trigger_Phase2L1GMT_KMTFCore_h @@ -16,12 +18,25 @@ namespace Phase2L1GMT { class KMTFCore { public: typedef ROOT::Math::SVector Vector2; + typedef ROOT::Math::SVector Vector3; + typedef ROOT::Math::SVector Vector4; typedef ROOT::Math::SMatrix > CovarianceMatrix2; + typedef ROOT::Math::SMatrix > CovarianceMatrix3; + typedef ROOT::Math::SMatrix > CovarianceMatrix4; typedef ROOT::Math::SMatrix Matrix32; + typedef ROOT::Math::SMatrix Matrix53; typedef ROOT::Math::SMatrix Matrix23; + typedef ROOT::Math::SMatrix Matrix45; + typedef ROOT::Math::SMatrix Matrix54; typedef ROOT::Math::SMatrix Matrix13; + typedef ROOT::Math::SMatrix Matrix35; typedef ROOT::Math::SMatrix Matrix31; typedef ROOT::Math::SMatrix Matrix33; + typedef ROOT::Math::SMatrix Matrix55; + typedef ROOT::Math::SMatrix Matrix15; + typedef ROOT::Math::SMatrix Matrix51; + typedef ROOT::Math::SMatrix Matrix52; + typedef ROOT::Math::SMatrix Matrix25; KMTFCore(const edm::ParameterSet& settings); @@ -44,12 +59,14 @@ namespace Phase2L1GMT { void vertexConstraintOffline(l1t::KMTFTrack& track); void vertexConstraintLUT(l1t::KMTFTrack& track); int hitPattern(const l1t::KMTFTrack& track); + int thetaDigiPattern(const l1t::KMTFTrack& track); int customBitmask(unsigned int bit1, unsigned int bit2, unsigned int bit3, unsigned int bit4); bool getBit(int bitmask, int pos); void setFourVectors(l1t::KMTFTrack& track); bool estimateChiSquare(l1t::KMTFTrack& track, bool vertex); void setRank(l1t::KMTFTrack& track, bool vertex); int wrapAround(int value, int maximum); + int satKSlope(int k); int encode(bool ownwheel, int sector, int tag); std::pair getByCode(const std::vector& tracks, int mask); uint twosCompToBits(int q); @@ -115,9 +132,13 @@ namespace Phase2L1GMT { //bits for fixed point precision static const int PHIBSCALE = 16; static const int PHIBSCALE_INT = 5; + static const int ZDELTAR_BITS = 14; + static const int ZDELTAR_BITSINT = 1; static const int BITSCURV = 16; static const int BITSPHI = 18; static const int BITSPHIB = 17; // 12 bits *28 (+5 bits) + static const int BITSZ = 16; + static const int BITSKSLOPE = 16; static const int BITSPARAM = 14; static const int GAIN_0 = 9; static const int GAIN_0INT = 6; @@ -134,12 +155,26 @@ namespace Phase2L1GMT { static const int GAIN2_4INT = 4; static const int GAIN2_5 = 12; static const int GAIN2_5INT = 0; + + static const int GAINT_6 = 12; //new theta view gain bits. + static const int GAINT_6INT = 3; + static const int GAINT_7 = 12; + static const int GAINT_7INT = 3; + static const int GAINT_8 = 12; + static const int GAINT_8INT = 3; + static const int GAINT_9 = 12; + static const int GAINT_9INT = 3; //STUFF NOT USED IN THE FIRMWARE BUT ONLY FOR DEBUGGING /////////////////////////////////////////////////////// bool useOfflineAlgo_; + //used for z propagation + std::vector zdeltaR_; + //multiple scattering constants used in multiple scattering matrix to build RMS values std::vector mScatteringPhi_; std::vector mScatteringPhiB_; + std::vector mScatteringz_; + std::vector mScatteringkSlope_; //point resolution for phi double pointResolutionPhi_; //point resolution for phiB @@ -149,6 +184,10 @@ namespace Phase2L1GMT { //double pointResolutionPhiB_; //point resolution for vertex double pointResolutionVertex_; + // point resolution for z + std::vector pointResolutionz_; + // point resolution for kSlope + std::vector pointResolutionkSlope_; std::vector curvResolution1_; std::vector curvResolution2_; //Sorter diff --git a/L1Trigger/Phase2L1GMT/interface/KMTFLUTs.h b/L1Trigger/Phase2L1GMT/interface/KMTFLUTs.h index 42027a4c38e43..03b8577d23282 100644 --- a/L1Trigger/Phase2L1GMT/interface/KMTFLUTs.h +++ b/L1Trigger/Phase2L1GMT/interface/KMTFLUTs.h @@ -11,9 +11,11 @@ namespace Phase2L1GMT { class KMTFLUTs { public: - KMTFLUTs(const std::string &filename) { + KMTFLUTs(const std::string &filename, const std::string &ThetaFilename) { edm::FileInPath path(filename); - lutFile_ = new TFile(path.fullPath().c_str()); + edm::FileInPath pathTheta(ThetaFilename); + lutFile_ = std::unique_ptr{TFile::Open(path.fullPath().c_str())}; + lutThetaFile_ = std::unique_ptr(TFile::Open(pathTheta.fullPath().c_str())); lut_[3 * 64 + 8] = (TH1 *)lutFile_->Get("gain_8_3"); lut_[2 * 64 + 8] = (TH1 *)lutFile_->Get("gain_8_2"); lut_[2 * 64 + 12] = (TH1 *)lutFile_->Get("gain_12_2"); @@ -63,12 +65,28 @@ namespace Phase2L1GMT { lut2LL_[1 * 64 + 2] = (TH1 *)lutFile_->Get("gain2_2_1_LL"); coarseEta_ = (TH1 *)lutFile_->Get("coarseETALUT"); + + lutTheta1D_[1 * 64 + 0] = (TH1 *)lutThetaFile_->Get("gain1D_0_1"); + lutTheta1D_[1 * 64 + 2] = (TH1 *)lutThetaFile_->Get("gain1D_2_1"); + lutTheta1D_[1 * 64 + 4] = (TH1 *)lutThetaFile_->Get("gain1D_4_1"); + lutTheta1D_[1 * 64 + 6] = (TH1 *)lutThetaFile_->Get("gain1D_6_1"); + lutTheta1D_[2 * 64 + 4] = (TH1 *)lutThetaFile_->Get("gain1D_4_2"); + lutTheta1D_[3 * 64 + 0] = (TH1 *)lutThetaFile_->Get("gain1D_0_3"); + lutTheta2D_[1 * 64 + 0] = (TH1 *)lutThetaFile_->Get("gain2D_0_1"); + lutTheta2D_[1 * 64 + 2] = (TH1 *)lutThetaFile_->Get("gain2D_2_1"); + lutTheta2D_[1 * 64 + 4] = (TH1 *)lutThetaFile_->Get("gain2D_4_1"); + lutTheta2D_[1 * 64 + 6] = (TH1 *)lutThetaFile_->Get("gain2D_6_1"); + lutTheta2D_[2 * 64 + 0] = (TH1 *)lutThetaFile_->Get("gain2D_0_2"); + lutTheta2D_[2 * 64 + 4] = (TH1 *)lutThetaFile_->Get("gain2D_4_2"); + lutTheta2D_[3 * 64 + 0] = (TH1 *)lutThetaFile_->Get("gain2D_0_3"); + lutTheta1D11_[2 * 64 + 0] = (TH1 *)lutThetaFile_->Get("gain1D_0_2_phi1100"); + lutTheta1D01_[2 * 64 + 0] = (TH1 *)lutThetaFile_->Get("gain1D_0_2_phi0100"); + lutTheta1D10_[2 * 64 + 0] = (TH1 *)lutThetaFile_->Get("gain1D_0_2_phi1000"); } ~KMTFLUTs() { lutFile_->Close(); - if (lutFile_ != nullptr) - delete lutFile_; + lutThetaFile_->Close(); } std::vector trackGain(uint step, uint bitmask, uint K) { @@ -110,12 +128,51 @@ namespace Phase2L1GMT { return uint((1 << 12) * coarseEta_->GetBinContent(coarseEta_->GetXaxis()->FindBin(mask)) / M_PI); } - TFile *lutFile_; + std::vector trackGainTheta(uint step, uint bitmask, uint K, bool is2D) const { + std::vector gain(4, 0.0); + const TH1 *h; + if (is2D) { + h = lutTheta2D_.at(64 * step + bitmask); + } else { + h = lutTheta1D_.at(64 * step + bitmask); + } + gain[0] = h->GetBinContent(K + 1); + gain[1] = h->GetBinContent(512 + K + 1); + gain[2] = h->GetBinContent(2 * 512 + K + 1); + gain[3] = h->GetBinContent(3 * 512 + K + 1); + return gain; + } + + std::vector trackGainTheta2(uint step, uint bitmask, uint phiBitmask, uint K) const { + std::vector gain(4, 0.0); + const TH1 *h; + if (phiBitmask == 0b1100) { + h = lutTheta1D11_.at(64 * step + bitmask); + } else if (phiBitmask == 0b1000) { + h = lutTheta1D10_.at(64 * step + bitmask); + } else { + h = lutTheta1D01_.at(64 * step + bitmask); + } + gain[0] = h->GetBinContent(K + 1); + gain[1] = h->GetBinContent(512 + K + 1); + gain[2] = h->GetBinContent(2 * 512 + K + 1); + gain[3] = h->GetBinContent(3 * 512 + K + 1); + return gain; + } + + std::unique_ptr lutFile_; + std::unique_ptr lutThetaFile_; std::map lut_; std::map lut2HH_; std::map lut2LH_; std::map lut2HL_; std::map lut2LL_; + + std::map lutTheta1D_; + std::map lutTheta2D_; + std::map lutTheta1D11_; + std::map lutTheta1D10_; + std::map lutTheta1D01_; const TH1 *coarseEta_; }; diff --git a/L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTBarrelStubProcessor.h b/L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTBarrelStubProcessor.h index 81607c571c702..523ef4649e865 100644 --- a/L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTBarrelStubProcessor.h +++ b/L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTBarrelStubProcessor.h @@ -5,6 +5,8 @@ #include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhContainer.h" #include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThDigi.h" #include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThContainer.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTExtPhiThetaPair.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTExtPhiThetaPairContainer.h" #include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "CondFormats/L1TObjects/interface/L1TMuonBarrelParams.h" @@ -17,9 +19,10 @@ class L1TPhase2GMTBarrelStubProcessor { ~L1TPhase2GMTBarrelStubProcessor(); - l1t::MuonStubCollection makeStubs(const L1Phase2MuDTPhContainer*, const L1MuDTChambThContainer*); + l1t::MuonStubCollection makeStubs(const L1Phase2MuDTExtPhiThetaPairContainer*); private: + l1t::MuonStub buildStubwithZandkSlope(const L1Phase2MuDTExtPhiThetaPair&); l1t::MuonStub buildStub(const L1Phase2MuDTPhDigi&, const L1MuDTChambThDigi*); l1t::MuonStub buildStubNoEta(const L1Phase2MuDTPhDigi&); diff --git a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTKMTFProducer.cc b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTKMTFProducer.cc index 04855cd154cb3..c8c3a6b0411fd 100644 --- a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTKMTFProducer.cc +++ b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTKMTFProducer.cc @@ -95,12 +95,18 @@ void Phase2L1TGMTKMTFProducer::produce(edm::Event& iEvent, const edm::EventSetup std::vector kmtfTracks; for (const auto& track : kmtfOutput.first) { kmtfTracks.push_back(track); + //convert kmtf track.zPosition (LSB_kmtf=1500./2<<16) into z0 for SAMuon. + //LSBSAz0 = 1.6cm is too small given only 5 bits. the range fro z0 is +- 25.6cm from DataFormats/L1TMuonPhase2/interface/Constants.h + //eff. LSB = 1.6cm * 16 = 25.6 cm to widen the z0 range that can covered given only 5 bits. + //full conversion is z0_SA=z0_kmtf*(LSB_kmtf)*(1/LSB_SA)*(1/16) to convert between kmtf->SAMuon digitizations + ap_fixed z0 = + track.zPosition() * ap_ufixed<18, 0>((1500.0 / (1 << 16)) / (LSBSAz0 * 16)); l1t::SAMuon p(track.p4(), (track.curvatureAtVertex() < 0), track.ptPrompt(), - track.coarseEta(), + round(track.eta() / (M_PI / (1 << 12))), track.phiAtMuon() / (1 << 5), - 0, + z0, 0, track.stubs().size() - 1); p.setTF(l1t::tftype::bmtf); @@ -123,12 +129,14 @@ void Phase2L1TGMTKMTFProducer::produce(edm::Event& iEvent, const edm::EventSetup for (const auto& track : kmtfOutput.second) { kmtfTracks.push_back(track); ap_int<7> dxy = track.dxy() * ap_ufixed<8, 1>(1.606); + ap_fixed z0 = + track.zPosition() * ap_ufixed<18, 0>((1500.0 / (1 << 16)) / (LSBSAz0 * 16)); l1t::SAMuon p(track.displacedP4(), (track.curvatureAtMuon() < 0), track.ptDisplaced(), - track.coarseEta(), + round(track.eta() / (M_PI / (1 << 12))), track.phiAtMuon() / (1 << 5), - 0, + z0, dxy, track.approxDispChi2()); p.setTF(l1t::tftype::bmtf); diff --git a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc index ed680955534ea..3f65c2aacd3db 100644 --- a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc +++ b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc @@ -11,6 +11,8 @@ #include "L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTEndcapStubProcessor.h" #include "L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTBarrelStubProcessor.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTExtPhiThetaPairContainer.h" + #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/Framework/interface/ESProducts.h" @@ -34,6 +36,7 @@ class Phase2L1TGMTStubProducer : public edm::stream::EDProducer<> { edm::EDGetTokenT> srcCSC_; edm::EDGetTokenT srcDT_; edm::EDGetTokenT srcDTTheta_; + edm::EDGetTokenT srcDTPairs_; edm::EDGetTokenT srcRPC_; L1TPhase2GMTEndcapStubProcessor* procEndcap_; @@ -47,6 +50,7 @@ Phase2L1TGMTStubProducer::Phase2L1TGMTStubProducer(const edm::ParameterSet& iCon consumes>(iConfig.getParameter("srcCSC"))), srcDT_(consumes(iConfig.getParameter("srcDT"))), srcDTTheta_(consumes(iConfig.getParameter("srcDTTheta"))), + srcDTPairs_(consumes(iConfig.getParameter("srcDTPairs"))), srcRPC_(consumes(iConfig.getParameter("srcRPC"))), procEndcap_(new L1TPhase2GMTEndcapStubProcessor(iConfig.getParameter("Endcap"))), procBarrel_(new L1TPhase2GMTBarrelStubProcessor(iConfig.getParameter("Barrel"))), @@ -107,6 +111,9 @@ void Phase2L1TGMTStubProducer::produce(edm::Event& iEvent, const edm::EventSetup Handle dtThetaDigis; iEvent.getByToken(srcDTTheta_, dtThetaDigis); + Handle dtPairs; + iEvent.getByToken(srcDTPairs_, dtPairs); + //Generate a unique stub ID l1t::MuonStubCollection stubs; l1t::MuonStubCollection stubsKMTF; @@ -115,7 +122,7 @@ void Phase2L1TGMTStubProducer::produce(edm::Event& iEvent, const edm::EventSetup for (auto& stub : stubsEndcap) { stubs.push_back(stub); } - l1t::MuonStubCollection stubsBarrel = procBarrel_->makeStubs(dtDigis.product(), dtThetaDigis.product()); + l1t::MuonStubCollection stubsBarrel = procBarrel_->makeStubs(dtPairs.product()); for (auto& stub : stubsBarrel) { //convert to Hybrid stubs.push_back(convertToHybrid(stub)); @@ -139,6 +146,7 @@ void Phase2L1TGMTStubProducer::fillDescriptions(edm::ConfigurationDescriptions& desc.add("srcCSC", edm::InputTag("simCscTriggerPrimitiveDigis")); desc.add("srcDT", edm::InputTag("dtTriggerPhase2PrimitiveDigis")); desc.add("srcDTTheta", edm::InputTag("simDtTriggerPrimitiveDigis")); + desc.add("srcDTPairs", edm::InputTag("dtTriggerPhase2PrimitivePairDigis")); desc.add("srcRPC", edm::InputTag("simMuonRPCDigis")); { edm::ParameterSetDescription psd0; diff --git a/L1Trigger/Phase2L1GMT/python/gmtKMTFMuons_cfi.py b/L1Trigger/Phase2L1GMT/python/gmtKMTFMuons_cfi.py index b328e18adac84..5119381b7c8fa 100644 --- a/L1Trigger/Phase2L1GMT/python/gmtKMTFMuons_cfi.py +++ b/L1Trigger/Phase2L1GMT/python/gmtKMTFMuons_cfi.py @@ -7,12 +7,14 @@ algo = cms.PSet( verbose = cms.bool(False), lutFile = cms.string("L1Trigger/Phase2L1GMT/data/packedGainLUTs.root"), + lutThetaFile = cms.string("L1Trigger/Phase2L1GMT/data/packedThetaGainLUTs.root"), initialK = cms.vdouble(-0.4576229536749278, -0.6364802777566145, -1.0305030909883524, -1.7272067322624118), initialK2 = cms.vdouble(-6.442002637356136e-05, -9.582709649965545e-05, -0.0002741064246218815, -0.0014910074450869175), eLoss = cms.vdouble(6.77765e-05,0,0,0), aPhi = cms.vdouble(5.6533349391874275, 0.03477876333443834, 0.032506522838098864, 0.024752809174909053), aPhiB = cms.vdouble(-2.02, -0.2994087741381382, -0.4033668521165302, -0.3592231728688621), + zdeltaR = cms.vdouble(445.0, 526.0-445.0, 635.0-526.0, 730.0-635.0), aPhiBNLO = cms.vdouble(9.04133e-05,0,0,0), bPhi = cms.vdouble(-1,.18245,.20898,.17286), @@ -58,11 +60,15 @@ ###Only for the offline algo -not in firmware -------------------- mScatteringPhi = cms.vdouble(0.1169021113298598, 0.00016777763395543814, 0.0004322078772344548, 0.00024985881710722107), mScatteringPhiB = cms.vdouble(.0522762, 0.01762000062188365, 0.03508319015441297, 0.03126825551530328), + mScatteringz = cms.vdouble(0.030625, 0.00010609, 0.00033489, 0.00033489), + mScatteringkSlope = cms.vdouble(0.083521, 0.032041, 0.047961, 0.047961), pointResolutionPhi = cms.double(1.), pointResolutionPhiB = cms.double(12493.7429036), pointResolutionPhiBH = cms.vdouble(19925.62953113343, 15583.06791339368, 10258.11768352221, 15462.112839170433), pointResolutionPhiBL = cms.vdouble(161519.85395846734, 155051.58394241595, 149693.88179343447, 174896.46766622085), pointResolutionVertex = cms.double(1.), + pointResolutionz = cms.vdouble(214369, 9980.01, 9254.44, 9254.44), + pointResolutionkSlope = cms.vdouble(186624, 350464, 375769, 375769), curvResolution1 = cms.vdouble(1, 2.36097e+03, 8.73003e+02, 2.58138e5), curvResolution2 = cms.vdouble(1, 4.903692e+00, 4.87941e+01, 0)), Nprompt = cms.uint32(12), diff --git a/L1Trigger/Phase2L1GMT/python/gmtStubs_cfi.py b/L1Trigger/Phase2L1GMT/python/gmtStubs_cfi.py index 1e4f32896bc7f..97053d7bcc162 100644 --- a/L1Trigger/Phase2L1GMT/python/gmtStubs_cfi.py +++ b/L1Trigger/Phase2L1GMT/python/gmtStubs_cfi.py @@ -5,6 +5,7 @@ srcCSC = cms.InputTag("simCscTriggerPrimitiveDigis"), srcDT = cms.InputTag("dtTriggerPhase2PrimitiveDigis"), srcDTTheta = cms.InputTag("simDtTriggerPrimitiveDigis"), + srcDTPairs = cms.InputTag("dtTriggerPhase2PrimitivePairDigis"), srcRPC = cms.InputTag("simMuonRPCDigis"), Endcap =cms.PSet( verbose = cms.uint32(0), diff --git a/L1Trigger/Phase2L1GMT/src/KMTF.cc b/L1Trigger/Phase2L1GMT/src/KMTF.cc index 918554895b131..b96989ee9cecb 100644 --- a/L1Trigger/Phase2L1GMT/src/KMTF.cc +++ b/L1Trigger/Phase2L1GMT/src/KMTF.cc @@ -72,74 +72,80 @@ std::pair, std::vector > KMTF::proce } bool pre_patterns = (verbose_ > 1) && ((Nstubs4 + Nstubs3 + Nstubs2 + Nstubs1) > 2); - //OK now process the data almost as in hardware for (unsigned int i = 0; i < 32; ++i) { //print the stubs taking into account - bool patterns = pre_patterns && ((i < Nstubs4) || (i < Nstubs3) || (i << Nstubs2)); + bool patterns = pre_patterns && ((i < Nstubs4) || (i < Nstubs3) || (i < Nstubs2)); if (patterns) { edm::LogInfo("KMTF") << "KMTFPattern " << std::flush; if (i < Nstubs4) edm::LogInfo("KMTF") << stubs4[0]->coord1() << " " << stubs4[0]->coord2() << " " << stubs4[0]->quality() << " " - << " 1 " << stubs4[0]->kmtf_address() << " 0 " << std::flush; + << " 1 " << stubs4[0]->kmtf_address() << " 0 " << stubs4[0]->eta1() << " " + << stubs4[0]->eta2() << " " << (stubs4[0]->etaQuality() > 0 ? 1 : 0) << " " << std::flush; else - edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 511 0 0 0 0 " << std::flush; if (i < Nstubs3) { for (const auto& s : stubs3) { edm::LogInfo("KMTF") << "" << s->coord1() << " " << s->coord2() << " " << s->quality() << " 1 " - << s->kmtf_address() << " 0 " << std::flush; + << s->kmtf_address() << " 0 " << s->eta1() << " " << s->eta2() << " " + << (s->etaQuality() > 0 ? 1 : 0) << " " << std::flush; } //pad with zeros for (unsigned int j = stubs3.size(); j < 32; ++j) { - edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 511 0 0 0 0 " << std::flush; } } else { for (unsigned int j = stubs3.size(); j < 32; ++j) { - edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 511 0 0 0 0 " << std::flush; } for (const auto& s : stubs3) { edm::LogInfo("KMTF") << "" << s->coord1() << " " << s->coord2() << " " << s->quality() << " 1 " - << s->kmtf_address() << " 0 " << std::flush; + << s->kmtf_address() << " 0 " << s->eta1() << " " << s->eta2() << " " + << (s->etaQuality() > 0 ? 1 : 0) << " " << std::flush; } } if (i < Nstubs2) { for (const auto& s : stubs2) { edm::LogInfo("KMTF") << "" << s->coord1() << " " << s->coord2() << " " << s->quality() << " 1 " - << s->kmtf_address() << " 0 " << std::flush; + << s->kmtf_address() << " 0 " << s->eta1() << " " << s->eta2() << " " + << (s->etaQuality() > 0 ? 1 : 0) << " " << std::flush; } //pad with zeros for (unsigned int j = stubs2.size(); j < 32; ++j) { - edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 511 0 0 0 0 " << std::flush; } } else { for (unsigned int j = stubs2.size(); j < 32; ++j) { - edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 511 0 0 0 0 " << std::flush; } for (const auto& s : stubs2) { edm::LogInfo("KMTF") << s->coord1() << " " << s->coord2() << " " << s->quality() << " 1 " << s->kmtf_address() - << " 0 " << std::flush; + << " 0 " << s->eta1() << " " << s->eta2() << " " << (s->etaQuality() > 0 ? 1 : 0) << " " + << std::flush; } } if (i < Nstubs1) { for (const auto& s : stubs1) { edm::LogInfo("KMTF") << s->coord1() << " " << s->coord2() << " " << s->quality() << " 1 " << s->kmtf_address() - << " 0 " << std::flush; + << " 0 " << s->eta1() << " " << s->eta2() << " " << (s->etaQuality() > 0 ? 1 : 0) << " " + << std::flush; } //pad with zeros for (unsigned int j = stubs1.size(); j < 32; ++j) { - edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 511 0 0 0 0 " << std::flush; } } else { for (unsigned int j = stubs1.size(); j < 32; ++j) { - edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 511 0 0 0 0 " << std::flush; } for (const auto& s : stubs1) { edm::LogInfo("KMTF") << s->coord1() << " " << s->coord2() << " " << s->quality() << " 1 " << s->kmtf_address() - << " 0 " << std::flush; + << " 0 " << s->eta1() << " " << s->eta2() << " " << (s->etaQuality() > 0 ? 1 : 0) << " " + << std::flush; } } } @@ -162,23 +168,24 @@ std::pair, std::vector > KMTF::proce if (tracks.first.id() & 0x1) edm::LogInfo("KMTF") << "1 " << (tracks.first.curvatureAtVertex() < 0 ? 1 : 0) << " " << tracks.first.ptPrompt() << " " << tracks.first.phiAtMuon() / (1 << 5) << " " - << tracks.first.coarseEta() << " " << int(tracks.first.dxy() * ap_ufixed<8, 1>(1.606)) - << " " << tracks.first.rankPrompt() << " " << std::flush; - + << int(round(tracks.first.eta() / (M_PI / (1 << 12)))) << " " + << int(tracks.first.dxy() * ap_ufixed<8, 1>(1.606)) << " " << tracks.first.rankPrompt() + << " " << tracks.first.zPosition() << " " << tracks.first.kSlope() << " " << std::flush; else - edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 0 0 " << std::flush; if (tracks.second.id() & 0x2) - edm::LogInfo("KMTF") << "1 " << (tracks.second.curvatureAtVertex() < 0 ? 1 : 0) << " " + edm::LogInfo("KMTF") << "1 " << (tracks.second.curvatureAtMuon() < 0 ? 1 : 0) << " " << tracks.second.ptDisplaced() << " " << tracks.second.phiAtMuon() / (1 << 5) << " " - << tracks.second.coarseEta() << " " << int(tracks.second.dxy() * ap_ufixed<8, 1>(1.606)) - << " " << tracks.second.rankDisp() << " " << std::flush; - + << int(round(tracks.second.eta() / (M_PI / (1 << 12)))) << " " + << int(tracks.second.dxy() * ap_ufixed<8, 1>(1.606)) << " " << tracks.second.rankDisp() + << " " << tracks.second.zPosition() << " " << tracks.second.kSlope() << " " + << std::flush; else - edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 0 0 " << std::flush; } } else if (patterns) { - edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush; - edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 0 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 0 0 " << std::flush; } if (i < Nstubs3) { @@ -196,23 +203,26 @@ std::pair, std::vector > KMTF::proce if (tracks.first.id() & 0x1) edm::LogInfo("KMTF") << "1 " << (tracks.first.curvatureAtVertex() < 0 ? 1 : 0) << " " << tracks.first.ptPrompt() << " " << tracks.first.phiAtMuon() / (1 << 5) << " " - << tracks.first.coarseEta() << " " << int(tracks.first.dxy() * ap_ufixed<8, 1>(1.606)) - << " " << tracks.first.rankPrompt() << " " << std::flush; + << int(round(tracks.first.eta() / (M_PI / (1 << 12)))) << " " + << int(tracks.first.dxy() * ap_ufixed<8, 1>(1.606)) << " " << tracks.first.rankPrompt() + << " " << tracks.first.zPosition() << " " << tracks.first.kSlope() << " " << std::flush; else - edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 0 0 " << std::flush; if (tracks.second.id() & 0x2) - edm::LogInfo("KMTF") << "1 " << (tracks.second.curvatureAtVertex() < 0 ? 1 : 0) << " " + edm::LogInfo("KMTF") << "1 " << (tracks.second.curvatureAtMuon() < 0 ? 1 : 0) << " " << tracks.second.ptDisplaced() << " " << tracks.second.phiAtMuon() / (1 << 5) << " " - << tracks.second.coarseEta() << " " << int(tracks.second.dxy() * ap_ufixed<8, 1>(1.606)) - << " " << tracks.second.rankDisp() << " " << std::flush; + << int(round(tracks.second.eta() / (M_PI / (1 << 12)))) << " " + << int(tracks.second.dxy() * ap_ufixed<8, 1>(1.606)) << " " << tracks.second.rankDisp() + << " " << tracks.second.zPosition() << " " << tracks.second.kSlope() << " " + << std::flush; else - edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 0 0 " << std::flush; } } else if (patterns) { - edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush; - edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 0 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 0 0 " << std::flush; } if (i < Nstubs2) { l1t::MuonStubRefVector stubs_proc; @@ -227,22 +237,25 @@ std::pair, std::vector > KMTF::proce if (tracks.first.id() & 0x1) edm::LogInfo("KMTF") << "1 " << (tracks.first.curvatureAtVertex() < 0 ? 1 : 0) << " " << tracks.first.ptPrompt() << " " << tracks.first.phiAtMuon() / (1 << 5) << " " - << tracks.first.coarseEta() << " " << int(tracks.first.dxy() * ap_ufixed<8, 1>(1.606)) - << " " << tracks.first.rankPrompt() << " " << std::flush; + << int(round(tracks.first.eta() / (M_PI / (1 << 12)))) << " " + << int(tracks.first.dxy() * ap_ufixed<8, 1>(1.606)) << " " << tracks.first.rankPrompt() + << " " << tracks.first.zPosition() << " " << tracks.first.kSlope() << " " << std::flush; else - edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 0 0 " << std::flush; if (tracks.second.id() & 0x2) - edm::LogInfo("KMTF") << "1 " << (tracks.second.curvatureAtVertex() < 0 ? 1 : 0) << " " + edm::LogInfo("KMTF") << "1 " << (tracks.second.curvatureAtMuon() < 0 ? 1 : 0) << " " << tracks.second.ptDisplaced() << " " << tracks.second.phiAtMuon() / (1 << 5) << " " - << tracks.second.coarseEta() << " " << int(tracks.second.dxy() * ap_ufixed<8, 1>(1.606)) - << " " << tracks.second.rankDisp(); + << int(round(tracks.second.eta() / (M_PI / (1 << 12)))) << " " + << int(tracks.second.dxy() * ap_ufixed<8, 1>(1.606)) << " " << tracks.second.rankDisp() + << " " << tracks.second.zPosition() << " " << tracks.second.kSlope() << " " + << std::flush; else - edm::LogInfo("KMTF") << "0 0 0 0 0 0 0" << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 0 0 " << std::flush; } } else if (patterns) { - edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush; - edm::LogInfo("KMTF") << "0 0 0 0 0 0 0"; + edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 0 0 " << std::flush; + edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 0 0"; } //Now the shift register emulation in C_++ if (stubs4.size() > 1) { @@ -301,6 +314,8 @@ void KMTF::overlapCleanTrack(l1t::KMTFTrack& source, const l1t::KMTFTrack& other int id2 = vertex ? other.id() & 0x1 : other.id() & 0x2; bool keep = true; unsigned int pattern = 0; + unsigned int thetaPattern = 0; + if (id1 == 0) keep = false; else if (id1 != 0 && id2 != 0) { @@ -320,10 +335,13 @@ void KMTF::overlapCleanTrack(l1t::KMTFTrack& source, const l1t::KMTFTrack& other if (ok) { stubs.push_back(s1); pattern = pattern | (1 << (s1->depthRegion() - 1)); + if (s1->depthRegion() != 4 && s1->etaQuality() > 0) + thetaPattern |= (1 << (s1->depthRegion() - 1)); } } source.setStubs(stubs); source.setHitPattern(pattern); + source.setThetaDigiPattern(thetaPattern); } std::vector KMTF::cleanRegion(const std::vector& tracks2, diff --git a/L1Trigger/Phase2L1GMT/src/KMTFCore.cc b/L1Trigger/Phase2L1GMT/src/KMTFCore.cc index fcbca8ba7284c..0cb775261d990 100644 --- a/L1Trigger/Phase2L1GMT/src/KMTFCore.cc +++ b/L1Trigger/Phase2L1GMT/src/KMTFCore.cc @@ -1,7 +1,8 @@ #include "L1Trigger/Phase2L1GMT/interface/KMTFCore.h" using namespace Phase2L1GMT; KMTFCore::KMTFCore(const edm::ParameterSet& settings) - : lutService_(new KMTFLUTs(settings.getParameter("lutFile"))), + : lutService_(new KMTFLUTs(settings.getParameter("lutFile"), + settings.getParameter("lutThetaFile"))), verbose_(settings.getParameter("verbose")), initK_(settings.getParameter >("initialK")), initK2_(settings.getParameter >("initialK2")), @@ -47,13 +48,18 @@ KMTFCore::KMTFCore(const edm::ParameterSet& settings) combos1_(settings.getParameter >("combos1")), useOfflineAlgo_(settings.getParameter("useOfflineAlgo")), + zdeltaR_(settings.getParameter >("zdeltaR")), mScatteringPhi_(settings.getParameter >("mScatteringPhi")), mScatteringPhiB_(settings.getParameter >("mScatteringPhiB")), + mScatteringz_(settings.getParameter >("mScatteringz")), + mScatteringkSlope_(settings.getParameter >("mScatteringkSlope")), pointResolutionPhi_(settings.getParameter("pointResolutionPhi")), pointResolutionPhiB_(settings.getParameter("pointResolutionPhiB")), pointResolutionPhiBH_(settings.getParameter >("pointResolutionPhiBH")), pointResolutionPhiBL_(settings.getParameter >("pointResolutionPhiBL")), pointResolutionVertex_(settings.getParameter("pointResolutionVertex")), + pointResolutionz_(settings.getParameter >("pointResolutionz")), + pointResolutionkSlope_(settings.getParameter >("pointResolutionkSlope")), curvResolution1_(settings.getParameter >("curvResolution1")), curvResolution2_(settings.getParameter >("curvResolution2")) {} @@ -78,11 +84,10 @@ std::pair KMTFCore::chain(const l1t::MuonStubRef default: throw cms::Exception("KMTFCore") << "Something really bad happend\n"; } - - l1t::KMTFTrack nullTrack(seed, seed->coord1(), correctedPhiB(seed)); + l1t::KMTFTrack nullTrack(seed, seed->coord1(), correctedPhiB(seed), seed->eta1(), satKSlope(seed->eta2())); seedQual = seed->quality(); for (const auto& mask : combinatorics) { - l1t::KMTFTrack track(seed, seed->coord1(), correctedPhiB(seed)); + l1t::KMTFTrack track(seed, seed->coord1(), correctedPhiB(seed), seed->eta1(), satKSlope(seed->eta2())); int phiB = correctedPhiB(seed); int charge; if (phiB == 0) @@ -103,16 +108,20 @@ std::pair KMTFCore::chain(const l1t::MuonStubRef initialK = pow(2, BITSCURV - 1) - 1; if (initialK <= -pow(2, BITSCURV - 1)) initialK = -pow(2, BITSCURV - 1) + 1; - track.setCoordinates(seed->depthRegion(), initialK, seed->coord1(), phiB); + + track.setCoordinates(seed->depthRegion(), initialK, seed->coord1(), phiB, seed->eta1(), satKSlope(seed->eta2())); + if (seed->quality() < 6) { - track.setCoordinates(seed->depthRegion(), initialK, seed->coord1(), 0); + track.setCoordinates(seed->depthRegion(), initialK, seed->coord1(), 0, seed->eta1(), satKSlope(seed->eta2())); } if (verbose_) { - edm::LogInfo("KMTFCore") << "Initial state: phiB=" << phiB << " addr=" << address << " K=" << initialK; + edm::LogInfo("KMTFCore") << "Initial state: phiB=" << phiB << " addr=" << address << " K=" << initialK + << " z=" << seed->eta1() << " kSlope=" << satKSlope(seed->eta2()); } track.setHitPattern(hitPattern(track)); + track.setThetaDigiPattern(thetaDigiPattern(track)); //set covariance - l1t::KMTFTrack::CovarianceMatrix covariance; + l1t::CovarianceMatrix5dim covariance; float DK = curvResolution1_[track.step() - 1] + curvResolution2_[track.step() - 1] * initialK * initialK; if (seed->quality() < 6) DK = pow(2, 22); @@ -120,11 +129,25 @@ std::pair KMTFCore::chain(const l1t::MuonStubRef covariance(0, 0) = DK * 4; covariance(0, 1) = 0; covariance(0, 2) = 0; + covariance(0, 3) = 0; + covariance(0, 4) = 0; covariance(1, 0) = 0; covariance(1, 1) = float(pointResolutionPhi_); covariance(1, 2) = 0; + covariance(1, 3) = 0; + covariance(1, 4) = 0; covariance(2, 0) = 0; covariance(2, 1) = 0; + covariance(2, 3) = 0; + covariance(2, 4) = 0; + covariance(3, 0) = 0; + covariance(3, 1) = 0; + covariance(3, 2) = 0; + covariance(3, 4) = 0; + covariance(4, 0) = 0; + covariance(4, 1) = 0; + covariance(4, 2) = 0; + covariance(4, 3) = 0; if (!(mask == 1 || mask == 2 || mask == 3 || mask == 4 || mask == 5 || mask == 9 || mask == 6 || mask == 10 || mask == 12)) covariance(2, 2) = float(pointResolutionPhiB_); @@ -134,12 +157,19 @@ std::pair KMTFCore::chain(const l1t::MuonStubRef else covariance(2, 2) = float(pointResolutionPhiBH_[seed->depthRegion() - 1]); } + if (seed->etaQuality() <= 0) { + covariance(3, 3) = pow(2, 22); + covariance(4, 4) = pow(2, 22); + } else { + covariance(3, 3) = float(pointResolutionz_[seed->depthRegion() - 1]); + covariance(4, 4) = float(pointResolutionkSlope_[seed->depthRegion() - 1]); + } track.setCovariance(covariance); - // if (verbose_) { edm::LogInfo("KMTFCore") << "New Kalman fit staring at step=" << track.step() << ", phi=" << track.positionAngle() - << ", phiB=" << track.bendingAngle() << ", with curvature=" << track.curvature(); + << ", phiB=" << track.bendingAngle() << ", z=" << track.zPosition() + << ",kSlope = " << track.kSlope() << ", with curvature=" << track.curvature(); edm::LogInfo("KMTFCore") << "BITMASK:" << std::flush; for (unsigned int i = 0; i < 4; ++i) edm::LogInfo("KMTFCore") << getBit(mask, i) << std::flush; @@ -152,8 +182,8 @@ std::pair KMTFCore::chain(const l1t::MuonStubRef edm::LogInfo("KMTFCore") << "station=" << stub->depthRegion() << " phi=" << stub->coord1() << " phiB=" << correctedPhiB(stub) << " qual=" << stub->quality() << " tag=" << stub->id() << " sector=" << stub->phiRegion() - << " wheel=" << stub->etaRegion() << " fineEta= " << stub->eta1() << " " - << stub->eta2(); + << " wheel=" << stub->etaRegion() << " z= " << stub->eta1() + << " kSlope = " << satKSlope(stub->eta2()); edm::LogInfo("KMTFCore") << "------------------------------------------------------"; edm::LogInfo("KMTFCore") << "------------------------------------------------------"; } @@ -163,7 +193,8 @@ std::pair KMTFCore::chain(const l1t::MuonStubRef while (track.step() > 0) { // muon station 1 if (track.step() == 1) { - track.setCoordinatesAtMuon(track.curvature(), track.positionAngle(), track.bendingAngle()); + track.setCoordinatesAtMuon( + track.curvature(), track.positionAngle(), track.bendingAngle(), track.zPosition(), track.kSlope()); passedU = estimateChiSquare(track, false); setRank(track, false); @@ -174,36 +205,64 @@ std::pair KMTFCore::chain(const l1t::MuonStubRef setFourVectors(track); //calculate coarse eta ////////////////////// - if (verbose_) + if (verbose_) { edm::LogInfo("KMTFCore") << "Unconstrained PT in Muon System: pt=" << track.displacedP4().pt(); + } calculateEta(track); } propagate(track); if (verbose_) edm::LogInfo("KMTFCore") << "propagated Coordinates step:" << track.step() << "phi=" << track.positionAngle() - << "phiB=" << track.bendingAngle() << "K=" << track.curvature(); - if (track.step() > 0) + << "phiB=" << track.bendingAngle() << "K=" << track.curvature() + << ", z=" << track.zPosition() << ", kSlope=" << track.kSlope(); + if (track.step() > 0) { if (getBit(mask, track.step() - 1)) { std::pair bestStub = match(seed, stubs, track.step()); if (verbose_) edm::LogInfo("KMTFCore") << "Found match =" << bestStub.first << " index=" << bestStub.second << " number of all stubs=" << stubs.size(); - - if ((!bestStub.first) || (!update(track, stubs[bestStub.second], mask, seedQual))) + const bool updated = bestStub.first ? update(track, stubs[bestStub.second], mask, seedQual) : false; + if ((!bestStub.first) || (!updated)) { + if (verbose_) { + edm::LogInfo("KMTFCore") << "[KMTF_VALIDDBG] Breaking Kalman chain before final ID assignment" + << " seed(st=" << seed->depthRegion() << ",sec=" << seed->phiRegion() + << ",wh=" << seed->etaRegion() << ",bx=" << seed->bxNum() << ",id=" << seed->id() + << ")" + << " step=" << track.step() << " mask=" << mask + << " hitPattern=" << track.hitPattern() << " matchFound=" << bestStub.first + << " matchIndex=" << bestStub.second << " updateOK=" << updated + << " partialID=" << track.id() << " nStubs=" << track.stubs().size(); + if (seed->depthRegion() == 2) { + edm::LogInfo("KMTFCore") << "[KMTF_VALIDDBG_STA2] break-on-no-update/no-match" + << " seed(st=2,sec=" << seed->phiRegion() << ",wh=" << seed->etaRegion() + << ",bx=" << seed->bxNum() << ",id=" << seed->id() << ")" + << " currentStep=" << track.step() << " mask=" << mask + << " hitPattern=" << track.hitPattern() + << " thetaPattern=" << track.thetaDigiPattern() << " passU_sofar=" << passedU + << " passV_sofar=" << passedV << " id_sofar=" << track.id() + << " phiMuon=" << track.phiAtMuon() << " phiVertex=" << track.phiAtVertex() + << " z=" << track.zPosition() << " kSlope=" << track.kSlope(); + } + } break; + } if (verbose_) { edm::LogInfo("KMTFCore") << "updated Coordinates step:" << track.step() << " phi=" << track.positionAngle() - << " phiB=" << track.bendingAngle() << " K=" << track.curvature(); + << " phiB=" << track.bendingAngle() << " K=" << track.curvature() + << ", z=" << track.zPosition() << ", kSlope=" << track.kSlope(); } } + } if (track.step() == 0) { - track.setCoordinatesAtVertex(track.curvature(), track.positionAngle(), track.bendingAngle()); + track.setCoordinatesAtVertex( + track.curvature(), track.positionAngle(), track.bendingAngle(), track.zPosition(), track.kSlope()); if (verbose_) edm::LogInfo("KMTFCore") << " Coordinates before vertex constraint step:" << track.step() << " phi=" << track.phiAtVertex() << " dxy=" << track.dxy() - << " K=" << track.curvatureAtVertex(); + << " K=" << track.curvatureAtVertex() << ", z=" << track.zPosition() + << ", kSlope=" << track.kSlope(); //apply vertex constraint for non single tracks if (track.stubs().size() > 1) @@ -226,12 +285,37 @@ std::pair KMTFCore::chain(const l1t::MuonStubRef } setFourVectors(track); //finally set the displaced or prompt ID + const int oldId = track.id(); track.setIDFlag(passedV, passedU); + if (verbose_) { + edm::LogInfo("KMTFCore") << "[KMTF_VALIDDBG] setIDFlag transition" + << " seed(st=" << seed->depthRegion() << ",sec=" << seed->phiRegion() + << ",wh=" << seed->etaRegion() << ",bx=" << seed->bxNum() << ",id=" << seed->id() + << ")" + << " mask=" << mask << " hitPattern=" << track.hitPattern() + << " thetaPattern=" << track.thetaDigiPattern() << " passPrompt=" << passedV + << " passDisp=" << passedU << " promptChi2=" << track.approxPromptChi2() + << " dispChi2=" << track.approxDispChi2() << " rankPrompt=" << track.rankPrompt() + << " rankDisp=" << track.rankDisp() << " oldID=" << oldId << " newID=" << track.id() + << " phiMuon=" << track.phiAtMuon() << " phiVertex=" << track.phiAtVertex() + << " nStubs=" << track.stubs().size(); + if (seed->depthRegion() == 2) { + edm::LogInfo("KMTFCore") << "[KMTF_VALIDDBG_STA2] final-id-decision" + << " seed(st=2,sec=" << seed->phiRegion() << ",wh=" << seed->etaRegion() + << ",bx=" << seed->bxNum() << ",id=" << seed->id() << ")" + << " mask=" << mask << " passPrompt=" << passedV << " passDisp=" << passedU + << " oldID=" << oldId << " newID=" << track.id() + << " rankPrompt=" << track.rankPrompt() << " rankDisp=" << track.rankDisp() + << " promptChi2=" << track.approxPromptChi2() + << " dispChi2=" << track.approxDispChi2() << " phiMuon=" << track.phiAtMuon() + << " phiVertex=" << track.phiAtVertex() << " z=" << track.zPosition() + << " kSlope=" << track.kSlope() << " nStubs=" << track.stubs().size(); + } + } if (verbose_) edm::LogInfo("KMTFCore") << "Floating point coordinates at vertex: pt=" << track.pt() << ", eta=" << track.eta() << " phi=" << track.phi(); - pretracks.push_back(track); } } @@ -281,8 +365,15 @@ std::vector KMTFCore::clean(const std::vector& t for (const auto& track : tracks) { if (vertex) { - if ((track.id() & 0x1) == 0) + if ((track.id() & 0x1) == 0) { + if (verbose_) { + edm::LogInfo("KMTFCore") << "[KMTF_VALIDDBG] clean(prompt) dropping pretrack due to prompt ID bit=0" + << " seedStep=" << seed << " id=" << track.id() + << " hitPattern=" << track.hitPattern() << " rankPrompt=" << track.rankPrompt() + << " rankDisp=" << track.rankDisp() << " nStubs=" << track.stubs().size(); + } continue; + } if (verbose_) edm::LogInfo("KMTFCore") << "Chain Cleaning : Pre Track = pattern = " << track.rankPrompt() << " rank=" << track.hitPattern(); @@ -290,8 +381,15 @@ std::vector KMTFCore::clean(const std::vector& t infoTrack[track.hitPattern()] = track; } else { - if ((track.id() & 0x2) == 0) + if ((track.id() & 0x2) == 0) { + if (verbose_) { + edm::LogInfo("KMTFCore") << "[KMTF_VALIDDBG] clean(displaced) dropping pretrack due to displaced ID bit=0" + << " seedStep=" << seed << " id=" << track.id() + << " hitPattern=" << track.hitPattern() << " rankPrompt=" << track.rankPrompt() + << " rankDisp=" << track.rankDisp() << " nStubs=" << track.stubs().size(); + } continue; + } infoRank[track.hitPattern()] = track.rankDisp(); infoTrack[track.hitPattern()] = track; } @@ -331,9 +429,21 @@ std::vector KMTFCore::clean(const std::vector& t selected = 1; auto search = infoTrack.find(selected); - if (search != infoTrack.end()) + if (search != infoTrack.end()) { + if (verbose_) { + const auto& kept = search->second; + edm::LogInfo("KMTFCore") << "[KMTF_VALIDDBG] clean(" << (vertex ? "prompt" : "displaced") + << ") keeping selected pretrack" + << " seedStep=" << seed << " selectedPattern=" << selected << " id=" << kept.id() + << " rankPrompt=" << kept.rankPrompt() << " rankDisp=" << kept.rankDisp() + << " hitPattern=" << kept.hitPattern() << " thetaPattern=" << kept.thetaDigiPattern() + << " phiMuon=" << kept.phiAtMuon() << " phiVertex=" << kept.phiAtVertex() + << " curvMuon=" << kept.curvatureAtMuon() << " curvVertex=" << kept.curvatureAtVertex() + << " z=" << kept.zPosition() << " kSlope=" << kept.kSlope() + << " nStubs=" << kept.stubs().size(); + } out.push_back(search->second); - + } return out; } @@ -429,8 +539,10 @@ void KMTFCore::propagate(l1t::KMTFTrack& track) { int phi = track.positionAngle(); int phiB = track.bendingAngle(); unsigned int step = track.step(); - + int z = track.zPosition(); + int kSlope = track.kSlope(); int charge = 1; + if (K != 0) charge = K / fabs(K); @@ -477,6 +589,27 @@ void KMTFCore::propagate(l1t::KMTFTrack& track) { << ap_ufixed(bPhiB_[step - 1]).to_float() << " = " << phiB12.to_int(); } + //z and kSlope propagation + // dR conversion factor comes from ZRES_CONV and KRES_CONV: ZRES_CONV/KRES_CONV=(65536/1500)/(65536/2) to go from physical (cm) to digitized units + double zdR_CONV = 2.0 / 1500.0; + double zdeltaR_dig = zdeltaR_[step - 1] * zdR_CONV; + int kSlopeNew = kSlope; + int zNew; + zNew = + ap_fixed(ap_fixed(z) - ap_ufixed(zdeltaR_dig) * + ap_fixed(kSlope)); + if (zNew > (1 << (BITSZ - 1)) - 1) { + if (verbose_) { + edm::LogInfo("KMTFCore") << "z saturated high during propagation, step=" << step; + } + zNew = (1 << (BITSZ - 1)) - 1; + } else if (zNew < -(1 << (BITSZ - 1))) { + if (verbose_) { + edm::LogInfo("KMTFCore") << "z saturated low during propagation, step=" << step; + } + zNew = -(1 << (BITSZ - 1)); + } + //Only for the propagation to vertex we use second order; if (step == 1) { ap_fixed<10, 4> aPhiB = aPhiB_[step - 1]; @@ -504,51 +637,76 @@ void KMTFCore::propagate(l1t::KMTFTrack& track) { //where we want to check what is happening in the covariance matrix //Create the transformation matrix - double a[9]; - a[0] = 1.; + double a[25]; + a[0] = 1.0; a[1] = 0.0; a[2] = 0.0; - a[3] = aPhi_[step - 1]; - // a[3] = 0.0; - a[4] = 1.0; - a[5] = -bPhi_[step - 1]; - //a[6]=0.0; - a[6] = aPhiB_[step - 1]; + a[3] = 0.0; + a[4] = 0.0; + a[5] = aPhi_[step - 1]; + a[6] = 1.0; + a[7] = -bPhi_[step - 1]; + a[8] = 0.0; + a[9] = 0.0; + a[10] = aPhiB_[step - 1]; if (step == 1) - a[6] = aPhiB_[step - 1] / 2.0; - - a[7] = 0.0; - a[8] = bPhiB_[step - 1]; - - ROOT::Math::SMatrix P(a, 9); + a[10] = aPhiB_[step - 1] / 2.0; + a[11] = 0.0; + a[12] = bPhiB_[step - 1]; + a[13] = 0.0; + a[14] = 0.0; + a[15] = 0.0; + a[16] = 0.0; + a[17] = 0.0; + a[18] = 1.0; + a[19] = -zdeltaR_dig; + a[20] = 0.0; + a[21] = 0.0; + a[22] = 0.0; + a[23] = 0.0; + a[24] = 1.0; + + ROOT::Math::SMatrix P(a, 25); const std::vector& covLine = track.covariance(); - l1t::KMTFTrack::CovarianceMatrix cov(covLine.begin(), covLine.end()); + l1t::CovarianceMatrix5dim cov(covLine.begin(), covLine.end()); cov = ROOT::Math::Similarity(P, cov); //Add the multiple scattering double phiRMS = mScatteringPhi_[step - 1] * K * K; double phiBRMS = mScatteringPhiB_[step - 1] * K * K; + double zRMS = mScatteringz_[step - 1] * K * K; + double kSlopeRMS = mScatteringkSlope_[step - 1] * K * K; - std::vector b(6); + std::vector b(15); b[0] = 0; b[1] = 0; b[2] = phiRMS; b[3] = 0; b[4] = 0; b[5] = phiBRMS; - - reco::Candidate::CovarianceMatrix MS(b.begin(), b.end()); + b[6] = 0; + b[7] = 0; + b[8] = 0; + b[9] = zRMS; + b[10] = 0; + b[11] = 0; + b[12] = 0; + b[13] = 0; + b[14] = kSlopeRMS; + + l1t::CovarianceMatrix5dim MS(b.begin(), b.end()); cov = cov + MS; if (verbose_) { edm::LogInfo("KMTFCore") << "Covariance term for phiB = " << cov(2, 2); edm::LogInfo("KMTFCore") << "Multiple scattering term for phiB = " << MS(2, 2); + edm::LogInfo("KMTFCore") << "Multiple scattering term for z = " << MS(3, 3); + edm::LogInfo("KMTFCore") << "Multiple scattering term for kSlope = " << MS(4, 4); } - track.setCovariance(cov); - track.setCoordinates(step - 1, KNew, phiNew, phiBNew); + track.setCoordinates(step - 1, KNew, phiNew, phiBNew, zNew, kSlopeNew); } bool KMTFCore::update(l1t::KMTFTrack& track, const l1t::MuonStubRef& stub, int mask, int seedQual) { @@ -567,77 +725,151 @@ bool KMTFCore::updateOffline(l1t::KMTFTrack& track, const l1t::MuonStubRef& stub int trackK = track.curvature(); int trackPhi = track.positionAngle(); int trackPhiB = track.bendingAngle(); + int trackz = track.zPosition(); + int trackSlope = track.kSlope(); int phi = stub->coord1(); int phiB = correctedPhiB(stub); + int z = stub->eta1(); + int kSlope = satKSlope(stub->eta2()); + int priorThetaPattern = track.thetaDigiPattern(); + int priorPhiPattern = track.hitPattern(); + int seedStation = track.stubs().empty() ? 0 : track.stubs()[0]->depthRegion(); - Vector2 residual; + Vector4 residual; residual[0] = ap_fixed(phi - trackPhi); residual[1] = phiB - trackPhiB; + residual[2] = ap_fixed(z - trackz); + residual[3] = ap_fixed(kSlope - trackSlope); - Matrix23 H; + Matrix45 H; H(0, 0) = 0.0; H(0, 1) = 1.0; H(0, 2) = 0.0; + H(0, 3) = 0.0; + H(0, 4) = 0.0; H(1, 0) = 0.0; H(1, 1) = 0.0; H(1, 2) = 1.0; + H(1, 3) = 0.0; + H(1, 4) = 0.0; + H(2, 0) = 0.0; + H(2, 1) = 0.0; + H(2, 2) = 0.0; + H(2, 3) = 1.0; + H(2, 4) = 0.0; + H(3, 0) = 0.0; + H(3, 1) = 0.0; + H(3, 2) = 0.0; + H(3, 3) = 0.0; + H(3, 4) = 1.0; const auto r11{stub->quality() < 6 ? pointResolutionPhiBL_[track.step() - 1] : pointResolutionPhiBH_[track.step() - 1]}; - const double r[]{pointResolutionPhi_, 0.0, 0.0, r11}; - const CovarianceMatrix2 R(r, 4); - + const double r[]{pointResolutionPhi_, + 0.0, + r11, + 0.0, + 0.0, + pointResolutionz_[track.step() - 1], + 0.0, + 0.0, + 0.0, + pointResolutionkSlope_[track.step() - 1]}; + + const CovarianceMatrix4 R(r, 10); const std::vector& covLine = track.covariance(); - const l1t::KMTFTrack::CovarianceMatrix cov(covLine.begin(), covLine.end()); - CovarianceMatrix2 S = ROOT::Math::Similarity(H, cov) + R; + const l1t::CovarianceMatrix5dim cov(covLine.begin(), covLine.end()); + + CovarianceMatrix4 S = ROOT::Math::Similarity(H, cov) + R; if (!S.Invert()) return false; - const Matrix32 Gain = cov * ROOT::Math::Transpose(H) * S; + const Matrix54 Gain = cov * ROOT::Math::Transpose(H) * S; - track.setKalmanGain( - track.step(), fabs(trackK), Gain(0, 0), Gain(0, 1), Gain(1, 0), Gain(1, 1), Gain(2, 0), Gain(2, 1)); + //track.setKalmanGain( + //track.step(), fabs(trackK), Gain(0, 0), Gain(0, 1), 1, 0, Gain(2, 0), Gain(2, 1)); int KNew = (trackK + int(Gain(0, 0) * residual(0) + Gain(0, 1) * residual(1))); if (fabs(KNew) > pow(2, BITSCURV - 1)) return false; - int phiNew = wrapAround(trackPhi + residual(0), pow(2, BITSPHI - 1)); int phiBNew = wrapAround(trackPhiB + int(Gain(2, 0) * residual(0) + Gain(2, 1) * residual(1)), pow(2, BITSPHIB - 1)); + int zNew = trackz + int(Gain(3, 2) * residual(2) + Gain(3, 3) * residual(3)); + int kSlopeNew = trackSlope + int(Gain(4, 2) * residual(2) + Gain(4, 3) * residual(3)); - track.setResidual(stub->depthRegion() - 1, fabs(phi - phiNew) + fabs(phiB - phiBNew)); + if ((zNew > ((1 << (BITSZ - 1)) - 1)) || (zNew < (-(1 << (BITSZ - 1))))) { + if (verbose_) + edm::LogInfo("KMTFCore") << "z saturated in updateOffline"; + return false; + } + if ((kSlopeNew > ((1 << (BITSKSLOPE - 1)) - 1)) || (kSlopeNew < (-(1 << (BITSKSLOPE - 1))))) { + if (verbose_) + edm::LogInfo("KMTFCore") << "kSlope saturated in updateOffline"; + return false; + } + + track.setResidual(stub->depthRegion() - 1, + fabs(phi - phiNew) + fabs(phiB - phiBNew) + fabs(z - zNew) + fabs(kSlope - kSlopeNew)); if (verbose_) { - edm::LogInfo("KMTFCore") << "residual " << phi << " - " << trackPhi << " = " << int(residual[0]) << " " << phiB - << " - " << trackPhiB << " = " << int(residual[1]); - edm::LogInfo("KMTFCore") << "Gains offline: " << Gain(0, 0) << " " << Gain(0, 1) << " " << Gain(2, 0) << " " - << Gain(2, 1); - edm::LogInfo("KMTFCore") << " K = " << trackK << " + " << Gain(0, 0) << " * " << residual(0) << " + " << Gain(0, 1) - << " * " << residual(1); - edm::LogInfo("KMTFCore") << " phiB = " << trackPhiB << " + " << Gain(2, 0) << " * " << residual(0) << " + " - << Gain(2, 1) << " * " << residual(1); + edm::LogInfo("KMTFCore") << "residual(0): " << phi << "-" << trackPhi << " = " << residual(0) << "\n"; + edm::LogInfo("KMTFCore") << "residual(1): " << phiB << "-" << trackPhiB << " = " << residual(1) << "\n"; + edm::LogInfo("KMTFCore") << "residual(2): " << z << "-" << trackz << " = " << residual(2) << "\n"; + edm::LogInfo("KMTFCore") << "residual(3): " << kSlope << "-" << trackSlope << " = " << residual(3) << "\n"; + edm::LogInfo("KMTFCore") << "Gain(0,0): " << Gain(0, 0) << "\n"; + edm::LogInfo("KMTFCore") << "Gain(0,1): " << Gain(0, 1) << "\n"; + edm::LogInfo("KMTFCore") << "Gain(2,0): " << Gain(2, 0) << "\n"; + edm::LogInfo("KMTFCore") << "Gain(2,1): " << Gain(2, 1) << "\n"; + edm::LogInfo("KMTFCore") << "Gain(3,2): " << Gain(3, 2) << "\n"; + edm::LogInfo("KMTFCore") << "Gain(3,3): " << Gain(3, 3) << "\n"; + edm::LogInfo("KMTFCore") << "Gain(4,2): " << Gain(4, 2) << "\n"; + edm::LogInfo("KMTFCore") << "Gain(4,3): " << Gain(4, 3) << "\n"; + edm::LogInfo("KMTFCore") << " KNew = " << trackK << "+" << Gain(0, 0) << "*" << residual(0) << "+" << Gain(0, 1) + << "*" << residual(1) << " = " << KNew << "\n"; + edm::LogInfo("KMTFCore") << " phiNew = " << trackPhi << "+" << residual(0) << " = " << phiNew << "\n"; + edm::LogInfo("KMTFCore") << " phiBNew = " << trackPhiB << "+" << Gain(2, 0) << "*" << residual(0) << "+" + << Gain(2, 1) << "*" << residual(1) << " = " << phiBNew << "\n"; + edm::LogInfo("KMTFCore") << " zNew = " << trackz << "+" << Gain(3, 2) << "*" << residual(2) << "+" << Gain(3, 3) + << "*" << residual(3) << " = " << zNew << "\n"; + edm::LogInfo("KMTFCore") << " kSlopeNew = " << trackSlope << "+" << Gain(4, 2) << "*" << residual(2) << "+" + << Gain(4, 3) << "*" << residual(3) << " = " << kSlopeNew << "\n"; } - track.setCoordinates(track.step(), KNew, phiNew, phiBNew); - const auto covNew{cov - Gain * (H * cov)}; - l1t::KMTFTrack::CovarianceMatrix c; + track.setCoordinates(track.step(), KNew, phiNew, phiBNew, zNew, kSlopeNew); + const Matrix55 covNew = cov - Gain * (H * cov); + l1t::CovarianceMatrix5dim c; - c(0, 0) = covNew(0, 0); - c(0, 1) = covNew(0, 1); - c(0, 2) = covNew(0, 2); - c(1, 0) = covNew(1, 0); - c(1, 1) = covNew(1, 1); - c(1, 2) = covNew(1, 2); - c(2, 0) = covNew(2, 0); - c(2, 1) = covNew(2, 1); - c(2, 2) = covNew(2, 2); - if (verbose_) { - edm::LogInfo("KMTFCore") << "Post Fit Covariance Matrix " << cov(0, 0) << " " << cov(1, 1) << " " << cov(2, 2); + for (int i = 0; i < 5; i++) { + for (int j = i; j < 5; j++) { + c(i, j) = covNew(i, j); + } } track.setCovariance(c); track.addStub(stub); track.setHitPattern(hitPattern(track)); + track.setThetaDigiPattern(thetaDigiPattern(track)); + track.setThetaGain(track.step(), + fabs(trackK), + priorThetaPattern, + seedStation, + priorPhiPattern, + Gain(3, 2), + Gain(3, 3), + Gain(4, 2), + Gain(4, 3)); + + if (verbose_) { + edm::LogInfo("KMTFCore") << "step: " << track.step() << "\n"; + edm::LogInfo("KMTFCore") << "|K|: " << fabs(trackK) << "\n"; + edm::LogInfo("KMTFCore") << "priorThetaPattern: " << priorThetaPattern << "\n"; + edm::LogInfo("KMTFCore") << "priorPhiPattern: " << priorPhiPattern << "\n"; + edm::LogInfo("KMTFCore") << "seed Station: " << seedStation << "\n"; + edm::LogInfo("KMTFCore") << "Gain32: " << Gain(3, 2) << "\n"; + edm::LogInfo("KMTFCore") << "Gain33: " << Gain(3, 3) << "\n"; + edm::LogInfo("KMTFCore") << "Gain42: " << Gain(4, 2) << "\n"; + edm::LogInfo("KMTFCore") << "Gain43: " << Gain(4, 3) << "\n"; + } return true; } @@ -646,54 +878,106 @@ bool KMTFCore::updateOffline1D(l1t::KMTFTrack& track, const l1t::MuonStubRef& st int trackK = track.curvature(); int trackPhi = track.positionAngle(); int trackPhiB = track.bendingAngle(); - + int trackz = track.zPosition(); + int trackSlope = track.kSlope(); int phi = stub->coord1(); + int z = stub->eta1(); + int kSlope = satKSlope(stub->eta2()); + int priorThetaPattern = track.thetaDigiPattern(); + int priorPhiPattern = track.hitPattern(); + int seedStation = track.stubs().empty() ? 0 : track.stubs()[0]->depthRegion(); - double residual = ap_fixed(phi - trackPhi); + Vector3 residual; + residual[0] = ap_fixed(phi - trackPhi); + residual[1] = ap_fixed(z - trackz); + residual[2] = ap_fixed(kSlope - trackSlope); - if (verbose_) - edm::LogInfo("KMTFCore") << "residuals " << phi << " - " << trackPhi << " = " << int(residual); + if (verbose_) { + edm::LogInfo("KMTFCore") << "residual phi: " << phi << " - " << trackPhi << " = " << int(residual(0)); + edm::LogInfo("KMTFCore") << "residual z: " << z << " - " << trackz << " = " << int(residual(1)); + edm::LogInfo("KMTFCore") << "residual kSlope: " << kSlope << " - " << trackSlope << " = " << int(residual(2)); + } - Matrix13 H; + Matrix35 H; H(0, 0) = 0.0; H(0, 1) = 1.0; H(0, 2) = 0.0; + H(0, 3) = 0.0; + H(0, 4) = 0.0; + H(1, 0) = 0.0; + H(1, 1) = 0.0; + H(1, 2) = 0.0; + H(1, 3) = 1.0; + H(1, 4) = 0.0; + H(2, 0) = 0.0; + H(2, 1) = 0.0; + H(2, 2) = 0.0; + H(2, 3) = 0.0; + H(2, 4) = 1.0; + + const double r[]{ + pointResolutionPhi_, 0.0, pointResolutionz_[track.step() - 1], 0.0, 0.0, pointResolutionkSlope_[track.step() - 1]}; + const CovarianceMatrix3 R(r, 6); const std::vector& covLine = track.covariance(); - l1t::KMTFTrack::CovarianceMatrix cov(covLine.begin(), covLine.end()); + l1t::CovarianceMatrix5dim cov(covLine.begin(), covLine.end()); - double S = ROOT::Math::Similarity(H, cov)(0, 0) + pointResolutionPhi_; - if (S == 0.0) + CovarianceMatrix3 S = ROOT::Math::Similarity(H, cov) + R; + if (!S.Invert()) return false; - Matrix31 Gain = cov * ROOT::Math::Transpose(H) / S; + Matrix53 Gain = cov * ROOT::Math::Transpose(H) * S; - track.setKalmanGain(track.step(), fabs(trackK), Gain(0, 0), 0.0, Gain(1, 0), 0.0, Gain(2, 0), 0.0); + //track.setKalmanGain(track.step(), fabs(trackK), Gain(0, 0), 0.0, 1, 0, Gain(2, 0), 0.0); - int KNew = wrapAround(trackK + int(Gain(0, 0) * residual), pow(2, BITSCURV - 1)); - int phiNew = wrapAround(trackPhi + residual, pow(2, BITSPHI - 1)); - int phiBNew = wrapAround(trackPhiB + int(Gain(2, 0) * residual), pow(2, BITSPHIB - 1)); - track.setCoordinates(track.step(), KNew, phiNew, phiBNew); - Matrix33 covNew = cov - Gain * (H * cov); - l1t::KMTFTrack::CovarianceMatrix c; + int KNew = wrapAround(trackK + int(Gain(0, 0) * residual(0)), pow(2, BITSCURV - 1)); + int phiNew = wrapAround(trackPhi + residual(0), pow(2, BITSPHI - 1)); + int phiBNew = wrapAround(trackPhiB + int(Gain(2, 0) * residual(0)), pow(2, BITSPHIB - 1)); + int zNew = trackz + int(Gain(3, 1) * residual(1) + Gain(3, 2) * residual(2)); + int kSlopeNew = trackSlope + int(Gain(4, 1) * residual(1) + Gain(4, 2) * residual(2)); + + if ((zNew > (1 << (BITSZ - 1)) - 1) || (zNew < -(pow(2, BITSZ - 1)))) { + if (verbose_) + edm::LogInfo("KMTFCore") << "z saturated in updateOffline1D"; + return false; + } + if ((kSlopeNew > (pow(2, BITSKSLOPE - 1) - 1)) || (kSlopeNew < -(pow(2, BITSKSLOPE - 1)))) { + if (verbose_) + edm::LogInfo("KMTFCore") << "kSlope saturated in updateOffline1D"; + return false; + } + + track.setCoordinates(track.step(), KNew, phiNew, phiBNew, zNew, kSlopeNew); + + Matrix55 covNew = cov - Gain * (H * cov); + l1t::CovarianceMatrix5dim c; if (verbose_) { - edm::LogInfo("KMTFCore") << "phiUpdate: " << int(Gain(0, 0) * residual) << " " << int(Gain(2, 0) * residual); - edm::LogInfo("KMTFCore") << " K = " << trackK << " + " << Gain(0, 0) << " * " << residual; - edm::LogInfo("KMTFCore") << " phiBNew = " << trackPhiB << " + " << Gain(2, 0) << " * " << residual; + edm::LogInfo("KMTFCore") << " phiNew: " << trackPhi << "+" << residual(0); + edm::LogInfo("KMTFCore") << " KNew = " << trackK << "+" << Gain(0, 0) << "*" << residual(0); + edm::LogInfo("KMTFCore") << " phiBNew = " << trackPhiB << "+" << Gain(2, 0) << "*" << residual(0); + edm::LogInfo("KMTFCore") << " zNew = " << trackz << "+" << Gain(3, 1) << "*" << residual(1) << "+" << Gain(3, 2) + << "*" << residual(2); + edm::LogInfo("KMTFCore") << " kSlopeNew = " << trackSlope << "+" << Gain(4, 1) << "*" << residual(1) << "+" + << Gain(4, 2) << "*" << residual(2); } - c(0, 0) = covNew(0, 0); - c(0, 1) = covNew(0, 1); - c(0, 2) = covNew(0, 2); - c(1, 0) = covNew(1, 0); - c(1, 1) = covNew(1, 1); - c(1, 2) = covNew(1, 2); - c(2, 0) = covNew(2, 0); - c(2, 1) = covNew(2, 1); - c(2, 2) = covNew(2, 2); + for (int i = 0; i < 5; i++) + for (int j = i; j < 5; j++) + c(i, j) = covNew(i, j); + track.setCovariance(c); track.addStub(stub); track.setHitPattern(hitPattern(track)); + track.setThetaDigiPattern(thetaDigiPattern(track)); + track.setThetaGain1D(track.step(), + fabs(trackK), + priorThetaPattern, + seedStation, + priorPhiPattern, + Gain(3, 1), + Gain(3, 2), + Gain(4, 1), + Gain(4, 2)); return true; } @@ -702,13 +986,19 @@ bool KMTFCore::updateLUT(l1t::KMTFTrack& track, const l1t::MuonStubRef& stub, in int trackK = track.curvature(); int trackPhi = track.positionAngle(); int trackPhiB = track.bendingAngle(); + int trackz = track.zPosition(); + int trackSlope = track.kSlope(); int phi = stub->coord1(); int phiB = correctedPhiB(stub); + int z = stub->eta1(); + int kSlope = satKSlope(stub->eta2()); - Vector2 residual; + Vector4 residual; ap_fixed residualPhi = phi - trackPhi; ap_fixed residualPhiB = phiB - trackPhiB; + ap_fixed residualz = z - trackz; + ap_fixed residualSlope = kSlope - trackSlope; if (verbose_) edm::LogInfo("KMTFCore") << "residual " << phi << " - " << trackPhi << " = " << residualPhi.to_int() << " " << phiB @@ -719,6 +1009,7 @@ bool KMTFCore::updateLUT(l1t::KMTFTrack& track, const l1t::MuonStubRef& stub, in absK = pow(2, BITSCURV - 2) - 1; std::vector GAIN; + std::vector GAIN_THETA; if (verbose_) { edm::LogInfo("KMTFCore") << "Looking up LUTs for mask=" << mask << " with hit pattern=" << track.hitPattern(); } @@ -731,6 +1022,14 @@ bool KMTFCore::updateLUT(l1t::KMTFTrack& track, const l1t::MuonStubRef& stub, in } else { GAIN = lutService_->trackGain2(track.step(), track.hitPattern(), absK / 32, seedQual, stub->quality()); } + + const bool is2D = (mask == 3 || mask == 5 || mask == 9 || mask == 6 || mask == 10 || mask == 12); + if (!(is2D) && (track.step() == 2) && (track.thetaDigiPattern() == 0)) { + GAIN_THETA = lutService_->trackGainTheta2(track.step(), track.thetaDigiPattern(), track.hitPattern(), absK / 32); + } else { + GAIN_THETA = lutService_->trackGainTheta(track.step(), track.thetaDigiPattern(), absK / 32, is2D); + } + if (verbose_) { edm::LogInfo("KMTFCore") << "Gains (fp): " << GAIN[0] << " " << GAIN[1] << " " << GAIN[2] << " " << GAIN[3]; @@ -745,8 +1044,6 @@ bool KMTFCore::updateLUT(l1t::KMTFTrack& track, const l1t::MuonStubRef& stub, in << ap_ufixed(GAIN[3]).to_float(); } - track.setKalmanGain(track.step(), fabs(trackK), GAIN[0], GAIN[1], 1, 0, GAIN[2], GAIN[3]); - int KNew; if (!(mask == 3 || mask == 5 || mask == 9 || mask == 6 || mask == 10 || mask == 12)) { KNew = ap_fixed(ap_fixed(trackK) + @@ -794,9 +1091,31 @@ bool KMTFCore::updateLUT(l1t::KMTFTrack& track, const l1t::MuonStubRef& stub, in if ((phiBNew > (pow(2, BITSPHIB - 1) - 1)) || (phiBNew < (-pow(2, BITSPHIB - 1)))) return false; - track.setCoordinates(track.step(), KNew, phiNew, phiBNew); + int zNew; + int kSlopeNew; + zNew = ap_fixed(ap_fixed(trackz) + + ap_ufixed(GAIN_THETA[0]) * residualz - + ap_ufixed(GAIN_THETA[1]) * residualSlope); + kSlopeNew = ap_fixed(ap_fixed(trackSlope) - + ap_ufixed(GAIN_THETA[2]) * residualz + + ap_ufixed(GAIN_THETA[3]) * residualSlope); + + if ((zNew > (1 << (BITSZ - 1)) - 1) || (zNew < -(pow(2, BITSZ - 1)))) { + if (verbose_) + edm::LogInfo("KMTFCore") << "z has saturated"; + return false; + } + if ((kSlopeNew > (pow(2, BITSKSLOPE - 1) - 1)) || (kSlopeNew < -(pow(2, BITSKSLOPE - 1)))) { + if (verbose_) + edm::LogInfo("KMTFCore") << "kSlope has saturated"; + return false; + } + + track.setCoordinates(track.step(), KNew, phiNew, phiBNew, zNew, kSlopeNew); track.addStub(stub); track.setHitPattern(hitPattern(track)); + track.setThetaDigiPattern(thetaDigiPattern(track)); + if (verbose_) { edm::LogInfo("KMTFCore") << "Stub station =" << stub->depthRegion(); @@ -815,17 +1134,19 @@ void KMTFCore::vertexConstraint(l1t::KMTFTrack& track) { void KMTFCore::vertexConstraintOffline(l1t::KMTFTrack& track) { double residual = -track.dxy(); - Matrix13 H; + Matrix15 H; H(0, 0) = 0; H(0, 1) = 0; H(0, 2) = 1; + H(0, 3) = 0; + H(0, 4) = 0; const std::vector& covLine = track.covariance(); - l1t::KMTFTrack::CovarianceMatrix cov(covLine.begin(), covLine.end()); + l1t::CovarianceMatrix5dim cov(covLine.begin(), covLine.end()); double S = (ROOT::Math::Similarity(H, cov))(0, 0) + pointResolutionVertex_; S = 1.0 / S; - Matrix31 Gain = cov * (ROOT::Math::Transpose(H)) * S; + Matrix51 Gain = cov * (ROOT::Math::Transpose(H)) * S; track.setKalmanGain(track.step(), fabs(track.curvature()), Gain(0, 0), Gain(1, 0), Gain(2, 0)); if (verbose_) { @@ -838,20 +1159,35 @@ void KMTFCore::vertexConstraintOffline(l1t::KMTFTrack& track) { int dxyNew = wrapAround(int(track.dxy() + Gain(2, 0) * residual), pow(2, BITSPHIB)); if (verbose_) edm::LogInfo("KMTFCore") << "Post fit impact parameter=" << dxyNew; - track.setCoordinatesAtVertex(KNew, phiNew, -residual); - Matrix33 covNew = cov - Gain * (H * cov); - l1t::KMTFTrack::CovarianceMatrix c; + track.setCoordinatesAtVertex(KNew, phiNew, -residual, track.zPosition(), track.kSlope()); + Matrix55 covNew = cov - Gain * (H * cov); + l1t::CovarianceMatrix5dim c; c(0, 0) = covNew(0, 0); c(0, 1) = covNew(0, 1); c(0, 2) = covNew(0, 2); + c(0, 3) = covNew(0, 3); + c(0, 4) = covNew(0, 4); c(1, 0) = covNew(1, 0); c(1, 1) = covNew(1, 1); c(1, 2) = covNew(1, 2); + c(1, 3) = covNew(1, 3); + c(1, 4) = covNew(1, 4); c(2, 0) = covNew(2, 0); c(2, 1) = covNew(2, 1); c(2, 2) = covNew(2, 2); + c(2, 3) = covNew(2, 3); + c(2, 4) = covNew(2, 4); + c(3, 0) = covNew(3, 0); + c(3, 1) = covNew(3, 1); + c(3, 2) = covNew(3, 2); + c(3, 3) = covNew(3, 3); + c(3, 4) = covNew(3, 4); + c(4, 0) = covNew(4, 0); + c(4, 1) = covNew(4, 1); + c(4, 2) = covNew(4, 2); + c(4, 3) = covNew(4, 3); + c(4, 4) = covNew(4, 4); track.setCovariance(c); - // track.covariance = track.covariance - Gain*H*track.covariance; } void KMTFCore::vertexConstraintLUT(l1t::KMTFTrack& track) { @@ -876,7 +1212,7 @@ void KMTFCore::vertexConstraintLUT(l1t::KMTFTrack& track) { //int p_0 = fp_product(GAIN.second, int(residual), 7); int p_0 = GAIN.second * int(residual); int phiNew = wrapAround(track.positionAngle() + p_0, pow(2, BITSPHI - 1)); - track.setCoordinatesAtVertex(KNew, phiNew, -residual); + track.setCoordinatesAtVertex(KNew, phiNew, -residual, track.zPosition(), track.kSlope()); } int KMTFCore::hitPattern(const l1t::KMTFTrack& track) { @@ -887,6 +1223,18 @@ int KMTFCore::hitPattern(const l1t::KMTFTrack& track) { return mask; } +//returns mask pattern based on stubs with a theta digi or not. e.g. 0010 is a track with stub at station 2 with a theta digi stub +int KMTFCore::thetaDigiPattern(const l1t::KMTFTrack& track) { + unsigned int mask = 0; + for (const auto& stub : track.stubs()) { + if (stub->depthRegion() == 4) + continue; + if (stub->etaQuality() > 0) + mask |= (1 << (stub->depthRegion() - 1)); + } + return mask; +} + int KMTFCore::customBitmask(unsigned int bit1, unsigned int bit2, unsigned int bit3, unsigned int bit4) { return bit1 * 1 + bit2 * 2 + bit3 * 4 + bit4 * 8; } @@ -894,7 +1242,15 @@ int KMTFCore::customBitmask(unsigned int bit1, unsigned int bit2, unsigned int b bool KMTFCore::getBit(int bitmask, int pos) { return (bitmask & (1 << pos)) >> pos; } void KMTFCore::setFourVectors(l1t::KMTFTrack& track) { - int etaINT = track.coarseEta(); + //int etaINT = track.coarseEta(); + //legacy version of KMTF used coarse Eta to set the eta in SAMuons based on wheel-based LUT + //new approach uses kSlope to build eta for SAMuons + //matched KMTF output to gen muons and performed linear fit of gen eta vs kSlope of KMTF output + //eta=m*kslope+b where m and b come from fit + ap_ufixed<18, 0> m = 0.03602; + ap_ufixed<18, 0> b = 0.66840; + int etaINT = int(round(double(m * track.kSlope() + b))); + int etaINTDisp = int(round(double(m * track.kSlopeAtMuon() + b))); double lsbEta = M_PI / pow(2, 12); int charge = 1; @@ -908,21 +1264,24 @@ void KMTFCore::setFourVectors(l1t::KMTFTrack& track) { //Also set PT =0 and dxy=0 if (track.stubs().size() == 1) { ptC = 0; - track.setCoordinatesAtMuon(track.curvatureAtMuon(), track.stubs()[0]->coord1(), track.phiBAtMuon()); - track.setCoordinatesAtVertex(track.curvatureAtVertex(), track.phiAtVertex(), 0); + track.setCoordinatesAtMuon( + track.curvatureAtMuon(), track.stubs()[0]->coord1(), track.phiBAtMuon(), track.zPosition(), track.kSlope()); + track.setCoordinatesAtVertex(track.curvatureAtVertex(), track.phiAtVertex(), 0, track.zPosition(), track.kSlope()); } track.setPt(ptC, ptU); //shift the dxy by 10 bits - track.setCoordinatesAtVertex(track.curvatureAtVertex(), track.phiAtVertex(), track.dxy() / 1024); + track.setCoordinatesAtVertex( + track.curvatureAtVertex(), track.phiAtVertex(), track.dxy() / 1024, track.zPosition(), track.kSlope()); //vertex double pt = ptC * 0.03125; double phi = (track.phiAtMuon() / 32) * M_PI / pow(2, 12); double eta = etaINT * lsbEta; + double etaDisp = etaINTDisp * lsbEta; track.setPtEtaPhi(pt, eta, phi); track.setCharge(charge); pt = double(ptLUT(track.curvatureAtMuon())) * 0.03125; - track.setPtEtaPhiDisplaced(pt, eta, phi); + track.setPtEtaPhiDisplaced(pt, etaDisp, phi); } bool KMTFCore::estimateChiSquare(l1t::KMTFTrack& track, bool vertex) { @@ -947,6 +1306,15 @@ bool KMTFCore::estimateChiSquare(l1t::KMTFTrack& track, bool vertex) { std::vector cut; const l1t::MuonStubRef& innerStub = track.stubs()[track.stubs().size() - 1]; + if (verbose_) { + edm::LogInfo("KMTFCore") << "[KMTF_CHI2DBG] begin " << (vertex ? "prompt" : "displaced") + << " chi2 fit: hitPattern=" << track.hitPattern() + << " thetaPattern=" << track.thetaDigiPattern() << " nStubs=" << track.stubs().size() + << " innerDepth=" << innerStub->depthRegion() << " curvMuon=" << track.curvatureAtMuon() + << " curvVtx=" << track.curvatureAtVertex() << " phiMuon=" << track.phiAtMuon() + << " phiVtx=" << track.phiAtVertex() << " z=" << track.zPosition() + << " kSlope=" << track.kSlope(); + } if (vertex) { K = track.curvatureAtVertex(); @@ -1019,14 +1387,19 @@ bool KMTFCore::estimateChiSquare(l1t::KMTFTrack& track, bool vertex) { chi = chi + absDelta; chiErr = chiErr + err; if (verbose_) { - edm::LogInfo("KMTFCore") << "Chi Square stub for track with pattern=" << track.hitPattern() - << " inner stub depth=" << innerStub->depthRegion() << "-> AK=" << int(AK) - << " stubDepth=" << stub->depthRegion() << " diff1=" << diffPhi << " diff2=" << diffPhiB - << " delta=" << absDelta << " absK=" << uint(absK) << " err=" << err; + edm::LogInfo("KMTFCore") << "[KMTF_CHI2DBG] per-stub " << (vertex ? "prompt" : "displaced") + << " innerDepth=" << innerStub->depthRegion() << " stubDepth=" << stub->depthRegion() + << " diffPhi=" << diffPhi << " diffPhiB=" << diffPhiB << " propC=" << float(propC) + << " Kshifted=" << int(Kshifted) << " AK=" << int(AK) << " deltaSigned=" << delta + << " deltaAbs=" << absDelta << " posErrA=" << positionError << " errBTerm=" + << uint(ap_fixed<8, 2>(propErrB[stub->depthRegion() - innerStub->depthRegion() - 1]) * + absK) + << " errTotal=" << err << " chiRunning=" << chi << " chiErrRunning=" << chiErr; } } if (verbose_) { - edm::LogInfo("KMTFCore") << "Chi Square =" << chi << " ChiSquare Error = " << chiErr; + edm::LogInfo("KMTFCore") << "[KMTF_CHI2DBG] final " << (vertex ? "prompt" : "displaced") << " chi=" << chi + << " chiErr=" << chiErr << " pass=" << (chi <= chiErr); } track.setApproxChi2(chi, chiErr, vertex); @@ -1073,6 +1446,12 @@ int KMTFCore::wrapAround(int value, int maximum) { return value; } +int KMTFCore::satKSlope(int k) { + const int kmax = (1 << (BITSKSLOPE - 1)) - 1; + const int kmin = -(1 << (BITSKSLOPE - 1)); + return k > kmax ? kmax : (k < kmin ? kmin : k); +} + int KMTFCore::encode(bool ownwheel, int sector, int tag) { int wheel = ownwheel ? 1 : 0; int phi = 0; @@ -1086,7 +1465,6 @@ int KMTFCore::encode(bool ownwheel, int sector, int tag) { std::pair KMTFCore::getByCode(const std::vector& tracks, int mask) { for (uint i = 0; i < tracks.size(); ++i) { - edm::LogInfo("KMTFCore") << "Code=" << tracks[i].hitPattern() << ", track=" << mask; if (tracks[i].hitPattern() == mask) return std::make_pair(true, i); } diff --git a/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc b/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc index b8743c7e58f5e..6da8b0b2b9f8b 100644 --- a/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc +++ b/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc @@ -114,53 +114,106 @@ l1t::MuonStub L1TPhase2GMTBarrelStubProcessor::buildStubNoEta(const L1Phase2MuDT return stub; } -l1t::MuonStubCollection L1TPhase2GMTBarrelStubProcessor::makeStubs(const L1Phase2MuDTPhContainer* phiContainer, - const L1MuDTChambThContainer* etaContainer) { +l1t::MuonStub L1TPhase2GMTBarrelStubProcessor::buildStubwithZandkSlope(const L1Phase2MuDTExtPhiThetaPair& pairs) { + const auto& phiS = pairs.phiDigi(); + static constexpr int ZCenterDigitizedPositive[] = {11730, 23327}; + static constexpr int ZCenterDigitizedNegative[] = {-11697, -23290}; + static constexpr int ZCenterDigitizedZero[] = {22}; + static constexpr float RadiusStationPhys[] = {445., 526., 635., 730.}; + int wheel = phiS.whNum(); + int abswheel = fabs(phiS.whNum()); + int sector = phiS.scNum(); + int station = phiS.stNum(); + + ap_uint<18> normalization0 = sector * ap_uint<15>(21845); + ap_int<18> normalization1 = ap_int<18>(ap_int<17>(phiS.phi()) * ap_ufixed<8, 0>(0.3183)); + ap_int<18> kmtf_phi = ap_int<18>(normalization0 + normalization1); + int phi = int(kmtf_phi); + float globalPhi = phi * M_PI / (1 << 17); + + // double globalPhi = (sector * 30) + phiS.phi() * 30. / 65535.; + int tag = phiS.index(); + + int bx = phiS.bxNum() - 20; + int quality = phiS.quality(); + uint tfLayer = phiS.stNum() - 1; + + // instantiate stub with eta1=0, eta2=0, etaQuality=0 values which eventually get written over with stub.setEta below. + l1t::MuonStub stub(wheel, sector, station, tfLayer, phi, phiS.phiBend(), tag, bx, quality, 0, 0, 0, 1); + + //defining z, k, zPhys, kPhys for case where theta digi exists + ap_int<16> z = pairs.thetaDigi().z(); + ap_int<16> k = pairs.thetaDigi().k(); + float zPhys = z * (1500. / (1 << 16)); + float kPhys = k * (2. / (1 << 16)); + + //slight asymmetry in wheels w.r.t. the origin calls for different z_center values for case where no theta digi was matched + //defining z_center adn k_center for when theta digi does NOT exist!! + int z_centerDigi; + if (wheel > 0) { + z_centerDigi = ZCenterDigitizedPositive[abswheel - 1]; + } else if (wheel < 0) { + z_centerDigi = ZCenterDigitizedNegative[abswheel - 1]; + } else { + z_centerDigi = ZCenterDigitizedZero[0]; + } + float z_centerPhys = z_centerDigi * (1500. / (1 << 16)); + float R_centerPhys = RadiusStationPhys[station - 1]; + float k_centerPhys = z_centerPhys / R_centerPhys; + int k_centerDigi = k_centerPhys * ((1 << 16) / 2.); + //very important + //clamp to a signed 16-bit range. upstream z and kSlope were declared with keyword int from phi-theta digi matched pair dataformat + //. this triggers only in wheels 1/2 wher k can exceed +/-1.0 for case of no theta digi!!!!!!!!!!!!! + //point back as close to the origin as we can. fixed range of kSlope binds the value + if (k_centerDigi > (1 << 15) - 1) { + k_centerDigi = (1 << 15) - 1; + } + if (k_centerDigi < -(1 << 15)) { + k_centerDigi = -(1 << 15); + } + // check if theta digi exists with non-default constructor quality --> use z, k with etaQuality=3 from theta digi. + // if theta digi has no real data, use z_center and slope which points to origin with etaQuality=0.. + // stub set to etaQuality==3 if theta digi exists, 0 if not. + if (pairs.thetaDigi().quality() >= 0) { + stub.setEta(z, k, 3); + stub.setOfflineQuantities(globalPhi, float(phiS.phiBend() * 0.49e-3), zPhys, kPhys); + } else { + stub.setEta(z_centerDigi, k_centerDigi, 0); + stub.setOfflineQuantities(globalPhi, float(phiS.phiBend() * 0.49e-3), z_centerPhys, k_centerPhys); + } + return stub; +} + +l1t::MuonStubCollection L1TPhase2GMTBarrelStubProcessor::makeStubs( + const L1Phase2MuDTExtPhiThetaPairContainer* pairContainer) { l1t::MuonStubCollection out; for (int bx = minBX_; bx <= maxBX_; bx++) { ostringstream os; if (verbose_ == 2) os << "PATTERN "; - for (int wheel = -2; wheel <= 2; wheel++) { - for (int sector = 0; sector < 12; sector++) { - for (int station = 1; station < 5; station++) { - bool hasEta = false; - const L1MuDTChambThDigi* tseta = etaContainer->chThetaSegm(wheel, station, sector, bx); - if (tseta != nullptr) { - hasEta = true; - } - - for (const auto& phiDigi : *phiContainer->getContainer()) { - if ((phiDigi.bxNum() - 20) != bx || phiDigi.whNum() != wheel || phiDigi.scNum() != sector || - phiDigi.stNum() != station) - continue; - if (phiDigi.quality() < minPhiQuality_) - continue; - - if (verbose_ == 2) { - ap_uint<64> wphi = ap_uint<17>(phiDigi.phi()); - ap_uint<64> wphib = ap_uint<13>(phiDigi.phiBend()); - ap_uint<64> wr1 = ap_uint<21>(0); - ap_uint<64> wq = ap_uint<4>(phiDigi.quality()); - ap_uint<64> wr2 = ap_uint<9>(0); - ap_uint<64> sN = 0; - sN = sN | wphi; - sN = sN | (wphib << 17); - sN = sN | (wr1 << 30); - sN = sN | (wq << 51); - sN = sN | (wr2 << 55); - os << std::setw(0) << std::dec << sector << " " << wheel << " " << station << " "; - os << std::uppercase << std::setfill('0') << std::setw(16) << std::hex << uint64_t(sN) << " "; - } - - if (hasEta) { - out.push_back(buildStub(phiDigi, tseta)); - } else { - out.push_back(buildStubNoEta(phiDigi)); - } - } - } + for (const auto& pair : pairContainer->getContainer()) { + const auto& phiDigi = pair.phiDigi(); + if ((phiDigi.bxNum() - 20) != bx) + continue; + if (phiDigi.quality() < minPhiQuality_) + continue; + + if (verbose_ == 2) { + ap_uint<64> wphi = ap_uint<17>(phiDigi.phi()); + ap_uint<64> wphib = ap_uint<13>(phiDigi.phiBend()); + ap_uint<64> wr1 = ap_uint<21>(0); + ap_uint<64> wq = ap_uint<4>(phiDigi.quality()); + ap_uint<64> wr2 = ap_uint<9>(0); + ap_uint<64> sN = 0; + sN = sN | wphi; + sN = sN | (wphib << 17); + sN = sN | (wr1 << 30); + sN = sN | (wq << 51); + sN = sN | (wr2 << 55); + os << std::setw(0) << std::dec << phiDigi.scNum() << " " << phiDigi.whNum() << " " << phiDigi.stNum() << " "; + os << std::uppercase << std::setfill('0') << std::setw(16) << std::hex << uint64_t(sN) << " "; } + out.push_back(buildStubwithZandkSlope(pair)); } if (verbose_ == 2) edm::LogInfo("BarrelStub") << os.str() << std::endl;