diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/AlgoMuonBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/AlgoMuonBase.h deleted file mode 100644 index 70047cfe68a64..0000000000000 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/AlgoMuonBase.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * AlgoMuonBase.h - * - * Created on: Mar 1, 2019 - * Author: Karol Bunkowski kbunkow@cern.ch - */ - -#ifndef L1T_OmtfP1_ALGOMUONBASE_H_ -#define L1T_OmtfP1_ALGOMUONBASE_H_ - -#include "L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h" -#include "L1Trigger/L1TMuonOverlapPhase1/interface/MuonStub.h" -#include "L1Trigger/L1TMuonOverlapPhase1/interface/StubResult.h" -#include "boost/dynamic_bitset.hpp" - -class AlgoMuonBase { -public: - AlgoMuonBase(){}; - - AlgoMuonBase(const ProcConfigurationBase* config); - virtual ~AlgoMuonBase(); - - virtual int getEtaHw() const = 0; - - virtual bool isValid() const = 0; - - virtual unsigned int getFiredLayerCnt() const { - unsigned int count = 0; - for (auto& firedLayerBits : firedLayerBitsInBx) { - count += firedLayerBits.count(); - } - return count; - } - - virtual unsigned int getFiredLayerCnt(int bx) const { return firedLayerBitsInBx.at(bx).count(); } - - boost::dynamic_bitset<> getFiredLayerBits() - const { //TODO make it virtual, and change the return type in in the AlgoMuon to dynamic_bitset<> - boost::dynamic_bitset<> firedLayerBitsSum(firedLayerBitsInBx[0].size()); - for (auto& firedLayerBits : firedLayerBitsInBx) { - firedLayerBitsSum |= firedLayerBits; - } - return firedLayerBitsSum; - } - - virtual bool isLayerFired(unsigned int iLayer, unsigned int bx) const { return firedLayerBitsInBx.at(bx)[iLayer]; } - - virtual double getPdfSum() const = 0; - - virtual const StubResult& getStubResult(unsigned int iLayer) const = 0; - - virtual const StubResults& getStubResults() const = 0; - -protected: - ///bits representing fired logicLayers (including bending layers), - std::vector > firedLayerBitsInBx; -}; - -#endif /* L1T_OmtfP1_ALGOMUONBASE_H_ */ diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/AngleConverterBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/AngleConverterBase.h index e5f619f44c34a..a8dd733e69df3 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/AngleConverterBase.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/AngleConverterBase.h @@ -61,10 +61,8 @@ class AngleConverterBase { /// phiZero - desired phi where the scale should start, should be in the desired scale, use getProcessorPhiZero to obtain it virtual int getProcessorPhi(int phiZero, l1t::tftype part, int dtScNum, int dtPhi) const; - virtual int getProcessorPhi(int phiZero, - l1t::tftype part, - const CSCDetId& csc, - const CSCCorrelatedLCTDigi& digi) const; + virtual int getProcessorPhi( + int phiZero, l1t::tftype part, const CSCDetId& csc, const CSCCorrelatedLCTDigi& digi, unsigned int iInput) const; virtual int getProcessorPhi(unsigned int iProcessor, l1t::tftype part, diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStub.h b/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStub.h index 8b5bbb6dd20a2..abceed2db2d42 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStub.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStub.h @@ -43,7 +43,7 @@ struct MuonStub { static const int EMTPY_PHI = 0xffffff; int etaHw = 0; - int etaSigmaHw = 0; ///error of the eta measurement + int r = 0; //[cm] distance from beam pipe int qualityHw = 0; int bx = 0; @@ -52,6 +52,8 @@ struct MuonStub { //used to address LUTs unsigned int logicLayer = 0; + unsigned int input = 0; + //int roll = 0; //TODO remove int detId = 0; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStubMakerBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStubMakerBase.h index 8340fcafda826..953f22f84c36e 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStubMakerBase.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStubMakerBase.h @@ -14,6 +14,7 @@ #include "FWCore/Utilities/interface/EDGetToken.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/MuonStub.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/RpcClusterization.h" +#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IOMTFEmulationObserver.h" #include #include #include @@ -37,8 +38,12 @@ class DigiToStubsConverterBase { virtual void loadDigis(const edm::Event& event) = 0; - virtual void makeStubs( - MuonStubPtrs2D& muonStubsInLayers, unsigned int iProcessor, l1t::tftype procTyp, int bxFrom, int bxTo) = 0; + virtual void makeStubs(MuonStubPtrs2D& muonStubsInLayers, + unsigned int iProcessor, + l1t::tftype procTyp, + int bxFrom, + int bxTo, + std::vector >& observers) = 0; }; class DtDigiToStubsConverter : public DigiToStubsConverterBase { @@ -53,8 +58,12 @@ class DtDigiToStubsConverter : public DigiToStubsConverterBase { void loadDigis(const edm::Event& event) override; - void makeStubs( - MuonStubPtrs2D& muonStubsInLayers, unsigned int iProcessor, l1t::tftype procTyp, int bxFrom, int bxTo) override; + void makeStubs(MuonStubPtrs2D& muonStubsInLayers, + unsigned int iProcessor, + l1t::tftype procTyp, + int bxFrom, + int bxTo, + std::vector >& observers) override; //dtThDigis is provided as argument, because in the OMTF implementation the phi and eta digis are merged (even thought it is artificial) virtual void addDTphiDigi(MuonStubPtrs2D& muonStubsInLayers, @@ -94,8 +103,12 @@ class CscDigiToStubsConverter : public DigiToStubsConverterBase { void loadDigis(const edm::Event& event) override { event.getByToken(inputTokenCsc, cscDigis); } - void makeStubs( - MuonStubPtrs2D& muonStubsInLayers, unsigned int iProcessor, l1t::tftype procTyp, int bxFrom, int bxTo) override; + void makeStubs(MuonStubPtrs2D& muonStubsInLayers, + unsigned int iProcessor, + l1t::tftype procTyp, + int bxFrom, + int bxTo, + std::vector >& observers) override; //can add both phi and eta stubs virtual void addCSCstubs(MuonStubPtrs2D& muonStubsInLayers, @@ -128,8 +141,12 @@ class RpcDigiToStubsConverter : public DigiToStubsConverterBase { void loadDigis(const edm::Event& event) override { event.getByToken(inputTokenRpc, rpcDigis); } - void makeStubs( - MuonStubPtrs2D& muonStubsInLayers, unsigned int iProcessor, l1t::tftype procTyp, int bxFrom, int bxTo) override; + void makeStubs(MuonStubPtrs2D& muonStubsInLayers, + unsigned int iProcessor, + l1t::tftype procTyp, + int bxFrom, + int bxTo, + std::vector >& observers) override; virtual void addRPCstub(MuonStubPtrs2D& muonStubsInLayers, const RPCDetId& roll, @@ -166,8 +183,12 @@ class MuonStubMakerBase { void loadAndFilterDigis(const edm::Event& event); ///Method translating trigger digis into input matrix with global phi coordinates, fills the muonStubsInLayers - void buildInputForProcessor( - MuonStubPtrs2D& muonStubsInLayers, unsigned int iProcessor, l1t::tftype procTyp, int bxFrom = 0, int bxTo = 0); + void buildInputForProcessor(MuonStubPtrs2D& muonStubsInLayers, + unsigned int iProcessor, + l1t::tftype procTyp, + int bxFrom, + int bxTo, + std::vector >& observers); protected: const ProcConfigurationBase* config = nullptr; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h index f5023dc12f6a4..8e2665c37adfa 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h @@ -1,94 +1,167 @@ #ifndef L1T_OmtfP1_AlgoMuon_H #define L1T_OmtfP1_AlgoMuon_H -#include "L1Trigger/L1TMuonOverlapPhase1/interface/AlgoMuonBase.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternBase.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternResult.h" #include -class AlgoMuon : public AlgoMuonBase { +class AlgoMuon { public: - AlgoMuon() : AlgoMuonBase() {} + AlgoMuon() {} AlgoMuon(const GoldenPatternResult& gpResult, GoldenPatternBase* gp, unsigned int refHitNumber, int bx = 0) - : AlgoMuonBase(gp->getConfig()), - gpResult(gpResult), - goldenPatern(gp), - m_q(gpResult.getFiredLayerCnt()), //initial value of quality, can be altered later + : gpResultConstr(gpResult), + goldenPaternConstr(gp), + //m_q(gpResult.getFiredLayerCnt()), //initial value of quality, can be altered later m_bx(bx), m_rhitNumb(refHitNumber) {} - GoldenPatternBase* getGoldenPatern() const { return goldenPatern; } + GoldenPatternBase* getGoldenPatern() const { return goldenPaternConstr; } - ~AlgoMuon() override {} + ~AlgoMuon() {} - const GoldenPatternResult& getGpResult() const { return gpResult; } + //vertex-constrained golden pattern result + const GoldenPatternResult& getGpResultConstr() const { return gpResultConstr; } + + const GoldenPatternResult& getGpResultUnconstr() const { return gpResultUnconstr; } + + void setGpResultUnconstr(const GoldenPatternResult& gpResultUnconstr) { this->gpResultUnconstr = gpResultUnconstr; } + + void setEta(int eta) { gpResultConstr.setEta(eta); } + + int getEtaHw() const { return gpResultConstr.getEta(); } + + unsigned int getRefHitNumber() const { return m_rhitNumb; } + + void setRefHitNumber(unsigned int aRefHitNum) { m_rhitNumb = aRefHitNum; } + + int getRefLayer() const { return gpResultConstr.getRefLayer(); } - PdfValueType getDisc() const { return gpResult.getPdfSum(); } - int getPhi() const { return gpResult.getPhi(); } - int getEtaHw() const override { return gpResult.getEta(); } - int getRefLayer() const { return gpResult.getRefLayer(); } - unsigned int getFiredLayerBits() const { return gpResult.getFiredLayerBits(); } - int getQ() const { return m_q; } int getBx() const { return m_bx; } - int getPt() const { - if (goldenPatern == nullptr) - return -1; - return goldenPatern->key().thePt; + //hardware pt + int getPtConstr() const { + //TODO maybe it should return 0 and not -1? + return goldenPaternConstr == nullptr ? -1 : goldenPaternConstr->key().thePt; } - int getCharge() const { - if (goldenPatern == nullptr) - return 0; - return goldenPatern->key().theCharge; + //hardware upt, in the phase1 the upt scale unit is 1 GeV, while for the pt the unit is 0.5GeV + int getPtUnconstr() const { + //TODO maybe it should return 0 and not -1? + return goldenPaternUnconstr == nullptr ? -1 : (goldenPaternUnconstr->key().thePt - 1) / 2 + 1; } - int getPhiRHit() const { return gpResult.getRefHitPhi(); } - unsigned int getPatternNumber() const { - if (goldenPatern == nullptr) - return 0; - return goldenPatern->key().theNumber; + int getChargeConstr() const { return goldenPaternConstr == nullptr ? -1 : goldenPaternConstr->key().theCharge; } + + int getPhiRHit() const { return gpResultConstr.getRefHitPhi(); } + + unsigned int getPatternNum() const { + return (gpResultUnconstr.getPdfSumUnconstr() > gpResultConstr.getPdfSum() ? goldenPaternUnconstr->key().theNumber + : goldenPaternConstr->key().theNumber); } - unsigned int getHwPatternNumber() const { - if (goldenPatern == nullptr) - return 0; - return goldenPatern->key().getHwPatternNumber(); + unsigned int getPatternNumConstr() const { + return goldenPaternConstr == nullptr ? 0 : goldenPaternConstr->key().theNumber; } - unsigned int getRefHitNumber() const { return m_rhitNumb; } + unsigned int getPatternNumUnconstr() const { + return goldenPaternUnconstr == nullptr ? 0 : goldenPaternUnconstr->key().theNumber; + } - void setQ(int q) { m_q = q; } - void setEta(int eta) { gpResult.setEta(eta); } + unsigned int getHwPatternNumConstr() const { + return goldenPaternConstr == nullptr ? 0 : goldenPaternConstr->key().getHwPatternNumber(); + } - void setRefHitNumber(unsigned int aRefHitNum) { m_rhitNumb = aRefHitNum; } + unsigned int getHwPatternNumUnconstr() const { + return goldenPaternUnconstr == nullptr ? 0 : goldenPaternUnconstr->key().getHwPatternNumber(); + } + + bool isValid() const { + return (getPtConstr() > 0) || (getPtUnconstr() > 0); //should this really be pt or quality ?? FIXME + } - bool isValid() const override; + double getPdfSumConstr() const { return gpResultConstr.getPdfSum(); } - unsigned int getFiredLayerCnt() const override { return gpResult.getFiredLayerCnt(); } + double getPdfSum() const { + return (gpResultUnconstr.getPdfSumUnconstr() > gpResultConstr.getPdfSum() ? gpResultUnconstr.getPdfSumUnconstr() + : gpResultConstr.getPdfSum()); + } + + PdfValueType getDisc() const { + return (gpResultUnconstr.getPdfSumUnconstr() > gpResultConstr.getPdfSum() ? gpResultUnconstr.getPdfSumUnconstr() + : gpResultConstr.getPdfSum()); + } - double getPdfSum() const override { return gpResult.getPdfSum(); } + int getPhi() const { + return (gpResultUnconstr.getPdfSumUnconstr() > gpResultConstr.getPdfSum() ? gpResultUnconstr.getPhi() + : gpResultConstr.getPhi()); + } - const StubResult& getStubResult(unsigned int iLayer) const override { return gpResult.getStubResults().at(iLayer); } + unsigned int getFiredLayerCnt() const { + return (gpResultUnconstr.getPdfSumUnconstr() > gpResultConstr.getPdfSum() ? gpResultUnconstr.getFiredLayerCnt() + : gpResultConstr.getFiredLayerCnt()); + } - const StubResults& getStubResults() const override { return gpResult.getStubResults(); } + unsigned int getFiredLayerCntConstr() const { return gpResultConstr.getFiredLayerCnt(); } + + unsigned int getFiredLayerBits() const { + return (gpResultUnconstr.getPdfSumUnconstr() > gpResultConstr.getPdfSum() ? gpResultUnconstr.getFiredLayerBits() + : gpResultConstr.getFiredLayerBits()); + } + + int getQ() const { + return (gpResultUnconstr.getPdfSumUnconstr() > gpResultConstr.getPdfSum() ? gpResultUnconstr.getFiredLayerCnt() + : gpResultConstr.getFiredLayerCnt()); + } + + const StubResult& getStubResult(unsigned int iLayer) const { return gpResultConstr.getStubResults().at(iLayer); } + + const StubResults& getStubResultsConstr() const { return gpResultConstr.getStubResults(); } const bool isKilled() const { return killed; } void kill() { killed = true; } - bool operator<(const AlgoMuon& o) const; - friend std::ostream& operator<<(std::ostream& out, const AlgoMuon& o); + std::vector>& getKilledMuons() { return killedMuons; } + + GoldenPatternBase* getGoldenPaternUnconstr() const { return goldenPaternUnconstr; } + + void setGoldenPaternUnconstr(GoldenPatternBase* goldenPaternUnconstr) { + this->goldenPaternUnconstr = goldenPaternUnconstr; + } + + int getChargeNNConstr() const { return chargeNNConstr; } + + void setChargeNNConstr(int chargeNn = 0) { chargeNNConstr = chargeNn; } + + int getPtNNConstr() const { return ptNNConstr; } + + void setPtNNConstr(int ptNn = 0) { ptNNConstr = ptNn; } + + int getChargeNNUnconstr() const { return chargeNNUnconstr; } + + void setChargeNNUnconstr(int chargeNnUnconstr = 0) { chargeNNUnconstr = chargeNnUnconstr; } + + int getPtNNUnconstr() const { return ptNNUnconstr; } + + void setPtNNUnconstr(int ptNnUnconstr = 0) { ptNNUnconstr = ptNnUnconstr; } + private: ///FIXME maybe the gpResult cannot be a reference or pointer, ad not a copy - GoldenPatternResult gpResult; + GoldenPatternResult gpResultConstr; - GoldenPatternBase* goldenPatern = nullptr; + //GoldenPatternResult without vertex constraint (unconstrained pt) + //TODO make it pointer + GoldenPatternResult gpResultUnconstr; - int m_q = -1; + GoldenPatternBase* goldenPaternConstr = nullptr; + + //GoldenPattern without vertex constraint (unconstrained pt) + GoldenPatternBase* goldenPaternUnconstr = nullptr; + + //int m_q = -1; int m_bx = 0; unsigned int m_rhitNumb = 0; @@ -96,6 +169,14 @@ class AlgoMuon : public AlgoMuonBase { bool killed = false; unsigned int index = 0; + + std::vector> killedMuons; + + int ptNNConstr = 0; + int chargeNNConstr = 0; + + int ptNNUnconstr = 0; + int chargeNNUnconstr = 0; }; typedef std::shared_ptr AlgoMuonPtr; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GhostBuster.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GhostBuster.h index a650b4715de11..bd835a0973b08 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GhostBuster.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GhostBuster.h @@ -4,14 +4,6 @@ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IGhostBuster.h" -#include -#include - -#include -#include - -#include - class GhostBuster : public IGhostBuster { private: const OMTFConfiguration* omtfConfig; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GhostBusterPreferRefDt.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GhostBusterPreferRefDt.h index 9f221fa6578a2..c921a780581fa 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GhostBusterPreferRefDt.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GhostBusterPreferRefDt.h @@ -4,13 +4,6 @@ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IGhostBuster.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h" -#include -#include - -#include -#include - -#include class GhostBusterPreferRefDt : public IGhostBuster { private: diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternBase.h index 406fbad502f86..cce6d74ef5bb9 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternBase.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternBase.h @@ -102,7 +102,8 @@ class GoldenPatternBase { virtual StubResult process1Layer1RefLayer(unsigned int iRefLayer, unsigned int iLayer, MuonStubPtrs1D layerStubs, - const MuonStubPtr refStub); + const std::vector& extrapolatedPhi, + const MuonStubPtr& refStub); ///Propagate phi from given reference layer to MB2 or ME2 ///ME2 is used if eta of reference hit is larger than 1.1 diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternResult.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternResult.h index ae4b163ff7342..09ed691d0bae4 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternResult.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternResult.h @@ -23,10 +23,14 @@ class GoldenPatternResult { int eta = 0; ///Sum of pdfValues - //omtfPdfValueType double pdfSum = 0; ///Number of fired layers - excluding bending layers + ///Sum of pdfValues without vertex constraint (unconstrained pt) + //i.e. not counting the pdfValue of the phiB of the refLayer + double pdfSumUnconstr = 0; + + ///Number of fired layers unsigned int firedLayerCnt = 0; ///bits representing fired logicLayers (including bending layers), @@ -80,6 +84,8 @@ class GoldenPatternResult { */ PdfValueType getPdfSum() const { return pdfSum; } + PdfValueType getPdfSumUnconstr() const { return pdfSumUnconstr; } + const StubResults& getStubResults() const { return stubResults; } int getPhi() const { return phi; } @@ -120,6 +126,10 @@ class GoldenPatternResult { void finalise8(); void finalise9(); + + void finalise10(); + + void finalise11(); //bool empty() const; friend std::ostream& operator<<(std::ostream& out, const GoldenPatternResult& aResult); diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternWithStat.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternWithStat.h index c6442c9b74e89..121883f105fc9 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternWithStat.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternWithStat.h @@ -14,7 +14,7 @@ class OMTFConfiguration; class GoldenPatternWithStat : public GoldenPatternWithThresh { public: static const unsigned int STAT_BINS = 1; //TODO change value if needed - typedef boost::multi_array StatArrayType; + typedef boost::multi_array StatArrayType; GoldenPatternWithStat(const Key& aKey, unsigned int nLayers, unsigned int nRefLayers, unsigned int nPdfAddrBits); diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IOMTFEmulationObserver.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IOMTFEmulationObserver.h index 543d6722bce4e..88ce2edbea7b6 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IOMTFEmulationObserver.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IOMTFEmulationObserver.h @@ -14,6 +14,9 @@ #include "FWCore/Framework/interface/EventSetup.h" #include "DataFormats/L1TMuon/interface/RegionalMuonCand.h" #include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h" + +#include + #include #include @@ -28,6 +31,10 @@ class IOMTFEmulationObserver { virtual void beginRun(edm::EventSetup const& eventSetup) {} + virtual void observeProcesorBegin(unsigned int iProcessor, l1t::tftype mtfType){}; + + virtual void addProcesorData(std::string key, boost::property_tree::ptree& procDataTree){}; + virtual void observeProcesorEmulation(unsigned int iProcessor, l1t::tftype mtfType, const std::shared_ptr& input, diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h index 5708b96a9bdec..0be9fc6615513 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h @@ -21,7 +21,10 @@ class IProcessorEmulator { public: virtual ~IProcessorEmulator() {} - virtual void processInput(unsigned int iProcessor, l1t::tftype mtfType, const OMTFinput& aInput) = 0; + virtual void processInput(unsigned int iProcessor, + l1t::tftype mtfType, + const OMTFinput& aInput, + std::vector >& observers) = 0; ///allows to use other IGhostBuster implementation than the default one virtual void setGhostBuster(IGhostBuster* ghostBuster) = 0; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h index 0b49e7f3f95ec..475ae3a3392c4 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h @@ -98,10 +98,11 @@ class OMTFConfiguration : public ProcConfigurationBase { unsigned int nPdfValBits() const { return rawParams.nPdfValBits(); }; int pdfMaxValue() const { return pdfMaxVal; }; unsigned int nPhiBins() const override { return rawParams.nPhiBins(); }; + double omtfPhiUnit() const { return 2 * M_PI / nPhiBins(); } unsigned int nRefHits() const { return rawParams.nRefHits(); }; unsigned int nTestRefHits() const { return rawParams.nTestRefHits(); }; //processors number per detector side - unsigned int nProcessors() const { return rawParams.nProcessors(); }; + unsigned int nProcessors() const override { return rawParams.nProcessors(); }; //total number of processors in the system unsigned int processorCnt() const { return 2 * rawParams.nProcessors(); }; unsigned int nLogicRegions() const { return rawParams.nLogicRegions(); }; @@ -139,15 +140,26 @@ class OMTFConfiguration : public ProcConfigurationBase { ///uGMT pt scale conversion double hwPtToGev(int hwPt) const override { return (hwPt - 1.) * ptUnit; } + double uptUnit = 1; // GeV/unit + double hwUPtToGev(int hwPt) const override { return (hwPt - 1.) * uptUnit; } + ///uGMT pt scale conversion: [0GeV, 0.5GeV) = 1 [0.5GeV, 1 Gev) = 2 int ptGevToHw(double ptGev) const override { return (ptGev / ptUnit + 1); } + int calcGlobalPhi(int locPhi, int proc) const; + double etaUnit = 0.010875; //=2.61/240 TODO value taken from the interface note, should be defined somewhere globally ///center of eta bin virtual double hwEtaToEta(int hwEta) const { return (hwEta * etaUnit); } int etaToHwEta(double eta) const override { return (eta / etaUnit); } + static unsigned int eta2Bits(unsigned int eta); + + static unsigned int etaBits2HwEta(unsigned int eta); + + static int etaBit2Code(unsigned int bit); + double phiGmtUnit = 2. * M_PI / 576; //TODO from the interface note, should be defined somewhere globally //phi in radians virtual int phiToGlobalHwPhi(double phi) const { return std::floor(phi / phiGmtUnit); } @@ -250,8 +262,29 @@ class OMTFConfiguration : public ProcConfigurationBase { void setGhostBusterType(const std::string& ghostBusterType = "") { this->ghostBusterType = ghostBusterType; } + bool usePhiBExtrapolationMB1() const { return this->usePhiBExtrapolationFromMB1_; } + + bool usePhiBExtrapolationMB2() const { return this->usePhiBExtrapolationFromMB2_; } + + int getDtRefHitMinQuality() const { return dtRefHitMinQuality; } + + void setDtRefHitMinQuality(int dtRefHitMinQuality = 2) { this->dtRefHitMinQuality = dtRefHitMinQuality; } + + bool getDumpResultToXML() const { return dumpResultToXML; } + void printConfig() const; + bool useEndcapStubsRInExtr() const { return useEndcapStubsRInExtr_; } + + bool useStubQualInExtr() const { return useStubQualInExtr_; } + + //[cm] + int minCSCStubRME12() const { return minCSCStubRME12_; } + //[cm], othere CSC station than ME1/2 + int minCscStubR() const { return minCSCStubR_; } + + bool cleanStubs() const { return cleanStubs_; } + private: L1TMuonOverlapParams rawParams; @@ -306,11 +339,33 @@ class OMTFConfiguration : public ProcConfigurationBase { int goldenPatternResultFinalizeFunction = 0; + //likelihood of "no hit" in the pdf bool noHitValueInPdf = false; int sorterType = 0; std::string ghostBusterType = ""; + + //if true, in the OMTFProcessor::processInput the phiB extrapolation is used for the refHit of the MB1, i.e. logicLayer 0 and 1 + bool usePhiBExtrapolationFromMB1_ = false; + + //if true, in the OMTFProcessor::processInput the phiB extrapolation is used for the refHit of the MB2, i.e. logicLayer 2 and 3 + bool usePhiBExtrapolationFromMB2_ = false; + + bool useStubQualInExtr_ = false; + + bool useEndcapStubsRInExtr_ = false; + + //min quality of the DT phi hit used as the reference hit + //Remember that it is on the top of the minDtPhiQuality + int dtRefHitMinQuality = 2; + + int minCSCStubRME12_ = 0; + int minCSCStubR_ = 0; + + bool dumpResultToXML = false; + + bool cleanStubs_ = false; }; #endif diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h index 96ce12bf1631c..68ce5b1dac266 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h @@ -13,8 +13,6 @@ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h" -#include - #include "FWCore/Framework/interface/Event.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -28,6 +26,9 @@ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPattern.h" +#include +#include + class OMTFinput; namespace edm { @@ -54,9 +55,41 @@ class OMTFProcessor : public ProcessorBase, public IProcessor return ProcessorBase::configure(omtfParams, omtfPatterns); }*/ + //targetStubQuality matters only for the barrel stubs, + //targetStubR - radial distance from the z axis (beam), matters only for the endcap stubs + //floating point version, it is used to generate the extrapolFactors for the fixed point version + int extrapolateDtPhiBFloatPoint(const int& refLogicLayer, + const int& refPhi, + const int& refPhiB, + unsigned int targetLayer, + const int& targetStubPhi, + const int& targetStubQuality, + const int& targetStubEta, + const int& targetStubR, + const OMTFConfiguration* omtfConfig); + + //fixed point, firmware like extrapolation + int extrapolateDtPhiBFixedPoint(const int& refLogicLayer, + const int& refPhi, + const int& refPhiB, + unsigned int targetLayer, + const int& targetStubPhi, + const int& targetStubQuality, + const int& targetStubEta, + const int& targetStubR, + const OMTFConfiguration* omtfConfig); + + int extrapolateDtPhiB(const MuonStubPtr& refStub, + const MuonStubPtr& targetStub, + unsigned int targetLayer, + const OMTFConfiguration* omtfConfig); + ///Process input data from a single event ///Input data is represented by hits in logic layers expressed in local coordinates - void processInput(unsigned int iProcessor, l1t::tftype mtfType, const OMTFinput& aInput) override; + void processInput(unsigned int iProcessor, + l1t::tftype mtfType, + const OMTFinput& aInput, + std::vector >& observers) override; AlgoMuons sortResults(unsigned int iProcessor, l1t::tftype mtfType, int charge = 0) override; @@ -85,6 +118,9 @@ class OMTFProcessor : public ProcessorBase, public IProcessor void printInfo() const override; + void saveExtrapolFactors(); + void loadExtrapolFactors(const std::string& filename); + private: virtual void init(const edm::ParameterSet& edmCfg, edm::EventSetup const& evSetup); @@ -102,6 +138,18 @@ class OMTFProcessor : public ProcessorBase, public IProcessor //ptAssignment should be destroyed where it is created, i.e. by OmtfEmulation or OMTFReconstruction PtAssignmentBase* ptAssignment = nullptr; + + bool useStubQualInExtr = false; + bool useEndcapStubsRInExtr = false; + + //if true, the extrapolateDtPhiBFloatPoint, and the extrapolation factors are generated + //if false, extrapolateDtPhiBFixedPoint is used + bool useFloatingPointExtrapolation = false; + + int extrapolMultiplier = 128; + + std::vector > > extrapolFactors; //[refLayer][targetLayer][etaCode] + std::vector > > extrapolFactorsNorm; }; #endif diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinput.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinput.h index ff48ede05ded2..05a52a4c18e84 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinput.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinput.h @@ -8,6 +8,8 @@ #include #include +#include "boost/dynamic_bitset.hpp" + class XMLConfigReader; class OMTFConfiguration; @@ -27,6 +29,7 @@ class OMTFinput : public MuonStubsInput { ///Method used in DiMuon studies. void mergeData(const OMTFinput *aInput); + //TODOO make it: if the layer is bending layer, the phiB from the iLayer -1 is returned, change in all places it is used const MuonStubPtr getMuonStub(unsigned int iLayer, unsigned int iInput) const { return muonStubsInLayers.at(iLayer).at(iInput); } @@ -37,7 +40,10 @@ class OMTFinput : public MuonStubsInput { //if the layer is bending layer, the eta from the iLayer -1 is returned const int getHitEta(unsigned int iLayer, unsigned int iInput) const; - std::bitset<128> getRefHits(unsigned int iProcessor) const; + //if the layer is bending layer, the eta from the iLayer -1 is returned + const int getHitQual(unsigned int iLayer, unsigned int iInput) const; + + boost::dynamic_bitset<> getRefHits(unsigned int iProcessor) const; friend std::ostream &operator<<(std::ostream &out, const OMTFinput &aInput); diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h index 8914e85f6749a..d3dca1e738b31 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h @@ -21,10 +21,10 @@ class OmtfAngleConverter : public AngleConverterBase { virtual int getGlobalEta(const DTChamberId dTChamberId, const L1MuDTChambThContainer *dtThDigis, int bxNum) const; ///Convert local eta coordinate to global digital microGMT scale. - virtual int getGlobalEta(unsigned int rawid, const CSCCorrelatedLCTDigi &aDigi) const; + virtual int getGlobalEta(unsigned int rawid, const CSCCorrelatedLCTDigi &aDigi, float &r) const; ///Convert local eta coordinate to global digital microGMT scale. - virtual int getGlobalEtaRpc(unsigned int rawid, const unsigned int &aDigi) const; + virtual int getGlobalEtaRpc(unsigned int rawid, const unsigned int &aDigi, float &r) const; //to avoid Clang Warnings "hides overloaded virtual functions" using AngleConverterBase::getGlobalEta; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfName.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfName.h index a535b738ce646..6786094c381e2 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfName.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfName.h @@ -1,11 +1,13 @@ #ifndef L1Trigger_L1TMuonOverlapP1_OmtfName_H #define L1Trigger_L1TMuonOverlapP1_OmtfName_H -#include -#include +#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h" #include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h" +#include +#include + class OmtfName { public: enum Board { @@ -30,13 +32,13 @@ class OmtfName { OmtfName(const std::string& name); //by giving procesor id [0,5] and endcap position {+1,-1} as in uGMT. - explicit OmtfName(unsigned int iProcesor, int endcap); + explicit OmtfName(unsigned int iProcesor, int endcap, const OMTFConfiguration* omtfConfig); //by giving procesor id [0,5] and endcap position as l1t::tftype of omtf_pos or omtf_neg. - explicit OmtfName(unsigned int iProcesor, l1t::tftype endcap); + explicit OmtfName(unsigned int iProcesor, l1t::tftype endcap, const OMTFConfiguration* omtfConfig); //by giving procesor continous index [0,11]. - explicit OmtfName(unsigned int iProcesor); + explicit OmtfName(unsigned int iProcesor, const OMTFConfiguration* omtfConfig); operator int() const { return theBoard; } bool operator==(const OmtfName& o) const { return theBoard == o.theBoard; } diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h index 0a4b16ffa1e7d..0f0a7a6ffc901 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h @@ -9,6 +9,7 @@ #define L1T_OmtfP1_PTASSIGNMENTBASE_H_ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h" +#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IOMTFEmulationObserver.h" /* * base class for the objects providing an alternative pt assignment on top of the OMTF golden pattern (like neural network) @@ -19,7 +20,8 @@ class PtAssignmentBase { PtAssignmentBase(const OMTFConfiguration* omtfConfig) : omtfConfig(omtfConfig){}; virtual ~PtAssignmentBase(); - virtual std::vector getPts(const AlgoMuons::value_type& algoMuon) = 0; + virtual std::vector getPts(AlgoMuons::value_type& algoMuon, + std::vector >& observers) = 0; protected: const OMTFConfiguration* omtfConfig = nullptr; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLEventWriter.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLEventWriter.h index 07dba334ded36..cfbca57a38d3c 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLEventWriter.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLEventWriter.h @@ -12,8 +12,9 @@ #include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IOMTFEmulationObserver.h" -#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLConfigWriter.h" -#include "xercesc/util/XercesDefs.hpp" + +#include + #include #include #include @@ -24,6 +25,12 @@ class XMLEventWriter : public IOMTFEmulationObserver { ~XMLEventWriter() override; + void observeProcesorBegin(unsigned int iProcessor, l1t::tftype mtfType) override; + + void addProcesorData(std::string key, boost::property_tree::ptree& procDataTree) override { + procTree.add_child(key, procDataTree); + } + void observeProcesorEmulation(unsigned int iProcessor, l1t::tftype mtfType, const std::shared_ptr& input, @@ -40,8 +47,12 @@ class XMLEventWriter : public IOMTFEmulationObserver { private: const OMTFConfiguration* omtfConfig; - XMLConfigWriter xmlWriter; - xercesc::DOMElement* currentElement; + + boost::property_tree::ptree tree; + + boost::property_tree::ptree* eventTree = nullptr; + + boost::property_tree::ptree procTree; std::string fName; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h index dc03f683f2383..2b2cbb14b89e4 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h @@ -21,8 +21,12 @@ class ProcConfigurationBase { virtual unsigned int nPhiBins() const = 0; + virtual unsigned int nProcessors() const = 0; + virtual double hwPtToGev(int hwPt) const = 0; + virtual double hwUPtToGev(int hwPt) const = 0; + ///uGMT pt scale conversion: [0GeV, 0.5GeV) = 1 [0.5GeV, 1 Gev) = 2 virtual int ptGevToHw(double ptGev) const = 0; @@ -79,6 +83,23 @@ class ProcConfigurationBase { return this->fixCscGeometryOffset = fixCscGeometryOffset; } + enum class StubEtaEncoding { + //in the firmware the eta is encoded as fired bits in the 9bit word, this is DT phase-1 encoding. + //In the emulator in most of the places eta value is used, but with the DT-like binning, i.e. only certain values are valid, see OMTFConfiguration::eta2Bits() + //this is the OMTF run2 option + bits = 0, + //the phase1 eta scale is used, but all hw values are valid, i.e. the DT-phase one binnig is NOT used + valueP1Scale = 1, + }; + + StubEtaEncoding getStubEtaEncoding() const { return stubEtaEncoding; } + + void setStubEtaEncoding(StubEtaEncoding stubEtaEncoding) { this->stubEtaEncoding = stubEtaEncoding; } + + //[unit/rad] for DT segment phiB, as it is at the level of the algorithm + //in the link data it can be different, and it is converted in the DtDigiToStubsConverterOmtf::addDTphiDigi + double dtPhiBUnitsRad() const { return dtPhiBUnitsRad_; } + private: int cscLctCentralBx_ = 8; //CSCConstants::LCT_CENTRAL_BX; @@ -93,7 +114,11 @@ class ProcConfigurationBase { int minDtPhiBQuality = 2; //used on the top of the minDtPhiQuality + double dtPhiBUnitsRad_ = 512; //[unit/rad] for DT segment phiB, it is at the level of the algorithm, not inputs + bool fixCscGeometryOffset = false; + + StubEtaEncoding stubEtaEncoding = StubEtaEncoding::bits; }; #endif /* L1T_OmtfP1_PROCCONFIGURATIONBASE_H_ */ diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h index 74ebfbde68300..4e86b9651f83b 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h @@ -86,6 +86,8 @@ class MatchingResult { double genPhi = 0; const SimTrack* simTrack = nullptr; + const SimVertex* simVertex = nullptr; + const TrackingParticle* trackingParticle = nullptr; }; @@ -122,15 +124,15 @@ class CandidateSimMuonMatcher : public IOMTFEmulationObserver { //ghost busts at the same time the mtfCands and the gbCandidates //gbCandidates - all gbCandidates from all processors, should be one-to-one as the mtfCands, //and the ghostBustedProcMuons are one-to-onr to the returned RegionalMuonCands - static std::vector ghostBust(const l1t::RegionalMuonCandBxCollection* mtfCands, - const AlgoMuons& gbCandidates, - AlgoMuons& ghostBustedProcMuons); + std::vector ghostBust(const l1t::RegionalMuonCandBxCollection* mtfCands, + const AlgoMuons& gbCandidates, + AlgoMuons& ghostBustedProcMuons); FreeTrajectoryState simTrackToFts(const SimTrack& simTrack, const SimVertex& simVertex); FreeTrajectoryState simTrackToFts(const TrackingParticle& trackingParticle); - TrajectoryStateOnSurface atStation2(FreeTrajectoryState ftsStart, float eta) const; + TrajectoryStateOnSurface atStation2(const FreeTrajectoryState& ftsStart) const; TrajectoryStateOnSurface propagate(const SimTrack& simTrack, const edm::SimVertexContainer* simVertices); diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h index 3f1de0c71393f..2111b22d02816 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h @@ -9,6 +9,7 @@ #define L1T_OmtfP1_TOOLS_DATAROOTDUMPER2_H_ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EmulationObserverBase.h" +#include "L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" @@ -26,15 +27,33 @@ class TTree; struct OmtfEvent { public: - double muonPt = 0, muonEta = 0, muonPhi = 0; - int muonCharge = 0; + unsigned int eventNum = 0; + + //muonPt = 0 means that no muon was matched to the candidate + short muonEvent = -1; + float muonPt = 0, muonEta = 0, muonPhi = 0, muonPropEta = 0, muonPropPhi = 0; + char muonCharge = 0; + float muonDxy = 0; + float muonRho = 0; + + float omtfPt = 0, omtfEta = 0, omtfPhi = 0, omtfUPt = 0; + char omtfCharge = 0; + char omtfProcessor = 0; + short omtfScore = 0; + + short omtfHwEta = 0; + + char omtfQuality = 0; + char omtfRefLayer = 0; + char omtfRefHitNum = 0; - int omtfCharge = 0, omtfProcessor = 0, omtfScore = 0; - double omtfPt = 0, omtfEta = 0, omtfPhi = 0; - unsigned int omtfQuality = 0, omtfRefLayer = 0; unsigned int omtfFiredLayers = 0; - float omtfPtCont = 0; + bool killed = false; + + float deltaPhi = 0, deltaEta = 0; + + //float omtfPtCont = 0; struct Hit { union { @@ -58,20 +77,29 @@ struct OmtfEvent { class DataROOTDumper2 : public EmulationObserverBase { public: - DataROOTDumper2(const edm::ParameterSet& edmCfg, const OMTFConfiguration* omtfConfig, std::string rootFileName); + DataROOTDumper2(const edm::ParameterSet& edmCfg, + const OMTFConfiguration* omtfConfig, + CandidateSimMuonMatcher* candidateSimMuonMatcher); ~DataROOTDumper2() override; + void observeProcesorEmulation(unsigned int iProcessor, + l1t::tftype mtfType, + const std::shared_ptr&, + const AlgoMuons& algoCandidates, + const AlgoMuons& gbCandidates, + const std::vector& candMuons) override; + void observeEventEnd(const edm::Event& iEvent, std::unique_ptr& finalCandidates) override; void endJob() override; private: - void initializeTTree(std::string rootFileName); - void saveTTree(); + void initializeTTree(); + + CandidateSimMuonMatcher* candidateSimMuonMatcher = nullptr; - TFile* rootFile = nullptr; TTree* rootTree = nullptr; OmtfEvent omtfEvent; @@ -82,6 +110,8 @@ class DataROOTDumper2 : public EmulationObserverBase { TH1I* ptGenNeg = nullptr; std::vector hitVsPt; + + bool dumpKilledOmtfCands = false; }; #endif /* L1T_OmtfP1_TOOLS_DATAROOTDUMPER2_H_ */ diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EmulationObserverBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EmulationObserverBase.h index e0d495b781725..f2e7b90c6831c 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EmulationObserverBase.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EmulationObserverBase.h @@ -14,6 +14,7 @@ #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "SimDataFormats/Track/interface/SimTrackContainer.h" +#include "DataFormats/HepMCCandidate/interface/GenParticle.h" class EmulationObserverBase : public IOMTFEmulationObserver { public: @@ -37,6 +38,8 @@ class EmulationObserverBase : public IOMTFEmulationObserver { const SimTrack* findSimMuon(const edm::Event& event, const SimTrack* previous = nullptr); + const std::vector findGenMuon(const edm::Event& event); + protected: edm::ParameterSet edmCfg; const OMTFConfiguration* omtfConfig; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternGenerator.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternGenerator.h index e92f7ef9f9aa2..6b95241296579 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternGenerator.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternGenerator.h @@ -9,12 +9,14 @@ #define L1T_OmtfP1_PATTERNGENERATOR_H_ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternOptimizerBase.h" +#include "L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h" class PatternGenerator : public PatternOptimizerBase { public: PatternGenerator(const edm::ParameterSet& edmCfg, const OMTFConfiguration* omtfConfig, - GoldenPatternVec& gps); + GoldenPatternVec& gps, + CandidateSimMuonMatcher* candidateSimMuonMatcher); ~PatternGenerator() override; @@ -28,6 +30,10 @@ class PatternGenerator : public PatternOptimizerBase { void updateStat(); + void updateStatUsingMatcher2(); + + std::function updateStatFunction; + void upadatePdfs(); void saveHists(TFile& outfile) override; @@ -38,6 +44,8 @@ class PatternGenerator : public PatternOptimizerBase { void groupPatterns(); + CandidateSimMuonMatcher* candidateSimMuonMatcher = nullptr; + //indexing: [charge][iLayer] std::vector > ptDeltaPhiHists; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternOptimizerBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternOptimizerBase.h index 15a2ffeb756ca..e1f18b026093e 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternOptimizerBase.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternOptimizerBase.h @@ -49,10 +49,12 @@ class PatternOptimizerBase : public EmulationObserverBase { GoldenPatternVec& goldenPatterns; - TH1I* simMuPt; - TH1I* simMuFoundByOmtfPt; + TH1I* simMuPt = nullptr; + TH1I* simMuFoundByOmtfPt = nullptr; - TH1F* simMuPtSpectrum; + TH1F* simMuPtSpectrum = nullptr; + TH2I* simMuPtVsDispl = nullptr; + TH2I* simMuPtVsRho = nullptr; bool writeLayerStat = false; }; diff --git a/L1Trigger/L1TMuonOverlapPhase1/plugins/L1TMuonOverlapPhase1TrackProducer.cc b/L1Trigger/L1TMuonOverlapPhase1/plugins/L1TMuonOverlapPhase1TrackProducer.cc index 6c3743ebf9ddb..8dfe3b7c63160 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/plugins/L1TMuonOverlapPhase1TrackProducer.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/plugins/L1TMuonOverlapPhase1TrackProducer.cc @@ -1,5 +1,4 @@ #include "L1TMuonOverlapPhase1TrackProducer.h" - #include "FWCore/Utilities/interface/EDGetToken.h" #include "FWCore/Utilities/interface/InputTag.h" @@ -8,6 +7,7 @@ #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticleFwd.h" #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h" +#include "DataFormats/HepMCCandidate/interface/GenParticle.h" #include "DataFormats/Common/interface/DetSetVector.h" #include "SimDataFormats/RPCDigiSimLink/interface/RPCDigiSimLink.h" #include "SimDataFormats/TrackerDigiSimLink/interface/StripDigiSimLink.h" @@ -43,6 +43,9 @@ L1TMuonOverlapPhase1TrackProducer::L1TMuonOverlapPhase1TrackProducer(const edm:: if (edmParameterSet.exists("trackingParticleTag")) mayConsume(edmParameterSet.getParameter("trackingParticleTag")); + if (edmParameterSet.exists("genParticleTag")) + mayConsume(edmParameterSet.getParameter("genParticleTag")); + if (edmParameterSet.exists("rpcSimHitsInputTag")) mayConsume(edmParameterSet.getParameter("rpcSimHitsInputTag")); if (edmParameterSet.exists("cscSimHitsInputTag")) diff --git a/L1Trigger/L1TMuonOverlapPhase1/python/fakeOmtfParams_cff.py b/L1Trigger/L1TMuonOverlapPhase1/python/fakeOmtfParams_cff.py index bc15b2f51bb05..de16fbe42240e 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/python/fakeOmtfParams_cff.py +++ b/L1Trigger/L1TMuonOverlapPhase1/python/fakeOmtfParams_cff.py @@ -13,8 +13,9 @@ patternsXMLFiles = cms.VPSet( #cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x0003.xml")), #cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x0009_oldSample_3_10Files_classProb1.xml") ), + #cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_template.xml")), cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x00012_oldSample_3_30Files_grouped1_classProb17_recalib2.xml")), - + #cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_layerStat_ExtraplMB1nadMB2_t10_classProb17_recalib2.xml")), ), configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0008.xml"), ) diff --git a/L1Trigger/L1TMuonOverlapPhase1/python/simOmtfDigis_cfi.py b/L1Trigger/L1TMuonOverlapPhase1/python/simOmtfDigis_cfi.py index 8fb1f8d797932..d3d8dc360f2e3 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/python/simOmtfDigis_cfi.py +++ b/L1Trigger/L1TMuonOverlapPhase1/python/simOmtfDigis_cfi.py @@ -2,32 +2,32 @@ ###OMTF emulator configuration simOmtfDigis = cms.EDProducer("L1TMuonOverlapPhase1TrackProducer", - + srcDTPh = cms.InputTag('simDtTriggerPrimitiveDigis'), srcDTTh = cms.InputTag('simDtTriggerPrimitiveDigis'), srcCSC = cms.InputTag('simCscTriggerPrimitiveDigis','MPCSORTED'), - srcRPC = cms.InputTag('simMuonRPCDigis'), - - #g4SimTrackSrc = cms.InputTag('g4SimHits'), + srcRPC = cms.InputTag('simMuonRPCDigis'), + + #g4SimTrackSrc = cms.InputTag('g4SimHits'), dumpResultToXML = cms.bool(False), dumpDetailedResultToXML = cms.bool(False), - XMLDumpFileName = cms.string("TestEvents.xml"), - dumpGPToXML = cms.bool(False), + XMLDumpFileName = cms.string("TestEvents.xml"), + dumpGPToXML = cms.bool(False), readEventsFromXML = cms.bool(False), eventsXMLFiles = cms.vstring("TestEvents.xml"), - dropRPCPrimitives = cms.bool(False), - dropDTPrimitives = cms.bool(False), + dropRPCPrimitives = cms.bool(False), + dropDTPrimitives = cms.bool(False), dropCSCPrimitives = cms.bool(False), processorType = cms.string("OMTFProcessor"), - + #ghostBusterType = cms.string("GhostBusterPreferRefDt"), - + #patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x00020007.xml") - #patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x0003.xml") + #patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x0003.xml") #if commented the default values are 0-0 #-3 to 4 is the range of the OMTF DAQ readout, so should be used e.g. in the DQM data to emulator comparison bxMin = cms.int32(0), - bxMax = cms.int32(0) -) + bxMax = cms.int32(0), +) diff --git a/L1Trigger/L1TMuonOverlapPhase1/python/simOmtfDigis_extrapolSimple_cfi.py b/L1Trigger/L1TMuonOverlapPhase1/python/simOmtfDigis_extrapolSimple_cfi.py new file mode 100644 index 0000000000000..87d5133e039b4 --- /dev/null +++ b/L1Trigger/L1TMuonOverlapPhase1/python/simOmtfDigis_extrapolSimple_cfi.py @@ -0,0 +1,26 @@ +import FWCore.ParameterSet.Config as cms + +###OMTF emulator configuration with simple extrapolation algorithm +from L1Trigger.L1TMuonOverlapPhase1.simOmtfDigis_cfi import simOmtfDigis + +## add parameters to enable simple extrapolation algorithm +simOmtfDigis_extrapolSimple = simOmtfDigis.clone( + noHitValueInPdf = cms.bool(True), + minDtPhiQuality = cms.int32(2), + minDtPhiBQuality = cms.int32(4), + + dtRefHitMinQuality = cms.int32(4), + + stubEtaEncoding = cms.string("bits"), + + usePhiBExtrapolationFromMB1 = cms.bool(True), + usePhiBExtrapolationFromMB2 = cms.bool(True), + useStubQualInExtr = cms.bool(False), + useEndcapStubsRInExtr = cms.bool(False), + useFloatingPointExtrapolation = cms.bool(False), + + extrapolFactorsFilename = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/ExtrapolationFactors_simple.xml"), + sorterType = cms.string("byLLH"), + ghostBusterType = cms.string("byRefLayer"), # byLLH byRefLayer GhostBusterPreferRefDt + goldenPatternResultFinalizeFunction = cms.int32(10) +) diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/AlgoMuonBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/AlgoMuonBase.cc deleted file mode 100644 index 9a2aa6d0c6702..0000000000000 --- a/L1Trigger/L1TMuonOverlapPhase1/src/AlgoMuonBase.cc +++ /dev/null @@ -1,13 +0,0 @@ -/* - * AlgoMuonBase.cc - * - * Created on: Mar 1, 2019 - * Author: Karol Bunkowski kbunkow@cern.ch - */ - -#include "L1Trigger/L1TMuonOverlapPhase1/interface/AlgoMuonBase.h" - -AlgoMuonBase::AlgoMuonBase(const ProcConfigurationBase* config) - : firedLayerBitsInBx(config->getBxToProcess(), boost::dynamic_bitset<>(config->nLayers())) {} - -AlgoMuonBase::~AlgoMuonBase() {} diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/AngleConverterBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/AngleConverterBase.cc index bbbd157c078f3..35c1bde1863e1 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/AngleConverterBase.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/AngleConverterBase.cc @@ -65,7 +65,7 @@ int AngleConverterBase::getProcessorPhi(int phiZero, l1t::tftype part, int dtScN int sector = dtScNum + 1; //NOTE: there is a inconsistency in DT sector numb. Thus +1 needed to get detector numb. double scale = 1. / dtPhiBins / hsPhiPitch; - int scale_coeff = lround(scale * pow(2, 11)); + int scale_coeff = lround(scale * pow(2, 11)); // 216.2688 int ichamber = sector - 1; if (ichamber > 6) @@ -80,10 +80,8 @@ int AngleConverterBase::getProcessorPhi(int phiZero, l1t::tftype part, int dtScN } /////////////////////////////////////// /////////////////////////////////////// -int AngleConverterBase::getProcessorPhi(int phiZero, - l1t::tftype part, - const CSCDetId& csc, - const CSCCorrelatedLCTDigi& digi) const { +int AngleConverterBase::getProcessorPhi( + int phiZero, l1t::tftype part, const CSCDetId& csc, const CSCCorrelatedLCTDigi& digi, unsigned int iInput) const { const double hsPhiPitch = 2 * M_PI / nPhiBins; // // get offset for each chamber. @@ -105,8 +103,8 @@ int AngleConverterBase::getProcessorPhi(int phiZero, const CSCLayer* layer = chamber->layer(3); int order = (layer->centerOfStrip(2).phi() - layer->centerOfStrip(1).phi() > 0) ? 1 : -1; double stripPhiPitch = cspec->stripPhiPitch(); - double scale = fabs(stripPhiPitch / hsPhiPitch / 2.); - if (fabs(scale - 1.) < 0.0002) + double scale = std::abs(stripPhiPitch / hsPhiPitch / 2.); + if (std::abs(scale - 1.) < 0.0002) scale = 1.; double phiHalfStrip0 = layer->centerOfStrip(1).phi() - order * stripPhiPitch / 4.; @@ -128,9 +126,17 @@ int AngleConverterBase::getProcessorPhi(int phiZero, // a quick fix for towards geometry changes due to global tag. // in case of MC tag fixOff should be identical to offsetLoc - if (config->getFixCscGeometryOffset()) - fixOff = fixCscOffsetGeom(offsetLoc); //TODO does not work in when phiZero is always 0. Fix this - + if (config->getFixCscGeometryOffset()) { + if (config->nProcessors() == 6) //phase1 + fixOff = fixCscOffsetGeom(offsetLoc); //TODO does not work in when phiZero is always 0. Fix this + else if (config->nProcessors() == 3) { //phase2 + //TODO fix this bricolage!!!!!!!!!!!!!! + if (iInput >= 14) + fixOff = fixCscOffsetGeom(offsetLoc - 900) + 900; + else + fixOff = fixCscOffsetGeom(offsetLoc); + } + } int phi = fixOff + order * scale * halfStrip; //the phi conversion is done like above - and not simply converting the layer->centerOfStrip(halfStrip/2 +1).phi() - to mimic this what is done by the firmware, //where phi of the stub is calculated with use of the offset and scale provided by an register @@ -169,7 +175,7 @@ int AngleConverterBase::getProcessorPhi( double stripPhi2 = (roll->toGlobal(roll->centreOfStrip((int)digi2))).phi(); // note [-pi,pi] // the case when the two strips are on different sides of phi = pi - if (std::signbit(stripPhi1) != std::signbit(stripPhi2) && abs(stripPhi1) > M_PI / 2.) { + if (std::signbit(stripPhi1) != std::signbit(stripPhi2) && std::abs(stripPhi1) > M_PI / 2.) { if (std::signbit(stripPhi1)) { //stripPhi1 is negative stripPhi1 += 2 * M_PI; } else //stripPhi2 is negative @@ -235,7 +241,7 @@ EtaValue AngleConverterBase::getGlobalEtaDt(const DTChamberId& detId) const { EtaValue etaValue = { config->etaToHwEta(chamberMiddleGP.eta()), - config->etaToHwEta(fabs(chamberMiddleGP.eta() - chambNeighMiddleGP.eta())) / 2, + config->etaToHwEta(std::abs(chamberMiddleGP.eta() - chambNeighMiddleGP.eta())) / 2, 0, //quality 0, //bx 0 //timin @@ -387,8 +393,8 @@ EtaValue AngleConverterBase::getGlobalEta(unsigned int rawid, const unsigned int int neighbRoll = 1; //neighbor roll in eta //roll->chamber()->nrolls() does not work if (id.region() == 0) { //barel - if (id.station() == 2 && - ((abs(id.ring()) == 2 && id.layer() == 2) || (abs(id.ring()) != 2 && id.layer() == 1))) { //three-roll chamber + if (id.station() == 2 && ((std::abs(id.ring()) == 2 && id.layer() == 2) || + (std::abs(id.ring()) != 2 && id.layer() == 1))) { //three-roll chamber if (id.roll() == 2) neighbRoll = 1; else { @@ -410,7 +416,7 @@ EtaValue AngleConverterBase::getGlobalEta(unsigned int rawid, const unsigned int const GlobalPoint gpNeigh = rollNeigh->toGlobal(lpNeigh); EtaValue etaValue = {config->etaToHwEta(gp.eta()), - config->etaToHwEta(abs(gp.eta() - gpNeigh.eta())) / + config->etaToHwEta(std::abs(gp.eta() - gpNeigh.eta())) / 2, //half of the size of the strip in eta - not precise, but OK 0}; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/MuonStub.cc b/L1Trigger/L1TMuonOverlapPhase1/src/MuonStub.cc index 77550af8c5b17..0ec7d25d0b820 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/MuonStub.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/MuonStub.cc @@ -24,7 +24,7 @@ std::ostream &operator<<(std::ostream &out, const MuonStub &stub) { << stub.phiHw //<<" ("< >& observers) { if (!dtPhDigis) return; @@ -47,8 +51,12 @@ void DtDigiToStubsConverter::makeStubs( /////////////////////////////////////// /////////////////////////////////////// -void CscDigiToStubsConverter::makeStubs( - MuonStubPtrs2D& muonStubsInLayers, unsigned int iProcessor, l1t::tftype procTyp, int bxFrom, int bxTo) { +void CscDigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers, + unsigned int iProcessor, + l1t::tftype procTyp, + int bxFrom, + int bxTo, + std::vector >& observers) { if (!cscDigis) return; @@ -73,8 +81,12 @@ void CscDigiToStubsConverter::makeStubs( } } -void RpcDigiToStubsConverter::makeStubs( - MuonStubPtrs2D& muonStubsInLayers, unsigned int iProcessor, l1t::tftype procTyp, int bxFrom, int bxTo) { +void RpcDigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers, + unsigned int iProcessor, + l1t::tftype procTyp, + int bxFrom, + int bxTo, + std::vector >& observers) { if (!rpcDigis) return; //LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ <<" RPC HITS, processor : " << iProcessor<<" "<loadDigis(event); } -void MuonStubMakerBase::buildInputForProcessor( - MuonStubPtrs2D& muonStubsInLayers, unsigned int iProcessor, l1t::tftype procTyp, int bxFrom, int bxTo) { +void MuonStubMakerBase::buildInputForProcessor(MuonStubPtrs2D& muonStubsInLayers, + unsigned int iProcessor, + l1t::tftype procTyp, + int bxFrom, + int bxTo, + std::vector >& observers) { //LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " iProcessor " << iProcessor << " preocType " // << procTyp << std::endl; for (auto& digiToStubsConverter : digiToStubsConverters) - digiToStubsConverter->makeStubs(muonStubsInLayers, iProcessor, procTyp, bxFrom, bxTo); + digiToStubsConverter->makeStubs(muonStubsInLayers, iProcessor, procTyp, bxFrom, bxTo, observers); } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/AlgoMuon.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/AlgoMuon.cc index b409b738148c3..b04116c645b41 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/AlgoMuon.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/AlgoMuon.cc @@ -5,30 +5,12 @@ #include #include -bool AlgoMuon::isValid() const { - return getPt() > 0; //should this realy be pt or quality ?? FIXME -} - -bool AlgoMuon::operator<(const AlgoMuon &o) const { - if (this->getQ() > o.getQ()) - return false; - else if (this->getQ() == o.getQ() && this->getDisc() > o.getDisc()) - return false; - else if (getQ() == o.getQ() && getDisc() == o.getDisc() && getPatternNumber() > o.getPatternNumber()) - return false; - else if (getQ() == o.getQ() && getDisc() == o.getDisc() && getPatternNumber() == o.getPatternNumber() && - getRefHitNumber() < o.getRefHitNumber()) - return false; - else - return true; -} - std::ostream &operator<<(std::ostream &out, const AlgoMuon &o) { out << "AlgoMuon: "; - out << " pt: " << o.getPt() << ", phi: " << o.getPhi() << ", eta: " << o.getEtaHw() - << ", hits: " << std::bitset<18>(o.getFiredLayerBits()).to_string() << ", q: " << o.getQ() - << ", bx: " << o.getBx() << ", charge: " << o.getCharge() << ", disc: " << o.getDisc() - << " refLayer: " << o.getRefLayer() << " m_patNumb: " << o.getPatternNumber(); + out << " pt: " << o.getPtConstr() << " upt: " << o.getPtUnconstr() << ", phi: " << o.getPhi() + << ", eta: " << o.getEtaHw() << ", hits: " << std::bitset<18>(o.getFiredLayerBits()).to_string() + << ", q: " << o.getQ() << ", bx: " << o.getBx() << ", charge: " << o.getChargeConstr() + << ", disc: " << o.getDisc() << " refLayer: " << o.getRefLayer() << " m_patNumb: " << o.getPatternNumConstr(); return out; } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBuster.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBuster.cc index 40609d974ab3b..7cc8378a4ab76 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBuster.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBuster.cc @@ -11,7 +11,25 @@ AlgoMuons GhostBuster::select(AlgoMuons refHitCands, int charge) { AlgoMuons refHitCleanCands; // Sort candidates with decreased goodness, auto customLess = [&](const AlgoMuons::value_type& a, const AlgoMuons::value_type& b) -> bool { - return (*a) < (*b); //< operator of AlgoMuon + if (!a->isValid()) { + return true; + } + if (!b->isValid()) { + return false; + } + + if (a->getQ() > b->getQ()) + return false; + else if (a->getQ() == b->getQ() && a->getDisc() > b->getDisc()) + return false; + else if (a->getQ() == b->getQ() && a->getDisc() == b->getDisc() && + a->getPatternNumConstr() > b->getPatternNumConstr()) + return false; + else if (a->getQ() == b->getQ() && a->getDisc() == b->getDisc() && + a->getPatternNumConstr() == b->getPatternNumConstr() && a->getRefHitNumber() < b->getRefHitNumber()) + return false; + else + return true; }; std::sort(refHitCands.rbegin(), refHitCands.rend(), customLess); @@ -30,8 +48,11 @@ AlgoMuons GhostBuster::select(AlgoMuons refHitCands, int charge) { //TODO here the candidate that is killed does not kill other candidates - check if the firmware does the same (KB) } } - if ((*it1)->getQ() > 0 && !isGhost) + if ((*it1)->getQ() > 0 && !isGhost) { refHitCleanCands.emplace_back(new AlgoMuon(**it1)); + if (omtfConfig->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::bits) + refHitCleanCands.back()->setEta(OMTFConfiguration::etaBits2HwEta((*it1)->getEtaHw())); + } if (refHitCleanCands.size() >= 3) break; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc index 3b85591573bf1..e73072ab742af 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc @@ -5,17 +5,9 @@ #include -namespace { - - struct AlgoMuonEtaFix : public AlgoMuon { - AlgoMuonEtaFix(const AlgoMuon& mu) : AlgoMuon(mu), fixedEta(mu.getEtaHw()) {} - unsigned int fixedEta; - }; - -} // namespace - AlgoMuons GhostBusterPreferRefDt::select(AlgoMuons muonsIN, int charge) { // sorting within GB. + //this function is only for the OMTF version without unconstrained pt auto customLess = [&](const AlgoMuons::value_type& a, const AlgoMuons::value_type& b) -> bool { if (!a->isValid()) { return true; @@ -26,17 +18,19 @@ AlgoMuons GhostBusterPreferRefDt::select(AlgoMuons muonsIN, int charge) { int aRefLayerLogicNum = omtfConfig->getRefToLogicNumber()[a->getRefLayer()]; int bRefLayerLogicNum = omtfConfig->getRefToLogicNumber()[b->getRefLayer()]; - if (a->getQ() > b->getQ()) + if (a->getFiredLayerCntConstr() > b->getFiredLayerCntConstr()) return false; - else if (a->getQ() == b->getQ() && aRefLayerLogicNum < bRefLayerLogicNum) { + else if (a->getFiredLayerCntConstr() == b->getFiredLayerCntConstr() && aRefLayerLogicNum < bRefLayerLogicNum) { return false; - } else if (a->getQ() == b->getQ() && aRefLayerLogicNum == bRefLayerLogicNum && a->getDisc() > b->getDisc()) + } else if (a->getFiredLayerCntConstr() == b->getFiredLayerCntConstr() && aRefLayerLogicNum == bRefLayerLogicNum && + a->getPdfSumConstr() > b->getPdfSumConstr()) return false; - else if (a->getQ() == b->getQ() && aRefLayerLogicNum == bRefLayerLogicNum && a->getDisc() == b->getDisc() && - a->getPatternNumber() > b->getPatternNumber()) + else if (a->getFiredLayerCntConstr() == b->getFiredLayerCntConstr() && aRefLayerLogicNum == bRefLayerLogicNum && + a->getPdfSumConstr() == b->getPdfSumConstr() && a->getPatternNumConstr() > b->getPatternNumConstr()) return false; - else if (a->getQ() == b->getQ() && aRefLayerLogicNum == bRefLayerLogicNum && a->getDisc() == b->getDisc() && - a->getPatternNumber() == b->getPatternNumber() && a->getRefHitNumber() < b->getRefHitNumber()) + else if (a->getFiredLayerCntConstr() == b->getFiredLayerCntConstr() && aRefLayerLogicNum == bRefLayerLogicNum && + a->getPdfSumConstr() == b->getPdfSumConstr() && a->getPatternNumConstr() == b->getPatternNumConstr() && + a->getRefHitNumber() < b->getRefHitNumber()) return false; else return true; @@ -50,15 +44,15 @@ AlgoMuons GhostBusterPreferRefDt::select(AlgoMuons muonsIN, int charge) { return false; } - if (a->getQ() > b->getQ()) - return false; - else if (a->getQ() == b->getQ()) { + if (a->getFiredLayerCntConstr() > b->getFiredLayerCntConstr()) return false; - } else if (a->getQ() == b->getQ() && a->getDisc() > b->getDisc()) + else if (a->getFiredLayerCntConstr() == b->getFiredLayerCntConstr() && a->getPdfSumConstr() > b->getPdfSumConstr()) return false; - else if (a->getQ() == b->getQ() && a->getDisc() == b->getDisc() && a->getPatternNumber() > b->getPatternNumber()) + else if (a->getFiredLayerCntConstr() == b->getFiredLayerCntConstr() && + a->getPdfSumConstr() == b->getPdfSumConstr() && a->getPatternNumConstr() > b->getPatternNumConstr()) return false; - else if (a->getQ() == b->getQ() && a->getDisc() == b->getDisc() && a->getPatternNumber() == b->getPatternNumber() && + else if (a->getFiredLayerCntConstr() == b->getFiredLayerCntConstr() && + a->getPdfSumConstr() == b->getPdfSumConstr() && a->getPatternNumConstr() == b->getPatternNumConstr() && a->getRefHitNumber() < b->getRefHitNumber()) return false; else @@ -73,18 +67,19 @@ AlgoMuons GhostBusterPreferRefDt::select(AlgoMuons muonsIN, int charge) { return false; } - if (a->getDisc() > b->getDisc()) + if (a->getPdfSumConstr() > b->getPdfSumConstr()) return false; - else if (a->getDisc() == b->getDisc() && a->getPatternNumber() > b->getPatternNumber()) + else if (a->getPdfSumConstr() == b->getPdfSumConstr() && a->getPatternNumConstr() > b->getPatternNumConstr()) return false; - else if (a->getDisc() == b->getDisc() && a->getPatternNumber() == b->getPatternNumber() && + else if (a->getPdfSumConstr() == b->getPdfSumConstr() && a->getPatternNumConstr() == b->getPatternNumConstr() && a->getRefHitNumber() < b->getRefHitNumber()) return false; else return true; }; - auto customLessByReLayer = [&](const AlgoMuons::value_type& a, const AlgoMuons::value_type& b) -> bool { + //this function is for the OMTF version with unconstrained pt + auto customByRefLayer = [&](const AlgoMuons::value_type& a, const AlgoMuons::value_type& b) -> bool { if (!a->isValid()) { return true; } @@ -97,17 +92,13 @@ AlgoMuons GhostBusterPreferRefDt::select(AlgoMuons muonsIN, int charge) { if (aRefLayerLogicNum < bRefLayerLogicNum) { return false; - } - //TODO maybe use getQ here? - // if(a->getQ() > b->getQ()) - // return false; - else if (aRefLayerLogicNum == bRefLayerLogicNum && a->getDisc() > b->getDisc()) + } else if (aRefLayerLogicNum == bRefLayerLogicNum && a->getPdfSum() > b->getPdfSum()) return false; - else if (aRefLayerLogicNum == bRefLayerLogicNum && a->getDisc() == b->getDisc() && - a->getPatternNumber() > b->getPatternNumber()) + else if (aRefLayerLogicNum == bRefLayerLogicNum && a->getPdfSum() == b->getPdfSum() && + a->getPatternNum() > b->getPatternNum()) return false; - else if (aRefLayerLogicNum == bRefLayerLogicNum && a->getDisc() == b->getDisc() && - a->getPatternNumber() == b->getPatternNumber() && a->getRefHitNumber() < b->getRefHitNumber()) + else if (aRefLayerLogicNum == bRefLayerLogicNum && a->getPdfSum() == b->getPdfSum() && + a->getPatternNum() == b->getPatternNum() && a->getRefHitNumber() < b->getRefHitNumber()) return false; else return true; @@ -117,46 +108,61 @@ AlgoMuons GhostBusterPreferRefDt::select(AlgoMuons muonsIN, int charge) { std::sort(muonsIN.rbegin(), muonsIN.rend(), customLessByLLH); else if (omtfConfig->getGhostBusterType() == "byFPLLH") std::sort(muonsIN.rbegin(), muonsIN.rend(), customLessByFPLLH); - else if (omtfConfig->getGhostBusterType() == "byReLayer") - std::sort(muonsIN.rbegin(), muonsIN.rend(), customLessByReLayer); + else if (omtfConfig->getGhostBusterType() == "byRefLayer") + std::sort(muonsIN.rbegin(), muonsIN.rend(), customByRefLayer); else std::sort(muonsIN.rbegin(), muonsIN.rend(), customLess); // actual GhostBusting. Overwrite eta in case of no DT info. - std::vector refHitCleanCandsFixedEta; - for (const auto& muIN : muonsIN) { - if (!muIN->isValid()) + AlgoMuons refHitCleanCandsFixedEta; + + for (unsigned int iMu1 = 0; iMu1 < muonsIN.size(); iMu1++) { + refHitCleanCandsFixedEta.emplace_back(new AlgoMuon(*(muonsIN[iMu1]))); + + if (omtfConfig->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::bits) + refHitCleanCandsFixedEta.back()->setEta(OMTFConfiguration::etaBits2HwEta(muonsIN[iMu1]->getEtaHw())); + } + + for (unsigned int iMu1 = 0; iMu1 < refHitCleanCandsFixedEta.size(); iMu1++) { + auto& muIN1 = refHitCleanCandsFixedEta[iMu1]; + //watch out: the muIN1 is AlgoMuonPtr, so setting the eta here changes the eta in the input muonsIN + //this affects algoCandidates in OMTFProcessor::run + + if (!muIN1->isValid() || muIN1->isKilled()) continue; - //LogTrace("l1tOmtfEventPrint")<< "GhostBusting "<<*muIN<<" phiGMT "<procPhiToGmtPhi(muIN->getPhi())<< std::endl; - - refHitCleanCandsFixedEta.push_back(*muIN); //FIXME to much copying here... - auto killIt = refHitCleanCandsFixedEta.end(); - - //do not accept candidates with similar phi (any charge combination) - //veto window 5 degree in GMT scale is 5/360*576=8 units - for (auto it1 = refHitCleanCandsFixedEta.begin(); it1 != refHitCleanCandsFixedEta.end(); ++it1) { - for (auto it2 = std::next(it1); it2 != refHitCleanCandsFixedEta.end(); ++it2) { - if (it2->isValid() && - std::abs(omtfConfig->procPhiToGmtPhi(it1->getPhi()) - omtfConfig->procPhiToGmtPhi(it2->getPhi())) < 8) { - killIt = it2; - if ((omtfConfig->fwVersion() >= 6) && - ((abs(it1->getEtaHw()) == 75 || abs(it1->getEtaHw()) == 79 || abs(it1->getEtaHw()) == 92)) && - ((abs(it2->getEtaHw()) != 75 && abs(it2->getEtaHw()) != 79 && abs(it2->getEtaHw()) != 92))) - it1->fixedEta = it2->getEtaHw(); + for (unsigned int iMu2 = refHitCleanCandsFixedEta.size() - 1; iMu2 >= iMu1 + 1; iMu2--) { + auto& muIN2 = refHitCleanCandsFixedEta[iMu2]; + if (muIN2->isValid() && + std::abs(omtfConfig->procPhiToGmtPhi(muIN1->getPhi()) - omtfConfig->procPhiToGmtPhi(muIN2->getPhi())) < 8) { + //the candidates are sorted, so only the muIN2 can be killed, as it is "worse" than the muIN1 + refHitCleanCandsFixedEta[iMu2]->kill(); + refHitCleanCandsFixedEta[iMu1]->getKilledMuons().emplace_back(muIN2); + + //for the DT stubs, if there is no eta, the middle of the chamber is set as the stub eta, i.e. 75, 79 or 92 respectively + //in this case the eta can be replaced by the eta from the killed algoMuon + if (omtfConfig->getRefToLogicNumber()[muIN1->getRefLayer()] <= 5 && (omtfConfig->fwVersion() >= 6) && + ((abs(muIN1->getEtaHw()) == 75 || abs(muIN1->getEtaHw()) == 79 || abs(muIN1->getEtaHw()) == 92)) && + ((abs(muIN2->getEtaHw()) != 75 && abs(muIN2->getEtaHw()) != 79 && + abs(muIN2->getEtaHw()) != 92))) { //FIXME condition in this do not affects the final result + + muIN1->setEta(muIN2->getEtaHw()); } } } - if (killIt != refHitCleanCandsFixedEta.end()) - refHitCleanCandsFixedEta.erase(killIt); } // fill outgoing collection + /* there is nowhere a cut on the pdfSum > 0 for a muon to be valid + * muon is valid if getPtConstr() > 0 || getPtUnconstr() > 0, + * i.e. when there was a fitting pattern + * this mean there can be a muon with pdfSumConstrained = 0 but with not 0 PtConstr + * which is OK. See also comment in the GoldenPatternResult::finalise10() + */ AlgoMuons refHitCleanCands; for (const auto& mu : refHitCleanCandsFixedEta) { - AlgoMuon fixed = mu; - fixed.setEta(mu.fixedEta); - refHitCleanCands.emplace_back(new AlgoMuon(fixed)); + if (mu->isValid() && !(mu->isKilled())) + refHitCleanCands.emplace_back(mu); if (refHitCleanCands.size() >= 3) break; } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPattern.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPattern.cc index 2f7a8b991d747..180d08735ca39 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPattern.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPattern.cc @@ -4,7 +4,6 @@ #include int GoldenPattern::meanDistPhiValue(unsigned int iLayer, unsigned int iRefLayer, int refLayerPhiB) const { - //return meanDistPhi[iLayer][iRefLayer][0]; return (((meanDistPhi[iLayer][iRefLayer][1] * refLayerPhiB) >> myOmtfConfig->nPdfAddrBits()) + meanDistPhi[iLayer][iRefLayer][0]); //assumes that the meanDistPhi[1] is float alpha from the fit to the phiB-phi distribution multiplied by 2^myOmtfConfig->nPdfAddrBits() @@ -14,7 +13,6 @@ int GoldenPattern::meanDistPhiValue(unsigned int iLayer, unsigned int iRefLayer, //////////////////////////////////////////////////// int GoldenPattern::propagateRefPhi(int phiRef, int etaRef, unsigned int iRefLayer) { unsigned int iLayer = 2; //MB2 - //if(etaRef>101) iLayer = 7;//RE2 return phiRef + meanDistPhi[iLayer][iRefLayer][0]; //FIXME if the meanDistPhiAlpha is non-zero, then meanDistPhi is alone not good for propagation of the phi //other value should be used, or the ref_layer phiB should be included @@ -42,17 +40,6 @@ std::ostream &operator<<(std::ostream &out, const GoldenPattern &aPattern) { out << ")" << std::endl; } - /* if(aPattern.meanDistPhiCounts.size()){ - out<<"Counts number per layer:"<& extrapolatedPhi, + const MuonStubPtr& refStub) { //if (this->getDistPhiBitShift(iLayer, iRefLayer) != 0) LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<getDistPhiBitShift(iLayer, iRefLayer)<meanDistPhiValue(iLayer, iRefLayer, refStub->phiBHw); - int phiDistMin = myOmtfConfig->nPhiBins(); //1<<(myOmtfConfig->nPdfAddrBits()); //"infinite" value for the beginning + int phiDistMin = myOmtfConfig->nPhiBins(); ///Select hit closest to the mean of probability ///distribution in given layer @@ -63,7 +64,8 @@ StubResult GoldenPatternBase::process1Layer1RefLayer(unsigned int iRefLayer, phiRefHit = 0; //phi ref hit for the bending layer set to 0, since it should not be included in the phiDist } - for (auto& stub : layerStubs) { + for (size_t iStub = 0; iStub < layerStubs.size(); iStub++) { + const auto& stub = layerStubs[iStub]; if (!stub) //empty pointer continue; @@ -76,33 +78,29 @@ StubResult GoldenPatternBase::process1Layer1RefLayer(unsigned int iRefLayer, if (hitPhi >= (int)myOmtfConfig->nPhiBins()) //TODO is this needed now? the empty hit will be empty stub continue; //empty itHits are marked with nPhiBins() in OMTFProcessor::restrictInput - int phiDist = this->myOmtfConfig->foldPhi(hitPhi - phiMean - phiRefHit); - //for standard omtf foldPhi is not needed, but if one processor works for full phi then it is - //if (this->getDistPhiBitShift(iLayer, iRefLayer) != 0) + int phiDist = this->myOmtfConfig->foldPhi(hitPhi - extrapolatedPhi[iStub] - phiMean - phiRefHit); /*LogTrace("l1tOmtfEventPrint") <<"\n"<<__FUNCTION__<<":"<<__LINE__<<" "<> this->getDistPhiBitShift(iLayer, iRefLayer); + phiDist = std::abs(phiDist) >> this->getDistPhiBitShift(iLayer, iRefLayer); phiDist *= sign; //if the shift is done here, it means that the phiMean in the xml should be the same as without shift //if (this->getDistPhiBitShift(iLayer, iRefLayer) != 0) std::cout<<__FUNCTION__<<":"<<__LINE__<<" phiDist "<myOmtfConfig->isNoHitValueInPdf()) { - PdfValueType pdfVal = this->pdfValue(iLayer, iRefLayer, 0); - return StubResult(pdfVal, false, myOmtfConfig->nPhiBins(), iLayer, selectedStub); - } else { - return StubResult(0, false, myOmtfConfig->nPhiBins(), iLayer, selectedStub); //2018 version - } + PdfValueType pdfVal = 0; + if (this->myOmtfConfig->isNoHitValueInPdf()) + pdfVal = this->pdfValue(iLayer, iRefLayer, 0); + return StubResult(pdfVal, false, myOmtfConfig->nPhiBins(), iLayer, selectedStub); } int pdfMiddle = 1 << (myOmtfConfig->nPdfAddrBits() - 1); @@ -110,14 +108,13 @@ StubResult GoldenPatternBase::process1Layer1RefLayer(unsigned int iRefLayer, /* debug if(phiDistMin != 128 && iRefLayer == 0 && iLayer == 1)*/ /*LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" iRefLayer "<getDistPhiBitShift(iLayer, iRefLayer)<getDistPhiBitShift(iLayer, iRefLayer)< ((1 << (myOmtfConfig->nPdfAddrBits() - 1)) - 1)) { + if (std::abs(phiDistMin) > ((1 << (myOmtfConfig->nPdfAddrBits() - 1)) - 1)) { return StubResult(0, false, phiDistMin + pdfMiddle, iLayer, selectedStub); - //return GoldenPatternResult::LayerResult(this->pdfValue(iLayer, iRefLayer, 0), false, phiDistMin + pdfMiddle, selHit); //in some algorithms versions with thresholds we use the bin 0 to store the pdf value returned when there was no hit. //in the version without thresholds, the value in the bin 0 should be 0 } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPatternResult.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPatternResult.cc index 0312ec1d265cc..34c61bbe7ffa2 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPatternResult.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPatternResult.cc @@ -78,6 +78,10 @@ void GoldenPatternResult::init(const OMTFConfiguration* omtfConfig) { finalise = [this]() { finalise8(); }; else if (finalizeFunction == 9) finalise = [this]() { finalise9(); }; + else if (finalizeFunction == 10) + finalise = [this]() { finalise10(); }; + else if (finalizeFunction == 11) + finalise = [this]() { finalise11(); }; else finalise = [this]() { finalise0(); }; @@ -94,6 +98,7 @@ void GoldenPatternResult::reset() { phi = 0; eta = 0; pdfSum = 0; + pdfSumUnconstr = 0; firedLayerCnt = 0; firedLayerBits = 0; refHitPhi = 0; @@ -133,7 +138,6 @@ void GoldenPatternResult::finalise0() { //////////////////////////////////////////// //for the algo version with thresholds void GoldenPatternResult::finalise1() { - //cout<<__FUNCTION__<<":"<<__LINE__<getLogicToLogic().at(iLogicLayer); if (omtfConfig->isBendingLayer(iLogicLayer)) { //the DT phiB layer is counted only when the phi layer is fired if ((firedLayerBits & (1 << iLogicLayer)) && (firedLayerBits & (1 << connectedLayer))) { - // && (stubResults[iLogicLayer].getMuonStub()->qualityHw >= 4) this is not needed, as the rejecting the low quality phiB hits is on the input of the algorithm firedLayerCnt++; } else { firedLayerBits &= ~(1 << iLogicLayer); @@ -289,21 +292,20 @@ void GoldenPatternResult::finalise9() { firedLayerBits &= ~(1 << iLogicLayer); stubResults[iLogicLayer].setValid(false); //there was hit, but it did not fit to the pdf - this is not possible here, since the bending layer is fired here - //therefore the below line is has no sense - //if(stubResults[iLogicLayer].getPdfVal() == 0) pdfSum -= 64;; - //so in this case simply: - //pdfSum += 0; + //therefore there is no sense to apply the penalty when the stubResults[iLogicLayer].getPdfVal() == 0 + //so in this case simply pdfSum += 0; } } else { - //bending layer fired, but not fits to the pdf, N.B works only with the patterns having "no hit value" and with noHitValueInPdf = True if (stubResults[iLogicLayer].getPdfVal() == 0) - pdfSum -= 32; + //there is a hit, but does not fit to the pdf (therefore in firedLayerBits is 0, but getPdfVal() is not 0), so apply the penalty (-32) + //N.B it is possible only with the patterns having "no hit value" and with noHitValueInPdf = True + pdfSum -= 32; // penaly else pdfSum += stubResults[iLogicLayer].getPdfVal(); //bending layer not fired at all } } else { if (iLogicLayer < 10 && stubResults[iLogicLayer].getPdfVal() == 0) - pdfSum -= 32; + pdfSum -= 32; // penaly else pdfSum += stubResults[iLogicLayer].getPdfVal(); if (firedLayerBits & (1 << iLogicLayer)) { //pdfSum is counted always @@ -316,6 +318,121 @@ void GoldenPatternResult::finalise9() { //by default result becomes valid here, but can be overwritten later } +void GoldenPatternResult::finalise10() { + for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) { + unsigned int connectedLayer = omtfConfig->getLogicToLogic().at(iLogicLayer); + + if (omtfConfig->isBendingLayer(iLogicLayer)) { //the DT phiB layer is counted only when the phi layer is fired + if (firedLayerBits & (1 << iLogicLayer)) { + if (firedLayerBits & (1 << connectedLayer)) { + firedLayerCnt++; + pdfSum += stubResults[iLogicLayer].getPdfVal(); + } else { + firedLayerBits &= ~(1 << iLogicLayer); + stubResults[iLogicLayer].setValid(false); + //there is no sense to apply the penalty in this case, + //because as the layer is fired, the stubResults[iLogicLayer].getPdfVal() cannot be 0 + //so in this case simply pdfSum += 0; + } + } else { + //the penalty is not applied here when the phiB does not fit to the pdf + //because when extrapolation from the ref layer using the phiB is applied + //it "normal" for the displaced muons to not fit to the pdf + pdfSum += stubResults[iLogicLayer].getPdfVal(); + } + } else { + if (iLogicLayer < 10 && stubResults[iLogicLayer].getPdfVal() == 0) + pdfSum -= 32; // penaly + else + pdfSum += stubResults[iLogicLayer].getPdfVal(); + if (firedLayerBits & (1 << iLogicLayer)) { //pdfSum is counted always + firedLayerCnt++; + } + } + } + + if ((omtfConfig->usePhiBExtrapolationMB1() && refLayer == 0) || + (omtfConfig->usePhiBExtrapolationMB2() && refLayer == 2)) { + auto refLayerLogicNumber = omtfConfig->getRefToLogicNumber()[refLayer]; + //Unconstrained pt is obtained by not including the pdfValue from the phiB of the refHit + //TODO get logic layer from connectedLayer + pdfSumUnconstr = pdfSum - stubResults[refLayerLogicNumber + 1].getPdfVal(); + //here there is an issue with the firedLayerBits and quality assignment: + //in case if the displaced muon the phiB layer of the ref hit might not be fired (pdfVal might be 0) + //which in principle has no sense, because by the displaced algorithm construction it is fired + //an effect of that is that some fraction of displaced muons get the quality 8 assigned + //the efficiency difference between quality 8 and 12 seems to be at a level of 1-2% + //but in the uGT menu e.g. the L1_DoubleMu0_Upt6_IP_Min1_Upt4 uses quality >= 0, so should be OK + + //hard cut - the phiB of the refHit must fit to the pdf + //but this cut has sometimes side effect: there can be a muon which has has pdfSum = 0 for every pattern, + //then in the OMTFSorter::sortRefHitResults the first pattern that has FiredLayerCnt >= 3 is chosen + //and not the one with highest pdfSum as it should be + //TODO what should be done is to set the pt of such a muons to 0, but after the sorter. + //Or maybe not - if the pt is 0, then the muon is not valid. So the displaced muon will be lost. + //So the way it is done now actually is good. Such a muon will have some low constrained pt probably. + //what can be done is to assign to it the hwPt = 1 , but not 0 + //TODO modify this condition to use the firedLayerBits and not getPdfVal + //as it would be much easier for the firmware + if (stubResults[refLayerLogicNumber + 1].getPdfVal() == 0) + pdfSum = 0; + } else + pdfSumUnconstr = 0; + + valid = true; + //by default result becomes valid here, but can be overwritten later +} + +// the same as finalise10 but without: +//if (stubResults[refLayerLogicNumber + 1].getPdfVal() == 0) +// pdfSum = 0; +void GoldenPatternResult::finalise11() { + for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) { + unsigned int connectedLayer = omtfConfig->getLogicToLogic().at(iLogicLayer); + + if (omtfConfig->isBendingLayer(iLogicLayer)) { //the DT phiB layer is counted only when the phi layer is fired + if (firedLayerBits & (1 << iLogicLayer)) { + if (firedLayerBits & (1 << connectedLayer)) { + firedLayerCnt++; + pdfSum += stubResults[iLogicLayer].getPdfVal(); + } else { + firedLayerBits &= ~(1 << iLogicLayer); + stubResults[iLogicLayer].setValid(false); + //there is no sense to apply the penalty in this case, + //because as the layer is fired, the stubResults[iLogicLayer].getPdfVal() cannot be 0 + //so in this case simply pdfSum += 0; + } + } else { + //the penalty is not applied here when the phiB does not fit to the pdf + //because when extrapolation from the ref layer using the phiB is applied + //it "normal" for the displaced muons to not fit to the pdf + pdfSum += stubResults[iLogicLayer].getPdfVal(); //bending layer not fired at all + } + } else { + if (iLogicLayer < 10 && stubResults[iLogicLayer].getPdfVal() == 0) + pdfSum -= 32; // penaly + else + pdfSum += stubResults[iLogicLayer].getPdfVal(); + if (firedLayerBits & (1 << iLogicLayer)) { //pdfSum is counted always + firedLayerCnt++; + } + } + } + + if ((omtfConfig->usePhiBExtrapolationMB1() && refLayer == 0) || + (omtfConfig->usePhiBExtrapolationMB2() && refLayer == 2)) { + auto refLayerLogicNumber = omtfConfig->getRefToLogicNumber()[refLayer]; + //Unconstrained pt is obtained by not including the pdfValue from the phiB of the refHit + //TODO get logic layer from connectedLayer + pdfSumUnconstr = pdfSum - stubResults[refLayerLogicNumber + 1].getPdfVal(); + + } else + pdfSumUnconstr = 0; + + valid = true; + //by default result becomes valid here, but can be overwritten later +} + //////////////////////////////////////////// //////////////////////////////////////////// std::ostream& operator<<(std::ostream& out, const GoldenPatternResult& gpResult) { @@ -351,6 +468,9 @@ std::ostream& operator<<(std::ostream& out, const GoldenPatternResult& gpResult) out << " sumOverFiredLayers: "; out << sumOverFiredLayers << "\t"; + out << " Sum over layers unconstr: "; + out << gpResult.getPdfSumUnconstr() << "\t"; + out << " Number of hits: "; out << gpResult.getFiredLayerCnt() << "\t"; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc index 83be5fc758129..f9a8165a5d05b 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc @@ -66,13 +66,18 @@ void OMTFConfiguration::configure(const L1TMuonOverlapParams *omtfParams) { const std::vector *connectedSectorsStartVec = omtfParams->connectedSectorsStart(); const std::vector *connectedSectorsEndVec = omtfParams->connectedSectorsEnd(); - std::copy(connectedSectorsStartVec->begin(), connectedSectorsStartVec->begin() + 6, barrelMin.begin()); - std::copy(connectedSectorsStartVec->begin() + 6, connectedSectorsStartVec->begin() + 12, endcap10DegMin.begin()); - std::copy(connectedSectorsStartVec->begin() + 12, connectedSectorsStartVec->end(), endcap20DegMin.begin()); - - std::copy(connectedSectorsEndVec->begin(), connectedSectorsEndVec->begin() + 6, barrelMax.begin()); - std::copy(connectedSectorsEndVec->begin() + 6, connectedSectorsEndVec->begin() + 12, endcap10DegMax.begin()); - std::copy(connectedSectorsEndVec->begin() + 12, connectedSectorsEndVec->end(), endcap20DegMax.begin()); + std::copy(connectedSectorsStartVec->begin(), connectedSectorsStartVec->begin() + nProcessors(), barrelMin.begin()); + std::copy(connectedSectorsStartVec->begin() + nProcessors(), + connectedSectorsStartVec->begin() + 2 * nProcessors(), + endcap10DegMin.begin()); + std::copy( + connectedSectorsStartVec->begin() + 2 * nProcessors(), connectedSectorsStartVec->end(), endcap20DegMin.begin()); + + std::copy(connectedSectorsEndVec->begin(), connectedSectorsEndVec->begin() + nProcessors(), barrelMax.begin()); + std::copy(connectedSectorsEndVec->begin() + nProcessors(), + connectedSectorsEndVec->begin() + 2 * nProcessors(), + endcap10DegMax.begin()); + std::copy(connectedSectorsEndVec->begin() + 2 * nProcessors(), connectedSectorsEndVec->end(), endcap20DegMax.begin()); ///Set connections tables const std::vector *layerMap = omtfParams->layerMap(); @@ -162,15 +167,18 @@ void OMTFConfiguration::configure(const L1TMuonOverlapParams *omtfParams) { //the default values of the parameters are used, if not set here, so don't mess them! if (fwVersion() <= 4) { setMinDtPhiQuality(4); + setMinDtPhiBQuality(4); } else if (fwVersion() == 5) { setMinDtPhiQuality(2); + setMinDtPhiBQuality(2); setGhostBusterType("GhostBusterPreferRefDt"); } else if (fwVersion() == 6) { setMinDtPhiQuality(2); + setMinDtPhiBQuality(2); setGhostBusterType("GhostBusterPreferRefDt"); } else if (fwVersion() == 8) { setMinDtPhiQuality(2); - setMinDtPhiBQuality(2); //should be 4, but in the fwVersion = 8 was not yet implemented + setMinDtPhiBQuality(2); setSorterType(1); //"byLLH" @@ -183,6 +191,28 @@ void OMTFConfiguration::configure(const L1TMuonOverlapParams *omtfParams) { setNoHitValueInPdf(true); setGhostBusterType("GhostBusterPreferRefDt"); + } else if (fwVersion() == 9) { + setMinDtPhiQuality(2); + setMinDtPhiBQuality(4); + + setSorterType(1); //"byLLH" + + setRpcMaxClusterSize(3); + setRpcMaxClusterCnt(2); + setRpcDropAllClustersIfMoreThanMax(true); + + setGoldenPatternResultFinalizeFunction(10); + + setNoHitValueInPdf(true); + + usePhiBExtrapolationFromMB1_ = true; + usePhiBExtrapolationFromMB2_ = true; + useStubQualInExtr_ = false; + useEndcapStubsRInExtr_ = false; + + dtRefHitMinQuality = 4; + + setGhostBusterType("byRefLayer"); } } @@ -224,6 +254,51 @@ void OMTFConfiguration::configureFromEdmParameterSet(const edm::ParameterSet &ed } setFixCscGeometryOffset(true); //for the OMTF by default is true, read from python if needed + + if (edmParameterSet.exists("usePhiBExtrapolationFromMB1")) { + usePhiBExtrapolationFromMB1_ = edmParameterSet.getParameter("usePhiBExtrapolationFromMB1"); + edm::LogVerbatim("OMTFReconstruction") + << "usePhiBExtrapolationFromMB1: " << usePhiBExtrapolationFromMB1_ << std::endl; + } + + if (edmParameterSet.exists("usePhiBExtrapolationFromMB2")) { + usePhiBExtrapolationFromMB2_ = edmParameterSet.getParameter("usePhiBExtrapolationFromMB2"); + edm::LogVerbatim("OMTFReconstruction") + << "usePhiBExtrapolationFromMB2: " << usePhiBExtrapolationFromMB2_ << std::endl; + } + + if (edmParameterSet.exists("useStubQualInExtr")) { + useStubQualInExtr_ = edmParameterSet.getParameter("useStubQualInExtr"); + edm::LogVerbatim("OMTFReconstruction") << "useStubQualInExtr: " << useStubQualInExtr_ << std::endl; + } + + if (edmParameterSet.exists("useEndcapStubsRInExtr")) { + useEndcapStubsRInExtr_ = edmParameterSet.getParameter("useEndcapStubsRInExtr"); + edm::LogVerbatim("OMTFReconstruction") << "useEndcapStubsRInExtr: " << useEndcapStubsRInExtr_ << std::endl; + } + + if (edmParameterSet.exists("dtRefHitMinQuality")) { + dtRefHitMinQuality = edmParameterSet.getParameter("dtRefHitMinQuality"); + edm::LogVerbatim("OMTFReconstruction") << "dtRefHitMinQuality: " << dtRefHitMinQuality << std::endl; + } + + if (edmParameterSet.exists("dumpResultToXML")) { + dumpResultToXML = edmParameterSet.getParameter("dumpResultToXML"); + } + + if (edmParameterSet.exists("minCSCStubRME12")) { + minCSCStubRME12_ = edmParameterSet.getParameter("minCSCStubRME12"); + edm::LogVerbatim("OMTFReconstruction") << "minCSCStubRME12: " << minCSCStubRME12_ << std::endl; + } + + if (edmParameterSet.exists("minCSCStubR")) { + minCSCStubR_ = edmParameterSet.getParameter("minCSCStubR"); + edm::LogVerbatim("OMTFReconstruction") << "minCSCStubR: " << minCSCStubR_ << std::endl; + } + + if (edmParameterSet.exists("cleanStubs")) { + cleanStubs_ = edmParameterSet.getParameter("cleanStubs"); + } } /////////////////////////////////////////////// @@ -324,6 +399,126 @@ uint32_t OMTFConfiguration::getLayerNumber(uint32_t rawId) const { return hwNumber; } +int OMTFConfiguration::calcGlobalPhi(int locPhi, int proc) const { + int globPhi = 0; + //60 degree sectors = 96 in int-scale + globPhi = (proc) * 96 * 6 / nProcessors() + locPhi; + // first processor starts at CMS phi = 15 degrees (24 in int)... Handle wrap-around with %. Add 576 to make sure the number is positive + globPhi = (globPhi + 600) % 576; + return globPhi; +} + +unsigned int OMTFConfiguration::eta2Bits(unsigned int eta) { + if (eta == 73) + return 0b100000000; + else if (eta == 78) + return 0b010000000; + else if (eta == 85) + return 0b001000000; + else if (eta == 90) + return 0b000100000; + else if (eta == 94) + return 0b000010000; + else if (eta == 99) + return 0b000001000; + else if (eta == 103) + return 0b000000100; + else if (eta == 110) + return 0b000000010; + else if (eta == 75) + return 0b110000000; + else if (eta == 79) + return 0b011000000; + else if (eta == 92) + return 0b000110000; + else if (eta == 115) + return 0b000000001; + else if (eta == 121) + return 0b000000000; + else + return 0b111111111; + ; +} + +unsigned int OMTFConfiguration::etaBits2HwEta(unsigned int bits) { + if (bits == 0b100000000) + return 73; + else if (bits == 0b010000000) + return 78; + else if (bits == 0b001000000) + return 85; + else if (bits == 0b000100000) + return 90; + else if (bits == 0b000010000) + return 94; + else if (bits == 0b000001000) + return 99; + else if (bits == 0b000000100) + return 103; + else if (bits == 0b000000010) + return 110; + else if (bits == 0b110000000) + return 75; + else if (bits == 0b011000000) + return 79; + else if (bits == 0b000110000) + return 92; + else if (bits == 0b000000001) + return 115; + else if (bits == 0b000000000) + return 121; + else + return 0b111111111; + ; +} + +int OMTFConfiguration::etaBit2Code(unsigned int bit) { + int code = 73; + switch (bit) { + case 0: { + code = 115; + break; + } + case 1: { + code = 110; + break; + } + case 2: { + code = 103; + break; + } + case 3: { + code = 99; + break; + } + case 4: { + code = 94; + break; + } + case 5: { + code = 90; + break; + } + case 6: { + code = 85; + break; + } + case 7: { + code = 78; + break; + } + case 8: { + code = 73; + break; + } + default: { + code = 95; + break; + } + } + return code; +} + /////////////////////////////////////////////// // phiRad should be in the range [-pi,pi] int OMTFConfiguration::getProcScalePhi(unsigned int iProcessor, double phiRad) const { @@ -402,4 +597,12 @@ void OMTFConfiguration::printConfig() const { edm::LogVerbatim("OMTFReconstruction") << "noHitValueInPdf " << noHitValueInPdf << std::endl; edm::LogVerbatim("OMTFReconstruction") << "sorterType " << sorterType << std::endl; edm::LogVerbatim("OMTFReconstruction") << "ghostBusterType " << ghostBusterType << std::endl; + + edm::LogVerbatim("OMTFReconstruction") << "usePhiBExtrapolationFromMB1 " << usePhiBExtrapolationFromMB1_ << std::endl; + edm::LogVerbatim("OMTFReconstruction") << "usePhiBExtrapolationFromMB2 " << usePhiBExtrapolationFromMB2_ << std::endl; + edm::LogVerbatim("OMTFReconstruction") << "useStubQualInExtr " << useStubQualInExtr_ << std::endl; + edm::LogVerbatim("OMTFReconstruction") << "useEndcapStubsRInExtr " << useEndcapStubsRInExtr_ << std::endl; + edm::LogVerbatim("OMTFReconstruction") << "dtRefHitMinQuality " << dtRefHitMinQuality << std::endl; + + edm::LogVerbatim("OMTFReconstruction") << "cleanStubs " << cleanStubs_ << std::endl; } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc index 94ebe061d8c89..f783e47ec9009 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc @@ -21,10 +21,14 @@ #include #include #include +#include #include #include #include +#include +#include + /////////////////////////////////////////////// /////////////////////////////////////////////// template @@ -46,7 +50,10 @@ OMTFProcessor::OMTFProcessor(OMTFConfiguration* omtfConfig, }; template -OMTFProcessor::~OMTFProcessor() {} +OMTFProcessor::~OMTFProcessor() { + if (useFloatingPointExtrapolation) + saveExtrapolFactors(); +} template void OMTFProcessor::init(const edm::ParameterSet& edmCfg, edm::EventSetup const& evSetup) { @@ -54,7 +61,8 @@ void OMTFProcessor::init(const edm::ParameterSet& edmCfg, edm //initialize with the default sorter if (this->myOmtfConfig->getGhostBusterType() == "GhostBusterPreferRefDt" || - this->myOmtfConfig->getGhostBusterType() == "byLLH") { + this->myOmtfConfig->getGhostBusterType() == "byLLH" || this->myOmtfConfig->getGhostBusterType() == "byFPLLH" || + this->myOmtfConfig->getGhostBusterType() == "byRefLayer") { setGhostBuster(new GhostBusterPreferRefDt(this->myOmtfConfig)); edm::LogVerbatim("OMTFReconstruction") << "setting " << this->myOmtfConfig->getGhostBusterType() << std::endl; } else { @@ -63,6 +71,31 @@ void OMTFProcessor::init(const edm::ParameterSet& edmCfg, edm } edm::LogVerbatim("OMTFReconstruction") << "fwVersion 0x" << hex << this->myOmtfConfig->fwVersion() << std::endl; + + useStubQualInExtr = this->myOmtfConfig->useStubQualInExtr(); + useEndcapStubsRInExtr = this->myOmtfConfig->useEndcapStubsRInExtr(); + + if (edmCfg.exists("useFloatingPointExtrapolation")) + useFloatingPointExtrapolation = edmCfg.getParameter("useFloatingPointExtrapolation"); + + std::string extrapolFactorsFilename; + if (edmCfg.exists("extrapolFactorsFilename")) { + extrapolFactorsFilename = edmCfg.getParameter("extrapolFactorsFilename").fullPath(); + } + + if (this->myOmtfConfig->usePhiBExtrapolationMB1() || this->myOmtfConfig->usePhiBExtrapolationMB2()) { + extrapolFactors.resize(2, std::vector >(this->myOmtfConfig->nLayers())); + extrapolFactorsNorm.resize(2, std::vector >(this->myOmtfConfig->nLayers())); + + //when useFloatingPointExtrapolation is true the extrapolFactors are not used, + //all calculations are done in the extrapolateDtPhiBFloatPoint + if (!extrapolFactorsFilename.empty() && !useFloatingPointExtrapolation) + loadExtrapolFactors(extrapolFactorsFilename); + } + + edm::LogVerbatim("OMTFReconstruction") << "useFloatingPointExtrapolation " << useFloatingPointExtrapolation + << std::endl; + edm::LogVerbatim("OMTFReconstruction") << "extrapolFactorsFilename " << extrapolFactorsFilename << std::endl; } template @@ -73,8 +106,20 @@ std::vector OMTFProcessor::getFinalcan for (auto& myCand : algoCands) { l1t::RegionalMuonCand candidate; - candidate.setHwPt(myCand->getPt()); - candidate.setHwEta(myCand->getEtaHw()); + + //the charge is only for the constrained measurement. The constrained measurement is always defined for a valid candidate + if (ptAssignment) { + candidate.setHwPt(myCand->getPtNNConstr()); + candidate.setHwSign(myCand->getChargeNNConstr() < 0 ? 1 : 0); + } else { + candidate.setHwPt(myCand->getPtConstr()); + candidate.setHwSign(myCand->getChargeConstr() < 0 ? 1 : 0); + } + + if (mtfType == l1t::omtf_pos) + candidate.setHwEta(myCand->getEtaHw()); + else + candidate.setHwEta((-1) * myCand->getEtaHw()); int phiValue = myCand->getPhi(); if (phiValue >= int(this->myOmtfConfig->nPhiBins())) @@ -82,14 +127,19 @@ std::vector OMTFProcessor::getFinalcan phiValue = this->myOmtfConfig->procPhiToGmtPhi(phiValue); candidate.setHwPhi(phiValue); - candidate.setHwSign(myCand->getCharge() < 0 ? 1 : 0); candidate.setHwSignValid(1); + if (myCand->getPtUnconstr() >= 0) { //empty PtUnconstrained is -1, maybe should be corrected on the source + //the upt has different hardware scale than the pt, the upt unit is 1 GeV + candidate.setHwPtUnconstrained(myCand->getPtUnconstr()); + } else + candidate.setHwPtUnconstrained(0); + unsigned int quality = 12; if (this->myOmtfConfig->fwVersion() <= 6) - quality = checkHitPatternValidity(myCand->getFiredLayerBits()) ? 0 | (1 << 2) | (1 << 3) : 0 | (1 << 2); + quality = checkHitPatternValidity(myCand->getFiredLayerBits()) ? 0 | (1 << 2) | (1 << 3) : 0 | (1 << 2); //12 : 4 - if (abs(myCand->getEtaHw()) == 115 && + if (abs(myCand->getEtaHw()) == 115 && //115 is eta 1.25 rrrrrrrrccccdddddd (static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("100000001110000000").to_ulong() || static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000001110000000").to_ulong() || static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("100000000110000000").to_ulong() || @@ -127,7 +177,7 @@ std::vector OMTFProcessor::getFinalcan static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("010000000000110000").to_ulong() || static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("100000000000110000").to_ulong()) quality = 1; - } else if (this->myOmtfConfig->fwVersion() >= 8) { //TODO fix the fwVersion + } else if (this->myOmtfConfig->fwVersion() >= 8) { //TODO fix the fwVersion rrrrrrrrccccdddddd if (static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000110000000011").to_ulong() || static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000100000000011").to_ulong() || static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000010000000011").to_ulong() || @@ -219,23 +269,19 @@ std::vector OMTFProcessor::getFinalcan static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000100000000110000").to_ulong()) quality = 8; } // if (abs(myCand->getEta()) == 121) quality = 4; - if (abs(myCand->getEtaHw()) == 121) + if (abs(myCand->getEtaHw()) >= 121) quality = 0; // changed from 4 on request from HI candidate.setHwQual(quality); std::map trackAddr; trackAddr[0] = myCand->getFiredLayerBits(); + //TODO in the hardware, the uPt is sent to the uGMT at the trackAddr = (uPt << 18) + trackAddr; + //check if it matters if it needs to be here as well trackAddr[1] = myCand->getRefLayer(); trackAddr[2] = myCand->getDisc(); + trackAddr[3] = myCand->getGpResultUnconstr().getPdfSumUnconstr(); if (candidate.hwPt() > 0) { - if (ptAssignment) { - auto pts = ptAssignment->getPts(myCand); - for (unsigned int i = 0; i < pts.size(); i++) { - trackAddr[10 + i] = this->myOmtfConfig->ptGevToHw(pts[i]); - } - } - candidate.setTrackAddress(trackAddr); candidate.setTFIdentifiers(iProcessor, mtfType); result.push_back(candidate); @@ -286,13 +332,251 @@ AlgoMuons OMTFProcessor::sortResults(unsigned int iProcessor, unsigned int procIndx = this->myOmtfConfig->getProcIndx(iProcessor, mtfType); return sorter->sortResults(procIndx, this->getPatterns(), charge); } + +template +int OMTFProcessor::extrapolateDtPhiBFloatPoint(const int& refLogicLayer, + const int& refPhi, + const int& refPhiB, + unsigned int targetLayer, + const int& targetStubPhi, + const int& targetStubQuality, + const int& targetStubEta, + const int& targetStubR, + const OMTFConfiguration* omtfConfig) { + LogTrace("l1tOmtfEventPrint") << "\n" + << __FUNCTION__ << ":" << __LINE__ << " refLogicLayer " << refLogicLayer + << " targetLayer " << targetLayer << std::endl; + LogTrace("l1tOmtfEventPrint") << "refPhi " << refPhi << " refPhiB " << refPhiB << " targetStubPhi " << targetStubPhi + << " targetStubQuality " << targetStubQuality << std::endl; + + int phiExtr = 0; //delta phi extrapolated + + float rRefLayer = 431.133; //[cm], MB1 i.e. refLogicLayer = 0 + if (refLogicLayer == 2) + rRefLayer = 512.401; //MB2 + else if (refLogicLayer != 0) { + return 0; + //throw cms::Exception("OMTFProcessor::extrapolateDtPhiB: wrong refStubLogicLayer " + std::to_string(refLogicLayer) ); + } + + int reflLayerIndex = refLogicLayer == 0 ? 0 : 1; + + if (targetLayer == 0 || targetLayer == 2 || targetLayer == 4 || (targetLayer >= 10 && targetLayer <= 14)) { + //all units are cm. Values from the CMS geometry + float rTargetLayer = 512.401; //MB2 + + if (targetLayer == 0) + rTargetLayer = 431.133; //MB1 + else if (targetLayer == 4) + rTargetLayer = 617.946; //MB3 + + else if (targetLayer == 10) + rTargetLayer = 413.675; //RB1in + else if (targetLayer == 11) + rTargetLayer = 448.675; //RB1out + else if (targetLayer == 12) + rTargetLayer = 494.975; //RB2in + else if (targetLayer == 13) + rTargetLayer = 529.975; //RB2out + else if (targetLayer == 14) + rTargetLayer = 602.150; //RB3 + + if (useStubQualInExtr) { + if (targetLayer == 0 || targetLayer == 2 || targetLayer == 4) { + if (targetStubQuality == 2 || targetStubQuality == 0) + rTargetLayer = rTargetLayer - 23.5 / 2; //inner superlayer + else if (targetStubQuality == 3 || targetStubQuality == 1) + rTargetLayer = rTargetLayer + 23.5 / 2; //outer superlayer + } + } + + float d = rTargetLayer - rRefLayer; + //formula in the form as in the slides explaining the extrapolation algorithm + //float deltaPhiExtr = d/rTargetLayer * refPhiB / omtfConfig->dtPhiBUnitsRad(); //[rad] + //phiExtr = round(deltaPhiExtr / omtfConfig->omtfPhiUnit()); //[halfStrip] + + //formula with approximation, used to calculate extrFactor + float extrFactor = d / rTargetLayer / omtfConfig->dtPhiBUnitsRad() / omtfConfig->omtfPhiUnit(); + phiExtr = extrFactor * (float)refPhiB; //[halfStrip] + + //formula without approximation + float deltaPhiExtr = atan(d / rTargetLayer * tan(refPhiB / omtfConfig->dtPhiBUnitsRad())); //[rad] + phiExtr = round(deltaPhiExtr / omtfConfig->omtfPhiUnit()); //[halfStrip] + + if (useStubQualInExtr & (targetLayer == 0 || targetLayer == 2 || targetLayer == 4)) { + extrapolFactors[reflLayerIndex][targetLayer][targetStubQuality] = extrFactor; + extrapolFactorsNorm[reflLayerIndex][targetLayer][targetStubQuality] = 1; + } else { + extrapolFactors[reflLayerIndex][targetLayer][0] = extrFactor; + extrapolFactorsNorm[reflLayerIndex][targetLayer][0] = 1; + } + + //LogTrace("l1tOmtfEventPrint") <<__FUNCTION__<<":"<<__LINE__<<" deltaPhiExtr "<omtfPhiUnit() * omtfConfig->dtPhiBUnitsRad()); + + phiExtr = refPhiB - deltaPhi; //phiExtr is also in phi_b hw scale + LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " deltaPhi " << deltaPhi << " phiExtr " + << phiExtr << std::endl; + } else if ((targetLayer >= 6 && targetLayer <= 9) || (targetLayer >= 15 && targetLayer <= 17)) { + //if true, for the CSC and endcap RPC the R is taken from the hit coordinates + + float rME = targetStubR; + if (!useEndcapStubsRInExtr) { + //all units are cm. This are the average R values for a given chamber (more or less middle of the chamber, but taking into account the OMTF eta range) + if (targetLayer == 6 || targetLayer == 15) //ME1/3, RE1/3, + rME = 600.; + else if (targetLayer == 7 || targetLayer == 15) { //ME2/2, RE2/3, + if (refLogicLayer == 0) + rME = 600.; + else + rME = 640.; + } else if (targetLayer == 8 || rME == 16) { //ME3/2, RE3/3, + if (refLogicLayer == 0) + rME = 620.; + else + rME = 680.; + } else if (targetLayer == 9) { + rME = 460.; //for the refLogicLayer = 1. refLogicLayer = 2 is impossible + } + } + + float d = rME - rRefLayer; + //formula in the form as in the slides explaining the extrapolation algorithm + //float deltaPhiExtr = d / rME * refPhiB / omtfConfig->dtPhiBUnitsRad(); //[rad] + //phiExtr = round(deltaPhiExtr / omtfConfig->omtfPhiUnit()); //[halfStrip] + + //formula with approximation, used to calculate extrFactor + float extrFactor = d / rME / omtfConfig->dtPhiBUnitsRad() / omtfConfig->omtfPhiUnit(); + phiExtr = extrFactor * refPhiB; //[halfStrip] + + //formula without approximation + float deltaPhiExtr = atan(d / rME * tan(refPhiB / omtfConfig->dtPhiBUnitsRad())); //[rad] + phiExtr = round(deltaPhiExtr / omtfConfig->omtfPhiUnit()); //[halfStrip] + + if (useEndcapStubsRInExtr) { + extrapolFactors[reflLayerIndex][targetLayer][abs(targetStubEta)] += extrFactor; + extrapolFactorsNorm[reflLayerIndex][targetLayer][abs(targetStubEta)]++; + //extrapolFactors[reflLayerIndex][targetLayer][0] += extrFactor; + //extrapolFactorsNorm[reflLayerIndex][targetLayer][0]++; + } else { + extrapolFactors[reflLayerIndex][targetLayer][0] = extrFactor; + extrapolFactorsNorm[reflLayerIndex][targetLayer][0] = 1; + } + LogTrace("l1tOmtfEventPrint") << "\n" + << __FUNCTION__ << ":" << __LINE__ << " refLogicLayer " << refLogicLayer + << " targetLayer " << std::setw(2) << targetLayer << " targetStubR " << targetStubR + << " targetStubEta " << targetStubEta << " extrFactor " + << " rRefLayer " << rRefLayer << " d " << d << " deltaPhiExtr " << deltaPhiExtr + << " phiExtr " << phiExtr << std::endl; + } + //TODO restrict the range of the phiExtr and refPhiB !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + return phiExtr; +} + +template +int OMTFProcessor::extrapolateDtPhiBFixedPoint(const int& refLogicLayer, + const int& refPhi, + const int& refPhiB, + unsigned int targetLayer, + const int& targetStubPhi, + const int& targetStubQuality, + const int& targetStubEta, + const int& targetStubR, + const OMTFConfiguration* omtfConfig) { + int phiExtr = 0; //delta phi extrapolated + + int reflLayerIndex = refLogicLayer == 0 ? 0 : 1; + int extrFactor = 0; + + if (targetLayer == 0 || targetLayer == 2 || targetLayer == 4) { + if (useStubQualInExtr) + extrFactor = extrapolFactors[reflLayerIndex][targetLayer][targetStubQuality]; + else + extrFactor = extrapolFactors[reflLayerIndex][targetLayer][0]; + } else if (targetLayer == 1 || targetLayer == 3 || targetLayer == 5) { + int deltaPhi = targetStubPhi - refPhi; //[halfStrip] + + int scaleFactor = this->myOmtfConfig->omtfPhiUnit() * this->myOmtfConfig->dtPhiBUnitsRad() * 512; + //= 305 for phase-1, 512 is multiplier so that scaleFactor is non-zero integer + + deltaPhi = (deltaPhi * scaleFactor) / 512; //here deltaPhi is converted to the phi_b hw scale + + phiExtr = refPhiB - deltaPhi; //phiExtr is also in phi_b hw scale + //LogTrace("l1tOmtfEventPrint") <<__FUNCTION__<<":"<<__LINE__<<" deltaPhi "<= 10 && targetLayer <= 14) { + extrFactor = extrapolFactors[reflLayerIndex][targetLayer][0]; + } else if ((targetLayer >= 6 && targetLayer <= 9) || (targetLayer >= 15 && targetLayer <= 17)) { + if (useEndcapStubsRInExtr) { + //if given abs(targetStubEta) value is not present in the map, it is added with default value of 0 + //so it should be good. The only problem is that the map can grow... + extrFactor = extrapolFactors[reflLayerIndex][targetLayer][abs(targetStubEta)]; + } else { + extrFactor = extrapolFactors[reflLayerIndex][targetLayer][0]; + } + } + + if (this->myOmtfConfig->isBendingLayer(targetLayer) == false) { + phiExtr = extrFactor * refPhiB / extrapolMultiplier; + } + + LogTrace("l1tOmtfEventPrint") << "\n" + << __FUNCTION__ << ":" << __LINE__ << " refLogicLayer " << refLogicLayer + << " targetLayer " << targetLayer << std::endl; + LogTrace("l1tOmtfEventPrint") << "refPhi " << refPhi << " refPhiB " << refPhiB << " targetStubPhi " << targetStubPhi + << " targetStubQuality " << targetStubQuality << " targetStubEta " << targetStubEta + << " extrFactor " << extrFactor << " phiExtr " << phiExtr << std::endl; + + return phiExtr; +} + +template +int OMTFProcessor::extrapolateDtPhiB(const MuonStubPtr& refStub, + const MuonStubPtr& targetStub, + unsigned int targetLayer, + const OMTFConfiguration* omtfConfig) { + if (useFloatingPointExtrapolation) + return OMTFProcessor::extrapolateDtPhiBFloatPoint(refStub->logicLayer, + refStub->phiHw, + refStub->phiBHw, + targetLayer, + targetStub->phiHw, + targetStub->qualityHw, + targetStub->etaHw, + targetStub->r, + omtfConfig); + return OMTFProcessor::extrapolateDtPhiBFixedPoint(refStub->logicLayer, + refStub->phiHw, + refStub->phiBHw, + targetLayer, + targetStub->phiHw, + targetStub->qualityHw, + targetStub->etaHw, + targetStub->r, + omtfConfig); +} /////////////////////////////////////////////// /////////////////////////////////////////////// //const std::vector & template void OMTFProcessor::processInput(unsigned int iProcessor, l1t::tftype mtfType, - const OMTFinput& aInput) { + const OMTFinput& aInput, + std::vector >& observers) { unsigned int procIndx = this->myOmtfConfig->getProcIndx(iProcessor, mtfType); for (auto& itGP : this->theGPs) { for (auto& result : itGP->getResults()[procIndx]) { @@ -300,63 +584,142 @@ void OMTFProcessor::processInput(unsigned int iProcessor, } } + LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << "\n" + << __LINE__ << " iProcessor " << iProcessor << " mtfType " << mtfType << " procIndx " + << procIndx << " ----------------------" << std::endl; ////////////////////////////////////// ////////////////////////////////////// - std::bitset<128> refHitsBits = aInput.getRefHits(iProcessor); - if (refHitsBits.none()) - return; // myResults; + std::vector refHitDefs; + { + auto refHitsBits = aInput.getRefHits(iProcessor); + if (refHitsBits.none()) + return; // myResults; + + //loop over all possible refHits, e.g. 128 + for (unsigned int iRefHit = 0; iRefHit < this->myOmtfConfig->nRefHits(); ++iRefHit) { + if (!refHitsBits[iRefHit]) + continue; + + refHitDefs.push_back(&(this->myOmtfConfig->getRefHitsDefs()[iProcessor][iRefHit])); + + if (refHitDefs.size() == this->myOmtfConfig->nTestRefHits()) + break; + } + } + + boost::property_tree::ptree procDataTree; + LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << " " << __LINE__; for (unsigned int iLayer = 0; iLayer < this->myOmtfConfig->nLayers(); ++iLayer) { //debug /*for(auto& h : layerHits) { if(h != 5400) LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<" "<<__LINE__<<" iLayer "<myOmtfConfig->nTestRefHits(); - for (unsigned int iRefHit = 0; iRefHit < this->myOmtfConfig->nRefHits(); - ++iRefHit) { //loop over all possible refHits, i.e. 128 - if (!refHitsBits[iRefHit]) - continue; - if (nTestedRefHits-- == 0) - break; - const RefHitDef& aRefHitDef = this->myOmtfConfig->getRefHitsDefs()[iProcessor][iRefHit]; + for (unsigned int iRefHit = 0; iRefHit < refHitDefs.size(); iRefHit++) { + const RefHitDef& aRefHitDef = *(refHitDefs[iRefHit]); unsigned int refLayerLogicNum = this->myOmtfConfig->getRefToLogicNumber()[aRefHitDef.iRefLayer]; const MuonStubPtr refStub = aInput.getMuonStub(refLayerLogicNum, aRefHitDef.iInput); - int phiRef = refStub->phiHw; - int etaRef = refStub->etaHw; + //int etaRef = refStub->etaHw; unsigned int iRegion = aRefHitDef.iRegion; - if (this->myOmtfConfig->getBendingLayers().count(iLayer)) //this iLayer is a bending layer - phiRef = 0; //then in the delta_phi in process1Layer1RefLayer one obtains simply the iLayer phi - MuonStubPtrs1D restrictedLayerStubs = this->restrictInput(iProcessor, iRegion, iLayer, aInput); - //LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<" "<<__LINE__<<" iLayer "<nTestRefHits()-nTestedRefHits-1<<" iRefHit "<myOmtfConfig->nTestRefHits() - nTestedRefHits - 1; + std::vector extrapolatedPhi(restrictedLayerStubs.size(), 0); + + //TODO make sure the that the iRefLayer numbers used here corresponds to this in the hwToLogicLayer_0x000X.xml + if ((this->myOmtfConfig->usePhiBExtrapolationMB1() && aRefHitDef.iRefLayer == 0) || + (this->myOmtfConfig->usePhiBExtrapolationMB2() && aRefHitDef.iRefLayer == 2)) { + if ((iLayer != refLayerLogicNum) && (iLayer != refLayerLogicNum + 1)) { + unsigned int iStub = 0; + for (auto& targetStub : restrictedLayerStubs) { + if (targetStub) { + extrapolatedPhi[iStub] = extrapolateDtPhiB(refStub, targetStub, iLayer, this->myOmtfConfig); + + LogTrace("l1tOmtfEventPrint") + << "\n" + << __FUNCTION__ << ":" << __LINE__ << " extrapolating from layer " << refLayerLogicNum + << " - iRefLayer " << aRefHitDef.iRefLayer << " to layer " << iLayer << " stub " << targetStub + << " value " << extrapolatedPhi[iStub] << std::endl; + + if (this->myOmtfConfig->getDumpResultToXML()) { + auto& extrapolatedPhiTree = procDataTree.add_child("extrapolatedPhi", boost::property_tree::ptree()); + extrapolatedPhiTree.add(".refLayer", refLayerLogicNum); + extrapolatedPhiTree.add(".layer", iLayer); + extrapolatedPhiTree.add(".refPhiBHw", refStub->phiBHw); + extrapolatedPhiTree.add(".iStub", iStub); + extrapolatedPhiTree.add(".qualityHw", targetStub->qualityHw); + extrapolatedPhiTree.add(".etaHw", targetStub->etaHw); + extrapolatedPhiTree.add(".phiExtr", extrapolatedPhi[iStub]); + + if (this->myOmtfConfig->isBendingLayer(iLayer)) + extrapolatedPhiTree.add(".dist_phi", targetStub->phiBHw - extrapolatedPhi[iStub]); + else + extrapolatedPhiTree.add(".dist_phi", targetStub->phiHw - extrapolatedPhi[iStub]); + } + } + iStub++; + } + } + } + for (auto& itGP : this->theGPs) { if (itGP->key().thePt == 0) //empty pattern continue; StubResult stubResult = - itGP->process1Layer1RefLayer(aRefHitDef.iRefLayer, iLayer, restrictedLayerStubs, refStub); + itGP->process1Layer1RefLayer(aRefHitDef.iRefLayer, iLayer, restrictedLayerStubs, extrapolatedPhi, refStub); - //fixme this unnecessary repeated for every layer - but in this layout of loops must be like that - int phiRefSt2 = itGP->propagateRefPhi(phiRef, etaRef, aRefHitDef.iRefLayer); + /* LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__ + <<" layerResult: valid"<getResults()[procIndx][refHitNumber].setStubResult(iLayer, stubResult); - //fixme this unnecessary repeated for every layer - but in this layout of loops must be like that - itGP->getResults()[procIndx][refHitNumber].set(aRefHitDef.iRefLayer, phiRefSt2, etaRef, phiRef); + itGP->getResults()[procIndx][iRefHit].setStubResult(iLayer, stubResult); } } } + + for (unsigned int iRefHit = 0; iRefHit < refHitDefs.size(); iRefHit++) { + const RefHitDef& aRefHitDef = *(refHitDefs[iRefHit]); + + unsigned int refLayerLogicNum = this->myOmtfConfig->getRefToLogicNumber()[aRefHitDef.iRefLayer]; + const MuonStubPtr refStub = aInput.getMuonStub(refLayerLogicNum, aRefHitDef.iInput); + + int phiRef = refStub->phiHw; + int etaRef = refStub->etaHw; + + //calculating the phiExtrp in the case the RefLayer is MB1, to include it in the candidate phi of candidate + int phiExtrp = 0; + if ((this->myOmtfConfig->usePhiBExtrapolationMB1() && aRefHitDef.iRefLayer == 0)) { + //||(this->myOmtfConfig->getUsePhiBExtrapolationMB2() && aRefHitDef.iRefLayer == 2) ) { //the extrapolation from the layer 2 to the layer 2 has no sense, so phiExtrp is 0 + LogTrace("l1tOmtfEventPrint") << "\n" + << __FUNCTION__ << ":" << __LINE__ + << "extrapolating ref hit to get the phi of the candidate" << std::endl; + if (useFloatingPointExtrapolation) + phiExtrp = extrapolateDtPhiBFloatPoint( + aRefHitDef.iRefLayer, phiRef, refStub->phiBHw, 2, 0, 6, 0, 0, this->myOmtfConfig); + else + phiExtrp = extrapolateDtPhiBFixedPoint( + aRefHitDef.iRefLayer, phiRef, refStub->phiBHw, 2, 0, 6, 0, 0, this->myOmtfConfig); + } + + for (auto& itGP : this->theGPs) { + if (itGP->key().thePt == 0) //empty pattern + continue; + + int phiRefSt2 = itGP->propagateRefPhi(phiRef + phiExtrp, etaRef, aRefHitDef.iRefLayer); + itGP->getResults()[procIndx][iRefHit].set(aRefHitDef.iRefLayer, phiRefSt2, etaRef, phiRef); + } + } + ////////////////////////////////////// ////////////////////////////////////// { @@ -371,6 +734,9 @@ void OMTFProcessor::processInput(unsigned int iProcessor, } } + for (auto& obs : observers) + obs->addProcesorData("extrapolation", procDataTree); + return; } /////////////////////////////////////////////////////// @@ -386,18 +752,49 @@ std::vector OMTFProcessor::run( //uncomment if you want to check execution time of each method //boost::timer::auto_cpu_timer t("%ws wall, %us user in getProcessorCandidates\n"); + for (auto& obs : observers) + obs->observeProcesorBegin(iProcessor, mtfType); + //input is shared_ptr because the observers may need them after the run() method execution is finished std::shared_ptr input = std::make_shared(this->myOmtfConfig); - inputMaker->buildInputForProcessor(input->getMuonStubs(), iProcessor, mtfType, bx, bx); + inputMaker->buildInputForProcessor(input->getMuonStubs(), iProcessor, mtfType, bx, bx, observers); + + if (this->myOmtfConfig->cleanStubs()) { + //this has sense for the pattern generation from the tracks with the secondaries + //if more than one stub is in a given layer, all stubs are removed from this layer + for (unsigned int iLayer = 0; iLayer < input->getMuonStubs().size(); ++iLayer) { + auto& layerStubs = input->getMuonStubs()[iLayer]; + int count = std::count_if(layerStubs.begin(), layerStubs.end(), [](auto& ptr) { return ptr != nullptr; }); + if (count > 1) { + for (auto& ptr : layerStubs) + ptr.reset(); + + LogTrace("OMTFReconstruction") << __FUNCTION__ << ":" << __LINE__ << "cleaning stubs in the layer " << iLayer + << " stubs count :" << count << std::endl; + } + } + } //LogTrace("l1tOmtfEventPrint")<<"buildInputForProce "; t.report(); - processInput(iProcessor, mtfType, *(input.get())); + processInput(iProcessor, mtfType, *(input.get()), observers); //LogTrace("l1tOmtfEventPrint")<<"processInput "; t.report(); AlgoMuons algoCandidates = sortResults(iProcessor, mtfType); + if (ptAssignment) { + for (auto& myCand : algoCandidates) { + if (myCand->isValid()) { + auto pts = ptAssignment->getPts(myCand, observers); + /*for (unsigned int i = 0; i < pts.size(); i++) { + trackAddr[10 + i] = this->myOmtfConfig->ptGevToHw(pts[i]); + }*/ + } + } + } + //LogTrace("l1tOmtfEventPrint")<<"sortResults "; t.report(); // perform GB + //watch out: etaBits2HwEta is used in the ghostBust to convert the AlgoMuons eta, it affect algoCandidates as they are pointers AlgoMuons gbCandidates = ghostBust(algoCandidates); //LogTrace("l1tOmtfEventPrint")<<"ghostBust"; t.report(); @@ -424,6 +821,92 @@ void OMTFProcessor::printInfo() const { ProcessorBase::printInfo(); } +template +void OMTFProcessor::saveExtrapolFactors() { + //if(this->myOmtfConfig->nProcessors() == 3) //phase2 + extrapolMultiplier = 512; + + boost::property_tree::ptree tree; + auto& extrFactorsTree = tree.add("ExtrapolationFactors", ""); + extrFactorsTree.add(".multiplier", extrapolMultiplier); + + edm::LogVerbatim("OMTFReconstruction") << "saving extrapolFactors to ExtrapolationFactors.xml" << std::endl; + for (unsigned int iRefLayer = 0; iRefLayer < extrapolFactors.size(); iRefLayer++) { + for (unsigned int iLayer = 0; iLayer < extrapolFactors[iRefLayer].size(); iLayer++) { + edm::LogVerbatim("OMTFReconstruction") << " iRefLayer " << iRefLayer << " iLayer " << iLayer << std::endl; + + auto& layerTree = extrFactorsTree.add_child("Lut", boost::property_tree::ptree()); + layerTree.add(".RefLayer", std::to_string(iRefLayer)); + layerTree.add(".Layer", iLayer); + + if (useStubQualInExtr && (iLayer == 0 || iLayer == 2 || iLayer == 4)) + layerTree.add(".KeyType", "quality"); + else if (useEndcapStubsRInExtr && ((iLayer >= 6 && iLayer <= 9) || (iLayer >= 15 && iLayer <= 17))) + layerTree.add(".KeyType", "eta"); + else + layerTree.add(".KeyType", "none"); + + for (auto& extrFactors : extrapolFactors[iRefLayer][iLayer]) { + int norm = 1; + if (!extrapolFactorsNorm[iRefLayer][iLayer].empty()) + norm = extrapolFactorsNorm[iRefLayer][iLayer][extrFactors.first]; + auto& lutVal = layerTree.add_child("LutVal", boost::property_tree::ptree()); + if (useEndcapStubsRInExtr && ((iLayer >= 6 && iLayer <= 9) || (iLayer >= 15 && iLayer <= 17))) + lutVal.add(".key", extrFactors.first); + else + lutVal.add(".key", extrFactors.first); + + double value = round(extrapolMultiplier * extrFactors.second / norm); + lutVal.add(".value", value); + + edm::LogVerbatim("OMTFReconstruction") + << std::setw(4) << " key = " << extrFactors.first << " extrFactors.second " << std::setw(10) + << extrFactors.second << " norm " << std::setw(6) << norm << " value/norm " << std::setw(10) + << extrFactors.second / norm << " value " << value << std::endl; + } + } + } + + boost::property_tree::write_xml("ExtrapolationFactors.xml", + tree, + std::locale(), + boost::property_tree::xml_parser::xml_writer_make_settings(' ', 2)); +} + +template +void OMTFProcessor::loadExtrapolFactors(const std::string& filename) { + boost::property_tree::ptree tree; + + boost::property_tree::read_xml(filename, tree); + + edm::LogVerbatim("OMTFReconstruction") << "loadExtrapolFactors from file " << filename << std::endl; + + extrapolMultiplier = tree.get("ExtrapolationFactors..multiplier"); + edm::LogVerbatim("OMTFReconstruction") << "extrapolMultiplier " << extrapolMultiplier << std::endl; + + auto& lutNodes = tree.get_child("ExtrapolationFactors"); + for (boost::property_tree::ptree::value_type& lutNode : lutNodes) { + if (lutNode.first == "Lut") { + int iRefLayer = lutNode.second.get(".RefLayer"); + int iLayer = lutNode.second.get(".Layer"); + std::string keyType = lutNode.second.get(".KeyType"); + + edm::LogVerbatim("OMTFReconstruction") + << "iRefLayer " << iRefLayer << " iLayer " << iLayer << " keyType " << keyType << std::endl; + + auto& valueNodes = lutNode.second; + for (boost::property_tree::ptree::value_type& valueNode : valueNodes) { + if (valueNode.first == "LutVal") { + int key = valueNode.second.get(".key"); + float value = valueNode.second.get(".value"); + extrapolFactors.at(iRefLayer).at(iLayer)[key] = value; + edm::LogVerbatim("OMTFReconstruction") << "key " << key << " value " << value << std::endl; + } + } + } + } +} + ///////////////////////////////////////////////////////// template class OMTFProcessor; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc index b49613075a588..45053cad082e6 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc @@ -157,13 +157,6 @@ void OMTFReconstruction::beginRun(edm::Run const& run, } else { //in principle should not happen throw cms::Exception("OMTFReconstruction::beginRun: omtfParams is nullptr"); } - auto omtfProcGoldenPat = dynamic_cast*>(omtfProc.get()); - - if (edmParameterSet.exists("generatePatterns") && edmParameterSet.getParameter("generatePatterns")) { - observers.emplace_back( - std::make_unique(edmParameterSet, omtfConfig.get(), omtfProcGoldenPat->getPatterns())); - edm::LogVerbatim("OMTFReconstruction") << "generatePatterns: true " << std::endl; - } } } else { throw cms::Exception("OMTFReconstruction::beginRun: unknown GoldenPattern type: " + patternType); @@ -217,8 +210,32 @@ void OMTFReconstruction::addObservers( } if (edmParameterSet.exists("dumpHitsToROOT") && edmParameterSet.getParameter("dumpHitsToROOT")) { - std::string rootFileName = edmParameterSet.getParameter("dumpHitsFileName"); - observers.emplace_back(std::make_unique(edmParameterSet, omtfConfig.get(), rootFileName)); + //std::string rootFileName = edmParameterSet.getParameter("dumpHitsFileName"); + if (candidateSimMuonMatcher == nullptr) { + edm::LogVerbatim("OMTFReconstruction") + << "dumpHitsToROOT needs candidateSimMuonMatcher, but it is null " << std::endl; + throw cms::Exception("dumpHitsToROOT needs candidateSimMuonMatcher, but it is null"); + } + observers.emplace_back( + std::make_unique(edmParameterSet, omtfConfig.get(), candidateSimMuonMatcher)); + } + } + + auto omtfProcGoldenPatWithStat = dynamic_cast*>(omtfProc.get()); + if (omtfProcGoldenPatWithStat) { + if (edmParameterSet.exists("eventCaptureDebug")) + if (edmParameterSet.getParameter("eventCaptureDebug")) { + observers.emplace_back(std::make_unique( + edmParameterSet, omtfConfig.get(), candidateSimMuonMatcher, muonGeometryTokens + //&(omtfProcGoldenPat->getPatterns() ), + //watch out, will crash if the proc is re-constructed from the DB after L1TMuonOverlapParamsRcd change + )); + } + + if (edmParameterSet.exists("generatePatterns") && edmParameterSet.getParameter("generatePatterns")) { + observers.emplace_back(std::make_unique( + edmParameterSet, omtfConfig.get(), omtfProcGoldenPatWithStat->getPatterns(), candidateSimMuonMatcher)); + edm::LogVerbatim("OMTFReconstruction") << "generatePatterns: true " << std::endl; } } } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFSorter.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFSorter.cc index 49edd617240c5..00eb6c5e06e39 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFSorter.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFSorter.cc @@ -17,7 +17,8 @@ template AlgoMuons::value_type OMTFSorter::sortRefHitResults( unsigned int procIndx, unsigned int iRefHit, const GoldenPatternVec& gPatterns, int charge) { GoldenPatternType* bestGP = nullptr; //the GoldenPattern with the best result for this iRefHit - //std::cout <<" ====== sortRefHitResults: " << std::endl; + + GoldenPatternType* bestGpUnconstr = nullptr; for (auto& itGP : gPatterns) { if (!itGP->getResults()[procIndx][iRefHit].isValid()) @@ -35,29 +36,37 @@ AlgoMuons::value_type OMTFSorter::sortRefHitResults( } else if (myType == 0 && itGP->getResults()[procIndx][iRefHit].getFiredLayerCnt() > bestGP->getResults()[procIndx][iRefHit].getFiredLayerCnt()) { bestGP = itGP.get(); - /* - std::cout <<" sorter, byQual, now best is: " - <key() << " " - <getResults()[procIndx][iRefHit] - <getResults()[procIndx][iRefHit].getFiredLayerCnt() == bestGP->getResults()[procIndx][iRefHit].getFiredLayerCnt())) { if (itGP->getResults()[procIndx][iRefHit].getPdfSum() > bestGP->getResults()[procIndx][iRefHit].getPdfSum()) { //if the PdfWeigtSum is equal, we take the GP with the lower number, i.e. lower pt = check if this is ok for physics FIXME (KB) bestGP = itGP.get(); - /* - std::cout <<" sorter, byDisc, now best is: " - <key() << " " - <getResults()[procIndx][iRefHit] - <getResults()[procIndx][iRefHit].getPdfSumUnconstr() > 0) + bestGpUnconstr = itGP.get(); + } else if (myType == 0 && itGP->getResults()[procIndx][iRefHit].getFiredLayerCnt() > + bestGpUnconstr->getResults()[procIndx][iRefHit].getFiredLayerCnt()) { + bestGpUnconstr = itGP.get(); + } else if (myType == 1 || (itGP->getResults()[procIndx][iRefHit].getFiredLayerCnt() == + bestGpUnconstr->getResults()[procIndx][iRefHit].getFiredLayerCnt())) { + if (itGP->getResults()[procIndx][iRefHit].getPdfSumUnconstr() > + bestGpUnconstr->getResults()[procIndx][iRefHit].getPdfSumUnconstr()) { + //if the PdfWeigtSum is equal, we take the GP with the lower number, i.e. lower pt = check if this is ok for physics FIXME (KB) + bestGpUnconstr = itGP.get(); } } } if (bestGP) { AlgoMuons::value_type candidate(new AlgoMuon(bestGP->getResults()[procIndx][iRefHit], bestGP, iRefHit)); - //std::cout<<__FUNCTION__<<" line "<<__LINE__ <<" return: " << *candidate << std::endl; + + if (bestGpUnconstr) { + candidate->setGpResultUnconstr(bestGpUnconstr->getResults()[procIndx][iRefHit]); + candidate->setGoldenPaternUnconstr(bestGpUnconstr); + } + return candidate; } else { AlgoMuons::value_type candidate(new AlgoMuon()); diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinput.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinput.cc index 9c6f4e5ec0c91..4453522426567 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinput.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinput.cc @@ -1,13 +1,15 @@ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinput.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + #include /////////////////////////////////////////////////// /////////////////////////////////////////////////// -const int inputsPerLayer = 14; OMTFinput::OMTFinput(const OMTFConfiguration* omtfConfig) : MuonStubsInput(omtfConfig) { myOmtfConfig = omtfConfig; + const int inputsPerLayer = myOmtfConfig->nInputs(); muonStubsInLayers.assign(omtfConfig->nLayers(), std::vector(inputsPerLayer)); //nullptrs are assigned here for every input } @@ -32,8 +34,6 @@ int OMTFinput::getPhiHw(unsigned int iLayer, unsigned int iInput) const { } const int OMTFinput::getHitEta(unsigned int iLayer, unsigned int iInput) const { - /* assert(iLayer < muonStubsInLayers.size()); - assert(iInput < muonStubsInLayers[iLayer].size());*/ if (this->myOmtfConfig->isBendingLayer(iLayer)) { MuonStubPtr stub = getMuonStub(iLayer - 1, iInput); if (stub) @@ -47,22 +47,44 @@ const int OMTFinput::getHitEta(unsigned int iLayer, unsigned int iInput) const { return myOmtfConfig->nPhiBins(); } +const int OMTFinput::getHitQual(unsigned int iLayer, unsigned int iInput) const { + /* assert(iLayer < muonStubsInLayers.size()); + assert(iInput < muonStubsInLayers[iLayer].size());*/ + if (this->myOmtfConfig->isBendingLayer(iLayer)) { + MuonStubPtr stub = getMuonStub(iLayer - 1, iInput); + if (stub) + return stub->qualityHw; + } + + MuonStubPtr stub = getMuonStub(iLayer, iInput); + if (stub) + return stub->qualityHw; + + return myOmtfConfig->nPhiBins(); +} + /////////////////////////////////////////////////// /////////////////////////////////////////////////// -std::bitset<128> OMTFinput::getRefHits(unsigned int iProcessor) const { - std::bitset<128> refHits; +boost::dynamic_bitset<> OMTFinput::getRefHits(unsigned int iProcessor) const { + boost::dynamic_bitset<> refHits(myOmtfConfig->nRefHits()); unsigned int iRefHit = 0; for (auto iRefHitDef : myOmtfConfig->getRefHitsDefs()[iProcessor]) { - int iPhi = getPhiHw(myOmtfConfig->getRefToLogicNumber()[iRefHitDef.iRefLayer], iRefHitDef.iInput); + auto refHitLogicLayer = myOmtfConfig->getRefToLogicNumber()[iRefHitDef.iRefLayer]; + + int iPhi = getPhiHw(refHitLogicLayer, iRefHitDef.iInput); if (iPhi < (int)myOmtfConfig->nPhiBins()) { - refHits.set(iRefHit, iRefHitDef.fitsRange(iPhi)); + //TODO use a constant defined somewhere instead of 6 + if (refHitLogicLayer >= 6 || + getMuonStub(refHitLogicLayer, iRefHitDef.iInput)->qualityHw >= myOmtfConfig->getDtRefHitMinQuality()) + refHits.set(iRefHit, iRefHitDef.fitsRange(iPhi)); } iRefHit++; } return refHits; } + /////////////////////////////////////////////////// /////////////////////////////////////////////////// std::ostream& operator<<(std::ostream& out, const OMTFinput& aInput) { diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinputMaker.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinputMaker.cc index df4aeb533a3ed..a1fd384f8a1bc 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinputMaker.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinputMaker.cc @@ -53,10 +53,9 @@ void DtDigiToStubsConverterOmtf::addDTphiDigi(MuonStubPtrs2D& muonStubsInLayers, OMTFinputMaker::getProcessorPhiZero(config, iProcessor), procTyp, digi.scNum(), digi.phi()); stub.etaHw = angleConverter->getGlobalEta(detid, dtThDigis, digi.bxNum()); - if (stub.qualityHw >= config->getMinDtPhiBQuality()) - stub.phiBHw = digi.phiB(); - else - stub.phiBHw = config->nPhiBins(); + //the cut if (stub.qualityHw >= config->getMinDtPhiBQuality()) is done in the ProcessorBase::restrictInput + //as is is done like that in the firmware + stub.phiBHw = digi.phiB(); stub.bx = digi.bxNum(); //TODO sholdn't it be BxCnt()? //stub.timing = digi.getTiming(); //TODO what about sub-bx timing, is is available? @@ -93,11 +92,13 @@ void CscDigiToStubsConverterOmtf::addCSCstubs(MuonStubPtrs2D& muonStubsInLayers, unsigned int iLayer = config->getHwToLogicLayer().at(hwNumber); unsigned int iInput = OMTFinputMaker::getInputNumber(config, rawid, iProcessor, procTyp); + float r = 0; MuonStub stub; stub.type = MuonStub::CSC_PHI_ETA; stub.phiHw = angleConverter->getProcessorPhi( - OMTFinputMaker::getProcessorPhiZero(config, iProcessor), procTyp, CSCDetId(rawid), digi); - stub.etaHw = angleConverter->getGlobalEta(rawid, digi); + OMTFinputMaker::getProcessorPhiZero(config, iProcessor), procTyp, CSCDetId(rawid), digi, iInput); + stub.etaHw = angleConverter->getGlobalEta(rawid, digi, r); + stub.r = round(r); stub.phiBHw = digi.getPattern(); //TODO change to phiB when implemented stub.qualityHw = digi.getQuality(); @@ -108,7 +109,15 @@ void CscDigiToStubsConverterOmtf::addCSCstubs(MuonStubPtrs2D& muonStubsInLayers, stub.logicLayer = iLayer; stub.detId = rawid; - OMTFinputMaker::addStub(config, muonStubsInLayers, iLayer, iInput, stub); + //TODO this cut is not yet implemented in the FW, + //but it is worth to apply it at least for the pattern generation and NN training + if (iLayer == 9) { + if (stub.r >= config->minCSCStubRME12()) + OMTFinputMaker::addStub(config, muonStubsInLayers, iLayer, iInput, stub); + } else if (stub.r >= config->minCscStubR()) { + OMTFinputMaker::addStub(config, muonStubsInLayers, iLayer, iInput, stub); + } + ///Accept CSC digis only up to eta=1.26. ///The nominal OMTF range is up to 1.24, but cutting at 1.24 ///kill efficiency at the edge. 1.26 is one eta bin above nominal. @@ -166,7 +175,10 @@ void RpcDigiToStubsConverterOmtf::addRPCstub(MuonStubPtrs2D& muonStubsInLayers, stub.type = MuonStub::RPC; stub.phiHw = angleConverter->getProcessorPhi( OMTFinputMaker::getProcessorPhiZero(config, iProcessor), procTyp, roll, cluster.firstStrip, cluster.lastStrip); - stub.etaHw = angleConverter->getGlobalEtaRpc(rawid, cluster.firstStrip); + + float r = 0; + stub.etaHw = angleConverter->getGlobalEtaRpc(rawid, cluster.firstStrip, r); + stub.r = round(r); stub.qualityHw = cluster.size(); @@ -359,8 +371,8 @@ unsigned int OMTFinputMaker::getInputNumber(const OMTFConfiguration* config, aSector = rpc.sector(); ///on the 0-2pi border we need to add 1 30 deg sector ///to get the correct index - if (iProcessor == 5 && aSector < 3) - aMin = -1; + if (iProcessor == (config->nProcessors() - 1) && aSector < 3) + aSector += 12; //aMin = -1; //Use division into rolls iRoll = rpc.roll(); ///Set roll number by hand to keep common input @@ -381,8 +393,8 @@ unsigned int OMTFinputMaker::getInputNumber(const OMTFConfiguration* config, aMin = config->getEndcap10DegMin()[iProcessor]; ///on the 0-2pi border we need to add 4 10 deg sectors ///to get the correct index - if (iProcessor == 5 && aSector < 5) - aMin = -4; + if (iProcessor == (config->nProcessors() - 1) && aSector < 5) + aSector += 36; //aMin = -4; } break; } @@ -391,8 +403,8 @@ unsigned int OMTFinputMaker::getInputNumber(const OMTFConfiguration* config, aSector = dt.sector(); ///on the 0-2pi border we need to add 1 30 deg sector ///to get the correct index - if (iProcessor == 5 && aSector < 3) - aMin = -1; + if (iProcessor == (config->nProcessors() - 1) && aSector < 3) + aSector += 12; //aMin = -1; break; } case MuonSubdetId::CSC: { @@ -401,15 +413,15 @@ unsigned int OMTFinputMaker::getInputNumber(const OMTFConfiguration* config, aMin = config->getEndcap10DegMin()[iProcessor]; ///on the 0-2pi border we need to add 4 10deg sectors ///to get the correct index - if (iProcessor == 5 && aSector < 5) - aMin = -4; + if (iProcessor == (config->nProcessors() - 1) && aSector < 5) + aSector += 36; //aMin = -4; ///Endcap region covers algo 10 deg sectors ///on the 0-2pi border we need to add 2 20deg sectors ///to get the correct index if ((type == l1t::tftype::emtf_pos || type == l1t::tftype::emtf_neg) && csc.station() > 1 && csc.ring() == 1) { aMin = config->getEndcap20DegMin()[iProcessor]; - if (iProcessor == 5 && aSector < 3) - aMin = -2; + if (iProcessor == (config->nProcessors() - 1) && aSector < 3) + aSector += 18; //aMin = -2; } break; } @@ -429,7 +441,8 @@ unsigned int OMTFinputMaker::getInputNumber(const OMTFConfiguration* config, int OMTFinputMaker::getProcessorPhiZero(const OMTFConfiguration* config, unsigned int iProcessor) { unsigned int nPhiBins = config->nPhiBins(); - int phiZero = nPhiBins / 6. * (iProcessor) + nPhiBins / 24; + int phiZero = + nPhiBins / config->nProcessors() * (iProcessor) + nPhiBins / 24; //this 24 gives 15deg (360deg/24 = 15deg) // "0" is 15degree moved cyclically to each processor, note [0,2pi] return config->foldPhi(phiZero); @@ -463,5 +476,6 @@ void OMTFinputMaker::addStub(const OMTFConfiguration* config, return; //in this implementation only two first stubs are added for a given iInput + stub.input = iInput; muonStubsInLayers.at(iLayer).at(iInput) = std::make_shared(stub); } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc index d86533ab531aa..beacb5fa3665f 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc @@ -6,6 +6,7 @@ */ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h" +#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h" #include "FWCore/Framework/interface/EventSetup.h" #include "Geometry/Records/interface/MuonGeometryRecord.h" @@ -22,6 +23,10 @@ #include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThContainer.h" #include "DataFormats/RPCDigi/interface/RPCDigi.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include + namespace { template int sgn(T val) { @@ -44,57 +49,10 @@ namespace { int etaVal2Bit(float eta) { return bounds.rend() - std::lower_bound(bounds.rbegin(), bounds.rend(), fabs(eta)); } - int etaBit2Code(unsigned int bit) { - int code = 73; - switch (bit) { - case 0: { - code = 115; - break; - } - case 1: { - code = 110; - break; - } - case 2: { - code = 103; - break; - } - case 3: { - code = 99; - break; - } - case 4: { - code = 94; - break; - } - case 5: { - code = 90; - break; - } - case 6: { - code = 85; - break; - } - case 7: { - code = 78; - break; - } - case 8: { - code = 73; - break; - } - default: { - code = 95; - break; - } - } - return code; - } - int etaVal2Code(double etaVal) { int sign = sgn(etaVal); int bit = etaVal2Bit(fabs(etaVal)); - int code = etaBit2Code(bit); + int code = OMTFConfiguration::etaBit2Code(bit); return sign * code; } @@ -104,33 +62,33 @@ namespace { if (keyWG < 49) etaCode = 121; else if (keyWG <= 57) - etaCode = etaBit2Code(0); + etaCode = OMTFConfiguration::etaBit2Code(0); else if (keyWG <= 63) - etaCode = etaBit2Code(1); + etaCode = OMTFConfiguration::etaBit2Code(1); } else if (detId.station() == 1 && detId.ring() == 3) { if (keyWG <= 2) - etaCode = etaBit2Code(2); + etaCode = OMTFConfiguration::etaBit2Code(2); else if (keyWG <= 8) - etaCode = etaBit2Code(3); + etaCode = OMTFConfiguration::etaBit2Code(3); else if (keyWG <= 15) - etaCode = etaBit2Code(4); + etaCode = OMTFConfiguration::etaBit2Code(4); else if (keyWG <= 23) - etaCode = etaBit2Code(5); + etaCode = OMTFConfiguration::etaBit2Code(5); else if (keyWG <= 31) - etaCode = etaBit2Code(6); + etaCode = OMTFConfiguration::etaBit2Code(6); } else if ((detId.station() == 2 || detId.station() == 3) && detId.ring() == 2) { if (keyWG < 24) etaCode = 121; else if (keyWG <= 29) - etaCode = etaBit2Code(0); + etaCode = OMTFConfiguration::etaBit2Code(0); else if (keyWG <= 43) - etaCode = etaBit2Code(1); + etaCode = OMTFConfiguration::etaBit2Code(1); else if (keyWG <= 49) - etaCode = etaBit2Code(2); + etaCode = OMTFConfiguration::etaBit2Code(2); else if (keyWG <= 56) - etaCode = etaBit2Code(3); + etaCode = OMTFConfiguration::etaBit2Code(3); else if (keyWG <= 63) - etaCode = etaBit2Code(4); + etaCode = OMTFConfiguration::etaBit2Code(4); } if (detId.endcap() == 2) @@ -187,12 +145,18 @@ int OmtfAngleConverter::getGlobalEta(const DTChamberId dTChamberId, } int signEta = sgn(dTChamberId.wheel()); iEta *= signEta; - return iEta; + + if (config->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::bits) + return OMTFConfiguration::eta2Bits(abs(iEta)); + else if (config->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::valueP1Scale) + return abs(iEta); + + return 0; } /////////////////////////////////////// /////////////////////////////////////// -int OmtfAngleConverter::getGlobalEta(unsigned int rawid, const CSCCorrelatedLCTDigi &aDigi) const { +int OmtfAngleConverter::getGlobalEta(unsigned int rawid, const CSCCorrelatedLCTDigi &aDigi, float &r) const { ///Code taken from GeometryTranslator. ///Will be replaced by direct CSC phi local to global scale ///transformation as used in FPGA implementation @@ -241,22 +205,37 @@ int OmtfAngleConverter::getGlobalEta(unsigned int rawid, const CSCCorrelatedLCTD const GlobalPoint final_gp( GlobalPoint::Polar(coarse_gp.theta(), (coarse_gp.phi().value() + phi_offset), coarse_gp.mag())); - // LogTrace("l1tOmtfEventPrint")<getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::bits) + return OMTFConfiguration::eta2Bits(abs(etaKeyWG2Code(id, keyWG))); + else if (config->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::valueP1Scale) { + const LocalPoint lpWg = layer_geom->localCenterOfWireGroup(keyWG); + const GlobalPoint gpWg = layer->surface().toGlobal(lpWg); - return etaKeyWG2Code(id, keyWG); + return config->etaToHwEta(abs(gpWg.eta())); + } else { + return 0; + } } /////////////////////////////////////// /////////////////////////////////////// -int OmtfAngleConverter::getGlobalEtaRpc(unsigned int rawid, const unsigned int &strip) const { +int OmtfAngleConverter::getGlobalEtaRpc(unsigned int rawid, const unsigned int &strip, float &r) const { const RPCDetId id(rawid); auto roll = _georpc->roll(id); const LocalPoint lp = roll->centreOfStrip((int)strip); const GlobalPoint gp = roll->toGlobal(lp); - return etaVal2Code(gp.eta()); + if (id.region() != 0) { //outside barrel + r = gp.perp(); + } + + if (config->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::bits) + return OMTFConfiguration::eta2Bits(abs(etaVal2Code(gp.eta()))); + else if (config->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::valueP1Scale) + return abs(config->etaToHwEta((gp.eta()))); + + return 0; } /////////////////////////////////////// diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfName.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfName.cc index a96ecbd0e2ffa..febe4fab1d017 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfName.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfName.cc @@ -7,24 +7,24 @@ namespace { } } // namespace -OmtfName::OmtfName(unsigned int iProcesor, int endcap) { - int iproc = (iProcesor <= 5) ? static_cast(iProcesor) : -1; +OmtfName::OmtfName(unsigned int iProcesor, int endcap, const OMTFConfiguration* omtfConfig) { + int iproc = (iProcesor < omtfConfig->nProcessors()) ? static_cast(iProcesor) : -1; int position = (abs(endcap) == 1) ? endcap : 0; theBoard = static_cast(sgn(position) * (iproc + 1)); } -OmtfName::OmtfName(unsigned int iProcesor, l1t::tftype endcap) { - int iproc = (iProcesor <= 5) ? static_cast(iProcesor) : -1; +OmtfName::OmtfName(unsigned int iProcesor, l1t::tftype endcap, const OMTFConfiguration* omtfConfig) { + int iproc = (iProcesor < omtfConfig->nProcessors()) ? static_cast(iProcesor) : -1; int position = (endcap == l1t::omtf_pos) ? 1 : ((endcap == l1t::omtf_neg) ? -1 : 0); theBoard = static_cast(sgn(position) * (iproc + 1)); } -OmtfName::OmtfName(unsigned int iProcesor) { +OmtfName::OmtfName(unsigned int iProcesor, const OMTFConfiguration* omtfConfig) { int board = 0; - if (iProcesor <= 5) //OMTFn + if (iProcesor < omtfConfig->nProcessors()) //OMTFn board = -iProcesor - 1; else //OMTFp - board = iProcesor - 5; + board = iProcesor - (omtfConfig->nProcessors() - 1); theBoard = static_cast(board); } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/ProcessorBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/ProcessorBase.cc index 23a29f8ba9376..56b863b2cc6b2 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/ProcessorBase.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/ProcessorBase.cc @@ -154,9 +154,11 @@ MuonStubPtrs1D ProcessorBase::restrictInput(unsigned int iPro for (unsigned int iInput = 0; iInput < input.getMuonStubs()[iLayer].size(); ++iInput) { if (iInput >= iStart && iInput <= iEnd) { if (this->myOmtfConfig->isBendingLayer(iLayer)) { - layerStubs.push_back(input.getMuonStub(iLayer - 1, iInput)); + if (input.getMuonStub(iLayer - 1, iInput) && + input.getMuonStub(iLayer - 1, iInput)->qualityHw >= myOmtfConfig->getMinDtPhiBQuality()) + layerStubs.push_back(input.getMuonStub(iLayer - 1, iInput)); } else - layerStubs.push_back(input.getMuonStub(iLayer, iInput)); //input.getHitPhi(iLayer, iInput) + layerStubs.push_back(input.getMuonStub(iLayer, iInput)); } } //LogTrace("OMTFReconstruction") <<__FUNCTION__<<":"<<__LINE__<<" layerHits.size() "< XMLConfigReader::buildGP(DOMElement *aGPEleme throw cms::Exception("OMTF::XMLConfigReader: aItemElement is 0"); std::string strVal = _toString(aItemElement->getAttribute(xmlTresh)); thresholds[iItem] = std::stof(strVal); - //LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" strVal "< XMLConfigReader::buildGP(DOMElement *aGPEleme ///PDF vector nItems = aLayerElement->getElementsByTagName(xmlPDF)->getLength(); - //debug - //if(nItems!=aConfig.nRefLayers()*exp2(aConfig.nPdfAddrBits())) - //LogTrace("l1tOmtfEventPrint")<<" iPt "<createDocument(nullptr, _toDOMS(docName), nullptr); theTopElement = theDoc->getDocumentElement(); - unsigned int version = myOMTFConfig->patternsVersion(); - unsigned int mask16bits = 0xFFFF; - - version &= mask16bits; + const unsigned int mask16bits = 0xFFFF; + const unsigned int version = (myOMTFConfig->patternsVersion() & mask16bits); std::ostringstream stringStr; stringStr.str(""); @@ -224,7 +222,7 @@ void XMLConfigWriter::writeAlgoMuon(xercesc::DOMElement* aTopElement, const Algo stringStr << aCand.getRefHitNumber(); aResult->setAttribute(_toDOMS("iRefHit"), _toDOMS(stringStr.str())); stringStr.str(""); - stringStr << aCand.getPt(); + stringStr << aCand.getPtConstr(); aResult->setAttribute(_toDOMS("ptCode"), _toDOMS(stringStr.str())); stringStr.str(""); stringStr << aCand.getPhi(); @@ -233,7 +231,7 @@ void XMLConfigWriter::writeAlgoMuon(xercesc::DOMElement* aTopElement, const Algo stringStr << eta2Bits(abs(aCand.getEtaHw())); aResult->setAttribute(_toDOMS("etaCode"), _toDOMS(stringStr.str())); stringStr.str(""); - stringStr << aCand.getCharge(); + stringStr << aCand.getChargeConstr(); aResult->setAttribute(_toDOMS("charge"), _toDOMS(stringStr.str())); stringStr.str(""); stringStr << aCand.getQ(); @@ -251,7 +249,7 @@ void XMLConfigWriter::writeAlgoMuon(xercesc::DOMElement* aTopElement, const Algo stringStr << aCand.getPhiRHit(); aResult->setAttribute(_toDOMS("phiRHit"), _toDOMS(stringStr.str())); stringStr.str(""); - stringStr << aCand.getHwPatternNumber(); + stringStr << aCand.getHwPatternNumConstr(); aResult->setAttribute(_toDOMS("patNum"), _toDOMS(stringStr.str())); aTopElement->appendChild(aResult); @@ -541,14 +539,6 @@ void XMLConfigWriter::writeGPs(const GoldenPatternVec& golden if (!gp) { throw cms::Exception("OMTF::XMLConfigWriter::writeGPs: the gps are not GoldenPatterns "); } - /*cout<key()<nLayers(); ++iLayer) { - for(unsigned int iRefLayer=0; iRefLayernRefLayers(); ++iRefLayer) { - if(gp->getPdf()[iLayer][iRefLayer][0] != 0) { - cout<<"iLayer "<getPdf()[iLayer][iRefLayer][0]<<"!!!!!!!!!!!!!!!!!!!!\n"; - } - } - }*/ gps[i] = gp; } writeGPData(gps[0], gps[1], gps[2], gps[3]); @@ -561,7 +551,7 @@ void XMLConfigWriter::writeConnectionsData( const std::vector >& measurements4D) { std::ostringstream stringStr; - for (unsigned int iProcessor = 0; iProcessor < 6; ++iProcessor) { + for (unsigned int iProcessor = 0; iProcessor < myOMTFConfig->nProcessors(); ++iProcessor) { xercesc::DOMElement* aProcessorElement = theDoc->createElement(_toDOMS("Processor")); stringStr.str(""); stringStr << iProcessor; @@ -579,13 +569,13 @@ void XMLConfigWriter::writeConnectionsData( unsigned int iRefHit = 0; /////// for (unsigned int iRefLayer = 0; iRefLayer < myOMTFConfig->nRefLayers(); ++iRefLayer) { - for (unsigned int iRegion = 0; iRegion < 6; ++iRegion) { + for (unsigned int iRegion = 0; iRegion < myOMTFConfig->nLogicRegions(); ++iRegion) { unsigned int maxHitCount = 0; - for (unsigned int iInput = 0; iInput < 14; ++iInput) { + for (unsigned int iInput = 0; iInput < myOMTFConfig->nInputs(); ++iInput) { if ((int)maxHitCount < myOMTFConfig->getMeasurements4Dref()[iProcessor][iRegion][iRefLayer][iInput]) maxHitCount = myOMTFConfig->getMeasurements4Dref()[iProcessor][iRegion][iRefLayer][iInput]; } - for (unsigned int iInput = 0; iInput < 14; ++iInput) { + for (unsigned int iInput = 0; iInput < myOMTFConfig->nInputs(); ++iInput) { unsigned int hitCount = myOMTFConfig->getMeasurements4Dref()[iProcessor][iRegion][iRefLayer][iInput]; if (hitCount < maxHitCount * 0.1) continue; @@ -658,7 +648,7 @@ void XMLConfigWriter::writeConnectionsData( } } //// - for (unsigned int iRegion = 0; iRegion < 6; ++iRegion) { + for (unsigned int iRegion = 0; iRegion < myOMTFConfig->nLogicRegions(); ++iRegion) { xercesc::DOMElement* aRegionElement = theDoc->createElement(_toDOMS("LogicRegion")); stringStr.str(""); stringStr << iRegion; @@ -697,7 +687,7 @@ void XMLConfigWriter::writeConnectionsData( unsigned int XMLConfigWriter::findMaxInput(const OMTFConfiguration::vector1D& myCounts) { unsigned int max = 0; unsigned int maxInput = 0; - for (unsigned int iInput = 0; iInput < 14; ++iInput) { + for (unsigned int iInput = 0; iInput < myOMTFConfig->nInputs(); ++iInput) { if (myCounts[iInput] > (int)max) { max = myCounts[iInput]; maxInput = iInput; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/XMLEventWriter.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/XMLEventWriter.cc index d6dd402e6dc2c..6da6ba45e1995 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/XMLEventWriter.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/XMLEventWriter.cc @@ -12,15 +12,47 @@ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinput.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLEventWriter.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include + +#include + XMLEventWriter::XMLEventWriter(const OMTFConfiguration* aOMTFConfig, std::string fName) - : omtfConfig(aOMTFConfig), xmlWriter(aOMTFConfig), currentElement(nullptr), fName(fName) { + : omtfConfig(aOMTFConfig), fName(fName) { //std::string fName = "OMTF"; - xmlWriter.initialiseXMLDocument("OMTF"); eventNum = 0; + + unsigned int version = aOMTFConfig->patternsVersion(); + const unsigned int mask16bits = 0xFFFF; + + version &= mask16bits; + + std::ostringstream stringStr; + stringStr.str(""); + stringStr << "0x" << std::hex << std::setfill('0') << std::setw(4) << version; + + tree.put("OMTF..version", stringStr.str()); }; XMLEventWriter::~XMLEventWriter() {} +void XMLEventWriter::observeProcesorBegin(unsigned int iProcessor, l1t::tftype mtfType) { + if (eventNum > 5000) + return; + + procTree.clear(); + + int endcap = (mtfType == l1t::omtf_neg) ? -1 : ((mtfType == l1t::omtf_pos) ? +1 : 0); + OmtfName board(iProcessor, endcap, omtfConfig); + procTree.add(".board", board.name()); + procTree.add(".iProcessor", iProcessor); + + std::ostringstream stringStr; + stringStr << (board.position() == 1 ? "+" : "") << board.position(); + procTree.add(".position", stringStr.str()); +} + void XMLEventWriter::observeProcesorEmulation(unsigned int iProcessor, l1t::tftype mtfType, const std::shared_ptr& input, @@ -31,29 +63,142 @@ void XMLEventWriter::observeProcesorEmulation(unsigned int iProcessor, return; int endcap = (mtfType == l1t::omtf_neg) ? -1 : ((mtfType == l1t::omtf_pos) ? +1 : 0); - OmtfName board(iProcessor, endcap); + OmtfName board(iProcessor, endcap, omtfConfig); if (candMuons.empty()) return; - //if(currentElement == nullptr) - // currentElement = xmlWriter.writeEventHeader(eventId); + for (unsigned int iLayer = 0; iLayer < omtfConfig->nLayers(); ++iLayer) { + boost::property_tree::ptree layerTree; + + for (unsigned int iHit = 0; iHit < input->getMuonStubs()[iLayer].size(); ++iHit) { + int hitPhi = input->getPhiHw(iLayer, iHit); + if (hitPhi >= (int)omtfConfig->nPhiBins()) + continue; + + auto& hitTree = layerTree.add("Hit", ""); - xercesc::DOMElement* aProcElement = xmlWriter.writeEventData(currentElement, board, *(input.get())); + hitTree.add(".iInput", iHit); + hitTree.add(".iEta", input->getHitEta(iLayer, iHit)); + hitTree.add(".iPhi", hitPhi); + + //in the firmware the hit quality is taken from link data only for the DT stubs + //for the CSC and RPC 1 means the hit is valid, 0 - not. + //in the input it is still worth to have the actual quality of the CSC and RPC + //Because it might be used in the neural network + if (iLayer >= 6) + hitTree.add(".iQual", 1); + else + hitTree.add(".iQual", input->getHitQual(iLayer, iHit)); + } + + if (!layerTree.empty()) { + layerTree.add(".iLayer", iLayer); + procTree.add_child("Layer", layerTree); + } + } for (auto& algoCand : algoCandidates) { ///Dump only regions, where a candidate was found if (algoCand->isValid()) { - xmlWriter.writeAlgoMuon(aProcElement, *algoCand); - /*if(dumpDetailedResultToXML){ - for(auto & itKey: results[iRefHit]) - xmlWriter.writeResultsData(aProcElement, iRefHit, itKey.first,itKey.second); - }*/ + auto& algoMuonTree = procTree.add("AlgoMuon", ""); + algoMuonTree.add(".charge", algoCand->getChargeConstr()); + algoMuonTree.add(".disc", algoCand->getDisc()); + algoMuonTree.add(".pdfSumConstr", algoCand->getGpResultConstr().getPdfSum()); + algoMuonTree.add(".pdfSumUnconstr", algoCand->getGpResultUnconstr().getPdfSumUnconstr()); + algoMuonTree.add(".etaCode", algoCand->getEtaHw()); + algoMuonTree.add(".iRefHit", algoCand->getRefHitNumber()); + algoMuonTree.add(".iRefLayer", algoCand->getRefLayer()); + + //algoMuonTree.add(".layers", std::bitset<18>(algoCand->getFiredLayerBits())); + + algoMuonTree.add(".layersConstr", std::bitset<18>(algoCand->getGpResultConstr().getFiredLayerBits())); + algoMuonTree.add(".layersUnconstr", + std::bitset<18>(algoCand->getGpResultUnconstr().getFiredLayerBits())); + + algoMuonTree.add(".nHits", algoCand->getQ()); + + algoMuonTree.add(".firedCntConstr", algoCand->getGpResultConstr().getFiredLayerCnt()); + algoMuonTree.add(".firedCntUnconstr", algoCand->getGpResultUnconstr().getFiredLayerCnt()); + + algoMuonTree.add(".patNumConstr", algoCand->getHwPatternNumConstr()); + algoMuonTree.add(".patNumUnconstr", algoCand->getHwPatternNumUnconstr()); + + algoMuonTree.add(".phiCode", algoCand->getPhi()); + + algoMuonTree.add(".phiConstr", algoCand->getGpResultConstr().getPhi()); + algoMuonTree.add(".phiUnConstr", algoCand->getGpResultUnconstr().getPhi()); + + algoMuonTree.add(".phiRHit", algoCand->getPhiRHit()); + + //in the firmware, the algoMuon has no pt nor upt yet, + //only the pattern number, which is converted to the hwpt in the ghostbuster + algoMuonTree.add(".ptCodeConstr", algoCand->getPtConstr()); + algoMuonTree.add(".ptCodeUnconstr", algoCand->getPtUnconstr()); + + auto& gpResultTree = algoMuonTree.add("gpResultConstr", ""); + auto& gpResultConstr = algoCand->getGpResultConstr(); + + gpResultTree.add(".patNum", algoCand->getHwPatternNumConstr()); + gpResultTree.add(".pdfSum", gpResultConstr.getPdfSum()); + + for (unsigned int iLogicLayer = 0; iLogicLayer < gpResultConstr.getStubResults().size(); ++iLogicLayer) { + auto& layerTree = gpResultTree.add("layer", ""); + layerTree.add(".num", iLogicLayer); + auto pdfBin = gpResultConstr.getStubResults()[iLogicLayer].getPdfBin(); + if (pdfBin == 5400) + pdfBin = 0; + layerTree.add(".pdfBin", pdfBin); + layerTree.add(".pdfVal", gpResultConstr.getStubResults()[iLogicLayer].getPdfVal()); + layerTree.add(".fired", gpResultConstr.isLayerFired(iLogicLayer)); + } + + if (algoCand->getGpResultUnconstr().isValid()) { + auto& gpResultTree = algoMuonTree.add("gpResultUnconstr", ""); + auto& gpResult = algoCand->getGpResultUnconstr(); + + gpResultTree.add(".patNum", algoCand->getHwPatternNumUnconstr()); + gpResultTree.add(".pdfSum", gpResult.getPdfSumUnconstr()); + + for (unsigned int iLogicLayer = 0; iLogicLayer < gpResult.getStubResults().size(); ++iLogicLayer) { + auto& layerTree = gpResultTree.add("layer", ""); + layerTree.add(".num", iLogicLayer); + auto pdfBin = gpResult.getStubResults()[iLogicLayer].getPdfBin(); + if (pdfBin == 5400) + pdfBin = 0; + layerTree.add(".pdfBin", pdfBin); + layerTree.add(".pdfVal", gpResult.getStubResults()[iLogicLayer].getPdfVal()); + layerTree.add(".fired", gpResult.isLayerFired(iLogicLayer)); + } + } } } - for (auto& candMuon : candMuons) - xmlWriter.writeCandMuon(aProcElement, candMuon); + for (auto& candMuon : candMuons) { + auto& candMuonTree = procTree.add("CandMuon", ""); + candMuonTree.add(".hwEta", candMuon.hwEta()); + candMuonTree.add(".hwPhi", candMuon.hwPhi()); + candMuonTree.add(".hwPt", candMuon.hwPt()); + candMuonTree.add(".hwUPt", candMuon.hwPtUnconstrained()); + candMuonTree.add(".hwQual", candMuon.hwQual()); + candMuonTree.add(".hwSign", candMuon.hwSign()); + candMuonTree.add(".hwSignValid", candMuon.hwSignValid()); + candMuonTree.add(".hwTrackAddress", std::bitset<29>(candMuon.trackAddress().at(0))); + candMuonTree.add(".link", candMuon.link()); + candMuonTree.add(".processor", candMuon.processor()); + + std::ostringstream stringStr; + if (candMuon.trackFinderType() == l1t::omtf_neg) + stringStr << "OMTF_NEG"; + else if (candMuon.trackFinderType() == l1t::omtf_pos) + stringStr << "OMTF_POS"; + else + stringStr << candMuon.trackFinderType(); + candMuonTree.add(".trackFinderType", stringStr.str()); + } + + if (!procTree.empty()) + eventTree->add_child("Processor", procTree); } void XMLEventWriter::observeEventBegin(const edm::Event& iEvent) { @@ -63,12 +208,20 @@ void XMLEventWriter::observeEventBegin(const edm::Event& iEvent) { return; //currentElement = xmlWriter.writeEventHeader(iEvent.id().event()); eventId = iEvent.id().event(); - currentElement = xmlWriter.writeEventHeader(eventId); + + eventTree = &(tree.add("OMTF.Event", "")); + eventTree->add(".iEvent", eventId); + + eventTree = &(eventTree->add("bx", "")); + eventTree->add(".iBx", 2 * eventId); } void XMLEventWriter::observeEventEnd(const edm::Event& iEvent, - std::unique_ptr& finalCandidates) { - currentElement = nullptr; -} + std::unique_ptr& finalCandidates) {} -void XMLEventWriter::endJob() { xmlWriter.finaliseXMLDocument(fName); } +void XMLEventWriter::endJob() { + edm::LogInfo("l1tOmtfEventPrint") << "XMLEventWriter::endJob() - writing the data to the xml - starting"; + boost::property_tree::write_xml( + fName, tree, std::locale(), boost::property_tree::xml_parser::xml_writer_make_settings(' ', 2)); + edm::LogInfo("l1tOmtfEventPrint") << "XMLEventWriter::endJob() - writing the data to the xml - done"; +} diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/ProcConfigurationBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/ProcConfigurationBase.cc index 7d5b1fe59847b..8e54b3b69c2e9 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/ProcConfigurationBase.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/ProcConfigurationBase.cc @@ -61,4 +61,23 @@ void ProcConfigurationBase::configureFromEdmParameterSet(const edm::ParameterSet edm::LogVerbatim("OMTFReconstruction") << "minDtPhiBQuality: " << edmParameterSet.getParameter("minDtPhiBQuality") << std::endl; } + + if (edmParameterSet.exists("stubEtaEncoding")) { + auto stubEtaEncodingStr = edmParameterSet.getParameter("stubEtaEncoding"); + if (stubEtaEncodingStr == "bits") + stubEtaEncoding = StubEtaEncoding::bits; + else if (stubEtaEncodingStr == "valueP1Scale") + stubEtaEncoding = StubEtaEncoding::valueP1Scale; + else + throw cms::Exception(std::string("ProcConfigurationBase::configureFromEdmParameterSet: stubEtaEncoding ") + + stubEtaEncodingStr + "is not correct"); + + edm::LogVerbatim("OMTFReconstruction") + << "stubEtaEncoding: " << static_cast(stubEtaEncoding) << " = " << stubEtaEncodingStr << std::endl; + } + + if (edmParameterSet.exists("dtPhiBUnitsRad")) { + dtPhiBUnitsRad_ = edmParameterSet.getParameter("dtPhiBUnitsRad"); + edm::LogVerbatim("OMTFReconstruction") << "dtPhiBUnitsRad: " << dtPhiBUnitsRad_ << std::endl; + } } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc index 516744af5dcb1..e4b3a1f73b765 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc @@ -20,11 +20,11 @@ #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h" +#include "boost/dynamic_bitset.hpp" + #include "TFile.h" #include "TH1D.h" -//#include "CLHEP/Units/GlobalPhysicalConstants.h" - double hwGmtPhiToGlobalPhi(int phi) { double phiGmtUnit = 2. * M_PI / 576.; return phi * phiGmtUnit; @@ -74,18 +74,19 @@ void CandidateSimMuonMatcher::observeProcesorEmulation(unsigned int iProcessor, const AlgoMuons& gbCandidates, const std::vector& candMuons) { //debug - /* unsigned int procIndx = omtfConfig->getProcIndx(iProcessor, mtfType); for (auto& gbCandidate : gbCandidates) { - if (gbCandidate->getPt() > 0) { - LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::observeProcesorEmulation procIndx" << procIndx<" "<< *gbCandidate << endl; + if (gbCandidate->getPtConstr() > 0) { + LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::observeProcesorEmulation procIndx" << procIndx << " " + << *gbCandidate << std::endl; this->gbCandidates.emplace_back(gbCandidate); } - }*/ + } } bool simTrackIsMuonInOmtf(const SimTrack& simTrack) { - if (abs(simTrack.type()) == 13 || abs(simTrack.type()) == 1000015) { //|| tpPtr->pt() > 20 //todo 1000015 is stau + if (std::abs(simTrack.type()) == 13 || + std::abs(simTrack.type()) == 1000015) { // 1000015 is stau, todo use other selection (e.g. pt>20) if needed //only muons } else return false; @@ -99,10 +100,10 @@ bool simTrackIsMuonInOmtf(const SimTrack& simTrack) { << simTrack.momentum().eta() << " phi " << std::setw(9) << simTrack.momentum().phi() << std::endl; - //higher margin for matching must be used than actual OMTF region (i.e. 0.82 - 1.24), + //some margin for matching must be used on top of actual OMTF region, + //i.e. (0.82-1.24)=>(0.72-1.3), //otherwise many candidates are marked as ghosts - //if( (fabs(simTrack.momentum().eta()) >= 0.82 ) && (fabs(simTrack.momentum().eta()) <= 1.24) ) { - if ((fabs(simTrack.momentum().eta()) >= 0.72) && (fabs(simTrack.momentum().eta()) <= 1.3)) { + if ((std::abs(simTrack.momentum().eta()) >= 0.72) && (std::abs(simTrack.momentum().eta()) <= 1.3)) { } else return false; @@ -116,17 +117,33 @@ bool simTrackIsMuonInOmtfBx0(const SimTrack& simTrack) { return simTrackIsMuonInOmtf(simTrack); } -bool trackingParticleIsMuonInOmtfBx0(const TrackingParticle& trackingParticle) { - /*if(trackingParticle.eventId().event() != 0) - LogTrace("l1tOmtfEventPrint") <<"trackingParticleIsMuonInOmtfBx0, pdgId "<20) if needed + //only muons + if (simTrack.eventId().bunchCrossing() == 0) + return true; + } + return false; +} + +bool trackingParticleIsMuonInBx0(const TrackingParticle& trackingParticle) { + if (std::abs(trackingParticle.pdgId()) == 13 || + std::abs(trackingParticle.pdgId()) == + 1000015) { // 1000015 is stau, todo use other selection (e.g. pt>20) if needed + //only muons + if (trackingParticle.eventId().bunchCrossing() == 0) + return true; + } + return false; +} +bool trackingParticleIsMuonInOmtfBx0(const TrackingParticle& trackingParticle) { if (trackingParticle.eventId().bunchCrossing() != 0) return false; - if (abs(trackingParticle.pdgId()) == 13 || abs(trackingParticle.pdgId()) == 1000015) { - // 1000015 is stau, todo use other selection if needed + if (std::abs(trackingParticle.pdgId()) == 13 || std::abs(trackingParticle.pdgId()) == 1000015) { + // 1000015 is stau, todo use other selection (e.g. pt>20) if needed //only muons } else return false; @@ -152,10 +169,10 @@ bool trackingParticleIsMuonInOmtfBx0(const TrackingParticle& trackingParticle) { << std::setw(9) << trackingParticle.momentum().phi() << " trackId " << trackingParticle.g4Tracks().at(0).trackId(); - //higher margin for matching must be used than actual OMTF region (i.e. 0.82 - 1.24), + //some margin for matching must be used on top of actual OMTF region, + //i.e. (0.82-1.24)=>(0.72-1.3), //otherwise many candidates are marked as ghosts - //if( (fabs(simTrack.momentum().eta()) >= 0.82 ) && (fabs(trackingParticle.momentum().eta()) <= 1.24) ) { - if ((fabs(trackingParticle.momentum().eta()) >= 0.72) && (fabs(trackingParticle.momentum().eta()) <= 1.3)) { + if ((std::abs(trackingParticle.momentum().eta()) >= 0.72) && (std::abs(trackingParticle.momentum().eta()) <= 1.3)) { } else return false; @@ -171,6 +188,7 @@ bool trackingParticleIsMuonInOmtfEvent0(const TrackingParticle& trackingParticle void CandidateSimMuonMatcher::observeEventEnd(const edm::Event& event, std::unique_ptr& finalCandidates) { + LogTrace("l1tOmtfEventPrint") << "\nCandidateSimMuonMatcher::observeEventEnd" << std::endl; AlgoMuons ghostBustedProcMuons; std::vector ghostBustedRegionalCands = CandidateSimMuonMatcher::ghostBust(finalCandidates.get(), gbCandidates, ghostBustedProcMuons); @@ -182,10 +200,14 @@ void CandidateSimMuonMatcher::observeEventEnd(const edm::Event& event, edm::Handle simVertices; event.getByLabel(edmCfg.getParameter("simVertexesTag"), simVertices); + LogTrace("l1tOmtfEventPrint") << "simTraksHandle size " << simTraksHandle.product()->size() << std::endl; + LogTrace("l1tOmtfEventPrint") << "simVertices size " << simVertices.product()->size() << std::endl; //TODO use other simTrackFilter if needed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - std::function const& simTrackFilter = simTrackIsMuonInOmtfBx0; + //we dont want to check the eta of the generated muon, as it is on the vertex, + //instead inside match, we check the eta of the propagated track to the second muons station + std::function const& simTrackFilter = simTrackIsMuonInBx0; //simTrackIsMuonInOmtfBx0; matchingResults = match( ghostBustedRegionalCands, ghostBustedProcMuons, simTraksHandle.product(), simVertices.product(), simTrackFilter); @@ -193,11 +215,12 @@ void CandidateSimMuonMatcher::observeEventEnd(const edm::Event& event, } else if (edmCfg.exists("trackingParticleTag")) { edm::Handle trackingParticleHandle; event.getByLabel(edmCfg.getParameter("trackingParticleTag"), trackingParticleHandle); - LogTrace("l1tOmtfEventPrint") << "trackingParticleHandle size " << trackingParticleHandle.product()->size() - << std::endl; + LogTrace("l1tOmtfEventPrint") << "\nCandidateSimMuonMatcher::observeEventEnd trackingParticleHandle size " + << trackingParticleHandle.product()->size() << std::endl; //TODO use other trackParticleFilter if needed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - std::function trackParticleFilter = trackingParticleIsMuonInOmtfBx0; + std::function trackParticleFilter = + trackingParticleIsMuonInBx0; //trackingParticleIsMuonInOmtfBx0; matchingResults = match(ghostBustedRegionalCands, ghostBustedProcMuons, trackingParticleHandle.product(), trackParticleFilter); } @@ -207,32 +230,40 @@ void CandidateSimMuonMatcher::endJob() {} std::vector CandidateSimMuonMatcher::ghostBust( const l1t::RegionalMuonCandBxCollection* mtfCands, const AlgoMuons& gbCandidates, AlgoMuons& ghostBustedProcMuons) { - if (gbCandidates.size() != mtfCands->size()) { + if (gbCandidates.size() != mtfCands->size(0)) { edm::LogError("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::ghostBust(): gbCandidates.size() " - << gbCandidates.size() << " != resultGbCandidates.size() " << mtfCands->size(); - throw cms::Exception("gbCandidates.size() != mtfCands->size()"); + << gbCandidates.size() << " != mtfCands.size() " << mtfCands->size(); } boost::dynamic_bitset<> isKilled(mtfCands->size(0), false); for (unsigned int i1 = 0; i1 < mtfCands->size(0); ++i1) { + if (mtfCands->at(0, i1).hwPt() == 0) + continue; + LogTrace("l1tOmtfEventPrint") << "\nCandidateSimMuonMatcher::ghostBust regionalCand pt " << std::setw(3) + << mtfCands->at(0, i1).hwPt() << " qual " << std::setw(2) + << mtfCands->at(0, i1).hwQual() << " proc " << std::setw(2) + << mtfCands->at(0, i1).processor(); for (unsigned int i2 = i1 + 1; i2 < mtfCands->size(0); ++i2) { auto& mtfCand1 = mtfCands->at(0, i1); auto& mtfCand2 = mtfCands->at(0, i2); + if (mtfCand2.hwPt() == 0) + continue; - if (abs(mtfCand1.hwEta() - mtfCand2.hwEta()) < (0.3 / 0.010875)) { - int gloablHwPhi1 = l1t::MicroGMTConfiguration::calcGlobalPhi( - mtfCand1.hwPhi(), mtfCand1.trackFinderType(), mtfCand1.processor()); - int gloablHwPhi2 = l1t::MicroGMTConfiguration::calcGlobalPhi( - mtfCand2.hwPhi(), mtfCand2.trackFinderType(), mtfCand2.processor()); + if (std::abs(mtfCand1.hwEta() - mtfCand2.hwEta()) < (0.3 / 0.010875)) { + int gloablHwPhi1 = omtfConfig->calcGlobalPhi(mtfCand1.hwPhi(), mtfCand1.processor()); + int gloablHwPhi2 = omtfConfig->calcGlobalPhi(mtfCand2.hwPhi(), mtfCand2.processor()); //one can use the phi in radians like that: - //double globalPhi1 = hwGmtPhiToGlobalPhi(l1t::MicroGMTConfiguration::calcGlobalPhi( mtfCand1.hwPhi(), mtfCand1.trackFinderType(), mtfCand1.processor() ) ); - //double globalPhi2 = hwGmtPhiToGlobalPhi(l1t::MicroGMTConfiguration::calcGlobalPhi( mtfCand2.hwPhi(), mtfCand2.trackFinderType(), mtfCand2.processor() ) ); + //double globalPhi1 = hwGmtPhiToGlobalPhi(omtfConfig->calcGlobalPhi( mtfCand1.hwPhi(), mtfCand1.processor() ) ); + //double globalPhi2 = hwGmtPhiToGlobalPhi(omtfConfig->calcGlobalPhi( mtfCand2.hwPhi(), mtfCand2.processor() ) ); //0.0872664626 = 5 deg, i.e. the same window as in the OMTF ghost buster - if (abs(gloablHwPhi1 - gloablHwPhi2) < 8) { - if (mtfCand1.hwQual() > mtfCand2.hwQual()) { + if (std::abs(gloablHwPhi1 - gloablHwPhi2) < 8) { + //if (mtfCand1.hwQual() > mtfCand2.hwQual()) //TODO this is used in the uGMT + if (gbCandidates[i1]->getFiredLayerCnt() > + gbCandidates[i2]->getFiredLayerCnt()) //but this should be better - but probably the difference is not big + { isKilled[i2] = true; } else isKilled[i1] = true; @@ -245,23 +276,26 @@ std::vector CandidateSimMuonMatcher::ghostBust( for (unsigned int i1 = 0; i1 < mtfCands->size(0); ++i1) { //dropping candidates with quality 0 !!!!!!!!!!!!!!!!!!!! fixme if not needed - if (!isKilled[i1] && mtfCands->at(0, i1).hwQual()) { + if (!isKilled[i1] && mtfCands->at(0, i1).hwPt()) { resultCands.push_back(&(mtfCands->at(0, i1))); ghostBustedProcMuons.push_back(gbCandidates.at(i1)); } - LogTrace("l1tOmtfEventPrint") - << "CandidateSimMuonMatcher::ghostBust\n regionalCand pt " << std::setw(3) << mtfCands->at(0, i1).hwPt() - << " qual " << std::setw(2) << mtfCands->at(0, i1).hwQual() << " proc " << std::setw(2) - << mtfCands->at(0, i1).processor() << " eta " << std::setw(4) << mtfCands->at(0, i1).hwEta() << " gloablEta " - << std::setw(8) << mtfCands->at(0, i1).hwEta() * 0.010875 << " hwPhi " << std::setw(3) - << mtfCands->at(0, i1).hwPhi() << " globalPhi " << std::setw(8) - << hwGmtPhiToGlobalPhi(l1t::MicroGMTConfiguration::calcGlobalPhi( - mtfCands->at(0, i1).hwPhi(), mtfCands->at(0, i1).trackFinderType(), mtfCands->at(0, i1).processor())) - << " fireadLayers " << std::bitset<18>(mtfCands->at(0, i1).trackAddress().at(0)) << " isKilled " - << isKilled.test(i1) << std::endl; - - LogTrace("l1tOmtfEventPrint") << *(gbCandidates.at(i1)) << std::endl; + if (mtfCands->at(0, i1).hwPt()) { + LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::ghostBust\n regionalCand pt " << std::setw(3) + << mtfCands->at(0, i1).hwPt() << " qual " << std::setw(2) + << mtfCands->at(0, i1).hwQual() << " proc " << std::setw(2) + << mtfCands->at(0, i1).processor() << " eta " << std::setw(4) + << mtfCands->at(0, i1).hwEta() << " gloablEta " << std::setw(8) + << mtfCands->at(0, i1).hwEta() * 0.010875 << " hwPhi " << std::setw(3) + << mtfCands->at(0, i1).hwPhi() << " globalPhi " << std::setw(8) + << hwGmtPhiToGlobalPhi(omtfConfig->calcGlobalPhi(mtfCands->at(0, i1).hwPhi(), + mtfCands->at(0, i1).processor())) + << " fireadLayers " << std::bitset<18>(mtfCands->at(0, i1).trackAddress().at(0)) + << " gb isKilled " << isKilled.test(i1) << std::endl; + + LogTrace("l1tOmtfEventPrint") << *(gbCandidates.at(i1)) << std::endl; + } } if (resultCands.size() >= 3) @@ -271,19 +305,20 @@ std::vector CandidateSimMuonMatcher::ghostBust( return resultCands; } -TrajectoryStateOnSurface CandidateSimMuonMatcher::atStation2(FreeTrajectoryState ftsStart, float eta) const { - ReferenceCountingPointer rpc; - if (eta < -1.24) //negative endcap, RE2 - rpc = ReferenceCountingPointer( - new BoundDisk(GlobalPoint(0., 0., -790.), TkRotation(), SimpleDiskBounds(300., 810., -10., 10.))); - else if (eta < 1.24) //barrel + overlap, 512.401cm is R of middle of the MB2 - rpc = ReferenceCountingPointer(new BoundCylinder( - GlobalPoint(0., 0., 0.), TkRotation(), SimpleCylinderBounds(512.401, 512.401, -900, 900))); - else - rpc = ReferenceCountingPointer( //positive endcap, RE2 - new BoundDisk(GlobalPoint(0., 0., 790.), TkRotation(), SimpleDiskBounds(300., 810., -10., 10.))); - +TrajectoryStateOnSurface CandidateSimMuonMatcher::atStation2(const FreeTrajectoryState& ftsStart) const { + // first propagate to MB2 assuming that muon is within barrel+overlap + // 512.401cm is R of middle of the MB2 + ReferenceCountingPointer rpc = ReferenceCountingPointer(new BoundCylinder( + GlobalPoint(0., 0., 0.), TkRotation(), SimpleCylinderBounds(512.401, 512.401, -900, 900))); TrajectoryStateOnSurface trackAtRPC = propagator->propagate(ftsStart, *rpc); + float zAtRPC = trackAtRPC.globalPosition().z(); + // check if propagated track within barrel+overlap, |z| = 660.5cm is edge of MB2 (B field on) + if (std::abs(zAtRPC) > 660.5) { //endcap, RE2, z = +-790cm + rpc = ReferenceCountingPointer(new BoundDisk(GlobalPoint(0., 0., std::copysign(790., zAtRPC)), + TkRotation(), + SimpleDiskBounds(300., 810., -10., 10.))); + trackAtRPC = propagator->propagate(ftsStart, *rpc); + } return trackAtRPC; } @@ -314,11 +349,10 @@ TrajectoryStateOnSurface CandidateSimMuonMatcher::propagate(const SimTrack& simT SimVertex simVertex; int vtxInd = simTrack.vertIndex(); if (vtxInd < 0) { - std::cout << "Track with no vertex, defaulting to (0,0,0)" << std::endl; + edm::LogImportant("l1tOmtfEventPrint") << "Track with no vertex, defaulting to (0,0,0)"; } else { simVertex = simVertices->at(vtxInd); if (((int)simVertex.vertexId()) != vtxInd) { - std::cout << "simVertex.vertexId() != vtxInd !!!!!!!!!!!!!!!!!" << std::endl; edm::LogImportant("l1tOmtfEventPrint") << "simVertex.vertexId() != vtxInd. simVertex.vertexId() " << simVertex.vertexId() << " vtxInd " << vtxInd << " !!!!!!!!!!!!!!!!!"; } @@ -326,7 +360,7 @@ TrajectoryStateOnSurface CandidateSimMuonMatcher::propagate(const SimTrack& simT FreeTrajectoryState ftsTrack = simTrackToFts(simTrack, simVertex); - TrajectoryStateOnSurface tsof = atStation2(ftsTrack, simTrack.momentum().eta()); //propagation + TrajectoryStateOnSurface tsof = atStation2(ftsTrack); //propagation return tsof; } @@ -334,7 +368,7 @@ TrajectoryStateOnSurface CandidateSimMuonMatcher::propagate(const SimTrack& simT TrajectoryStateOnSurface CandidateSimMuonMatcher::propagate(const TrackingParticle& trackingParticle) { FreeTrajectoryState ftsTrack = simTrackToFts(trackingParticle); - TrajectoryStateOnSurface tsof = atStation2(ftsTrack, trackingParticle.momentum().eta()); //propagation + TrajectoryStateOnSurface tsof = atStation2(ftsTrack); //propagation return tsof; } @@ -353,9 +387,9 @@ MatchingResult CandidateSimMuonMatcher::match(const l1t::RegionalMuonCand* muonC MatchingResult result(simTrack); double candGloablEta = muonCand->hwEta() * 0.010875; - if (abs(simTrack.momentum().eta() - candGloablEta) < 0.3) { - double candGlobalPhi = l1t::MicroGMTConfiguration::calcGlobalPhi( - muonCand->hwPhi(), muonCand->trackFinderType(), muonCand->processor()); + //if (std::abs(simTrack.momentum().eta() - candGloablEta) < 0.3) //has no sense for displaced muons + { + double candGlobalPhi = omtfConfig->calcGlobalPhi(muonCand->hwPhi(), muonCand->processor()); candGlobalPhi = hwGmtPhiToGlobalPhi(candGlobalPhi); if (candGlobalPhi > M_PI) @@ -386,7 +420,7 @@ MatchingResult CandidateSimMuonMatcher::match(const l1t::RegionalMuonCand* muonC if (simTrack.momentum().pt() > 100) treshold = 20. * sigma; - if (abs(result.deltaPhi - mean) < treshold) + if (std::abs(result.deltaPhi - mean) < treshold && std::abs(result.deltaEta) < 0.3) result.result = MatchingResult::ResultType::matched; LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match: simTrack type " << simTrack.type() << " pt " @@ -412,9 +446,9 @@ MatchingResult CandidateSimMuonMatcher::match(const l1t::RegionalMuonCand* muonC MatchingResult result(trackingParticle); double candGloablEta = muonCand->hwEta() * 0.010875; - if (abs(trackingParticle.momentum().eta() - candGloablEta) < 0.3) { - double candGlobalPhi = l1t::MicroGMTConfiguration::calcGlobalPhi( - muonCand->hwPhi(), muonCand->trackFinderType(), muonCand->processor()); + //if (std::abs(trackingParticle.momentum().eta() - candGloablEta) < 0.3) //has no sense for displaced muons + { + double candGlobalPhi = omtfConfig->calcGlobalPhi(muonCand->hwPhi(), muonCand->processor()); candGlobalPhi = hwGmtPhiToGlobalPhi(candGlobalPhi); if (candGlobalPhi > M_PI) @@ -447,19 +481,20 @@ MatchingResult CandidateSimMuonMatcher::match(const l1t::RegionalMuonCand* muonC if (trackingParticle.pt() > 100) treshold = 20. * sigma; - if (abs(result.deltaPhi - mean) < treshold) + if (std::abs(result.deltaPhi - mean) < treshold && std::abs(result.deltaEta) < 0.3) result.result = MatchingResult::ResultType::matched; - LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match: simTrack type " << trackingParticle.pdgId() - << " pt " << std::setw(8) << trackingParticle.pt() << " eta " << std::setw(8) - << trackingParticle.momentum().eta() << " phi " << std::setw(8) - << trackingParticle.momentum().phi() << " propagation eta " << std::setw(8) - << tsof.globalPosition().eta() << " phi " << tsof.globalPosition().phi() - << " muonCand pt " << std::setw(8) << muonCand->hwPt() << " candGloablEta " - << std::setw(8) << candGloablEta << " candGlobalPhi " << std::setw(8) << candGlobalPhi - << " hwQual " << muonCand->hwQual() << " deltaEta " << std::setw(8) << result.deltaEta - << " deltaPhi " << std::setw(8) << result.deltaPhi << " Likelihood " << std::setw(8) - << result.matchingLikelihood << " result " << (short)result.result << std::endl; + LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match: trackingParticle type " + << trackingParticle.pdgId() << " pt " << std::setw(8) << trackingParticle.pt() + << " eta " << std::setw(8) << trackingParticle.momentum().eta() << " phi " + << std::setw(8) << trackingParticle.momentum().phi() << " propagation eta " + << std::setw(8) << tsof.globalPosition().eta() << " phi " + << tsof.globalPosition().phi() << " muonCand pt " << std::setw(8) << muonCand->hwPt() + << " candGloablEta " << std::setw(8) << candGloablEta << " candGlobalPhi " + << std::setw(8) << candGlobalPhi << " hwQual " << muonCand->hwQual() << " deltaEta " + << std::setw(8) << result.deltaEta << " deltaPhi " << std::setw(8) << result.deltaPhi + << " Likelihood " << std::setw(8) << result.matchingLikelihood << " result " + << (short)result.result << std::endl; } return result; @@ -473,6 +508,7 @@ std::vector CandidateSimMuonMatcher::cleanMatching(std::vector bool { return a.matchingLikelihood > b.matchingLikelihood; }); + for (unsigned int i1 = 0; i1 < matchingResults.size(); i1++) { if (matchingResults[i1].result == MatchingResult::ResultType::matched) { for (unsigned int i2 = i1 + 1; i2 < matchingResults.size(); i2++) { @@ -575,6 +611,18 @@ std::vector CandidateSimMuonMatcher::match(std::vector= 0.7) && (std::abs(tsof.globalPosition().eta()) <= 1.31)) { + LogTrace("l1tOmtfEventPrint") + << "CandidateSimMuonMatcher::match simTrack IS in OMTF region, matching to the omtfCands"; + } else { + LogTrace("l1tOmtfEventPrint") << "simTrack NOT in OMTF region "; + continue; + } + /* TODO fix if filling of the deltaPhiPropCandMean and deltaPhiPropCandStdDev is needed double ptGen = simTrack.momentum().pt(); if(ptGen >= deltaPhiVertexProp->GetXaxis()->GetXmax()) @@ -587,7 +635,15 @@ std::vector CandidateSimMuonMatcher::match(std::vectorhwQual() > 1) { - MatchingResult result = match(muonCand, ghostBustedProcMuons.at(iCand), simTrack, tsof); + MatchingResult result; + if (tsof.isValid()) { + result = match(muonCand, ghostBustedProcMuons.at(iCand), simTrack, tsof); + } + int vtxInd = simTrack.vertIndex(); + if (vtxInd >= 0) { + result.simVertex = &( + simVertices->at(vtxInd)); //TODO ?????? something strange is here, was commented in the previous version + } if (result.result == MatchingResult::ResultType::matched) { matchingResults.push_back(result); matched = true; @@ -637,6 +693,19 @@ std::vector CandidateSimMuonMatcher::match( continue; //no sense to do matching } + LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match, tsof.globalPosition().eta() " + << tsof.globalPosition().eta(); + + //checking if the propagated track is inside the OMTF range, TODO - tune the range!!!!!!!!!!!!!!!!! + //eta 0.7 is the beginning of the MB2, while 1.31 is mid of RE2 + some margin + if ((std::abs(tsof.globalPosition().eta()) >= 0.7) && (std::abs(tsof.globalPosition().eta()) <= 1.31)) { + LogTrace("l1tOmtfEventPrint") + << "CandidateSimMuonMatcher::match trackingParticle IS in OMTF region, matching to the omtfCands"; + } else { + LogTrace("l1tOmtfEventPrint") << "trackingParticle NOT in OMTF region "; + continue; + } + /* TODO fix if filling of the deltaPhiPropCandMean and deltaPhiPropCandStdDev is needed double ptGen = trackingParticle.pt(); if(ptGen >= deltaPhiVertexProp->GetXaxis()->GetXmax()) @@ -644,6 +713,7 @@ std::vector CandidateSimMuonMatcher::match( deltaPhiVertexProp->Fill(ptGen, trackingParticle.momentum().phi() - tsof.globalPosition().phi()); */ + unsigned int iCand = 0; for (auto& muonCand : muonCands) { //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive then diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc index b6fa6d73b14bf..d02f50b31b9f5 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc @@ -7,6 +7,9 @@ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "FWCore/ServiceRegistry/interface/Service.h" + #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "DataFormats/MuonDetId/interface/CSCDetId.h" #include "DataFormats/MuonDetId/interface/RPCDetId.h" @@ -18,59 +21,83 @@ DataROOTDumper2::DataROOTDumper2(const edm::ParameterSet& edmCfg, const OMTFConfiguration* omtfConfig, - std::string rootFileName) - : EmulationObserverBase(edmCfg, omtfConfig) { + CandidateSimMuonMatcher* candidateSimMuonMatcher) + : EmulationObserverBase(edmCfg, omtfConfig), candidateSimMuonMatcher(candidateSimMuonMatcher) { edm::LogVerbatim("l1tOmtfEventPrint") << " omtfConfig->nTestRefHits() " << omtfConfig->nTestRefHits() << " event.omtfGpResultsPdfSum.num_elements() " << endl; - initializeTTree(rootFileName); + initializeTTree(); + + if (edmCfg.exists("dumpKilledOmtfCands")) + if (edmCfg.getParameter("dumpKilledOmtfCands")) + dumpKilledOmtfCands = true; - edm::LogVerbatim("l1tOmtfEventPrint") << " DataROOTDumper2 created" << std::endl; + edm::LogVerbatim("l1tOmtfEventPrint") << " DataROOTDumper2 created. dumpKilledOmtfCands " << dumpKilledOmtfCands + << std::endl; } -DataROOTDumper2::~DataROOTDumper2() { saveTTree(); } +DataROOTDumper2::~DataROOTDumper2() {} + +void DataROOTDumper2::initializeTTree() { + edm::Service fs; -void DataROOTDumper2::initializeTTree(std::string rootFileName) { - rootFile = new TFile(rootFileName.c_str(), "RECREATE"); - rootTree = new TTree("OMTFHitsTree", ""); + rootTree = fs->make("OMTFHitsTree", ""); + + rootTree->Branch("eventNum", &omtfEvent.eventNum); + rootTree->Branch("muonEvent", &omtfEvent.muonEvent); rootTree->Branch("muonPt", &omtfEvent.muonPt); rootTree->Branch("muonEta", &omtfEvent.muonEta); rootTree->Branch("muonPhi", &omtfEvent.muonPhi); + rootTree->Branch("muonPropEta", &omtfEvent.muonPropEta); + rootTree->Branch("muonPropPhi", &omtfEvent.muonPropPhi); rootTree->Branch("muonCharge", &omtfEvent.muonCharge); + rootTree->Branch("muonDxy", &omtfEvent.muonDxy); + rootTree->Branch("muonRho", &omtfEvent.muonRho); + rootTree->Branch("omtfPt", &omtfEvent.omtfPt); + rootTree->Branch("omtfUPt", &omtfEvent.omtfUPt); rootTree->Branch("omtfEta", &omtfEvent.omtfEta); rootTree->Branch("omtfPhi", &omtfEvent.omtfPhi); rootTree->Branch("omtfCharge", &omtfEvent.omtfCharge); + rootTree->Branch("omtfHwEta", &omtfEvent.omtfHwEta); + + rootTree->Branch("omtfProcessor", &omtfEvent.omtfProcessor); rootTree->Branch("omtfScore", &omtfEvent.omtfScore); rootTree->Branch("omtfQuality", &omtfEvent.omtfQuality); rootTree->Branch("omtfRefLayer", &omtfEvent.omtfRefLayer); - rootTree->Branch("omtfProcessor", &omtfEvent.omtfProcessor); + rootTree->Branch("omtfRefHitNum", &omtfEvent.omtfRefHitNum); rootTree->Branch("omtfFiredLayers", &omtfEvent.omtfFiredLayers); //<<<<<<<<<<<<<<<<<<<<<Branch("killed", &omtfEvent.killed); + + rootTree->Branch("hits", &omtfEvent.hits); -void DataROOTDumper2::saveTTree() { - rootFile->Write(); - ptGenPos->Write(); - ptGenNeg->Write(); + rootTree->Branch("deltaEta", &omtfEvent.deltaEta); + rootTree->Branch("deltaPhi", &omtfEvent.deltaPhi); - delete rootFile; - delete rootTree; + ptGenPos = fs->make("ptGenPos", "ptGenPos, eta at vertex 0.8 - 1.24", 400, 0, 200); //TODO + ptGenNeg = fs->make("ptGenNeg", "ptGenNeg, eta at vertex 0.8 - 1.24", 400, 0, 200); } +void DataROOTDumper2::observeProcesorEmulation(unsigned int iProcessor, + l1t::tftype mtfType, + const std::shared_ptr&, + const AlgoMuons& algoCandidates, + const AlgoMuons& gbCandidates, + const std::vector& candMuons) {} + void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, std::unique_ptr& finalCandidates) { + /* int muonCharge = 0; if (simMuon) { - if (abs(simMuon->momentum().eta()) < 0.8 || abs(simMuon->momentum().eta()) > 1.24) + if (std::abs(simMuon->momentum().eta()) < 0.8 || std::abs(simMuon->momentum().eta()) > 1.24) return; - muonCharge = (abs(simMuon->type()) == 13) ? simMuon->type() / -13 : 0; + muonCharge = (std::abs(simMuon->type()) == 13) ? simMuon->type() / -13 : 0; if (muonCharge > 0) ptGenPos->Fill(simMuon->momentum().pt()); else @@ -84,86 +111,248 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, omtfEvent.muonEta = simMuon->momentum().eta(); //TODO add cut on ete if needed - /* if(abs(event.muonEta) < 0.8 || abs(event.muonEta) > 1.24) - return;*/ + if(std::abs(event.muonEta) < 0.8 || std::abs(event.muonEta) > 1.24) + return; omtfEvent.muonPhi = simMuon->momentum().phi(); omtfEvent.muonCharge = muonCharge; //TODO + */ - if (omtfCand->getPt() > 0) { //&& omtfCand->getFiredLayerCnt() > 3 TODO add to the if needed - omtfEvent.omtfPt = omtfConfig->hwPtToGev(omtfCand->getPt()); - omtfEvent.omtfEta = omtfConfig->hwEtaToEta(omtfCand->getEtaHw()); - omtfEvent.omtfPhi = omtfCand->getPhi(); - omtfEvent.omtfCharge = std::pow(-1, regionalMuonCand.hwSign()); - omtfEvent.omtfScore = omtfCand->getPdfSum(); - omtfEvent.omtfQuality = regionalMuonCand.hwQual(); //omtfCand->getQ(); - omtfEvent.omtfFiredLayers = omtfCand->getFiredLayerBits(); - omtfEvent.omtfRefLayer = omtfCand->getRefLayer(); - omtfEvent.omtfProcessor = candProcIndx; - - omtfEvent.hits.clear(); - - auto& gpResult = omtfCand->getGpResult(); - - /* - edm::LogVerbatim("l1tOmtfEventPrint")<<"DataROOTDumper2:;observeEventEnd muonPt "<qualityHw; - hit.eta = stubResult.getMuonStub()->etaHw; //in which scale? - hit.valid = stubResult.getValid(); - - int hitPhi = stubResult.getMuonStub()->phiHw; - unsigned int refLayerLogicNum = omtfConfig->getRefToLogicNumber()[omtfCand->getRefLayer()]; - int phiRefHit = gpResult.getStubResults()[refLayerLogicNum].getMuonStub()->phiHw; - - if (omtfConfig->isBendingLayer(iLogicLayer)) { - hitPhi = stubResult.getMuonStub()->phiBHw; - phiRefHit = 0; //phi ref hit for the bending layer set to 0, since it should not be included in the phiDist - } + std::vector matchingResults = candidateSimMuonMatcher->getMatchingResults(); + LogTrace("l1tOmtfEventPrint") << "\nDataROOTDumper2::observeEventEnd matchingResults.size() " + << matchingResults.size() << std::endl; - //phiDist = hitPhi - phiRefHit; - hit.phiDist = hitPhi - phiRefHit; + //candidateSimMuonMatcher should use the trackingParticles, because the simTracks are not stored for the pile-up events + for (auto& matchingResult : matchingResults) { + omtfEvent.eventNum = iEvent.id().event(); - /* LogTrace("l1tOmtfEventPrint")<<" muonPt "<getGoldenPatern()->getDistPhiBitShift(iLogicLayer, omtfCand->getRefLayer()) - <<" meanDistPhiValue "<getGoldenPatern()->meanDistPhiValue(iLogicLayer, omtfCand->getRefLayer())//<<(phiDist != hit.phiDist? "!!!!!!!<<<<<" : "") - < 504 || hit.phiDist < -512) { - edm::LogVerbatim("l1tOmtfEventPrint") - << " muonPt " << omtfEvent.muonPt << " omtfPt " << omtfEvent.omtfPt << " RefLayer " - << omtfEvent.omtfRefLayer << " layer " << int(hit.layer) << " hit.phiDist " << hit.phiDist << " valid " - << stubResult.getValid() << " !!!!!!!!!!!!!!!!!!!!!!!!" << endl; - } + omtfEvent.muonEvent = trackingParticle->eventId().event(); - DetId detId(stubResult.getMuonStub()->detId); - if (detId.subdetId() == MuonSubdetId::CSC) { - CSCDetId cscId(detId); - hit.z = cscId.chamber() % 2; - } + omtfEvent.muonPt = trackingParticle->pt(); + omtfEvent.muonEta = trackingParticle->momentum().eta(); + omtfEvent.muonPhi = trackingParticle->momentum().phi(); + omtfEvent.muonPropEta = matchingResult.propagatedEta; + omtfEvent.muonPropPhi = matchingResult.propagatedPhi; + omtfEvent.muonCharge = (std::abs(trackingParticle->pdgId()) == 13) ? trackingParticle->pdgId() / -13 : 0; + + if (trackingParticle->parentVertex().isNonnull()) { + omtfEvent.muonDxy = trackingParticle->dxy(); + omtfEvent.muonRho = trackingParticle->parentVertex()->position().Rho(); + } + + omtfEvent.deltaEta = matchingResult.deltaEta; + omtfEvent.deltaPhi = matchingResult.deltaPhi; + + LogTrace("l1tOmtfEventPrint") << "DataROOTDumper2::observeEventEnd trackingParticle: eventId " + << trackingParticle->eventId().event() << " pdgId " << std::setw(3) + << trackingParticle->pdgId() << " trackId " + << trackingParticle->g4Tracks().at(0).trackId() << " pt " << std::setw(9) + << trackingParticle->pt() //<<" Beta "<momentum().Beta() + << " eta " << std::setw(9) << trackingParticle->momentum().eta() << " phi " + << std::setw(9) << trackingParticle->momentum().phi() << std::endl; + + if (std::abs(omtfEvent.muonEta) > 0.8 && std::abs(omtfEvent.muonEta) < 1.24) { + if (omtfEvent.muonCharge > 0) + ptGenPos->Fill(omtfEvent.muonPt); + else + ptGenNeg->Fill(omtfEvent.muonPt); + } + } else if (matchingResult.simTrack) { + auto simTrack = matchingResult.simTrack; + + omtfEvent.muonEvent = simTrack->eventId().event(); + + omtfEvent.muonPt = simTrack->momentum().pt(); + omtfEvent.muonEta = simTrack->momentum().eta(); + omtfEvent.muonPhi = simTrack->momentum().phi(); + omtfEvent.muonPropEta = matchingResult.propagatedEta; + omtfEvent.muonPropPhi = matchingResult.propagatedPhi; + omtfEvent.muonCharge = simTrack->charge(); + + if (!simTrack->noVertex() && matchingResult.simVertex) { + const math::XYZTLorentzVectorD& vtxPos = matchingResult.simVertex->position(); + omtfEvent.muonDxy = (-vtxPos.X() * simTrack->momentum().py() + vtxPos.Y() * simTrack->momentum().px()) / + simTrack->momentum().pt(); + omtfEvent.muonRho = vtxPos.Rho(); + } - omtfEvent.hits.push_back(hit.rawData); + omtfEvent.deltaEta = matchingResult.deltaEta; + omtfEvent.deltaPhi = matchingResult.deltaPhi; + + LogTrace("l1tOmtfEventPrint") << "DataROOTDumper2::observeEventEnd simTrack: eventId " + << simTrack->eventId().event() << " pdgId " << std::setw(3) + << simTrack->type() //<< " trackId " << simTrack->g4Tracks().at(0).trackId() + << " pt " << std::setw(9) + << simTrack->momentum().pt() //<<" Beta "<momentum().Beta() + << " eta " << std::setw(9) << simTrack->momentum().eta() << " phi " << std::setw(9) + << simTrack->momentum().phi() << std::endl; + + if (std::abs(omtfEvent.muonEta) > 0.8 && std::abs(omtfEvent.muonEta) < 1.24) { + if (omtfEvent.muonCharge > 0) + ptGenPos->Fill(omtfEvent.muonPt); + else + ptGenNeg->Fill(omtfEvent.muonPt); } + } else { + omtfEvent.muonEvent = -1; + + omtfEvent.muonPt = 0; + + omtfEvent.muonEta = 0; + omtfEvent.muonPhi = 0; + + omtfEvent.muonPropEta = 0; + omtfEvent.muonPropPhi = 0; + + omtfEvent.muonCharge = 0; //TODO + + omtfEvent.muonDxy = 0; + omtfEvent.muonRho = 0; } - //debug - /*if( (int)event.hits.size() != omtfCand->getQ()) { - LogTrace("l1tOmtfEventPrint")<<" muonPt "<getQ "<getQ()<<" !!!!!!!!!!!!!!!!!!aaa!!!!!!"<hwPtToGev(procMuon->getPtConstr()); + omtfEvent.omtfUPt = omtfConfig->hwUPtToGev(procMuon->getPtUnconstr()); + omtfEvent.omtfEta = omtfConfig->hwEtaToEta(procMuon->getEtaHw()); + omtfEvent.omtfPhi = procMuon->getPhi(); + omtfEvent.omtfCharge = procMuon->getChargeConstr(); + omtfEvent.omtfScore = procMuon->getPdfSum(); + + omtfEvent.omtfHwEta = procMuon->getEtaHw(); + + omtfEvent.omtfFiredLayers = procMuon->getFiredLayerBits(); + omtfEvent.omtfRefLayer = procMuon->getRefLayer(); + omtfEvent.omtfRefHitNum = procMuon->getRefHitNumber(); + + omtfEvent.hits.clear(); + + //TODO choose, which gpResult should be dumped + //auto& gpResult = procMuon->getGpResultConstr(); + auto& gpResult = (procMuon->getGpResultUnconstr().getPdfSumUnconstr() > procMuon->getGpResultConstr().getPdfSum()) + ? procMuon->getGpResultUnconstr() + : procMuon->getGpResultConstr(); + + /* + edm::LogVerbatim("l1tOmtfEventPrint")<<"DataROOTDumper2:;observeEventEnd muonPt "<isBendingLayer(iLogicLayer) && !stubResult.getMuonStub()) { + auto& stubResult = gpResult.getStubResults()[iLogicLayer-1]; + }*/ + + if (stubResult.getMuonStub()) { //&& stubResult.getValid() //TODO!!!!!!!!!!!!!!!!1 + OmtfEvent::Hit hit; + hit.layer = iLogicLayer; + hit.quality = stubResult.getMuonStub()->qualityHw; + hit.eta = stubResult.getMuonStub()->etaHw; //in which scale? + hit.valid = stubResult.getValid(); + + int hitPhi = stubResult.getMuonStub()->phiHw; + unsigned int refLayerLogicNum = omtfConfig->getRefToLogicNumber()[procMuon->getRefLayer()]; + int phiRefHit = gpResult.getStubResults()[refLayerLogicNum].getMuonStub()->phiHw; + + if (omtfConfig->isBendingLayer(iLogicLayer)) { + hitPhi = stubResult.getMuonStub()->phiBHw; + phiRefHit = 0; //phi ref hit for the bending layer set to 0, since it should not be included in the phiDist + } + + //phiDist = hitPhi - phiRefHit; + hit.phiDist = hitPhi - phiRefHit; + + /* LogTrace("l1tOmtfEventPrint")<<" muonPt "<getGoldenPatern()->getDistPhiBitShift(iLogicLayer, procMuon->getRefLayer()) + <<" meanDistPhiValue "<getGoldenPatern()->meanDistPhiValue(iLogicLayer, procMuon->getRefLayer())//<<(phiDist != hit.phiDist? "!!!!!!!<<<<<" : "") + < 504 || hit.phiDist < -512) { + edm::LogVerbatim("l1tOmtfEventPrint") + << " muonPt " << omtfEvent.muonPt << " omtfPt " << omtfEvent.omtfPt << " RefLayer " + << (int)omtfEvent.omtfRefLayer << " layer " << int(hit.layer) << " hit.phiDist " << hit.phiDist + << " valid " << stubResult.getValid() << " !!!!!!!!!!!!!!!!!!!!!!!!" << endl; + } + + DetId detId(stubResult.getMuonStub()->detId); + if (detId.subdetId() == MuonSubdetId::CSC) { + CSCDetId cscId(detId); + hit.z = cscId.chamber() % 2; + } + + omtfEvent.hits.push_back(hit.rawData); + } + } + + LogTrace("l1tOmtfEventPrint") << "DataROOTDumper2::observeEventEnd adding omtfCand : " << std::endl; + auto finalCandidate = matchingResult.muonCand; + LogTrace("l1tOmtfEventPrint") << " hwPt " << finalCandidate->hwPt() << " hwSign " << finalCandidate->hwSign() + << " hwQual " << finalCandidate->hwQual() << " hwEta " << std::setw(4) + << finalCandidate->hwEta() << std::setw(4) << " hwPhi " << finalCandidate->hwPhi() + << " eta " << std::setw(9) << (finalCandidate->hwEta() * 0.010875) + << " isKilled " << procMuon->isKilled() << " tRefLayer " << procMuon->getRefLayer() + << " RefHitNumber " << procMuon->getRefHitNumber() << std::endl; + }; + + if (matchingResult.muonCand && matchingResult.procMuon->getPtConstr() >= 0 && + matchingResult.muonCand->hwQual() >= 1) { + //TODO set the quality, quality 0 has the candidates with eta > 1.3(?) EtaHw >= 121 + //&& matchingResult.genPt < 20 + + omtfEvent.omtfQuality = matchingResult.muonCand->hwQual(); //procMuon->getQ(); + omtfEvent.killed = false; + omtfEvent.omtfProcessor = matchingResult.muonCand->processor(); + + if (matchingResult.muonCand->trackFinderType() == l1t::omtf_neg) { + omtfEvent.omtfProcessor *= -1; + } - rootTree->Fill(); - evntCnt++; + addOmtfCand(matchingResult.procMuon); + rootTree->Fill(); + + if (dumpKilledOmtfCands) { + for (auto& killedCand : matchingResult.procMuon->getKilledMuons()) { + omtfEvent.omtfQuality = 0; + omtfEvent.killed = true; + if (killedCand->isKilled() == false) { + edm::LogVerbatim("l1tOmtfEventPrint") << " killedCand->isKilled() == false !!!!!!!!"; + } + addOmtfCand(killedCand); + rootTree->Fill(); + } + } + } else if (omtfEvent.muonPt > 0) { //checking if there was a simMuon + LogTrace("l1tOmtfEventPrint") << "DataROOTDumper2::observeEventEnd no matching omtfCand" << std::endl; + + omtfEvent.omtfPt = 0; + omtfEvent.omtfUPt = 0; + omtfEvent.omtfEta = 0; + omtfEvent.omtfPhi = 0; + omtfEvent.omtfCharge = 0; + omtfEvent.omtfScore = 0; + + omtfEvent.omtfHwEta = 0; + + omtfEvent.omtfFiredLayers = 0; + omtfEvent.omtfRefLayer = 0; + omtfEvent.omtfRefHitNum = 0; + omtfEvent.omtfProcessor = 10; + + omtfEvent.omtfQuality = 0; + omtfEvent.killed = false; + + omtfEvent.hits.clear(); + + rootTree->Fill(); + } } + evntCnt++; } void DataROOTDumper2::endJob() { edm::LogVerbatim("l1tOmtfEventPrint") << " evntCnt " << evntCnt << endl; } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EmulationObserverBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EmulationObserverBase.cc index c8096745e943b..2b7ebb884bcd8 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EmulationObserverBase.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EmulationObserverBase.cc @@ -7,6 +7,7 @@ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EmulationObserverBase.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" #include "Math/VectorUtil.h" EmulationObserverBase::EmulationObserverBase(const edm::ParameterSet& edmCfg, const OMTFConfiguration* omtfConfig) @@ -27,7 +28,7 @@ void EmulationObserverBase::observeProcesorEmulation(unsigned int iProcessor, unsigned int i = 0; for (auto& gbCandidate : gbCandidates) { if (gbCandidate->getGoldenPatern() != nullptr && - gbCandidate->getGpResult().getFiredLayerCnt() > omtfCand->getGpResult().getFiredLayerCnt()) { + gbCandidate->getGpResultConstr().getFiredLayerCnt() > omtfCand->getGpResultConstr().getFiredLayerCnt()) { //LogTrace("l1tOmtfEventPrint") <<__FUNCTION__<<":"<<__LINE__<<" gbCandidate "< EmulationObserverBase::findGenMuon(const edm::Event& event) { + std::vector muons; + + if (edmCfg.exists("genParticleTag") == false) + return muons; + + edm::Handle genParticles; + + event.getByLabel(edmCfg.getParameter("genParticleTag"), genParticles); + + //todo + float etaCutFrom = 0.8; + float etaCutTo = 1.24; + + for (size_t i = 0; i < genParticles->size(); ++i) { + const reco::GenParticle& genPart = (*genParticles)[i]; + + if (std::abs(genPart.pdgId()) == 13) { + if (std::abs(genPart.momentum().eta()) >= etaCutFrom && std::abs(genPart.momentum().eta()) <= etaCutTo) { + genPart.momentum().eta(); + + muons.push_back(&genPart); + //int id = p.pdgId(); + LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " genParticle: pdgId " << genPart.pdgId() + << " px " << genPart.px() << " py " << genPart.py() << " pz " << genPart.pz() + << " pt " << genPart.pt() << " vx " << genPart.vx() << " vy " << genPart.vy() + << " vz " << genPart.vz() << " eta " << genPart.momentum().eta() << endl; + + LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " genParticle: pdgId " << genPart.pdgId() + << " px " << genPart.px() / genPart.p() << " py " << genPart.py() / genPart.p() + << " pz " << genPart.pz() / genPart.p() << " pt " << genPart.pt() << endl; + //<<" vx "<processorCnt()), algoMuonsInProcs(omtfConfig->processorCnt()), gbCandidatesInProcs(omtfConfig->processorCnt()) { - //LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" omtfConfig->nProcessors() "<nProcessors()<("simTracksTag"); else edm::LogImportant("OMTFReconstruction") << "EventCapture::EventCapture: no InputTag simTracksTag found" << std::endl; - if (this->candidateSimMuonMatcher) + //stubsSimHitsMatcher works only with the trackingParticle, because only them are stored in the pilup events + if (this->candidateSimMuonMatcher && edmCfg.exists("trackingParticleTag")) stubsSimHitsMatcher = std::make_unique(edmCfg, omtfConfig, muonGeometryTokens); } @@ -58,7 +58,7 @@ void EventCapture::observeEventBegin(const edm::Event& event) { event.getByLabel(simTracksTag, simTraksHandle); for (unsigned int iSimTrack = 0; iSimTrack != simTraksHandle->size(); iSimTrack++) { - if (abs((*simTraksHandle.product())[iSimTrack].type()) == 13) + if (std::abs((*simTraksHandle.product())[iSimTrack].type()) == 13) simMuons.emplace_back(simTraksHandle, iSimTrack); } } @@ -96,13 +96,12 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, if (candidateSimMuonMatcher) { std::vector matchingResults = candidateSimMuonMatcher->getMatchingResults(); - edm::LogVerbatim("l1tOmtfEventPrint") << "matchingResults.size() " << matchingResults.size() << std::endl; + LogTrace("l1tOmtfEventPrint") << "matchingResults.size() " << matchingResults.size() << std::endl; //candidateSimMuonMatcher should use the trackingParticles, because the simTracks are not stored for the pile-up events for (auto& matchingResult : matchingResults) { //TODO choose a condition, to print the desired candidates - if (matchingResult.muonCand && matchingResult.muonCand->hwQual() >= 12 && - matchingResult.muonCand->hwPt() > 38) { //&& matchingResult.genPt < 20 + if (matchingResult.muonCand) { dump = true; bool runStubsSimHitsMatcher = false; @@ -113,18 +112,25 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, << std::setw(9) << trackingParticle->pt() //<<" Beta "<momentum().Beta() << " eta " << std::setw(9) << trackingParticle->momentum().eta() << " phi " << std::setw(9) << trackingParticle->momentum().phi() << std::endl; + } else if (matchingResult.simTrack) { + runStubsSimHitsMatcher = true; + ostr << "SimMuon: eventId " << matchingResult.simTrack->eventId().event() << " pdgId " << std::setw(3) + << matchingResult.simTrack->type() << " pt " << std::setw(9) + << matchingResult.simTrack->momentum().pt() //<<" Beta "<momentum().Beta() + << " eta " << std::setw(9) << matchingResult.simTrack->momentum().eta() << " phi " << std::setw(9) + << matchingResult.simTrack->momentum().phi() << std::endl; } else { ostr << "no simMuon "; runStubsSimHitsMatcher = true; } ostr << "matched to: " << std::endl; auto finalCandidate = matchingResult.muonCand; - ostr << " hwPt " << finalCandidate->hwPt() << " hwSign " << finalCandidate->hwSign() << " hwQual " - << finalCandidate->hwQual() << " hwEta " << std::setw(4) << finalCandidate->hwEta() << std::setw(4) - << " hwPhi " << finalCandidate->hwPhi() << " eta " << std::setw(9) - << (finalCandidate->hwEta() * 0.010875) << " phi " << std::endl; + ostr << " hwPt " << finalCandidate->hwPt() << " hwUPt " << finalCandidate->hwPtUnconstrained() << " hwSign " + << finalCandidate->hwSign() << " hwQual " << finalCandidate->hwQual() << " hwEta " << std::setw(4) + << finalCandidate->hwEta() << std::setw(4) << " hwPhi " << finalCandidate->hwPhi() << " eta " + << std::setw(9) << (finalCandidate->hwEta() * 0.010875) << " phi " << std::endl; - if (runStubsSimHitsMatcher) + if (stubsSimHitsMatcher && runStubsSimHitsMatcher) stubsSimHitsMatcher->match(iEvent, matchingResult.muonCand, matchingResult.procMuon, ostr); } } @@ -134,8 +140,8 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, bool wasSimMuInOmtfNeg = false; for (auto& simMuon : simMuons) { //TODO choose a condition, to print the desired events - if (simMuon->eventId().event() == 0 && abs(simMuon->momentum().eta()) > 0.82 && - abs(simMuon->momentum().eta()) < 1.24 && simMuon->momentum().pt() >= 3.) { + if (simMuon->eventId().event() == 0 && std::abs(simMuon->momentum().eta()) > 0.82 && + std::abs(simMuon->momentum().eta()) < 1.24 && simMuon->momentum().pt() >= 3.) { ostr << "SimMuon: eventId " << simMuon->eventId().event() << " pdgId " << std::setw(3) << simMuon->type() << " pt " << std::setw(9) << simMuon->momentum().pt() //<<" Beta "<momentum().Beta() << " eta " << std::setw(9) << simMuon->momentum().eta() << " phi " << std::setw(9) @@ -208,11 +214,12 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, std::bitset<18> layerHitBits(layerHits); edm::LogVerbatim("l1tOmtfEventPrint") - << " bx " << bx << " hwPt " << finalCandidate.hwPt() << " hwSign " << finalCandidate.hwSign() << " hwQual " - << finalCandidate.hwQual() << " hwEta " << std::setw(4) << finalCandidate.hwEta() << std::setw(4) << " hwPhi " - << finalCandidate.hwPhi() << " eta " << std::setw(9) << (finalCandidate.hwEta() * 0.010875) << " phi " - << std::setw(9) << globalPhi << " " << layerHitBits << " processor " - << OmtfName(finalCandidate.processor(), finalCandidate.trackFinderType()) << std::endl; + << " bx " << bx << " hwPt " << finalCandidate.hwPt() << " hwUPt " << finalCandidate.hwPtUnconstrained() + << " hwSign " << finalCandidate.hwSign() << " hwQual " << finalCandidate.hwQual() << " hwEta " << std::setw(4) + << finalCandidate.hwEta() << std::setw(4) << " hwPhi " << finalCandidate.hwPhi() << " eta " << std::setw(9) + << (finalCandidate.hwEta() * 0.010875) << " phi " << std::setw(9) << globalPhi << " " << layerHitBits + << " processor " << OmtfName(finalCandidate.processor(), finalCandidate.trackFinderType(), omtfConfig) + << std::endl; for (auto& trackAddr : finalCandidate.trackAddress()) { if (trackAddr.first >= 10) @@ -225,7 +232,7 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, edm::LogVerbatim("l1tOmtfEventPrint") << std::endl; for (unsigned int iProc = 0; iProc < inputInProcs.size(); iProc++) { - OmtfName board(iProc); + OmtfName board(iProc, omtfConfig); std::ostringstream ostrInput; if (inputInProcs[iProc]) { @@ -238,7 +245,7 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, layerFired = true; auto globalPhiRad = omtfConfig->procHwPhiToGlobalPhi( - stub->phiHw, OMTFinputMaker::getProcessorPhiZero(omtfConfig, iProc % 6)); + stub->phiHw, OMTFinputMaker::getProcessorPhiZero(omtfConfig, iProc % omtfConfig->nProcessors())); ostrInput << (*stub) << " globalPhiRad " << globalPhiRad << std::endl; } if (layerFired) @@ -263,7 +270,11 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, if (algoMuon->isValid()) { edm::LogVerbatim("l1tOmtfEventPrint") << board.name() << " " << *algoMuon << " RefHitNum " << algoMuon->getRefHitNumber() << std::endl; - edm::LogVerbatim("l1tOmtfEventPrint") << algoMuon->getGpResult() << std::endl; + edm::LogVerbatim("l1tOmtfEventPrint") << algoMuon->getGpResultConstr(); + if (algoMuon->getGpResultUnconstr().isValid()) + edm::LogVerbatim("l1tOmtfEventPrint") + << "GpResultUnconstr " << algoMuon->getGoldenPaternUnconstr()->key() << "\n" + << algoMuon->getGpResultUnconstr() << std::endl; if (goldenPatterns) //watch out with the golden patterns for (auto& gp : *goldenPatterns) { @@ -287,6 +298,111 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, if (gbCandidate->isValid()) edm::LogVerbatim("l1tOmtfEventPrint") << board.name() << " " << *gbCandidate << std::endl; + { + edm::LogVerbatim("l1tOmtfEventPrint") << std::endl << std::endl << "\ngb_test " << board.name() << std::endl; + for (auto& algoMuon : algoMuonsInProcs[iProc]) { + edm::LogVerbatim("l1tOmtfEventPrint") + << " (" << std::setw(5) << algoMuon->getHwPatternNumConstr() << "," << std::setw(5) + << algoMuon->getHwPatternNumUnconstr() << "," + + << std::setw(5) << algoMuon->getGpResultConstr().getFiredLayerCnt() << "," << std::setw(5) + << algoMuon->getGpResultUnconstr().getFiredLayerCnt() + << "," + + //in the FW there is LSB added for some reason, therefore we multiply by 2 here + << std::setw(6) << algoMuon->getGpResultConstr().getFiredLayerBits() * 2 << "," << std::setw(6) + << algoMuon->getGpResultUnconstr().getFiredLayerBits() * 2 << "," + + << std::setw(5) << algoMuon->getGpResultConstr().getPdfSum() << "," << std::setw(5) + << algoMuon->getGpResultUnconstr().getPdfSumUnconstr() << "," + + << std::setw(5) << algoMuon->getGpResultConstr().getPhi() << "," << std::setw(5) + << algoMuon->getGpResultUnconstr().getPhi() + << "," + + //<getEtaHw()))<<", " + << std::setw(5) << algoMuon->getEtaHw() + << ", " + + //<getRefToLogicNumber()[algoMuon->getRefLayer()]<<"" + << std::setw(5) << algoMuon->getRefLayer() << "" + + << "), " << std::endl; + } + edm::LogVerbatim("l1tOmtfEventPrint") << "\ngbCandidates" << std::endl; + for (auto& gbCandidate : gbCandidatesInProcs[iProc]) + edm::LogVerbatim("l1tOmtfEventPrint") + << " (" << std::setw(5) << gbCandidate->getPtConstr() << "," << std::setw(5) + << gbCandidate->getPtUnconstr() << "," + + << std::setw(5) << gbCandidate->getGpResultConstr().getFiredLayerCnt() << "," << std::setw(5) + << gbCandidate->getGpResultUnconstr().getFiredLayerCnt() + << "," + + //in the FW there is LSB added for some reason, therefore we multiply by 2 here + << std::setw(6) << gbCandidate->getGpResultConstr().getFiredLayerBits() * 2 << "," << std::setw(6) + << gbCandidate->getGpResultUnconstr().getFiredLayerBits() * 2 << "," + + << std::setw(5) << gbCandidate->getGpResultConstr().getPdfSum() << "," << std::setw(5) + << gbCandidate->getGpResultUnconstr().getPdfSumUnconstr() << "," + + << std::setw(5) << gbCandidate->getGpResultConstr().getPhi() << "," << std::setw(5) + << gbCandidate->getGpResultUnconstr().getPhi() + << "," + + //<getEtaHw()))<<", " + << std::setw(5) << gbCandidate->getEtaHw() + << ", " + + //<getRefToLogicNumber()[gbCandidate->getRefLayer()]<<"" + << std::setw(5) << gbCandidate->getRefLayer() << "" + + << "), " + << " -- getFiredLayerBits " << std::setw(5) << gbCandidate->getGpResultConstr().getFiredLayerBits() + << std::endl; + + edm::LogVerbatim("l1tOmtfEventPrint") << "finalCandidates " << std::endl; + + std::ostringstream ostr; + if (finalCandidates->size(0) > 0) { + int iMu = 1; + for (auto finalCandidateIt = finalCandidates->begin(0); finalCandidateIt != finalCandidates->end(0); + finalCandidateIt++) { + auto& finalCandidate = *finalCandidateIt; + + auto omtfName = OmtfName(finalCandidate.processor(), finalCandidate.trackFinderType(), omtfConfig); + + if (omtfName == board.name()) { + int layerHits = (int)finalCandidate.trackAddress().at(0); + std::bitset<18> layerHitBits(layerHits); + + unsigned int trackAddr = finalCandidate.trackAddress().at(0); + unsigned int uPt = finalCandidate.hwPtUnconstrained(); + //if(uPt == 0) uPt = 5; //TODO remove when fixed in the FW + trackAddr = (uPt << 18) + trackAddr; + + ostr << "M" << iMu << ":" << std::setw(4) << finalCandidate.hwPt() << "," << std::setw(4) + << finalCandidate.hwQual() << "," << std::setw(4) << finalCandidate.hwPhi() << "," << std::setw(4) + << std::abs(finalCandidate.hwEta()) + << "," + //<nLayers();++iLogicLayer){ - for(unsigned int iInput=0;iInput<14;++iInput){ + for(unsigned int iInput=0;iInputnInputs();++iInput){ bool isHit = aInput.getLayerData(iLogicLayer)[iInput]<(int)myOmtfConfig->nPhiBins(); myOmtfConfig->getMeasurements4D()[iProcessor][iRegion][iLogicLayer][iInput]+=isHit; } @@ -122,7 +122,7 @@ void OMTFConfigMaker::printConnections(std::ostream& out, unsigned int iProcesso out<<"Measurement hits"<nLayers();++iLogicLayer){ out<<"Logic layer: "<nInputs();++iInput){ out<getMeasurements4D()[iProcessor][iRegion][iLogicLayer][iInput]<<"\t"; } out<& gps) - : PatternOptimizerBase(edmCfg, omtfConfig, gps), eventCntPerGp(gps.size(), 0) { + GoldenPatternVec& gps, + CandidateSimMuonMatcher* candidateSimMuonMatcher) + : PatternOptimizerBase(edmCfg, omtfConfig, gps), + updateStatFunction([this]() { updateStat(); }), + candidateSimMuonMatcher(candidateSimMuonMatcher), + eventCntPerGp(gps.size(), 0) { edm::LogImportant("l1tOmtfEventPrint") << "constructing PatternGenerator, type: " << edmCfg.getParameter("patternGenerator") << std::endl; - if (edmCfg.getParameter("patternGenerator") == "patternGen") + if (edmCfg.getParameter("patternGenerator") == "patternGen" || + edmCfg.getParameter("patternGenerator") == "2DHists" || + edmCfg.getParameter("patternGenerator") == "deltaPhiVsPhiRef") initPatternGen(); + + //2DHists are done for the displaced muons, then using the propagation for the matching is needed + if (edmCfg.getParameter("patternGenerator") == "2DHists" || + edmCfg.getParameter("patternGenerator") == "deltaPhiVsPhiRef") + updateStatFunction = [this]() { updateStatUsingMatcher2(); }; + + if (edmCfg.exists("simTracksTag") == false) + throw cms::Exception("PatternGenerator::PatternGenerator(): no simTracksTag !!!!!!!!!!!!!!!!!"); + + if (!candidateSimMuonMatcher) { + edm::LogImportant("l1tOmtfEventPrint") << "PatternGenerator: candidateSimMuonMatcher is null!!!!!!" << std::endl; + } } PatternGenerator::~PatternGenerator() {} @@ -37,16 +55,33 @@ void PatternGenerator::initPatternGen() { gp->reset(); - int statBinsCnt = 1024; //gp->getPdf()[0][0].size() * 8; //TODO should be big enough to comprise the pdf tails - gp->iniStatisitics(statBinsCnt, 1); //TODO + //1024 x 2048 is the maximum size that fits into 64GB of memory!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + int statBinsCnt1 = 1024 * 2; //TODO should be big enough to comprise the pdf tails + + int statBinsCnt2 = 1; //for normal pattern generation + + if (edmCfg.getParameter("patternGenerator") == "2DHists") + statBinsCnt2 = 1024 * 2; + //for 2D distribution, phiB vs phiDist, but if done for 8 ref layers, consumes too much memory + else if (edmCfg.getParameter("patternGenerator") == "deltaPhiVsPhiRef") + statBinsCnt2 = omtfConfig->nPhiBins() / omtfConfig->nProcessors(); + //for 2D distribution, phiB vs phiDist, but if done for 8 ref layers, consumes too much memory + //if(statBinsCnt2 > 10 && omtfConfig->nRefLayers() > 2) + // throw cms::Exception("PatternGenerator::initPatternGen(): statBinsCnt2 and omtfConfig->nRefLayers() too big, will consume too much memory"); + + gp->iniStatisitics(statBinsCnt1, statBinsCnt2); + + if (statBinsCnt2 < 10 && sizeof(gp->getStatistics()[0][0][0][0]) < 4) { + edm::LogImportant("l1tOmtfEventPrint") + << "PatternGenerator::initPatternGen():" << __LINE__ << "sizeof gp statistics " + << sizeof(gp->getStatistics()[0][0][0][0]) << std::endl; + throw cms::Exception("PatternGenerator::initPatternGen(): getStatistics type is short!!!!"); + } } edm::LogImportant("l1tOmtfEventPrint") << "PatternGenerator::initPatternGen():" << __LINE__ << " goldenPatterns.size() " << goldenPatterns.size() << std::endl; - //GoldenPatternResult::setFinalizeFunction(3); TODO why it was this one???? - // edm::LogImportant("l1tOmtfEventPrint") << "reseting golden pattern !!!!!" << std::endl; - //setting all pdf to 1, this will cause that when the OmtfProcessor process the input, the result will be based only on the number of fired layers, //and then the omtfCand will come from the processor that has the biggest number of fired layers //however, if the GoldenPatternResult::finalise3() is used - which just count the number of muonStubs (but do not check if it is valid, i.e. fired the pdf) @@ -87,14 +122,6 @@ void PatternGenerator::initPatternGen() { ptDeltaPhiHists[iCharge].push_back(nullptr); } }*/ - - /* cannot be called here, will cause crash - edm::LogImportant("OMTFReconstruction")<<" PatternGenerator constructor - patterns after modification "<key()<<" " - <getPatternPtRange(gp->key().theNumber).ptFrom - <<" - "<getPatternPtRange(gp->key().theNumber).ptTo<<" GeV"< matchingResults = candidateSimMuonMatcher->getMatchingResults(); + LogTrace("l1tOmtfEventPrint") << "matchingResults.size() " << matchingResults.size() << std::endl; + + //candidateSimMuonMatcher should use the trackingParticles, because the simTracks are not stored for the pile-up events + for (auto& matchingResult : matchingResults) { + if (matchingResult.muonCand && matchingResult.simTrack) { + //&& matchingResult.muonCand->hwQual() >= 12 && + //matchingResult.muonCand->hwPt() > 38 + + AlgoMuon* algoMuon = matchingResult.procMuon.get(); + if (!algoMuon) { + edm::LogImportant("l1tOmtfEventPrint") << ":" << __LINE__ << " algoMuon is null" << std::endl; + throw runtime_error("algoMuon is null"); + } + + double ptSim = matchingResult.simTrack->momentum().pt(); + int chargeSim = (abs(matchingResult.simTrack->type()) == 13) ? matchingResult.simTrack->type() / -13 : 0; + + double muDxy = (-1 * matchingResult.simVertex->position().x() * matchingResult.simTrack->momentum().py() + + matchingResult.simVertex->position().y() * matchingResult.simTrack->momentum().px()) / + matchingResult.simTrack->momentum().pt(); + + simMuPtVsDispl->Fill(matchingResult.simTrack->momentum().pt(), muDxy); + simMuPtVsRho->Fill(matchingResult.simTrack->momentum().pt(), matchingResult.simVertex->position().rho()); + + unsigned int exptPatNum = omtfConfig->getPatternNum(ptSim, chargeSim); + GoldenPatternWithStat* exptCandGp = goldenPatterns.at(exptPatNum).get(); // expected pattern + + eventCntPerGp[exptPatNum]++; + + candProcIndx = + omtfConfig->getProcIndx(matchingResult.muonCand->processor(), matchingResult.muonCand->trackFinderType()); + + //edm::LogImportant("l1tOmtfEventPrint")<<"\n" <<__FUNCTION__<<": "<<__LINE__<<" exptCandGp "<key()<<" candProcIndx "<nPdfAddrBits() - 1); + LogTrace("l1tOmtfEventPrint") << "updateStatUsingMatcher2 " << __LINE__ << std::endl; + //iRefHit is the index of the hit + for (unsigned int iRefHit = 0; iRefHit < exptCandGp->getResults()[candProcIndx].size(); ++iRefHit) { + auto& gpResult = exptCandGp->getResults()[candProcIndx][iRefHit]; + + if (gpResult.getFiredLayerCnt() >= 3) { + int refLayer = gpResult.getRefLayer(); + + if (refLayer < 0 || !gpResult.isValid()) + LogTrace("l1tOmtfEventPrint") << "updateStatUsingMatcher2 " << __LINE__ << " refLayer " << refLayer + << " gpResult.isValid() " << gpResult.isValid() << std::endl; + + int refLayerLogicNumber = omtfConfig->getRefToLogicNumber()[refLayer]; + + LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " updating statistic: candProcIndx " + << candProcIndx << " iRefHit " << iRefHit << " refLayer " << refLayer + << " exptPatNum " << exptPatNum << " ptSim " << ptSim << " chargeSim " + << chargeSim << " muDxy " << muDxy << " muRho " + << matchingResult.simVertex->position().rho() << " x " + << matchingResult.simVertex->position().x() << " y " + << matchingResult.simVertex->position().y() << " z " + << matchingResult.simVertex->position().z() << std::endl; + + int refPhiB = 0; + + if (omtfConfig->isBendingLayer(refLayerLogicNumber + 1)) + //if(refLayerLogicNumber < 5) + refPhiB = gpResult.getStubResults()[refLayerLogicNumber].getMuonStub()->phiBHw; + + int refPhiBShifted = refPhiB + exptCandGp->getStatistics()[0][refLayer][0].size() / 2; + + if (edmCfg.getParameter("patternGenerator") == "deltaPhiVsPhiRef") { + refPhiBShifted = gpResult.getStubResults()[refLayerLogicNumber].getMuonStub()->phiHw; + } + + if (refPhiBShifted < 0 || refPhiBShifted >= (int)exptCandGp->getStatistics()[0][refLayer][0].size()) { + edm::LogImportant("l1tOmtfEventPrint") << "\n" + << __FUNCTION__ << ": " << __LINE__ << " wrong refPhiB " << refPhiB + << " refPhiBShifted " << refPhiBShifted; + continue; + } + + for (unsigned int iLayer = 0; iLayer < gpResult.getStubResults().size(); iLayer++) { + //updating statistic for the gp which should have fired + + bool fired = false; + if (gpResult.getStubResults()[iLayer].getMuonStub()) { + fired = true; + } + + if (fired) { //the result is not empty + int meanDistPhi = 0; //exptCandGp->meanDistPhiValue(iLayer, refLayer, refPhiB); //should be 0 here + + int phiDist = gpResult.getStubResults()[iLayer].getPdfBin() + meanDistPhi - pdfMiddle; + //removing the shift applied in the GoldenPatternBase::process1Layer1RefLayer + + int lutMiddle = exptCandGp->getStatistics()[iLayer][refLayer].size() / 2; + + LogTrace("l1tOmtfEventPrint") + << __FUNCTION__ << ":" << __LINE__ << " refLayer " << refLayer << " iLayer " << iLayer << " phiDist " + << phiDist << " getPdfBin " << gpResult.getStubResults()[iLayer].getPdfBin() << " phiMean " + << meanDistPhi << " refPhiB " << refPhiB << std::endl; + + //updating statistic for the gp which found the candidate + //edm::LogImportant("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" updating statistic "< 0 && phiDistCorr < (int)(exptCandGp->getStatistics()[iLayer][refLayer].size())) { + LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " phiDistCorr " + << phiDistCorr + //<< " phiDistCorr + lutMiddle "<< phiDistCorr + lutMiddle + << " refPhiBShifted " << refPhiBShifted << std::endl; + exptCandGp->updateStat(iLayer, refLayer, phiDistCorr, refPhiBShifted, 1); + } + } else { //if there is no hit at all in a given layer, the bin = 0 is filled + int phiDist = 0; + exptCandGp->updateStat(iLayer, refLayer, phiDist, refPhiBShifted, 1); + } + } + } + } + } + } +} + void PatternGenerator::observeEventEnd(const edm::Event& iEvent, std::unique_ptr& finalCandidates) { if (simMuon == nullptr || omtfCand->getGoldenPatern() == nullptr) //no sim muon or empty candidate @@ -176,7 +328,9 @@ void PatternGenerator::observeEventEnd(const edm::Event& iEvent, PatternOptimizerBase::observeEventEnd(iEvent, finalCandidates); - updateStat(); + //updateStat(); + //updateStatUsingMatcher2(); + updateStatFunction(); } void PatternGenerator::endJob() { @@ -187,6 +341,12 @@ void PatternGenerator::endJob() { else if (edmCfg.getParameter("patternGenerator") == "patternGen") { upadatePdfs(); writeLayerStat = true; + } else if (edmCfg.getParameter("patternGenerator") == "2DHists") { + upadatePdfs(); + writeLayerStat = true; + } else if (edmCfg.getParameter("patternGenerator") == "deltaPhiVsPhiRef") { + upadatePdfs(); + writeLayerStat = true; } else if (edmCfg.getParameter("patternGenerator") == "patternGenFromStat") { std::string rootFileName = edmCfg.getParameter("patternsROOTFile").fullPath(); edm::LogImportant("l1tOmtfEventPrint") << "PatternGenerator::endJob() rootFileName " << rootFileName << std::endl; @@ -198,9 +358,6 @@ void PatternGenerator::endJob() { if (gp->key().thePt == 0) continue; - int statBinsCnt = 1024; //= gp->getPdf()[0][0].size() * 8; //TODO should be big enough to comprise the pdf tails - gp->iniStatisitics(statBinsCnt, 1); //TODO - for (unsigned int iLayer = 0; iLayer < gp->getPdf().size(); ++iLayer) { for (unsigned int iRefLayer = 0; iRefLayer < gp->getPdf()[iLayer].size(); ++iRefLayer) { ostrName.str(""); @@ -210,6 +367,14 @@ void PatternGenerator::endJob() { TH1I* histLayerStat = (TH1I*)curDir->Get(ostrName.str().c_str()); if (histLayerStat) { + int statBinsCnt = 1024 * 2; + if ((int)(gp->getStatistics()[iLayer][iRefLayer].size()) != histLayerStat->GetNbinsX()) { + statBinsCnt = histLayerStat->GetNbinsX(); + gp->iniStatisitics(statBinsCnt, 1); //TODO + edm::LogImportant("l1tOmtfEventPrint") + << "PatternGenerator::endJob() - " << ostrName.str() << "statBinsCnt = " << statBinsCnt << std::endl; + } + for (int iBin = 0; iBin < statBinsCnt; iBin++) { gp->updateStat(iLayer, iRefLayer, iBin, 0, histLayerStat->GetBinContent(iBin + 1)); } @@ -278,26 +443,24 @@ void PatternGenerator::upadatePdfs() { "gp->getDistPhiBitShift(iLayer, iRefLayer) != 0 - cannot change DistPhiBitShift then!!!!"); } - if ((gp->key().thePt <= 10) && (iLayer == 1 || iLayer == 3 || iLayer == 5)) { - gp->setDistPhiBitShift(1, iLayer, iRefLayer); - } else - gp->setDistPhiBitShift(0, iLayer, iRefLayer); - - //watch out: the shift in a given layer must be the same for patterns in one group - //todo make the setting of the shift on the group base - //TODO set the DistPhiBitShift - /*if( (gp->key().thePt <= 10) && (iLayer == 3 || iLayer == 5 ) && (iRefLayer == 0 || iRefLayer == 2 || iRefLayer == 6 || iRefLayer == 7)) { - gp->setDistPhiBitShift(3, iLayer, iRefLayer); - } - else if( (gp->key().thePt <= 10) && ( iLayer == 1 || iLayer == 3 || iLayer == 5 ) ) { + //watch out - the pt here is the hardware pt before the recalibration + //the shift for given pattern and layer should be the same same for all refLayers + //otherwise the firmware does not compile - at least the phase-1 + if ((gp->key().thePt <= 10) && + (iLayer == 1 || iLayer == 3 || iLayer == 5)) { //iRefLayer: MB2, iLayer: MB1 and MB2 phiB gp->setDistPhiBitShift(2, iLayer, iRefLayer); - } - else if( ( (gp->key().thePt <= 10) && (iLayer == 7 ||iLayer == 8 || iLayer == 17 ) ) ) { + } else if ((gp->key().thePt <= 10) && (iLayer == 10)) { //iRefLayer: MB2, iLayer: RB1_in gp->setDistPhiBitShift(1, iLayer, iRefLayer); - } - else if( (gp->key().thePt <= 10) && (iLayer == 10 || iLayer == 11 || iLayer == 12 || iLayer == 13) && (iRefLayer == 1)) { + } else if ((gp->key().thePt >= 11 && gp->key().thePt <= 17) && (iLayer == 1)) { //MB1 phiB + //due to grouping the patterns 4-7, the pdfs for the layer 1 in the pattern go outside of the range + //so the shift must be increased (or the group should be divided into to 2 groups, but it will increase fw occupancy + gp->setDistPhiBitShift(2, iLayer, iRefLayer); + } else if ((gp->key().thePt >= 11 && gp->key().thePt <= 17) && (iLayer == 3 || iLayer == 5)) { //MB1 phiB + //due to grouping the patterns 4-7, the pdfs for the layer 1 in the pattern go outside of the range + //so the shift must be increased (or the group should be divided into to 2 groups, but it will increase fw occupancy gp->setDistPhiBitShift(1, iLayer, iRefLayer); - }*/ + } else + gp->setDistPhiBitShift(0, iLayer, iRefLayer); } } } @@ -360,16 +523,39 @@ void PatternGenerator::upadatePdfs() { for (unsigned int iGroup = 0; iGroup < patternGroups.size(); iGroup++) { double meanDistPhi = 0; int mergedCnt = 0; + double norm = 0; for (unsigned int i = 0; i < patternGroups[iGroup].size(); i++) { auto gp = goldenPatterns.at(patternGroups[iGroup][i]).get(); - meanDistPhi += gp->meanDistPhiValue(iLayer, iRefLayer); - if (gp->meanDistPhiValue(iLayer, iRefLayer) != 0) + if (gp->meanDistPhiValue(iLayer, iRefLayer) != 0) { + double weight = 1. / gp->key().thePt; + meanDistPhi += weight * gp->meanDistPhiValue(iLayer, iRefLayer); mergedCnt++; + norm += weight; + } } if (mergedCnt) { - meanDistPhi /= mergedCnt; - //because for some gps the statistics can be too low, and then the meanDistPhiValue is 0, so it should not contribute + //because for some gps the statistics can be too low, and then the meanDistPhiValue is 0, so it should not contribute to meanDistPhi, therefore it is divide by mergedCnt + //meanDistPhi /= mergedCnt; + ///weighted average, weight is 1/pt + //for low pT patterns it shifts the pdf of the pattern with bigger width (i.e. lower pt) towards the center of LUT + //then higher value of shift can be avoided (sometimes). So this is just a simple trick + meanDistPhi /= norm; + + //setting the meanDistPhi to 0 if it is already small - this should save logic in FPGA + if (iLayer == 2) { + //the meanDistPhi for the iLayer == 2 i.e. MB2 is used to calculate the algoMuon output phi + //therefore it is not zero-ed, as it will affect this output phi, phi and thus e.g. ghostbusting + } else if (abs(round(meanDistPhi)) <= 3) + meanDistPhi = 0; + else if (goldenPatterns.at(patternGroups[iGroup][0]).get()->key().thePt >= 13) { + //RPC layers, one strip is 4.7 units, the minimal possinle spacing between two RPC hits is 2 strips + if (iLayer >= 10 && abs(round(meanDistPhi)) <= 8) + meanDistPhi = 0; + else if (abs(round(meanDistPhi)) <= 5) + meanDistPhi = 0; + } + for (unsigned int i = 0; i < patternGroups[iGroup].size(); i++) { auto gp = goldenPatterns.at(patternGroups[iGroup][i]).get(); gp->setMeanDistPhiValue(round(meanDistPhi), iLayer, iRefLayer); @@ -414,17 +600,12 @@ void PatternGenerator::upadatePdfs() { if (iBinStat >= 0 && iBinStat < (int)gp->getStatistics()[iLayer][iRefLayer].size()) { pdfVal += gp->getStatistics()[iLayer][iRefLayer][iBinStat][0]; - //cout<<__FUNCTION__<<": "<<__LINE__<<" "<key()<<" iLayer "<getStatistics()[iLayer][iRefLayer][iBinStat][0]< minHitCnt) { pdfVal /= (norm * statBinGroupSize); } else pdfVal = 0; - /*edm::LogImportant("l1tOmtfEventPrint") - << __FUNCTION__ << ": " << __LINE__ << " " << gp->key() << "calculating pdf: iLayer " << iLayer - << " iRefLayer " << iRefLayer //<< " norm " << std::setw(5) << norm - << " pdfVal " << pdfVal << endl;*/ } else { //iBinPdf == 0 i.e. no hit int iBinStat = 0; if (norm > 0) { @@ -446,7 +627,6 @@ void PatternGenerator::upadatePdfs() { } gp->setPdfValue(digitisedVal, iLayer, iRefLayer, iBinPdf); - //cout<<__FUNCTION__<<": "<<__LINE__<<" "<key()<<" iLayer "< #include @@ -73,6 +75,9 @@ PatternOptimizerBase::PatternOptimizerBase(const edm::ParameterSet& edmCfg, simMuPtSpectrum = new TH1F("simMuPtSpectrum", "simMuPtSpectrum", 800, 0, 400); + simMuPtVsDispl = new TH2I("simMuPtVsDispl", "simMuPtVsDispl;pt [GeV];dxy [cm]", 100, 0, 400, 100, 0, 400); + simMuPtVsRho = new TH2I("simMuPtVsRho", "simMuPtVsRho;pt [GeV];rho [cm]", 100, 0, 400, 100, 0, 400); + if (edmCfg.exists("simTracksTag") == false) edm::LogError("l1tOmtfEventPrint") << "simTracksTag not found !!!" << std::endl; } @@ -103,7 +108,9 @@ void PatternOptimizerBase::observeEventEnd(const edm::Event& iEvent, return; double ptSim = simMuon->momentum().pt(); - int chargeSim = (abs(simMuon->type()) == 13) ? simMuon->type() / -13 : 0; + int chargeSim = (std::abs(simMuon->type()) == 13) ? simMuon->type() / -13 : 0; + + //double muDxy = (-1 * genMuon->vx() * genMuon->py() + genMuon->vy() * genMuon->px()) / genMuon->pt();; unsigned int exptPatNum = omtfConfig->getPatternNum(ptSim, chargeSim); GoldenPatternWithStat* exptCandGp = goldenPatterns.at(exptPatNum).get(); // expected pattern @@ -133,9 +140,12 @@ void PatternOptimizerBase::savePatternsInRoot(std::string rootFileName) { simMuFoundByOmtfPt->Write(); simMuPtSpectrum->Write(); + simMuPtVsDispl->Write(); + simMuPtVsRho->Write(); outfile.mkdir("patternsPdfs")->cd(); outfile.mkdir("patternsPdfs/canvases"); + outfile.mkdir("patternsPdfs/canvases2"); outfile.mkdir("layerStats"); ostringstream ostrName; ostringstream ostrTtle; @@ -156,6 +166,64 @@ void PatternOptimizerBase::savePatternsInRoot(std::string rootFileName) { ostrName.str().c_str(), ostrTtle.str().c_str(), goldenPatterns.size(), -0.5, goldenPatterns.size() - 0.5)); } + auto gpsCnt = goldenPatterns.size(); + auto layerCnt = goldenPatterns[0]->getPdf().size(); + auto refLayerCnt = goldenPatterns[0]->getPdf().size(); + + vector > distPhiLayerRefLayer(layerCnt, vector(refLayerCnt, nullptr)); + vector > meanDistPhiLayerRefLayer(layerCnt, vector(refLayerCnt, nullptr)); + vector > pdfsLayerRefLayer(layerCnt, vector(refLayerCnt, nullptr)); + + for (unsigned int iLayer = 0; iLayer < layerCnt; ++iLayer) { + int rangeFactor = 1; + if (iLayer == 1 || iLayer == 3 || iLayer == 5) + rangeFactor = 2; + + for (unsigned int iRefLayer = 0; iRefLayer < refLayerCnt; ++iRefLayer) { + ostrName.str(""); + ostrName << "distPhi_refLayer_" << iRefLayer << "_layer_" << iLayer; + ostrTtle.str(""); + ostrTtle << "distPhi refLayer " << iRefLayer << " layer " << iLayer; + //edm::LogVerbatim("l1tOmtfEventPrint") <<__FUNCTION__<<": "<<__LINE__<<" creating hist "<nPdfBins() * rangeFactor * 2, + (int)(omtfConfig->nPdfBins()) * (-rangeFactor) - 0.5, + omtfConfig->nPdfBins() * rangeFactor - 0.5); + + ostrName.str(""); + ostrName << "meanDistPhi_refLayer_" << iRefLayer << "_Layer_" << iLayer; + ostrTtle.str(""); + ostrTtle << "meanDistPhi refLayer " << iRefLayer << " Layer " << iLayer; + //edm::LogVerbatim("l1tOmtfEventPrint") <<__FUNCTION__<<": "<<__LINE__<<" creating hist "<nPdfBins() * rangeFactor * 2, + (int)(omtfConfig->nPdfBins()) * (-rangeFactor) - 0.5, + omtfConfig->nPdfBins() * rangeFactor - 0.5); + + ostrName.str(""); + ostrName << "pdfs_refLayer_" << iRefLayer << "_layer_" << iLayer; + ostrTtle.str(""); + ostrTtle << "pdfs refLayer " << iRefLayer << " layer " << iLayer; + //edm::LogVerbatim("l1tOmtfEventPrint") <<__FUNCTION__<<": "<<__LINE__<<" creating hist "<nPdfBins(), + -0.5, + omtfConfig->nPdfBins() - 0.5); + } + } + for (auto& gp : goldenPatterns) { OMTFConfiguration::PatternPt patternPt = omtfConfig->getPatternPtRange(gp->key().theNumber); if (gp->key().thePt == 0) @@ -169,8 +237,8 @@ void PatternOptimizerBase::savePatternsInRoot(std::string rootFileName) { TCanvas* canvas = new TCanvas(ostrName.str().c_str(), ostrTtle.str().c_str(), 1200, 1000); canvas->Divide(gp->getPdf().size(), gp->getPdf()[0].size(), 0, 0); - for (unsigned int iLayer = 0; iLayer < gp->getPdf().size(); ++iLayer) { - for (unsigned int iRefLayer = 0; iRefLayer < gp->getPdf()[iLayer].size(); ++iRefLayer) { + for (unsigned int iRefLayer = 0; iRefLayer < gp->getPdf()[0].size(); ++iRefLayer) { + for (unsigned int iLayer = 0; iLayer < gp->getPdf().size(); ++iLayer) { canvas->cd(1 + iLayer + iRefLayer * gp->getPdf().size()); ostrName.str(""); ostrName << "PatNum_" << gp->key().theNumber << "_refLayer_" << iRefLayer << "_Layer_" << iLayer; @@ -182,12 +250,27 @@ void PatternOptimizerBase::savePatternsInRoot(std::string rootFileName) { //edm::LogVerbatim("l1tOmtfEventPrint") <<__FUNCTION__<<": "<<__LINE__<<" creating hist "<nPdfBins(), -0.5, omtfConfig->nPdfBins() - 0.5); + + int pdfMiddle = gp->getPdf()[iLayer][iRefLayer].size() / 2; + int shift = gp->getDistPhiBitShift(iLayer, iRefLayer); + for (unsigned int iPdf = 0; iPdf < gp->getPdf()[iLayer][iRefLayer].size(); iPdf++) { hist->Fill(iPdf, gp->pdfAllRef[iLayer][iRefLayer][iPdf]); + + distPhiLayerRefLayer[iLayer][iRefLayer]->Fill( + gp->key().theNumber, + (((int)iPdf - pdfMiddle) << shift) + gp->meanDistPhi[iLayer][iRefLayer][0], + gp->pdfAllRef[iLayer][iRefLayer][iPdf]); + + pdfsLayerRefLayer[iLayer][iRefLayer]->Fill( + gp->key().theNumber, (int)iPdf, gp->pdfAllRef[iLayer][iRefLayer][iPdf]); } if ((int)iLayer == (omtfConfig->getRefToLogicNumber()[iRefLayer])) hist->SetLineColor(kGreen); + meanDistPhiLayerRefLayer[iLayer][iRefLayer]->Fill( + gp->key().theNumber, gp->meanDistPhi[iLayer][iRefLayer][0], 1); + hist->GetYaxis()->SetRangeUser(0, omtfConfig->pdfMaxValue() + 1); hist->Draw("hist"); @@ -196,15 +279,53 @@ void PatternOptimizerBase::savePatternsInRoot(std::string rootFileName) { /////////////////////// histLayerStat if (writeLayerStat) { - string histName = "histLayerStat_" + ostrName.str(); - unsigned int binCnt = gp->getStatistics()[iLayer][iRefLayer].size(); - TH1I* histLayerStat = new TH1I(histName.c_str(), histName.c_str(), binCnt, -0.5, binCnt - 0.5); - for (unsigned int iBin = 0; iBin < binCnt; iBin++) { - histLayerStat->Fill(iBin, gp->getStatistics()[iLayer][iRefLayer][iBin][0]); - } + bool saveTh2 = false; + if (gp->getStatistics()[iLayer][iRefLayer][0].size() > 1) + saveTh2 = true; outfile.cd("layerStats"); - histLayerStat->Write(); + + string histName = "histLayerStat_" + ostrName.str(); + unsigned int binCnt1 = gp->getStatistics()[iLayer][iRefLayer].size(); + if (!saveTh2) { + TH1I* histLayerStat = new TH1I(histName.c_str(), histName.c_str(), binCnt1, -0.5, binCnt1 - 0.5); + for (unsigned int iBin = 0; iBin < binCnt1; iBin++) { + histLayerStat->Fill(iBin, gp->getStatistics()[iLayer][iRefLayer][iBin][0]); + } + histLayerStat->Write(); + } else { + if (iRefLayer == 0 || iRefLayer == 2) { //TODO!!!!!!!!!!!!!!!!!!!!!!!! + unsigned int binCnt2 = gp->getStatistics()[iLayer][iRefLayer][0].size(); + //TH2I* histLayerStat = new TH2I(histName.c_str(), (histName + ";ref phiB;delta_phi").c_str(), binCnt2, -0.5, binCnt2 - 0.5, binCnt1, -0.5, binCnt1 - 0.5); + double xmin = -0.5 - binCnt2 / 2; + double xmax = binCnt2 / 2 - 0.5; + if (edmCfg.getParameter("patternGenerator") == "deltaPhiVsPhiRef") { + xmin = -0.5; + xmax = binCnt2 - 0.5; + } + TH2I* histLayerStat = new TH2I(histName.c_str(), + (histName + ";ref phiB;delta_phi").c_str(), + binCnt2, + xmin, + xmax, + binCnt1, + -0.5 - binCnt1 / 2, + binCnt1 / 2 - 0.5); + + if (edmCfg.getParameter("patternGenerator") == "deltaPhiVsPhiRef") + histLayerStat->GetXaxis()->SetTitle("ref phi"); + + for (unsigned int iBin1 = 0; iBin1 < binCnt1; iBin1++) { //deltaPhi + for (unsigned int iBin2 = 0; iBin2 < binCnt2; iBin2++) { //phiB + //histLayerStat->Fill(iBin2, iBin1, gp->getStatistics()[iLayer][iRefLayer][iBin1][iBin2]); //looks that using Fill leads to huge memory cosumption + histLayerStat->SetBinContent( + iBin2 + 1, iBin1 + 1, gp->getStatistics()[iLayer][iRefLayer][iBin1][iBin2]); + } + } + histLayerStat->Write(); + histLayerStat->Delete(); + } + } } } } @@ -228,6 +349,52 @@ void PatternOptimizerBase::savePatternsInRoot(std::string rootFileName) { classProbHist->Write(); } + outfile.cd("patternsPdfs/canvases2"); + for (unsigned int iRefLayer = 0; iRefLayer < goldenPatterns[0]->getPdf()[0].size(); ++iRefLayer) { + ostrName.str(""); + ostrName << "distPhiForPatterns_Reflayer_" << iRefLayer; + ostrTtle.str(""); + ostrTtle << "distPhiForPatterns Reflayer " << iRefLayer; + + TCanvas* canvas = new TCanvas(ostrName.str().c_str(), ostrTtle.str().c_str(), 1200, 1000); + canvas->Divide(6, 3, 0, 0); + + for (unsigned int iLayer = 0; iLayer < distPhiLayerRefLayer.size(); ++iLayer) { + canvas->cd(iLayer + 1); + canvas->cd(iLayer + 1)->SetGridx(); + canvas->cd(iLayer + 1)->SetGridy(); + + //distPhiLayerRefLayer[iLayer][iRefLayer]->SetLineColor(kBlack); + distPhiLayerRefLayer[iLayer][iRefLayer]->Draw("colz"); + + meanDistPhiLayerRefLayer[iLayer][iRefLayer]->SetLineColor(kRed); + meanDistPhiLayerRefLayer[iLayer][iRefLayer]->Draw("boxsame"); + + distPhiLayerRefLayer[iLayer][iRefLayer]->Write(); + meanDistPhiLayerRefLayer[iLayer][iRefLayer]->Write(); + pdfsLayerRefLayer[iLayer][iRefLayer]->Write(); + } + + canvas->Write(); + + ostrName.str(""); + ostrName << "pdfsForPatterns_Reflayer_" << iRefLayer; + ostrTtle.str(""); + ostrTtle << "pdfsForPatterns Reflayer " << iRefLayer; + + canvas = new TCanvas(ostrName.str().c_str(), ostrTtle.str().c_str(), 1200, 1000); + canvas->Divide(6, 3, 0, 0); + for (unsigned int iLayer = 0; iLayer < distPhiLayerRefLayer.size(); ++iLayer) { + canvas->cd(iLayer + 1); + canvas->cd(iLayer + 1)->SetGridx(); + canvas->cd(iLayer + 1)->SetGridy(); + + pdfsLayerRefLayer[iLayer][iRefLayer]->Draw("colz"); + } + + canvas->Write(); + } + saveHists(outfile); outfile.Close(); diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc index 574decac17fa5..780cb394ae065 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc @@ -125,13 +125,13 @@ void StubsSimHitsMatcher::match(const edm::Event& iEvent, iEvent.getByLabel(trackingParticleTag, trackingParticleHandle); if (procMuon->isValid() && omtfCand) { - OmtfName board(omtfCand->processor(), omtfCand->trackFinderType()); + OmtfName board(omtfCand->processor(), omtfCand->trackFinderType(), omtfConfig); auto processorPhiZero = OMTFinputMaker::getProcessorPhiZero(omtfConfig, omtfCand->processor()); std::set matchedTrackInfos; ostr << board.name() << " " << *procMuon << std::endl; - auto& gpResult = procMuon->getGpResult(); + auto& gpResult = procMuon->getGpResultConstr(); for (unsigned int iLogicLayer = 0; iLogicLayer < gpResult.getStubResults().size(); ++iLogicLayer) { auto& stub = gpResult.getStubResults()[iLogicLayer].getMuonStub(); if (stub && gpResult.isLayerFired(iLogicLayer)) { @@ -158,7 +158,7 @@ void StubsSimHitsMatcher::match(const edm::Event& iEvent, auto strip = roll->strip(simHit.localPosition()); double simHitStripGlobalPhi = (roll->toGlobal(roll->centreOfStrip((int)strip))).phi(); - if (abs(stubGlobalPhi - simHitStripGlobalPhi) < 0.02) { + if (std::abs(stubGlobalPhi - simHitStripGlobalPhi) < 0.02) { matchedTrackInfos.insert(MatchedTrackInfo(simHit.eventId().event(), simHit.trackId())); } @@ -185,7 +185,7 @@ void StubsSimHitsMatcher::match(const edm::Event& iEvent, auto strip = rpcDigiSimLink.getStrip(); double simHitStripGlobalPhi = (roll->toGlobal(roll->centreOfStrip((int)strip))).phi(); - if (abs(stubGlobalPhi - simHitStripGlobalPhi) < 0.02) { + if (std::abs(stubGlobalPhi - simHitStripGlobalPhi) < 0.02) { auto matchedTrackInfo = matchedTrackInfos.insert( MatchedTrackInfo(rpcDigiSimLink.getEventId().event(), rpcDigiSimLink.getTrackId())); matchedTrackInfo.first->matchedDigiCnt.at(iLogicLayer)++; @@ -250,7 +250,7 @@ void StubsSimHitsMatcher::match(const edm::Event& iEvent, LocalPoint point(wireX, 0, 0); auto digiWireGlobal = layer->toGlobal(point); - if (abs(stubGlobalPhi - digiWireGlobal.phi()) < 0.03) { + if (std::abs(stubGlobalPhi - digiWireGlobal.phi()) < 0.03) { auto matchedTrackInfo = matchedTrackInfos.insert( MatchedTrackInfo(dtDigiSimLink->eventId().event(), dtDigiSimLink->SimTrackId())); matchedTrackInfo.first->matchedDigiCnt.at(iLogicLayer)++; @@ -316,7 +316,7 @@ void StubsSimHitsMatcher::match(const edm::Event& iEvent, auto strip = cscDigiSimLink.channel(); auto digiStripGlobalPhi = layer->centerOfStrip(strip).phi(); - if (abs(stubGlobalPhi - digiStripGlobalPhi) < 0.03) { + if (std::abs(stubGlobalPhi - digiStripGlobalPhi) < 0.03) { auto matchedTrackInfo = matchedTrackInfos.insert( MatchedTrackInfo(cscDigiSimLink.eventId().event(), cscDigiSimLink.SimTrackId())); matchedTrackInfo.first->matchedDigiCnt.at(iLogicLayer)++; @@ -351,7 +351,7 @@ void StubsSimHitsMatcher::match(const edm::Event& iEvent, } ostr << board.name() << " " << *procMuon << std::endl; - ostr << procMuon->getGpResult() << std::endl << std::endl; + ostr << procMuon->getGpResultConstr() << std::endl << std::endl; int maxMatchedStubs = 0; const TrackingParticle* bestMatchedPart = nullptr; diff --git a/L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/runMuonOverlapDataDump.py b/L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/runMuonOverlapDataDump.py index 01ca1a75e5640..a15c35f708e46 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/runMuonOverlapDataDump.py +++ b/L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/runMuonOverlapDataDump.py @@ -187,7 +187,6 @@ process.simOmtfDigis.bxMax = cms.int32(0) process.simOmtfDigis.dumpResultToXML = cms.bool(False) -process.simOmtfDigis.dumpResultToROOT = cms.bool(False) process.simOmtfDigis.dumpHitsToROOT = cms.bool(True) process.simOmtfDigis.dumpHitsFileName = cms.string(dumpHitsFileName + '.root') process.simOmtfDigis.eventCaptureDebug = cms.bool(False) @@ -206,6 +205,9 @@ process.simOmtfDigis.rpcMaxClusterCnt = cms.int32(2) process.simOmtfDigis.rpcDropAllClustersIfMoreThanMax = cms.bool(True) +process.simOmtfDigis.minCSCStubRME12 = cms.int32(410) #[cm] +process.simOmtfDigis.minCSCStubR = cms.int32(490) #[cm] + process.simOmtfDigis.goldenPatternResultFinalizeFunction = cms.int32(5) #valid values are 0, 1, 2, 3, 5 #process.simOmtfDigis.sorterType = cms.string("byLLH") #TODO diff --git a/L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/runMuonOverlapPatternGenerator.py b/L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/runMuonOverlapPatternGenerator.py index fa2c6d7e16740..7f560f36a179e 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/runMuonOverlapPatternGenerator.py +++ b/L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/runMuonOverlapPatternGenerator.py @@ -10,6 +10,9 @@ process.load("FWCore.MessageLogger.MessageLogger_cfi") verbose = True +#version = "ExtraplMB1nadMB2FullAlgo_t16" +#version = "ExtraplMB1nadMB2Simplified_t17" +version = "ExtraplMB1nadMB2DTQualAndEtaValueP1Scale_t18" if verbose: process.MessageLogger = cms.Service("MessageLogger", @@ -23,9 +26,9 @@ ), categories = cms.untracked.vstring('l1tOmtfEventPrint', 'OMTFReconstruction'), omtfEventPrint = cms.untracked.PSet( - filename = cms.untracked.string('log_Patterns_0x00011_oldSample_3_30Files_test'), + filename = cms.untracked.string('Patterns_layerStat_' + version), extension = cms.untracked.string('.txt'), - threshold = cms.untracked.string('DEBUG'), + threshold = cms.untracked.string('INFO'), default = cms.untracked.PSet( limit = cms.untracked.int32(0) ), #INFO = cms.untracked.int32(0), #DEBUG = cms.untracked.int32(0), @@ -42,13 +45,18 @@ process.options = cms.untracked.PSet(wantSummary = cms.untracked.bool(False), #SkipEvent = cms.untracked.vstring('ProductNotFound') ) + +# PostLS1 geometry used +process.load('Configuration.Geometry.GeometryExtended2026D86Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D86_cff') + # import of standard configurations process.load('Configuration.StandardSequences.Services_cff') process.load('SimGeneral.HepPDTESSource.pythiapdt_cfi') process.load('Configuration.EventContent.EventContent_cff') process.load('SimGeneral.MixingModule.mixNoPU_cfi') -process.load('Configuration.Geometry.GeometryExtended2026D41Reco_cff') -process.load('Configuration.Geometry.GeometryExtended2026D41_cff') +#process.load('Configuration.Geometry.GeometryExtended2026D41Reco_cff') +#process.load('Configuration.Geometry.GeometryExtended2026D41_cff') process.load('Configuration.StandardSequences.MagneticField_cff') #process.load('Configuration.StandardSequences.SimL1Emulator_cff') process.load('Configuration.StandardSequences.EndOfProcess_cff') @@ -66,7 +74,7 @@ #path = '/afs/cern.ch/work/k/kbunkow/public/data/SingleMuFullEta/721_FullEta_v4/' onlyfiles = [f for f in listdir(path) if isfile(join(path, f))] -#print onlyfiles +#print(onlyfiles) filesNameLike = sys.argv[1] #chosenFiles = ['file://' + path + f for f in onlyfiles if (('_p_10_' in f) or ('_m_10_' in f))] @@ -74,7 +82,7 @@ #chosenFiles = ['file://' + path + f for f in onlyfiles if (re.match('.*_._p_10.*', f))] #chosenFiles = ['file://' + path + f for f in onlyfiles if ((filesNameLike in f))] -#print onlyfiles +#print(onlyfiles) chosenFiles = [] @@ -95,11 +103,11 @@ for sign in ['_m', '_p'] : #, m selFilesPerPtBin = 0 - for i in range(1, 201, 1): #TODO + for i in range(1, 50, 1): #TODO for f in onlyfiles: if (( '_' + str(ptCode) + sign + '_' + str(i) + '_') in f): #TODO for 721_FullEta_v4/ #if (( '_' + str(ptCode) + sign + '_' + str(i) + ".") in f): #TODO for 9_3_14_FullEta_v2 - #print f + #print(f) chosenFiles.append('file://' + path + f) selFilesPerPtBin += 1 if(selFilesPerPtBin >= filesPerPtBin): @@ -110,16 +118,16 @@ for f in onlyfiles: if (( filesNameLike + '_' + str(i) + '_') in f): #TODO for 721_FullEta_v4/ #if (( filesNameLike + '_' + str(i) + '.') in f): #TODO for 9_3_14_FullEta_v2 - print f + print(f) chosenFiles.append('file://' + path + f) -print "chosenFiles" +print("chosenFiles") for chFile in chosenFiles: - print chFile + print(chFile) if len(chosenFiles) == 0 : - print "no files selected!!!!!!!!!!!!!!!" + print("no files selected!!!!!!!!!!!!!!! (argumetn should be e.g. 20_p") exit firstEv = 0#40000 @@ -147,7 +155,9 @@ ####Event Setup Producer process.load('L1Trigger.L1TMuonOverlapPhase1.fakeOmtfParams_cff') -#process.omtfParams.configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0008_patGen.xml"), +process.omtfParams.configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0009_patGen.xml") +process.omtfParams.patternsXMLFiles = cms.VPSet( + cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_template.xml")), ) process.esProd = cms.EDAnalyzer("EventSetupRecordDataGetter", toGet = cms.VPSet( @@ -162,11 +172,21 @@ ####OMTF Emulator process.load('L1Trigger.L1TMuonOverlapPhase1.simOmtfDigis_cfi') +#needed by candidateSimMuonMatcher +process.load("TrackPropagation.SteppingHelixPropagator.SteppingHelixPropagatorAlong_cfi") +#process.load("TrackPropagation.SteppingHelixPropagator.SteppingHelixPropagatorOpposite_cfi") +#process.load("TrackPropagation.SteppingHelixPropagator.SteppingHelixPropagatorAny_cfi") + +#process.simOmtfDigis.candidateSimMuonMatcher = cms.bool(True) +process.simOmtfDigis.simTracksTag = cms.InputTag('g4SimHits') +#process.simOmtfDigis.simVertexesTag = cms.InputTag('g4SimHits') +#process.simOmtfDigis.muonMatcherFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/muonMatcherHists_100files_smoothStdDev_withOvf.root") + + process.simOmtfDigis.bxMin = cms.int32(0) process.simOmtfDigis.bxMax = cms.int32(0) process.simOmtfDigis.dumpResultToXML = cms.bool(False) -process.simOmtfDigis.dumpResultToROOT = cms.bool(False) process.simOmtfDigis.eventCaptureDebug = cms.bool(False) process.simOmtfDigis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_template.xml") @@ -178,12 +198,31 @@ process.simOmtfDigis.patternType = cms.string("GoldenPatternWithStat") process.simOmtfDigis.generatePatterns = cms.bool(True) -process.simOmtfDigis.optimisedPatsXmlFile = cms.string("Patterns_0x00011_oldSample_3_30Files_layerStat_test.xml") +process.simOmtfDigis.optimisedPatsXmlFile = cms.string("Patterns_layerStat_" + version + ".xml") process.simOmtfDigis.rpcMaxClusterSize = cms.int32(3) process.simOmtfDigis.rpcMaxClusterCnt = cms.int32(2) process.simOmtfDigis.rpcDropAllClustersIfMoreThanMax = cms.bool(True) +process.simOmtfDigis.minCSCStubRME12 = cms.int32(410) #[cm] +process.simOmtfDigis.minCSCStubR = cms.int32(500) #[cm] + +process.simOmtfDigis.minDtPhiQuality = cms.int32(2) +process.simOmtfDigis.minDtPhiBQuality = cms.int32(4) + +process.simOmtfDigis.dtRefHitMinQuality = cms.int32(4) + +process.simOmtfDigis.usePhiBExtrapolationFromMB1 = cms.bool(True) +process.simOmtfDigis.usePhiBExtrapolationFromMB2 = cms.bool(True) + +process.simOmtfDigis.useStubQualInExtr = cms.bool(True) +process.simOmtfDigis.useEndcapStubsRInExtr = cms.bool(True) +process.simOmtfDigis.useFloatingPointExtrapolation = cms.bool(False) +process.simOmtfDigis.extrapolFactorsFilename = cms.FileInPath("ExtrapolationFactors_DTQualAndEtaValueP1Scale.xml") +process.simOmtfDigis.dtRefHitMinQuality = cms.int32(4) + +process.simOmtfDigis.stubEtaEncoding = cms.string("valueP1Scale") + process.simOmtfDigis.goldenPatternResultFinalizeFunction = cms.int32(3) ## is needed here , becasue it just counts the number of layers with a stub process.simOmtfDigis.lctCentralBx = cms.int32(6);#<<<<<<<<<<<<<<<= filesPerPtBin): - break - -else : - for i in range(1, 2, 1): - for f in onlyfiles: - if (( filesNameLike + '_' + str(i) + '_') in f): #TODO for 721_FullEta_v4/ - #if (( filesNameLike + '_' + str(i) + '.') in f): #TODO for 9_3_14_FullEta_v2 - print f - chosenFiles.append('file://' + path + f) - - -print "chosenFiles" +print("chosenFiles") for chFile in chosenFiles: - print chFile + print(chFile) if len(chosenFiles) == 0 : - print "no files selected!!!!!!!!!!!!!!!" + print("no files selected!!!!!!!!!!!!!!!") exit firstEv = 0#40000 @@ -142,7 +114,9 @@ ####Event Setup Producer process.load('L1Trigger.L1TMuonOverlapPhase1.fakeOmtfParams_cff') -#process.omtfParams.configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0008_patGen.xml"), +process.omtfParams.configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0009_patGen.xml") +process.omtfParams.patternsXMLFiles = cms.VPSet( + cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_template.xml")), ) process.esProd = cms.EDAnalyzer("EventSetupRecordDataGetter", toGet = cms.VPSet( @@ -161,7 +135,6 @@ process.simOmtfDigis.bxMax = cms.int32(0) process.simOmtfDigis.dumpResultToXML = cms.bool(False) -process.simOmtfDigis.dumpResultToROOT = cms.bool(False) process.simOmtfDigis.eventCaptureDebug = cms.bool(False) process.simOmtfDigis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_template.xml") @@ -180,12 +153,17 @@ #process.simOmtfDigis.patternGenerator = cms.string("groupPatterns") process.simOmtfDigis.patternGenerator = cms.string("patternGenFromStat") #process.simOmtfDigis.patternGenerator = cms.string("") #does nothing except storing the patterns in the root file -process.simOmtfDigis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_0x00011_oldSample_3_30Files_layerStat.root") +#process.simOmtfDigis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_0x00011_oldSample_3_30Files_layerStat.root") +#process.simOmtfDigis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_layerStat_ExtraplMB1nadMB2_t14.root") +#process.simOmtfDigis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_layerStat_ExtraplMB1nadMB2FullAlgo_t16.root") +process.simOmtfDigis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_layerStat_" + versionIn + ".root") process.simOmtfDigis.patternType = cms.string("GoldenPatternWithStat") process.simOmtfDigis.generatePatterns = cms.bool(True) #process.simOmtfDigis.optimisedPatsXmlFile = cms.string("Patterns_0x0009_oldSample_3_10Files_classProb3.xml") -process.simOmtfDigis.optimisedPatsXmlFile = cms.string("Patterns_0x00012_oldSample_3_30Files_grouped1_classProb17_recalib2.xml") +#process.simOmtfDigis.optimisedPatsXmlFile = cms.string("Patterns_0x00012_oldSample_3_30Files_grouped1_classProb17_recalib2.xml") +#process.simOmtfDigis.optimisedPatsXmlFile = cms.string("Patterns_ExtraplMB1nadMB2FullAlgo_t16_classProb17_recalib2.xml") +process.simOmtfDigis.optimisedPatsXmlFile = cms.string("Patterns_" + versionOut + ".xml") #process.simOmtfDigis.optimisedPatsXmlFile = cms.string("PatternsDisplaced_0x0007_p.xml") process.simOmtfDigis.rpcMaxClusterSize = cms.int32(3) @@ -195,6 +173,7 @@ process.simOmtfDigis.goldenPatternResultFinalizeFunction = cms.int32(3) #valid values are 0, 1, 2, 3, 5 process.simOmtfDigis.lctCentralBx = cms.int32(6);#<<<<<<<<<<<<<<<= filesPerPtBin): + break + +elif filesNameLike == 'mcWaw2022' : + cscBx = 8 + path = '/eos/user/k/kbunkow/cms_data/mc/mcWaw2022/' + chosenFiles.append('file://' + path + "DoubleMuPt1to100Eta24_1kevents.root") + +else : + cscBx = 6 + path = '/eos/user/k/kbunkow/cms_data/SingleMuFullEta/721_FullEta_v4/' #old sample, but very big + onlyfiles = [f for f in listdir(path) if isfile(join(path, f))] + + for i in range(1, 10, 1): + for f in onlyfiles: + if (( filesNameLike + '_' + str(i) + '_') in f): #TODO for 721_FullEta_v4/ + #if (( filesNameLike + '_' + str(i) + '.') in f): #TODO for 9_3_14_FullEta_v2 + print(f) + chosenFiles.append('file://' + path + f) + + +# input files (up to 255 files accepted) +process.source = cms.Source('PoolSource', +fileNames = cms.untracked.vstring( + #'file:/eos/user/k/kbunkow/cms_data/SingleMuFullEta/721_FullEta_v4/SingleMu_16_p_1_1_xTE.root', + #'file:/afs/cern.ch/user/k/kpijanow/Neutrino_Pt-2to20_gun_50.root', + list(chosenFiles), ), + skipEvents = cms.untracked.uint32(0), + inputCommands=cms.untracked.vstring( + 'keep *', + 'drop l1tEMTFHit2016Extras_simEmtfDigis_CSC_HLT', + 'drop l1tEMTFHit2016Extras_simEmtfDigis_RPC_HLT', + 'drop l1tEMTFHit2016s_simEmtfDigis__HLT', + 'drop l1tEMTFTrack2016Extras_simEmtfDigis__HLT', + 'drop l1tEMTFTrack2016s_simEmtfDigis__HLT') +) + + +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1)) + + + +#Calibrate Digis +process.load("L1Trigger.DTTriggerPhase2.CalibratedDigis_cfi") +process.CalibratedDigis.dtDigiTag = "simMuonDTDigis" +process.CalibratedDigis.scenario = 0 + +#DTTriggerPhase2 +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +process.dtTriggerPhase2PrimitiveDigis.debug = False +process.dtTriggerPhase2PrimitiveDigis.dump = False +process.dtTriggerPhase2PrimitiveDigis.scenario = 0 + +####Event Setup Producer +process.load('L1Trigger.L1TMuonOverlapPhase1.fakeOmtfParams_cff') +process.omtfParams.configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0009_patGen.xml") + +process.omtfParams.patternsXMLFiles = cms.VPSet( + #cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x0003.xml")), + #cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x0009_oldSample_3_10Files_classProb1.xml") ), + cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_template.xml")), + #cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x00012_oldSample_3_30Files_grouped1_classProb17_recalib2.xml")), + #cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_layerStat_ExtraplMB1nadMB2_t10_classProb17_recalib2.xml")), + ) + + + +process.esProd = cms.EDAnalyzer("EventSetupRecordDataGetter", + toGet = cms.VPSet( + cms.PSet(record = cms.string('L1TMuonOverlapParamsRcd'), + data = cms.vstring('L1TMuonOverlapParams')) + ), + verbose = cms.untracked.bool(False) +) + +#process.TFileService = cms.Service("TFileService", fileName = cms.string('omtfAnalysis1_1.root'), closeFileFast = cms.untracked.bool(True) ) + +####OMTF Emulator +process.load('L1Trigger.L1TMuonOverlapPhase1.simOmtfDigis_cfi') + +#needed by candidateSimMuonMatcher +process.load("TrackPropagation.SteppingHelixPropagator.SteppingHelixPropagatorAlong_cfi") +#process.load("TrackPropagation.SteppingHelixPropagator.SteppingHelixPropagatorOpposite_cfi") +#process.load("TrackPropagation.SteppingHelixPropagator.SteppingHelixPropagatorAny_cfi") + +process.simOmtfDigis.candidateSimMuonMatcher = cms.bool(True) +process.simOmtfDigis.simTracksTag = cms.InputTag('g4SimHits') +process.simOmtfDigis.simVertexesTag = cms.InputTag('g4SimHits') +process.simOmtfDigis.muonMatcherFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/muonMatcherHists_100files_smoothStdDev_withOvf.root") + + +process.simOmtfDigis.bxMin = cms.int32(0) +process.simOmtfDigis.bxMax = cms.int32(0) + +process.simOmtfDigis.dumpResultToXML = cms.bool(False) +process.simOmtfDigis.eventCaptureDebug = cms.bool(False) + +process.simOmtfDigis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_template.xml") +#process.simOmtfDigis.patternsXMLFiles = cms.VPSet(cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/GPs_parametrised_plus_v1.xml")), +# cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/GPs_parametrised_minus_v1.xml")) +#) + +#process.simOmtfDigis.patternGenerator = cms.string("patternGen") +#process.simOmtfDigis.patternGenerator = cms.string("2DHists") +process.simOmtfDigis.patternGenerator = cms.string("deltaPhiVsPhiRef") + + +process.simOmtfDigis.patternType = cms.string("GoldenPatternWithStat") +process.simOmtfDigis.generatePatterns = cms.bool(True) +process.simOmtfDigis.optimisedPatsXmlFile = cms.string("Patterns_dispalced_test_" + version + "_" + filesNameLike + ".xml") + +process.simOmtfDigis.rpcMaxClusterSize = cms.int32(3) +process.simOmtfDigis.rpcMaxClusterCnt = cms.int32(2) +process.simOmtfDigis.rpcDropAllClustersIfMoreThanMax = cms.bool(True) + +process.simOmtfDigis.minCSCStubRME12 = cms.int32(410) #[cm] +process.simOmtfDigis.minCSCStubR = cms.int32(490) #[cm] + +process.simOmtfDigis.minDtPhiQuality = cms.int32(2) +process.simOmtfDigis.minDtPhiBQuality = cms.int32(4) + +process.simOmtfDigis.dtRefHitMinQuality = cms.int32(4) + +#process.simOmtfDigis.usePhiBExtrapolationFromMB1 = cms.bool(True) +#process.simOmtfDigis.usePhiBExtrapolationFromMB2 = cms.bool(True) +process.simOmtfDigis.usePhiBExtrapolationFromMB1 = cms.bool(False) +process.simOmtfDigis.usePhiBExtrapolationFromMB2 = cms.bool(False) + +process.simOmtfDigis.useStubQualInExtr = cms.bool(True) +process.simOmtfDigis.useEndcapStubsRInExtr = cms.bool(True) +process.simOmtfDigis.useFloatingPointExtrapolation = cms.bool(True) +#process.simOmtfDigis.extrapolFactorsFilename = cms.FileInPath("ExtrapolationFactors_DTQualAndEtaValueP1Scale.xml") +#process.simOmtfDigis.extrapolFactorsFilename = cms.FileInPath("ExtrapolationFactors_simple.xml") +process.simOmtfDigis.extrapolFactorsFilename = cms.FileInPath("") + +process.simOmtfDigis.stubEtaEncoding = cms.string("valueP1Scale") +#process.simOmtfDigis.stubEtaEncoding = cms.string("bits") + +process.simOmtfDigis.goldenPatternResultFinalizeFunction = cms.int32(3) ## is needed here , becasue it just counts the number of layers with a stub +process.simOmtfDigis.lctCentralBx = cms.int32(cscBx);#<<<<<<<<<<<<<<<