diff --git a/L1Trigger/L1TMuonOverlapPhase1/BuildFile.xml b/L1Trigger/L1TMuonOverlapPhase1/BuildFile.xml
index e843803313dc9..6fbc9fecae7ad 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/BuildFile.xml
+++ b/L1Trigger/L1TMuonOverlapPhase1/BuildFile.xml
@@ -35,4 +35,3 @@
-
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/AngleConverterBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/AngleConverterBase.h
deleted file mode 100644
index d26bdfb5d5a11..0000000000000
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/AngleConverterBase.h
+++ /dev/null
@@ -1,116 +0,0 @@
-#ifndef L1T_OmtfP1_ANGLECONVERTER_H
-#define L1T_OmtfP1_ANGLECONVERTER_H
-
-#include "L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h"
-
-#include "FWCore/Framework/interface/ESHandle.h"
-#include "DataFormats/GeometryVector/interface/GlobalPoint.h"
-#include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h"
-#include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThContainerFwd.h"
-#include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigiFwd.h"
-#include "DataFormats/RPCDigi/interface/RPCDigiFwd.h"
-#include "DataFormats/MuonDetId/interface/DTChamberIdFwd.h"
-#include "DataFormats/MuonDetId/interface/CSCDetIdFwd.h"
-#include "DataFormats/MuonDetId/interface/RPCDetIdFwd.h"
-#include "Geometry/Records/interface/MuonGeometryRecord.h"
-#include "FWCore/Framework/interface/ESWatcher.h"
-
-#include
-
-namespace edm {
- class EventSetup;
-}
-
-class RPCGeometry;
-class CSCGeometry;
-class CSCLayer;
-class DTGeometry;
-
-class L1MuDTChambPhDigi;
-class L1MuDTChambThDigi;
-
-struct EtaValue {
- int eta = 0;
- ///error of the eta measurement
- int etaSigma = 0;
- int quality = 0;
-
- int bx = 0;
- int timing = 0; //sub-bx timing, should be already in scale common for all muon subsystems
-};
-
-struct MuonGeometryTokens {
- edm::ESGetToken rpcGeometryEsToken;
- edm::ESGetToken cscGeometryEsToken;
- edm::ESGetToken dtGeometryEsToken;
-};
-
-class AngleConverterBase {
-public:
- AngleConverterBase();
- virtual ~AngleConverterBase();
-
- ///Update the Geometry with current Event Setup
- virtual void checkAndUpdateGeometry(const edm::EventSetup&,
- const ProcConfigurationBase* config,
- const MuonGeometryTokens& muonGeometryTokens);
-
- /// get phi of DT,CSC and RPC azimutal angle digi in processor scale, used by OMTF algorithm.
- /// in case of wrong phi returns OMTFConfiguration::instance()->nPhiBins
- /// 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, unsigned int iInput) const;
-
- virtual int getProcessorPhi(unsigned int iProcessor,
- l1t::tftype part,
- const RPCDetId& rollId,
- const unsigned int& digi) const;
- virtual int getProcessorPhi(int phiZero,
- l1t::tftype part,
- const RPCDetId& rollId,
- const unsigned int& digi1,
- const unsigned int& digi2) const;
-
- ///returns the eta position of the DT chamber
- ///(n.b. in the DT phi and eta segments are independent)
- virtual EtaValue getGlobalEtaDt(const DTChamberId& detId) const;
-
- //adds the eta segments from the thetaDigi to etaSegments
- virtual void getGlobalEta(const L1MuDTChambThDigi& thetaDigi, std::vector& etaSegments) const;
- virtual std::vector getGlobalEta(const L1MuDTChambThContainer* dtThDigis, int bxFrom, int bxTo) const;
-
- ///Convert local eta coordinate to global digital microGMT scale.
- virtual EtaValue getGlobalEta(const CSCDetId& detId, const CSCCorrelatedLCTDigi& aDigi) const;
-
- ///returns the eta position of the CSC chamber
- virtual EtaValue getGlobalEtaCsc(const CSCDetId& detId) const;
-
- ///Convert local eta coordinate to global digital microGMT scale.
- ///EtaValue::etaSigma is half of the strip
- virtual EtaValue getGlobalEta(unsigned int rawid, const unsigned int& aDigi) const;
-
- float cscChamberEtaSize(const CSCDetId& id) const;
-
-protected:
- ///Check orientation of strips in given CSC chamber
- virtual bool isCSCCounterClockwise(const CSCLayer* layer) const;
-
- ///Find BTI group
- virtual const int findBTIgroup(const L1MuDTChambPhDigi& aDigi, const L1MuDTChambThContainer* dtThDigis);
-
- // pointers to the current geometry records
- unsigned long long _geom_cache_id = 0;
- edm::ESHandle _georpc;
- edm::ESHandle _geocsc;
- edm::ESHandle _geodt;
-
- edm::ESWatcher muonGeometryRecordWatcher;
-
- const ProcConfigurationBase* config = nullptr;
- ///Number of phi bins along 2Pi.
- unsigned int nPhiBins = 0;
-};
-
-#endif
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStubMakerBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStubMakerBase.h
index 4cd2efb411c37..c9b1c346df8e1 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStubMakerBase.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStubMakerBase.h
@@ -6,7 +6,6 @@
#include "DataFormats/GEMDigi/interface/GEMPadDigiCollection.h"
#include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambPhContainer.h"
#include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThContainer.h"
-#include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h"
#include "DataFormats/MuonDetId/interface/DTChamberId.h"
#include "DataFormats/MuonDetId/interface/RPCDetId.h"
#include "DataFormats/RPCDigi/interface/RPCDigiCollection.h"
@@ -167,7 +166,7 @@ class RpcDigiToStubsConverter : public DigiToStubsConverterBase {
const RpcClusterization* rpcClusterization;
};
-//forward declaration - MuonGeometryTokens is defined and used in the AngleConverterBase
+//forward declaration - MuonGeometryTokens is defined and used in the OmtfAngleConverter
struct MuonGeometryTokens;
class MuonStubMakerBase {
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h
index ab005a8b9e254..066b78b5c5bca 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h
@@ -42,10 +42,8 @@ class AlgoMuon {
//hardware pt
int getPtConstr() const { return goldenPaternConstr == nullptr ? 0 : goldenPaternConstr->key().thePt; }
- //hardware upt, in the phase1 the upt scale unit is 1 GeV, while for the pt the unit is 0.5GeV
- int getPtUnconstr() const {
- return goldenPaternUnconstr == nullptr ? 0 : (goldenPaternUnconstr->key().thePt - 1) / 2 + 1;
- }
+ //hardware upt, in the pattens scale, not in the GMT scale
+ int getPtUnconstr() const { return goldenPaternUnconstr == nullptr ? 0 : goldenPaternUnconstr->key().thePt; }
int getChargeConstr() const { return goldenPaternConstr == nullptr ? -1 : goldenPaternConstr->key().theCharge; }
@@ -125,21 +123,29 @@ class AlgoMuon {
this->goldenPaternUnconstr = goldenPaternUnconstr;
}
+ int getQuality() const { return quality; }
+
+ void setQuality(int quality = 0) { this->quality = quality; }
+
int getChargeNNConstr() const { return chargeNNConstr; }
void setChargeNNConstr(int chargeNn = 0) { chargeNNConstr = chargeNn; }
- int getPtNNConstr() const { return ptNNConstr; }
+ float getPtNNConstr() const { return ptNNConstr; }
+
+ void setPtNNConstr(float ptNn = 0) { ptNNConstr = ptNn; }
- void setPtNNConstr(int ptNn = 0) { ptNNConstr = ptNn; }
+ float getPtNNUnconstr() const { return ptNNUnconstr; }
- int getChargeNNUnconstr() const { return chargeNNUnconstr; }
+ void setPtNNUnconstr(float ptNnUnconstr) { ptNNUnconstr = ptNnUnconstr; }
- void setChargeNNUnconstr(int chargeNnUnconstr = 0) { chargeNNUnconstr = chargeNnUnconstr; }
+ int getDxyNn() const { return dxyNN; }
- int getPtNNUnconstr() const { return ptNNUnconstr; }
+ void setDxyNn(int dxyNn = 0) { dxyNN = dxyNn; }
- void setPtNNUnconstr(int ptNnUnconstr = 0) { ptNNUnconstr = ptNnUnconstr; }
+ const std::vector& getNnOutputs() const { return nnOutputs; }
+
+ void setNnOutputs(const std::vector& nnOutputs) { this->nnOutputs = nnOutputs; }
private:
///FIXME maybe the gpResult cannot be a reference or pointer, ad not a copy
@@ -165,11 +171,16 @@ class AlgoMuon {
std::vector> killedMuons;
- int ptNNConstr = 0;
+ int quality = 0;
+
+ float ptNNConstr = 0;
int chargeNNConstr = 0;
- int ptNNUnconstr = 0;
- int chargeNNUnconstr = 0;
+ float ptNNUnconstr = 0;
+
+ int dxyNN = 0;
+
+ std::vector nnOutputs;
};
typedef std::shared_ptr AlgoMuonPtr;
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h
new file mode 100644
index 0000000000000..b6f6524dcc8e7
--- /dev/null
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h
@@ -0,0 +1,117 @@
+/*
+ * FinalMuon.h
+ *
+ * Created on: Dec 17, 2024
+ * Author: kbunkow
+ */
+
+#ifndef L1T_OmtfP1_FinalMuon_H
+#define L1T_OmtfP1_FinalMuon_H
+
+#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h"
+
+#include
+#include
+#include
+
+class FinalMuon {
+public:
+ FinalMuon() {};
+ FinalMuon(const AlgoMuonPtr& algoMuon)
+ : algoMuon(algoMuon), quality(algoMuon->getQuality()), firedLayerCnt(algoMuon->getFiredLayerCnt()) {};
+
+ virtual ~FinalMuon() {};
+
+ const AlgoMuonPtr& getAlgoMuon() const { return algoMuon; }
+
+ int getSign() const { return sign; }
+
+ void setSign(int sign = 0) { this->sign = sign; }
+
+ void setBx(int bx = 0) { this->bx = bx; }
+
+ int getBx() const { return bx; }
+
+ int getProcessor() const { return processor; }
+
+ void setProcessor(int processor = -1) { this->processor = processor; }
+
+ void setTrackFinderType(l1t::tftype mtfType) { this->mtfType = mtfType; }
+ l1t::tftype trackFinderType() const { return mtfType; }
+
+ int getQuality() const { return quality; }
+
+ void setQuality(int quality = 0) { this->quality = quality; }
+
+ float getPtGev() const { return ptGev; }
+
+ void setPtGev(float ptGev = -1) { this->ptGev = ptGev; }
+
+ float getPtUnconstrGev() const { return ptUnconstrGev; }
+
+ void setPtUnconstrGev(float ptUnconstrGev = -1) { this->ptUnconstrGev = ptUnconstrGev; }
+
+ float getEtaRad() const { return etaRad; }
+
+ void setEtaRad(float etaRad = -10) { this->etaRad = etaRad; }
+
+ float getPhiRad() const { return phiRad; }
+
+ void setPhiRad(float phiRad = -10) { this->phiRad = phiRad; }
+
+ int getPtGmt() const { return ptGmt; }
+
+ void setPtGmt(int ptGmt = 0) { this->ptGmt = ptGmt; }
+
+ int getPtUnconstrGmt() const { return ptUnconstrGmt; }
+
+ void setPtUnconstrGmt(int ptUnconstrGmt = 0) { this->ptUnconstrGmt = ptUnconstrGmt; }
+
+ int getPhiGmt() const { return phiGmt; }
+
+ void setPhiGmt(int phiGmt = 0) { this->phiGmt = phiGmt; }
+
+ int getEtaGmt() const { return etaGmt; }
+
+ void setEtaGmt(int etaGmt = 0) { this->etaGmt = etaGmt; }
+
+ int getFiredLayerCnt() const { return firedLayerCnt; }
+
+ void setFiredLayerCnt(int firedLayerCnt = 0) { this->firedLayerCnt = firedLayerCnt; }
+
+ int getFiredLayerBits() const { return firedLayerBits; }
+
+ void setFiredLayerBits(int firedLayerBits = 0) { this->firedLayerBits = firedLayerBits; }
+
+ friend std::ostream& operator<<(std::ostream& out, const FinalMuon& finalMuon);
+
+private:
+ AlgoMuonPtr algoMuon;
+
+ int bx = 0;
+ int processor = -1;
+ l1t::tftype mtfType = l1t::omtf_pos;
+
+ int quality = 0;
+
+ int sign = 0;
+
+ float ptGev = -1;
+ float ptUnconstrGev = -1;
+ float phiRad = -10;
+ float etaRad = -10;
+
+ int ptGmt = 0;
+ int ptUnconstrGmt = 0;
+ int phiGmt = 0;
+ int etaGmt = 0;
+
+ int firedLayerCnt = 0;
+
+ int firedLayerBits = 0;
+};
+
+typedef std::shared_ptr FinalMuonPtr;
+typedef std::vector FinalMuons;
+
+#endif /* FinalMuon */
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPattern.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPattern.h
index 89f1d7d8692f7..edf8fee29a9c4 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPattern.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPattern.h
@@ -82,9 +82,8 @@ class GoldenPattern : public GoldenPatternBase {
///Reset contents of all data vectors, keeping the vectors size
virtual void reset();
- ///Propagate phi from given reference layer to MB2 or ME2
- ///expressed in integer MicroGMT scale: 1.1/2.61*240 = 101
- int propagateRefPhi(int phiRef, int etaRef, unsigned int iRefLayer) override;
+ ///Propagates phi from a given reference layer (iRefLayer) to a selected iLayer
+ int propagateRefPhi(int phiRef, int etaRef, unsigned int iRefLayer, unsigned int iLayer) override;
protected:
///Distributions for all reference layers
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternBase.h
index cce6d74ef5bb9..deacb0734bda4 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternBase.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternBase.h
@@ -105,10 +105,8 @@ class GoldenPatternBase {
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
- ///expressed in integer MicroGMT scale: 1.1/2.61*240 = 101
- virtual int propagateRefPhi(int phiRef, int etaRef, unsigned int iRefLayer) = 0;
+ ///Propagates phi from a given reference layer (iRefLayer) to a selected iLayer
+ virtual int propagateRefPhi(int phiRef, int etaRef, unsigned int iRefLayer, unsigned int iLayer) = 0;
resultsArrayType& getResults() { return results; }
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternResult.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternResult.h
index fd8aaa1bb3ccd..a090abf3cd4a2 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternResult.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternResult.h
@@ -58,8 +58,6 @@ class GoldenPatternResult {
void set(int refLayer, int phi, int eta, int refHitPhi);
- void setStubResult(float pdfVal, bool valid, int pdfBin, int layer, MuonStubPtr stub);
-
void setStubResult(int layer, StubResult& stubResult);
int getRefLayer() const { return this->refLayer; }
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IOMTFEmulationObserver.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IOMTFEmulationObserver.h
index 750d03f0a2e72..8f0e36d1490bb 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IOMTFEmulationObserver.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IOMTFEmulationObserver.h
@@ -9,6 +9,7 @@
#define L1T_OmtfP1_IOMTFRECONSTRUCTIONOBSERVER_H_
#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h"
+#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h"
#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinput.h"
#include "FWCore/Framework/interface/EventSetup.h"
@@ -40,12 +41,11 @@ class IOMTFEmulationObserver {
const std::shared_ptr& input,
const AlgoMuons& algoCandidates,
const AlgoMuons& gbCandidates,
- const std::vector& candMuons) = 0;
+ const FinalMuons& finalMuons) = 0;
virtual void observeEventBegin(const edm::Event& iEvent) {}
- virtual void observeEventEnd(const edm::Event& iEvent,
- std::unique_ptr& finalCandidates) {};
+ virtual void observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMuons) {};
virtual void endJob() = 0;
};
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h
index 0be9fc6615513..0efaf399bece6 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h
@@ -33,17 +33,17 @@ class IProcessorEmulator {
virtual AlgoMuons ghostBust(AlgoMuons refHitCands, int charge = 0) = 0;
- virtual bool checkHitPatternValidity(unsigned int hits) = 0;
+ virtual FinalMuons getFinalMuons(unsigned int iProcessor, l1t::tftype mtfType, const AlgoMuons& gbCandidates) = 0;
- virtual std::vector getFinalcandidates(unsigned int iProcessor,
- l1t::tftype mtfType,
- const AlgoMuons& algoCands) = 0;
+ virtual std::vector getRegionalMuonCands(unsigned int iProcessor,
+ l1t::tftype mtfType,
+ FinalMuons& finalMuons) = 0;
- virtual std::vector run(unsigned int iProcessor,
- l1t::tftype mtfType,
- int bx,
- OMTFinputMaker* inputMaker,
- std::vector >& observers) = 0;
+ virtual FinalMuons run(unsigned int iProcessor,
+ l1t::tftype mtfType,
+ int bx,
+ OMTFinputMaker* inputMaker,
+ std::vector >& observers) = 0;
virtual void printInfo() const = 0;
};
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h
index 475ae3a3392c4..4a1e3c4410f9e 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h
@@ -136,23 +136,44 @@ class OMTFConfiguration : public ProcConfigurationBase {
const vector4D& getMeasurements4D() const { return measurements4D; }
const vector4D& getMeasurements4Dref() const { return measurements4Dref; }
- double ptUnit = 0.5; // GeV/unit
+ //pt unit of the OMTF patrterns, the same as in the phase-1 uGMT
+ //TODO refactor to omtfPtUnit
+ const double ptUnit = 0.5; // GeV/unit
///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; }
+ //TODO refactor to omtfPtToGev
+ double hwPtToGev(int hwPt) const override { return (hwPt == 0 ? 0 : (hwPt - 1.) * ptUnit); }
///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); }
+ virtual double hwEtaToEta(int hwEta) const { return (hwEta * etaUnit_); }
+
+ //TODO use version with round
+ int etaToHwEta(double eta) const override { return (eta / etaUnit_); }
+ //int etaToHwEta(double eta) const override { return std::lround(eta / etaUnit_); }
+
+ //TODO the phase-1 values 92, 79 and 75 are quite far from the chamber middle, should be fixed for phase-2
+ //eta of the middle DT Wheel 2 MB1, in the OMTF scale
+ int mb1W2Eta() const override {
+ //92 in phase 1 scale
+ return etaToHwEta(1.0005);
+ }
+
+ //eta of the middle DT Wheel 2 MB2, in the OMTF scale
+ int mb2W2Eta() const override {
+ //79 in phase 1 scale
+ return etaToHwEta(0.859125);
+ }
- int etaToHwEta(double eta) const override { return (eta / etaUnit); }
+ //eta of the middle DT Wheel 2 MB3, in the OMTF scale
+ int mb3W2Eta() const override {
+ //75 in phase 1 scale
+ return etaToHwEta(0.815625);
+ }
+
+ //eta of the middle DT Wheel 2 MB4, in the OMTF scale
+ int mb4W2Eta() const override { return etaToHwEta(0.67); }
static unsigned int eta2Bits(unsigned int eta);
@@ -160,12 +181,7 @@ class OMTFConfiguration : public ProcConfigurationBase {
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); }
-
- //phi in radians
- virtual double hwPhiToGlobalPhi(int phi) const { return phi * phiGmtUnit; }
+ const double phiGmtUnit = 2. * M_PI / 576; //phase-1, from the interface note, should be defined somewhere globally
///iProcessor - 0...5
///phiRad [-pi,pi]
@@ -176,9 +192,16 @@ class OMTFConfiguration : public ProcConfigurationBase {
return 0; // TODO replace getProcScalePhi(unsigned int iProcessor, double phiRad) with this function
}
- double procHwPhiToGlobalPhi(int procHwPhi, int procHwPhi0) const;
+ //returns the global phi in the OMTF scale
+ int procPhiOmtfToGlobalPhiOmtf(unsigned int iProcessor, int procHwPhi) const;
- int procPhiToGmtPhi(int procPhi) const {
+ //phi in radians, -pi to pi convention
+ double procPhiOmtfToPhiRad(unsigned int iProcessor, int procHwPhi) const {
+ auto procPhi = procPhiOmtfToGlobalPhiOmtf(iProcessor, procHwPhi) * 2. * M_PI / nPhiBins();
+ return (procPhi > M_PI) ? procPhi - 2. * M_PI : procPhi;
+ };
+
+ int procPhiToGmtPhase1Phi(int procPhi) const {
///conversion factor from OMTF to uGMT scale is 5400/576 i.e. phiValue/=9.375;
return floor(procPhi * 437. / (1 << 12)); // ie. use as in hw: 9.3729977
//cannot be (procPhi * 437) >> 12, because this floor is needed
@@ -285,6 +308,8 @@ class OMTFConfiguration : public ProcConfigurationBase {
bool cleanStubs() const { return cleanStubs_; }
+ bool usePhase2DTPrimitives() const { return usePhase2DTPrimitives_; }
+
private:
L1TMuonOverlapParams rawParams;
@@ -366,6 +391,8 @@ class OMTFConfiguration : public ProcConfigurationBase {
bool dumpResultToXML = false;
bool cleanStubs_ = false;
+
+ bool usePhase2DTPrimitives_ = false;
};
#endif
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h
index 68ce5b1dac266..7f41caf37a3f5 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h
@@ -2,6 +2,7 @@
#define L1T_OmtfP1_OMTFProcessor_H
#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h"
+#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h"
#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPattern.h"
#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/GoldenPatternResult.h"
#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IGhostBuster.h"
@@ -11,8 +12,6 @@
#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/ProcessorBase.h"
#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/SorterBase.h"
-#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h"
-
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
@@ -61,6 +60,7 @@ class OMTFProcessor : public ProcessorBase, public IProcessor
int extrapolateDtPhiBFloatPoint(const int& refLogicLayer,
const int& refPhi,
const int& refPhiB,
+ const int& refHitSuperLayer,
unsigned int targetLayer,
const int& targetStubPhi,
const int& targetStubQuality,
@@ -72,6 +72,7 @@ class OMTFProcessor : public ProcessorBase, public IProcessor
int extrapolateDtPhiBFixedPoint(const int& refLogicLayer,
const int& refPhi,
const int& refPhiB,
+ const int& refHitSuperLayer,
unsigned int targetLayer,
const int& targetStubPhi,
const int& targetStubQuality,
@@ -97,10 +98,15 @@ class OMTFProcessor : public ProcessorBase, public IProcessor
return ghostBuster->select(refHitCands, charge);
}
- //convert algo muon to outgoing Candidates
- std::vector getFinalcandidates(unsigned int iProcessor,
- l1t::tftype mtfType,
- const AlgoMuons& algoCands) override;
+ void assignQuality(AlgoMuons::value_type& algoMuon);
+
+ FinalMuons getFinalMuons(unsigned int iProcessor, l1t::tftype mtfType, const AlgoMuons& gbCandidates) override;
+
+ void convertToGmtScalesPhase1(unsigned int iProcessor, l1t::tftype mtfType, FinalMuonPtr& finalMuon);
+
+ std::vector getRegionalMuonCands(unsigned int iProcessor,
+ l1t::tftype mtfType,
+ FinalMuons& finalMuons) override;
///allows to use other sorter implementation than the default one
virtual void setSorter(SorterBase* sorter) { this->sorter.reset(sorter); }
@@ -108,13 +114,11 @@ class OMTFProcessor : public ProcessorBase, public IProcessor
///allows to use other IGhostBuster implementation than the default one
void setGhostBuster(IGhostBuster* ghostBuster) override { this->ghostBuster.reset(ghostBuster); }
- virtual void setPtAssignment(PtAssignmentBase* ptAssignment) { this->ptAssignment = ptAssignment; }
-
- std::vector run(unsigned int iProcessor,
- l1t::tftype mtfType,
- int bx,
- OMTFinputMaker* inputMaker,
- std::vector >& observers) override;
+ FinalMuons run(unsigned int iProcessor,
+ l1t::tftype mtfType,
+ int bx,
+ OMTFinputMaker* inputMaker,
+ std::vector >& observers) override;
void printInfo() const override;
@@ -130,15 +134,12 @@ class OMTFProcessor : public ProcessorBase, public IProcessor
///Candidate with invalid hit patterns is assigned quality=0.
///Currently the list of invalid patterns is hardcoded.
///This has to be read from configuration.
- bool checkHitPatternValidity(unsigned int hits) override;
+ static bool checkHitPatternValidity(unsigned int hits);
std::unique_ptr > sorter;
std::unique_ptr ghostBuster;
- //ptAssignment should be destroyed where it is created, i.e. by OmtfEmulation or OMTFReconstruction
- PtAssignmentBase* ptAssignment = nullptr;
-
bool useStubQualInExtr = false;
bool useEndcapStubsRInExtr = false;
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h
index 868077a7f755a..9829f9361837c 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h
@@ -35,7 +35,7 @@ class OMTFConfigMaker;
class OMTFReconstruction {
public:
- OMTFReconstruction(const edm::ParameterSet&, MuStubsInputTokens& muStubsInputTokens);
+ OMTFReconstruction(const edm::ParameterSet&, const MuStubsInputTokens& muStubsInputTokens);
virtual ~OMTFReconstruction();
@@ -43,12 +43,12 @@ class OMTFReconstruction {
void endJob();
- void beginRun(edm::Run const& run,
- edm::EventSetup const& iSetup,
- edm::ESGetToken& omtfParamsEsToken,
- const MuonGeometryTokens& muonGeometryTokens,
- const edm::ESGetToken& magneticFieldEsToken,
- const edm::ESGetToken& propagatorEsToken);
+ virtual void beginRun(edm::Run const& run,
+ edm::EventSetup const& iSetup,
+ edm::ESGetToken& omtfParamsEsToken,
+ const MuonGeometryTokens& muonGeometryTokens,
+ const edm::ESGetToken& magneticFieldEsToken,
+ const edm::ESGetToken& propagatorEsToken);
std::unique_ptr reconstruct(const edm::Event&, const edm::EventSetup&);
@@ -62,7 +62,7 @@ class OMTFReconstruction {
protected:
edm::ParameterSet edmParameterSet;
- MuStubsInputTokens& muStubsInputTokens;
+ const MuStubsInputTokens& muStubsInputTokens;
int bxMin, bxMax;
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinputMaker.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinputMaker.h
index 883f57adcec6c..89dea0898a1a4 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinputMaker.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinputMaker.h
@@ -98,7 +98,7 @@ class RpcDigiToStubsConverterOmtf : public RpcDigiToStubsConverter {
class OMTFinputMaker : public MuonStubMakerBase {
public:
OMTFinputMaker(const edm::ParameterSet& edmParameterSet,
- MuStubsInputTokens& muStubsInputTokens,
+ const MuStubsInputTokens& muStubsInputTokens,
const OMTFConfiguration* config,
std::unique_ptr angleConverter);
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h
index 7c12d7aa6b6a3..4ee8ee7ceac4b 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h
@@ -8,26 +8,87 @@
#ifndef L1T_OmtfP1_OMTFANGLECONVERTER_H_
#define L1T_OmtfP1_OMTFANGLECONVERTER_H_
-#include "L1Trigger/L1TMuonOverlapPhase1/interface/AngleConverterBase.h"
+#include "L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h"
-class OmtfAngleConverter : public AngleConverterBase {
+#include "FWCore/Framework/interface/ESHandle.h"
+#include "DataFormats/GeometryVector/interface/GlobalPoint.h"
+#include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h"
+#include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambPhContainer.h"
+#include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThContainer.h"
+#include "DataFormats/MuonDetId/interface/DTChamberId.h"
+#include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigiCollection.h"
+#include "DataFormats/MuonDetId/interface/CSCDetId.h"
+#include "DataFormats/RPCDigi/interface/RPCDigiFwd.h"
+#include "DataFormats/MuonDetId/interface/RPCDetId.h"
+#include "Geometry/Records/interface/MuonGeometryRecord.h"
+#include "FWCore/Framework/interface/ESWatcher.h"
+
+#include
+
+class RPCGeometry;
+class CSCGeometry;
+class CSCLayer;
+class DTGeometry;
+
+struct MuonGeometryTokens {
+ edm::ESGetToken rpcGeometryEsToken;
+ edm::ESGetToken cscGeometryEsToken;
+ edm::ESGetToken dtGeometryEsToken;
+};
+
+class OmtfAngleConverter {
public:
- OmtfAngleConverter() : AngleConverterBase() {}
+ OmtfAngleConverter() {}
+
+ virtual ~OmtfAngleConverter();
+
+ ///Update the Geometry with current Event Setup
+ virtual void checkAndUpdateGeometry(const edm::EventSetup&,
+ const ProcConfigurationBase* config,
+ const MuonGeometryTokens& muonGeometryTokens);
- ~OmtfAngleConverter() override;
+ /// get phi of DT,CSC and RPC azimutal angle digi in processor scale, used by OMTF algorithm.
+ /// in case of wrong phi returns OMTFConfiguration::instance()->nPhiBins
+ /// 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, unsigned int iInput) const;
+
+ virtual int getProcessorPhi(int phiZero,
+ l1t::tftype part,
+ const RPCDetId& rollId,
+ const unsigned int& digi1,
+ const unsigned int& digi2) const;
///Convert local eta coordinate to global digital microGMT scale.
///theta is returned only if in the dtThDigis is only one hit, otherwise eta = 95 or middle of the chamber
- virtual int getGlobalEta(const DTChamberId dTChamberId, const L1MuDTChambThContainer *dtThDigis, int bxNum) const;
+ 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, float &r) 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, float &r) const;
+ virtual int getGlobalEtaRpc(unsigned int rawid, const unsigned int& strip, float& r) const;
+
+protected:
+ ///Check orientation of strips in given CSC chamber
+ virtual bool isCSCCounterClockwise(const CSCLayer* layer) const;
+
+ ///Find BTI group
+ virtual int findBTIgroup(const L1MuDTChambPhDigi& aDigi, const L1MuDTChambThContainer* dtThDigis) const;
+
+ // pointers to the current geometry records
+ unsigned long long _geom_cache_id = 0;
+ edm::ESHandle _georpc;
+ edm::ESHandle _geocsc;
+ edm::ESHandle _geodt;
+
+ edm::ESWatcher muonGeometryRecordWatcher;
- //to avoid Clang Warnings "hides overloaded virtual functions"
- using AngleConverterBase::getGlobalEta;
+ const ProcConfigurationBase* config = nullptr;
+ ///Number of phi bins along 2Pi.
+ unsigned int nPhiBins = 0;
};
#endif /* L1T_OmtfP1_OMTFANGLECONVERTER_H_ */
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h
deleted file mode 100644
index 83b098918f3ce..0000000000000
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * PtAssignmentBase.h
- *
- * Created on: Mar 16, 2020
- * Author: kbunkow
- */
-
-#ifndef L1T_OmtfP1_PTASSIGNMENTBASE_H_
-#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)
- * getPts() is called inside OMTFProcessor::getFinalcandidates
- */
-class PtAssignmentBase {
-public:
- PtAssignmentBase(const OMTFConfiguration* omtfConfig) : omtfConfig(omtfConfig) {}
- virtual ~PtAssignmentBase();
-
- virtual std::vector getPts(AlgoMuons::value_type& algoMuon,
- std::vector >& observers) = 0;
-
-protected:
- const OMTFConfiguration* omtfConfig = nullptr;
-};
-
-#endif /* L1T_OmtfP1_PTASSIGNMENTBASE_H_ */
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLEventWriter.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLEventWriter.h
index cfbca57a38d3c..1e22f9711a895 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLEventWriter.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLEventWriter.h
@@ -36,12 +36,11 @@ class XMLEventWriter : public IOMTFEmulationObserver {
const std::shared_ptr& input,
const AlgoMuons& algoCandidates,
const AlgoMuons& gbCandidates,
- const std::vector& candMuons) override;
+ const FinalMuons& finalMuons) override;
void observeEventBegin(const edm::Event& iEvent) override;
- void observeEventEnd(const edm::Event& iEvent,
- std::unique_ptr& finalCandidates) override;
+ void observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMuons) override;
void endJob() override;
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h
index 2b2cbb14b89e4..dc27315ca2152 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h
@@ -9,6 +9,8 @@
#define L1T_OmtfP1_PROCCONFIGURATIONBASE_H_
#include "FWCore/ParameterSet/interface/ParameterSet.h"
+#include
+
class ProcConfigurationBase {
public:
ProcConfigurationBase();
@@ -25,8 +27,6 @@ class ProcConfigurationBase {
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;
@@ -35,6 +35,18 @@ class ProcConfigurationBase {
virtual int etaToHwEta(double eta) const = 0;
+ //eta of the middle DT Wheel 2 MB1, in the OMTF scale
+ virtual int mb1W2Eta() const = 0;
+
+ //eta of the middle DT Wheel 2 MB2, in the OMTF scale
+ virtual int mb2W2Eta() const = 0;
+
+ //eta of the middle DT Wheel 2 MB3, in the OMTF scale
+ virtual int mb3W2Eta() const = 0;
+
+ //eta of the middle DT Wheel 2 MB4, in the OMTF scale
+ virtual int mb4W2Eta() const = 0;
+
//returns address for the pdf LUTs
virtual unsigned int ptHwToPtBin(int ptHw) const { return 0; }
@@ -55,6 +67,10 @@ class ProcConfigurationBase {
virtual void setCscLctCentralBx(int lctCentralBx) { this->cscLctCentralBx_ = lctCentralBx; }
+ virtual int dtBxShift() const { return dtBxShift_; }
+
+ virtual void setDtBxShift(int dtBxShift) { this->dtBxShift_ = dtBxShift; }
+
virtual bool getRpcDropAllClustersIfMoreThanMax() const { return rpcDropAllClustersIfMoreThanMax; }
virtual void setRpcDropAllClustersIfMoreThanMax(bool rpcDropAllClustersIfMoreThanMax = true) {
@@ -85,11 +101,12 @@ class ProcConfigurationBase {
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()
+ //In the emulator in most of the places eta value is used, but with the DT-like bining, 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
+ //the phase1 eta scale is used, but all hw values are valid, i.e. the DT-phase-1 bining is NOT used
valueP1Scale = 1,
+ valueP2Scale = 2,
};
StubEtaEncoding getStubEtaEncoding() const { return stubEtaEncoding; }
@@ -100,9 +117,16 @@ class ProcConfigurationBase {
//in the link data it can be different, and it is converted in the DtDigiToStubsConverterOmtf::addDTphiDigi
double dtPhiBUnitsRad() const { return dtPhiBUnitsRad_; }
+ double etaUnit() const { return etaUnit_; }
+
+protected:
+ double etaUnit_ = 0.010875; //=2.61/240 - value from the phase1 interface note
+
private:
int cscLctCentralBx_ = 8; //CSCConstants::LCT_CENTRAL_BX;
+ int dtBxShift_ = 20; //phase-2 DT segment BX shift, different for MC and data
+
//parameters of the RpcClusterization
unsigned int rpcMaxClusterSize = 3;
unsigned int rpcMaxClusterCnt = 2;
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/StubResult.h b/L1Trigger/L1TMuonOverlapPhase1/interface/StubResult.h
index 9260297345b2d..223a1f32ad216 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/StubResult.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/StubResult.h
@@ -15,13 +15,15 @@ class StubResult {
public:
StubResult() {} //empty result
- StubResult(float pdfVal, bool valid, int pdfBin, int layer, MuonStubPtr stub)
- : pdfVal(pdfVal), valid(valid), pdfBin(pdfBin), layer(layer), stub(stub) {}
+ StubResult(float pdfVal, bool valid, int pdfBin, int deltaPhi, int layer, MuonStubPtr stub)
+ : pdfVal(pdfVal), valid(valid), pdfBin(pdfBin), deltaPhi(deltaPhi), layer(layer), stub(stub) {}
const MuonStubPtr& getMuonStub() const { return stub; }
int getPdfBin() const { return pdfBin; }
+ int getDeltaPhi() const { return deltaPhi; }
+
float getPdfVal() const { return pdfVal; }
void setPdfVal(float pdfVal) { this->pdfVal = pdfVal; }
@@ -36,6 +38,7 @@ class StubResult {
pdfVal = 0;
valid = false;
pdfBin = 0;
+ deltaPhi = 0;
layer = 0;
stub.reset();
}
@@ -47,6 +50,9 @@ class StubResult {
//stub and pdfBin should be needed only for debug, testing, generating patterns, etc, but rather not in the firmware
int pdfBin = 0;
+ //input for the neural network
+ int deltaPhi = 0;
+
//n.b, layer might be different then the the stub->layer, because it might be the result of the bending layer (how about eta?)
int layer = 0;
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h
index efa54c9b4facc..8cb869fa57d24 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h
@@ -52,19 +52,9 @@ class MatchingResult {
MatchingResult() {}
- MatchingResult(const SimTrack& simTrack) : simTrack(&simTrack) {
- pdgId = simTrack.type();
- genPt = simTrack.momentum().pt();
- genEta = simTrack.momentum().eta();
- genPhi = simTrack.momentum().phi();
- }
-
- MatchingResult(const TrackingParticle& trackingParticle) : trackingParticle(&trackingParticle) {
- pdgId = trackingParticle.pdgId();
- genPt = trackingParticle.pt();
- genEta = trackingParticle.momentum().eta();
- genPhi = trackingParticle.momentum().phi();
- }
+ MatchingResult(const SimTrack& simTrack, const SimVertex* simVertex);
+
+ MatchingResult(const TrackingParticle& trackingParticle);
ResultType result = ResultType::notMatched;
//bool propagationFailed = false;
@@ -76,19 +66,28 @@ class MatchingResult {
double matchingLikelihood = 0;
- const l1t::RegionalMuonCand* muonCand = nullptr;
- AlgoMuonPtr procMuon; //Processor gbCandidate
+ FinalMuonPtr muonCand;
//to avoid using simTrack or trackingParticle
- double pdgId = 0;
+ int pdgId = 0;
+ //int parrentPdgId = 0;
double genPt = 0;
double genEta = 0;
double genPhi = 0;
+ int genCharge = 0;
+
+ float vertexEta = 0;
+ float vertexPhi = 0;
+ float muonDxy = 0;
+ float muonRho = 0;
+ int parentPdgId = 0;
const SimTrack* simTrack = nullptr;
const SimVertex* simVertex = nullptr;
const TrackingParticle* trackingParticle = nullptr;
+
+ friend std::ostream& operator<<(std::ostream& out, const MatchingResult& matchingResult);
};
/*
@@ -97,7 +96,8 @@ class MatchingResult {
class CandidateSimMuonMatcher : public IOMTFEmulationObserver {
public:
CandidateSimMuonMatcher(const edm::ParameterSet& edmCfg,
- const OMTFConfiguration* omtfConfig,
+ //const OMTFConfiguration* omtfConfig,
+ int nProcessors,
const edm::ESGetToken& magneticFieldEsToken,
const edm::ESGetToken& propagatorEsToken);
@@ -110,73 +110,73 @@ class CandidateSimMuonMatcher : public IOMTFEmulationObserver {
const std::shared_ptr&,
const AlgoMuons& algoCandidates,
const AlgoMuons& gbCandidates,
- const std::vector& candMuons) override;
+ const FinalMuons& finalMuons) override;
void observeEventBegin(const edm::Event& event) override;
- void observeEventEnd(const edm::Event& event,
- std::unique_ptr& finalCandidates) override;
+ void observeEventEnd(const edm::Event& event, FinalMuons& finalMuons) override;
void endJob() override;
+ int calcGlobalPhi(int locPhi, int proc);
+
//simplified ghost busting
- //only candidates in the bx=0 are included
- //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
- std::vector ghostBust(const l1t::RegionalMuonCandBxCollection* mtfCands,
- const AlgoMuons& gbCandidates,
- AlgoMuons& ghostBustedProcMuons);
+ FinalMuons ghostBust(const FinalMuons& finalMuons);
FreeTrajectoryState simTrackToFts(const SimTrack& simTrack, const SimVertex& simVertex);
FreeTrajectoryState simTrackToFts(const TrackingParticle& trackingParticle);
+ TrajectoryStateOnSurface atStation1(const FreeTrajectoryState& ftsStart) const;
+
TrajectoryStateOnSurface atStation2(const FreeTrajectoryState& ftsStart) const;
TrajectoryStateOnSurface propagate(const SimTrack& simTrack, const edm::SimVertexContainer* simVertices);
TrajectoryStateOnSurface propagate(const TrackingParticle& trackingParticle);
- //tsof should be the result of track propagation
- MatchingResult match(const l1t::RegionalMuonCand* omtfCand,
- const AlgoMuonPtr& procMuon,
- const SimTrack& simTrack,
- TrajectoryStateOnSurface& tsof);
+ void propagate(MatchingResult& result);
- MatchingResult match(const l1t::RegionalMuonCand* omtfCand,
- const AlgoMuonPtr& procMuon,
- const TrackingParticle& trackingParticle,
- TrajectoryStateOnSurface& tsof);
+ void match(const FinalMuons& finalMuons, MatchingResult& result, std::vector& matchingResults);
- std::vector cleanMatching(std::vector matchingResults,
- std::vector& muonCands,
- AlgoMuons& ghostBustedProcMuons);
+ void match(const FinalMuonPtr& finalMuon3, MatchingResult& result);
- std::vector match(std::vector& muonCands,
- AlgoMuons& ghostBustedProcMuons,
+ std::vector cleanMatching(std::vector matchingResults, const FinalMuons& finalMuons);
+
+ std::vector match(const FinalMuons& finalMuons,
const edm::SimTrackContainer* simTracks,
const edm::SimVertexContainer* simVertices,
std::function const& simTrackFilter);
- std::vector match(std::vector& muonCands,
- AlgoMuons& ghostBustedProcMuons,
+ std::vector match(const FinalMuons& finalMuons,
const TrackingParticleCollection* trackingParticles,
std::function const& simTrackFilter);
//matching without any propagation, just checking basic geometrical agreement between simMuon and candidates
//problem with propagation is the it does not work for low pt muons (pt < ~3GeV)
//which is not good for dumping the data for the NN training. So for that purpose it is better to use the matchSimple
- std::vector matchSimple(std::vector& muonCands,
- AlgoMuons& ghostBustedProcMuons,
+ std::vector matchSimple(const FinalMuons& finalMuons,
const edm::SimTrackContainer* simTracks,
const edm::SimVertexContainer* simVertices,
std::function const& simTrackFilter);
+ //no matching, just collect muonCands
+ std::vector collectMuonCands(const FinalMuons& finalMuons);
+
std::vector getMatchingResults() { return matchingResults; }
+ enum class MatchingType : short {
+ noMatcher = -1,
+ withPropagator = 0,
+ simplePropagation = 1,
+ simpleMatching = 2,
+ collectMuonCands = 3
+ };
+
+ MatchingType getMatchingType() const { return matchingType; }
+
private:
- const OMTFConfiguration* omtfConfig;
+ int nProcessors = 6;
const edm::ParameterSet& edmCfg;
@@ -189,10 +189,16 @@ class CandidateSimMuonMatcher : public IOMTFEmulationObserver {
edm::ESHandle magField;
edm::ESHandle propagator;
- TH1D* deltaPhiPropCandMean = nullptr;
- TH1D* deltaPhiPropCandStdDev = nullptr;
+ TH1* minDelta_pos = nullptr;
+ TH1* maxDelta_pos = nullptr;
+ TH1* medianDelta_pos = nullptr;
+
+ TH1* minDelta_neg = nullptr;
+ TH1* maxDelta_neg = nullptr;
+ TH1* medianDelta_neg = nullptr;
- bool usePropagation = false;
+ MatchingType matchingType = MatchingType::simpleMatching;
+ //bool usePropagation = false;
};
#endif /* L1T_OmtfP1_TOOLS_MUONCANDIDATEMATCHER_H_ */
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h
index 1543e9d831525..4d7cbfd872d7a 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h
@@ -22,6 +22,8 @@
#include "TH2.h"
#include
+#include
+#include
class TTree;
@@ -35,11 +37,16 @@ struct OmtfEvent {
char muonCharge = 0;
float muonDxy = 0;
float muonRho = 0;
+ //pdgId in principle should be int
+ short parentPdgId = 0;
+ float vertexEta = 0;
+ float vertexPhi = 0;
float omtfPt = 0, omtfEta = 0, omtfPhi = 0, omtfUPt = 0;
char omtfCharge = 0;
char omtfProcessor = 0;
short omtfScore = 0;
+ short omtfRefHitPhi = 0;
short omtfHwEta = 0;
@@ -62,9 +69,9 @@ struct OmtfEvent {
struct {
char layer;
char quality;
- char z;
+ char etaHw;
char valid;
- short eta;
+ short deltaR;
short phiDist;
};
};
@@ -72,6 +79,9 @@ struct OmtfEvent {
~Hit() {}
};
+ // ensure the packed Hit view fits in the unsigned long rawData storage
+ static_assert(sizeof(Hit) <= sizeof(unsigned long), "OmtfEvent::Hit must fit into unsigned long rawData");
+
std::vector hits;
};
@@ -88,10 +98,9 @@ class DataROOTDumper2 : public EmulationObserverBase {
const std::shared_ptr&,
const AlgoMuons& algoCandidates,
const AlgoMuons& gbCandidates,
- const std::vector& candMuons) override;
+ const FinalMuons& finalMuons) override;
- void observeEventEnd(const edm::Event& iEvent,
- std::unique_ptr& finalCandidates) override;
+ void observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMuons) override;
void endJob() override;
@@ -109,11 +118,9 @@ class DataROOTDumper2 : public EmulationObserverBase {
TH1I* ptGenPos = nullptr;
TH1I* ptGenNeg = nullptr;
- std::vector hitVsPt;
+ //std::vector hitVsPt;
bool dumpKilledOmtfCands = false;
-
- bool usePropagation = false;
};
#endif /* L1T_OmtfP1_TOOLS_DATAROOTDUMPER2_H_ */
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EmulationObserverBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EmulationObserverBase.h
index f2e7b90c6831c..18617066fd2d8 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EmulationObserverBase.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EmulationObserverBase.h
@@ -27,7 +27,7 @@ class EmulationObserverBase : public IOMTFEmulationObserver {
const std::shared_ptr& input,
const AlgoMuons& algoCandidates,
const AlgoMuons& gbCandidates,
- const std::vector& candMuons) override;
+ const FinalMuons& finalMuons) override;
void observeEventBegin(const edm::Event& iEvent) override;
@@ -41,7 +41,7 @@ class EmulationObserverBase : public IOMTFEmulationObserver {
const std::vector findGenMuon(const edm::Event& event);
protected:
- edm::ParameterSet edmCfg;
+ const edm::ParameterSet& edmCfg;
const OMTFConfiguration* omtfConfig;
const SimTrack* simMuon = nullptr;
@@ -49,7 +49,7 @@ class EmulationObserverBase : public IOMTFEmulationObserver {
//candidate found by omtf in a given event
AlgoMuons::value_type omtfCand;
- l1t::RegionalMuonCand regionalMuonCand;
+ FinalMuonPtr finalMuon;
//AlgoMuons algoCandidates;
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EventCapture.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EventCapture.h
index df9f23524226b..3d4e086c4c257 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EventCapture.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/EventCapture.h
@@ -34,12 +34,11 @@ class EventCapture : public IOMTFEmulationObserver {
const std::shared_ptr&,
const AlgoMuons& algoCandidates,
const AlgoMuons& gbCandidates,
- const std::vector& candMuons) override;
+ const FinalMuons& finalMuons) override;
void observeEventBegin(const edm::Event& event) override;
- void observeEventEnd(const edm::Event& event,
- std::unique_ptr& finalCandidates) override;
+ void observeEventEnd(const edm::Event& event, FinalMuons& finalMuons) override;
void endJob() override;
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternGenerator.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternGenerator.h
index 6b95241296579..66f53d7f01d7e 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternGenerator.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternGenerator.h
@@ -20,8 +20,7 @@ class PatternGenerator : public PatternOptimizerBase {
~PatternGenerator() override;
- void observeEventEnd(const edm::Event& iEvent,
- std::unique_ptr& finalCandidates) override;
+ void observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMuons) override;
void endJob() override;
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternOptimizerBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternOptimizerBase.h
index 549d67948f186..50bcfce47f089 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternOptimizerBase.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/PatternOptimizerBase.h
@@ -33,8 +33,7 @@ class PatternOptimizerBase : public EmulationObserverBase {
~PatternOptimizerBase() override;
- void observeEventEnd(const edm::Event& iEvent,
- std::unique_ptr& finalCandidates) override;
+ void observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMuons) override;
void endJob() override;
diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/StubsSimHitsMatcher.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/StubsSimHitsMatcher.h
index aa6796067fcfb..fc52564544e6c 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/StubsSimHitsMatcher.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/StubsSimHitsMatcher.h
@@ -9,6 +9,7 @@
#define L1T_OmtfP1_TOOLS_STUBSSIMHITSMATCHER_H_
#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h"
+#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h"
#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinput.h"
#include "FWCore/Framework/interface/EventSetup.h"
@@ -39,8 +40,7 @@ class StubsSimHitsMatcher {
void endJob();
void match(const edm::Event& iEvent,
- const l1t::RegionalMuonCand* omtfCand,
- const AlgoMuonPtr& procMuon,
+ const FinalMuonPtr& finalMuon,
std::ostringstream& ostr); //Processor gbCandidate);
class MatchedTrackInfo {
diff --git a/L1Trigger/L1TMuonOverlapPhase1/plugins/L1TMuonOverlapPhase1TrackProducer.h b/L1Trigger/L1TMuonOverlapPhase1/plugins/L1TMuonOverlapPhase1TrackProducer.h
index 4ab0e27c19322..fbf5ccdbeaa7d 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/plugins/L1TMuonOverlapPhase1TrackProducer.h
+++ b/L1Trigger/L1TMuonOverlapPhase1/plugins/L1TMuonOverlapPhase1TrackProducer.h
@@ -46,7 +46,7 @@ class L1TMuonOverlapPhase1TrackProducer : public edm::one::EDProducer omtfParamsEsToken;
- //needed for AngleConverterBase
+ //needed for OmtfAngleConverter
MuonGeometryTokens muonGeometryTokens;
///needed by tools/CandidateSimMuonMatcher.h
diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/AngleConverterBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/AngleConverterBase.cc
deleted file mode 100644
index 35c1bde1863e1..0000000000000
--- a/L1Trigger/L1TMuonOverlapPhase1/src/AngleConverterBase.cc
+++ /dev/null
@@ -1,457 +0,0 @@
-#include "L1Trigger/L1TMuonOverlapPhase1/interface/AngleConverterBase.h"
-#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h"
-
-#include "DataFormats/CSCDigi/interface/CSCConstants.h"
-#include "L1Trigger/DTUtilities/interface/DTTrigGeom.h"
-
-#include "FWCore/Framework/interface/EventSetup.h"
-#include "Geometry/Records/interface/MuonGeometryRecord.h"
-#include "Geometry/CSCGeometry/interface/CSCGeometry.h"
-#include "Geometry/DTGeometry/interface/DTGeometry.h"
-#include "Geometry/RPCGeometry/interface/RPCGeometry.h"
-#include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigi.h"
-#include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambPhDigi.h"
-#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) {
- return (T(0) < val) - (val < T(0));
- }
-
- int fixCscOffsetGeom(int offsetLoc) {
- // fix for CSC geo dependence from GlobalTag
-
- // dump of CSC offsets for MC global tag
- const std::vector offCSC = {-154, -133, -17, -4, 4, 17, 133, 146, 154, 167, 283, 296, 304, 317,
- 433, 446, 454, 467, 583, 596, 604, 617, 733, 746, 754, 767, 883, 904};
- auto gep = std::lower_bound(offCSC.begin(), offCSC.end(), offsetLoc);
- int fixOff = (gep != offCSC.end()) ? *gep : *(gep - 1);
- if (gep != offCSC.begin() && std::abs(*(gep - 1) - offsetLoc) < std::abs(fixOff - offsetLoc))
- fixOff = *(gep - 1);
- return fixOff;
- }
-
-} // namespace
-
-AngleConverterBase::AngleConverterBase() : _geom_cache_id(0ULL) {}
-///////////////////////////////////////
-///////////////////////////////////////
-AngleConverterBase::~AngleConverterBase() {}
-///////////////////////////////////////
-///////////////////////////////////////
-void AngleConverterBase::checkAndUpdateGeometry(const edm::EventSetup& es,
- const ProcConfigurationBase* config,
- const MuonGeometryTokens& muonGeometryTokens) {
- if (muonGeometryRecordWatcher.check(es)) {
- _georpc = es.getHandle(muonGeometryTokens.rpcGeometryEsToken);
- _geocsc = es.getHandle(muonGeometryTokens.cscGeometryEsToken);
- _geodt = es.getHandle(muonGeometryTokens.dtGeometryEsToken);
- }
- this->config = config;
- nPhiBins = config->nPhiBins();
-}
-///////////////////////////////////////
-///////////////////////////////////////
-int AngleConverterBase::getProcessorPhi(int phiZero, l1t::tftype part, int dtScNum, int dtPhi) const {
- int dtPhiBins = 4096;
-
- double hsPhiPitch = 2 * M_PI / nPhiBins; // width of phi Pitch, related to halfStrip at CSC station 2
-
- 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)); // 216.2688
-
- int ichamber = sector - 1;
- if (ichamber > 6)
- ichamber = ichamber - 12;
-
- int offsetGlobal = (int)nPhiBins * ichamber / 12;
-
- int phiConverted = floor(dtPhi * scale_coeff / pow(2, 11)) + offsetGlobal - phiZero;
-
- //LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" phiZero "<foldPhi(phi)<foldPhi(phiConverted);
-}
-///////////////////////////////////////
-///////////////////////////////////////
-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.
- // FIXME: These parameters depends on processor and chamber only so may be precomputed and put in map
- //
-
- int halfStrip = digi.getStrip(); // returns halfStrip 0..159
-
- const CSCChamber* chamber = _geocsc->chamber(csc);
-
- //in the PhaseIITDRSpring19DR dataset (generated with CMSSW_10_6_1_patch2?), in case of the ME1/1 ring 4 (higher eta) the detId in the CSCCorrelatedLCTDigiCollection is ME1/1 ring 1 (instead ME1/1/4 as it was before),
- //and the digi.getStrip() is increased by 2*64 (i.e. number of half strips in the chamber roll)
- if (csc.station() == 1 && csc.ring() == 1 && halfStrip > 128) {
- CSCDetId cscME11 = CSCDetId(csc.endcap(), csc.station(), 4, csc.chamber()); //changing ring to 4
- chamber = _geocsc->chamber(cscME11);
- }
-
- const CSCChamberSpecs* cspec = chamber->specs();
- 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 = std::abs(stripPhiPitch / hsPhiPitch / 2.);
- if (std::abs(scale - 1.) < 0.0002)
- scale = 1.;
-
- double phiHalfStrip0 = layer->centerOfStrip(1).phi() - order * stripPhiPitch / 4.;
-
- int offsetLoc = lround((phiHalfStrip0) / hsPhiPitch - phiZero);
- offsetLoc = config->foldPhi(offsetLoc);
-
- if (csc.station() == 1 && csc.ring() == 1 && halfStrip > 128) { //ME1/1/
- /* if(cspec->nStrips() != 64)
- edm::LogImportant("l1tOmtfEventPrint") <<__FUNCTION__<<":"<<__LINE__<<" cspec->nStrips() != 64 in case of the ME1/1, phi of the muon stub will be not correct. chamber "
- <nStrips() "<nStrips()<nStrips() = 48. but the offset of 128 half strips in the digi.getStrip() looks to be good*/
- halfStrip -= 128;
- }
-
- //FIXME: to be checked (only important for ME1/3) keep more bits for offset, truncate at the end
-
- int fixOff = offsetLoc;
- // 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()) {
- 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
-
- /*//debug
- auto localPoint = layer->toLocal(layer->centerOfStrip(halfStrip));
- LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << 147 << " csc: " <id()<<" "<id().rawId()
- << " halfStrip "<centerOfStrip(halfStrip).phi()<<" local phi "<foldPhi(phi)<<" ("<centerOfStrip(halfStrip/2 +1).phi() )
- <<" centerOfStrip/hsPhiPitch "<< ( (layer->centerOfStrip(halfStrip/2 + 1).phi() )/hsPhiPitch)<<" hsPhiPitch "<geometry()->phiSpan().first<<" phiSpan.s "<geometry()->phiSpan().second
- <<" nStrips "<nStrips()
- //<<" strip 1 "<centerOfStrip(1).phi() )<<" strip last "<centerOfStrip(cspec->nStrips()).phi() )
- << std::endl;*/
-
- return config->foldPhi(phi);
-}
-
-///////////////////////////////////////
-///////////////////////////////////////
-int AngleConverterBase::getProcessorPhi(
- int phiZero, l1t::tftype part, const RPCDetId& rollId, const unsigned int& digi1, const unsigned int& digi2) const {
- const double hsPhiPitch = 2 * M_PI / nPhiBins;
- const int dummy = nPhiBins;
- const RPCRoll* roll = _georpc->roll(rollId);
- if (!roll)
- return dummy;
-
- double stripPhi1 = (roll->toGlobal(roll->centreOfStrip((int)digi1))).phi(); // note [-pi,pi]
- 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) && std::abs(stripPhi1) > M_PI / 2.) {
- if (std::signbit(stripPhi1)) { //stripPhi1 is negative
- stripPhi1 += 2 * M_PI;
- } else //stripPhi2 is negative
- stripPhi2 += 2 * M_PI;
- }
- int halfStrip = lround(((stripPhi1 + stripPhi2) / 2.) / hsPhiPitch);
- halfStrip = config->foldPhi(halfStrip); //only for the case when the two strips are on different sides of phi = pi
-
- LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << 185 << " roll " << rollId.rawId() << " " << rollId
- << " cluster: firstStrip " << digi1 << " stripPhi1Global " << stripPhi1
- << " stripPhi1LocalPhi " << roll->centreOfStrip((int)digi1).x() << " y "
- << roll->centreOfStrip((int)digi1).y() << " lastStrip " << digi2 << " stripPhi2Global "
- << stripPhi2 << " stripPhi2LocalPhi x " << roll->centreOfStrip((int)digi2).x() << " y "
- << roll->centreOfStrip((int)digi2).y() << " halfStrip " << halfStrip << std::endl;
-
- return config->foldPhi(halfStrip - phiZero);
-}
-
-int AngleConverterBase::getProcessorPhi(unsigned int iProcessor,
- l1t::tftype part,
- const RPCDetId& rollId,
- const unsigned int& digi) const {
- const double hsPhiPitch = 2 * M_PI / nPhiBins;
- const int dummy = nPhiBins;
- int processor = iProcessor + 1;
- const RPCRoll* roll = _georpc->roll(rollId);
- if (!roll)
- return dummy;
-
- double phi15deg = M_PI / 3. * (processor - 1) + M_PI / 12.;
- // "0" is 15degree moved cyclically to each processor, note [0,2pi]
-
- double stripPhi = (roll->toGlobal(roll->centreOfStrip((int)digi))).phi(); // note [-pi,pi]
-
- // adjust [0,2pi] and [-pi,pi] to get deltaPhi difference properly
- switch (processor) {
- case 1:
- break;
- case 6: {
- phi15deg -= 2 * M_PI;
- break;
- }
- default: {
- if (stripPhi < 0)
- stripPhi += 2 * M_PI;
- break;
- }
- }
-
- // local angle in CSC halfStrip usnits
- int halfStrip = lround((stripPhi - phi15deg) / hsPhiPitch);
-
- return halfStrip;
-}
-///////////////////////////////////////
-///////////////////////////////////////
-EtaValue AngleConverterBase::getGlobalEtaDt(const DTChamberId& detId) const {
- Local2DPoint chamberMiddleLP(0, 0);
- GlobalPoint chamberMiddleGP = _geodt->chamber(detId)->toGlobal(chamberMiddleLP);
-
- const DTChamberId baseidNeigh(detId.wheel() + (detId.wheel() >= 0 ? -1 : +1), detId.station(), detId.sector());
- GlobalPoint chambNeighMiddleGP = _geodt->chamber(baseidNeigh)->toGlobal(chamberMiddleLP);
-
- EtaValue etaValue = {
- config->etaToHwEta(chamberMiddleGP.eta()),
- config->etaToHwEta(std::abs(chamberMiddleGP.eta() - chambNeighMiddleGP.eta())) / 2,
- 0, //quality
- 0, //bx
- 0 //timin
- };
-
- //LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" rawid "<& etaSegments) const {
- const DTChamberId baseid(thetaDigi.whNum(), thetaDigi.stNum(), thetaDigi.scNum() + 1);
- DTTrigGeom trig_geom(_geodt->chamber(baseid), false);
-
- // super layer 2 is the theta superlayer in a DT chamber
- // station 4 does not have a theta super layer
- // the BTI index from the theta trigger is an OR of some BTI outputs
- // so, we choose the BTI that's in the middle of the group
- // as the BTI that we get theta from
- // TODO:::::>>> need to make sure this ordering doesn't flip under wheel sign
- const int NBTI_theta = trig_geom.nCell(2);
- for (unsigned int btiGroup = 0; btiGroup < 7; ++btiGroup) {
- if (thetaDigi.position(btiGroup)) {
- unsigned btiActual = btiGroup * NBTI_theta / 7 + NBTI_theta / 14 + 1;
- DTBtiId thetaBTI = DTBtiId(baseid, 2, btiActual);
- GlobalPoint theta_gp = trig_geom.CMSPosition(thetaBTI);
-
- EtaValue etaValue = {
- config->etaToHwEta(theta_gp.eta()),
- 0,
- thetaDigi.quality(btiGroup),
- thetaDigi.bxNum(),
- 0 //TODO what about sub-bx timing???
- };
- etaSegments.emplace_back(etaValue);
-
- //LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" bx "< AngleConverterBase::getGlobalEta(const L1MuDTChambThContainer* dtThDigis,
- int bxFrom,
- int bxTo) const {
- //LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" dtThDigis size "<getContainer()->size()< etaSegments;
-
- for (auto& thetaDigi : (*(dtThDigis->getContainer()))) {
- if (thetaDigi.bxNum() >= bxFrom && thetaDigi.bxNum() <= bxTo) {
- getGlobalEta(thetaDigi, etaSegments);
- }
- }
- return etaSegments;
-}
-
-//just read from the drawing
-float AngleConverterBase::cscChamberEtaSize(const CSCDetId& detId) const {
- if (detId.station() == 1) {
- if (detId.ring() == 1)
- return (2.5 - 1.6) / 2.;
- ///ME1/1 lower eta (b?, eta < ~2.1), L1TkMuonBayes eta bins 6-11 - but getGlobalEtaCsc(const CSCDetId& detId) gives the midle of the full chamber, so here we put the size of the full chamber
- if (detId.ring() == 2)
- return (1.7 - 1.2) / 2.;
- if (detId.ring() == 3)
- return (1.12 - 0.9) / 2.;
- if (detId.ring() == 4)
- return (2.5 - 1.6) / 2.; ///ME1/1 higher eta (a?, eta > ~2.1), L1TkMuonBayes eta bins 10-15
- } else if (detId.station() == 2) {
- if (detId.ring() == 1)
- return (2.5 - 1.6) / 2.;
- if (detId.ring() == 2)
- return (1.6 - 1.0) / 2.;
- } else if (detId.station() == 3) {
- if (detId.ring() == 1)
- return (2.5 - 1.7) / 2.;
- if (detId.ring() == 2)
- return (1.7 - 1.1) / 2.;
- } else if (detId.station() == 4) {
- if (detId.ring() == 1)
- return (2.45 - 1.8) / 2.;
- if (detId.ring() == 2)
- return (1.8 - 1.2) / 2.;
- }
- return 0;
-}
-
-EtaValue AngleConverterBase::getGlobalEta(const CSCDetId& detId, const CSCCorrelatedLCTDigi& aDigi) const {
- ///Code taken from GeometryTranslator.
- ///Will be replaced by direct CSC phi local to global scale
- ///transformation as used in FPGA implementation
-
- // alot of this is transcription and consolidation of the CSC
- // global phi calculation code
- // this works directly with the geometry
- // rather than using the old phi luts
-
- auto chamb = _geocsc->chamber(detId);
- auto layer_geom = chamb->layer(CSCConstants::KEY_ALCT_LAYER)->geometry();
- auto layer = chamb->layer(CSCConstants::KEY_ALCT_LAYER);
-
- const uint16_t keyWG = aDigi.getKeyWG();
-
- const LocalPoint lpWg = layer_geom->localCenterOfWireGroup(keyWG);
- const GlobalPoint gpWg = layer->surface().toGlobal(lpWg);
-
- EtaValue etaSegment = {
- config->etaToHwEta(gpWg.eta()),
- 0, //config->etaToHwEta(cscChamberEtaSize(id) ),
- 0,
- aDigi.getBX(),
- 0 //tming???
- };
-
- //LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" csc "<chamber(detId);
-
- Local2DPoint chamberMiddleLP(0, 0);
- GlobalPoint chamberMiddleGP = chamb->toGlobal(chamberMiddleLP);
-
- EtaValue etaValue = {
- config->etaToHwEta(chamberMiddleGP.eta()),
- config->etaToHwEta(cscChamberEtaSize(detId)),
- 0,
- 0, //bx
- 0 //timnig
- };
-
- //LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" rawid "<roll(id);
- const LocalPoint lp = roll->centreOfStrip((int)strip);
- const GlobalPoint gp = roll->toGlobal(lp);
-
- int neighbRoll = 1; //neighbor roll in eta
- //roll->chamber()->nrolls() does not work
- if (id.region() == 0) { //barel
- 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 {
- neighbRoll = 2;
- }
- } else //two-roll chamber
- neighbRoll = (id.roll() == 1 ? 3 : 1);
- } else { //endcap
- neighbRoll = id.roll() + (id.roll() == 1 ? +1 : -1);
- }
-
- const RPCDetId idNeigh =
- RPCDetId(id.region(), id.ring(), id.station(), id.sector(), id.layer(), id.subsector(), neighbRoll);
- //LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" rpc "<roll(idNeigh);
- const LocalPoint lpNeigh = rollNeigh->centreOfStrip((int)strip);
- const GlobalPoint gpNeigh = rollNeigh->toGlobal(lpNeigh);
-
- EtaValue etaValue = {config->etaToHwEta(gp.eta()),
- config->etaToHwEta(std::abs(gp.eta() - gpNeigh.eta())) /
- 2, //half of the size of the strip in eta - not precise, but OK
- 0};
-
- //LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" rpc "<geometry()->numberOfStrips();
- const double phi1 = layer->centerOfStrip(1).phi();
- const double phiN = layer->centerOfStrip(nStrips).phi();
- return ((std::abs(phi1 - phiN) < M_PI && phi1 >= phiN) || (std::abs(phi1 - phiN) >= M_PI && phi1 < phiN));
-}
-///////////////////////////////////////
-///////////////////////////////////////
-const int AngleConverterBase::findBTIgroup(const L1MuDTChambPhDigi& aDigi, const L1MuDTChambThContainer* dtThDigis) {
- int bti_group = -1;
-
- const L1MuDTChambThDigi* theta_segm =
- dtThDigis->chThetaSegm(aDigi.whNum(), aDigi.stNum(), aDigi.scNum(), aDigi.bxNum());
- if (!theta_segm)
- return bti_group;
-
- for (unsigned int i = 0; i < 7; ++i) {
- if (theta_segm->position(i) && bti_group < 0)
- bti_group = i;
- ///If there are more than one theta digi we do not take is
- ///due to unresolved ambiguity. In this case we take eta of the
- ///middle of the chamber.
- else if (theta_segm->position(i) && bti_group > -1)
- return -1;
- }
-
- return bti_group;
-}
-///////////////////////////////////////
-///////////////////////////////////////
diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/MuonStubMakerBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/MuonStubMakerBase.cc
index 459a1d9c0b953..41200216c4d5c 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/src/MuonStubMakerBase.cc
+++ b/L1Trigger/L1TMuonOverlapPhase1/src/MuonStubMakerBase.cc
@@ -54,6 +54,8 @@ void CscDigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers,
int bxFrom,
int bxTo,
std::vector >& observers) {
+ boost::property_tree::ptree procDataTree;
+
auto chamber = cscDigis->begin();
auto chend = cscDigis->end();
for (; chamber != chend; ++chamber) {
@@ -65,14 +67,32 @@ void CscDigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers,
auto digi = (*chamber).second.first;
auto dend = (*chamber).second.second;
+
+ auto& cscChamber = procDataTree.add_child("cscChamber", boost::property_tree::ptree());
+ cscChamber.add(".name", csc.chamberName());
+
for (; digi != dend; ++digi) {
///Check if LCT trigger primitive has the right BX.
int digiBx = digi->getBX() - config->cscLctCentralBx();
if (digiBx >= bxFrom && digiBx <= bxTo)
addCSCstubs(muonStubsInLayers, rawid, *digi, iProcessor, procTyp);
+
+ auto& cscDigi = cscChamber.add_child("cscDigi", boost::property_tree::ptree());
+ cscDigi.add(".halfStrip", digi->getStrip());
+ cscDigi.add(".keyWG", digi->getKeyWG());
+ cscDigi.add(".pattern", digi->getPattern());
+ cscDigi.add(".slope", digi->getSlope());
+ cscDigi.add(".bend", digi->getBend());
+ cscDigi.add(".fractionalSlope", digi->getFractionalSlope());
+ cscDigi.add(".quality", digi->getQuality());
+ cscDigi.add(".QuartStrip", (int)(digi->getQuartStripBit()));
+ cscDigi.add(".eighthStrip", (int)(digi->getEighthStripBit()));
}
}
+
+ for (auto& obs : observers)
+ obs->addProcesorData("cscData", procDataTree);
}
void RpcDigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers,
diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/FinalMuon.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/FinalMuon.cc
new file mode 100644
index 0000000000000..823c873efdabb
--- /dev/null
+++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/FinalMuon.cc
@@ -0,0 +1,25 @@
+/*
+ * FinalMuon.cc
+ *
+ * Created on: Nov 10, 2025
+ * Author: kbunkow
+ */
+
+#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h"
+
+#include
+#include
+
+std::ostream &operator<<(std::ostream &out, const FinalMuon &finalMuon) {
+ out << "finalMuon";
+ out << " pt " << std::setw(8) << finalMuon.ptGev << " GeV";
+ out << " phi " << std::setw(8) << finalMuon.phiRad;
+ out << " sign " << std::setw(2) << finalMuon.sign;
+ out << " eta " << std::setw(8) << finalMuon.etaRad;
+ out << " ptGmt " << std::setw(8) << finalMuon.getPtGmt();
+ out << " etaGmt " << std::setw(8) << finalMuon.getEtaGmt();
+ out << " phiGmt " << std::setw(8) << finalMuon.getPhiGmt();
+ //<< " hwPhi " << muonCand->hwPhi();
+ out << " hwQual " << finalMuon.getQuality() << " processor " << finalMuon.getProcessor();
+ return out;
+}
diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBuster.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBuster.cc
index 7cc8378a4ab76..674014ce85959 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBuster.cc
+++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBuster.cc
@@ -40,7 +40,8 @@ AlgoMuons GhostBuster::select(AlgoMuons refHitCands, int charge) {
//do not accept candidates with similar phi (any charge combination)
//veto window 5deg(=half of logic cone)=5/360*5760=80"logic strips"
//veto window 5 degree in GMT scale is 5/360*576=8 units
- if (std::abs(omtfConfig->procPhiToGmtPhi((*it1)->getPhi()) - omtfConfig->procPhiToGmtPhi((*it2)->getPhi())) < 8) {
+ if (std::abs(omtfConfig->procPhiToGmtPhase1Phi((*it1)->getPhi()) -
+ omtfConfig->procPhiToGmtPhase1Phi((*it2)->getPhi())) < 8) {
// if(std::abs(it1->getPhi() - it2->getPhi())<5/360.0*nPhiBins){
isGhost = true;
break;
diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc
index 4da5c102f5d3f..9040241b231cf 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc
+++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc
@@ -105,12 +105,55 @@ AlgoMuons GhostBusterPreferRefDt::select(AlgoMuons muonsIN, int charge) {
return true;
};
+ //this function is for the OMTF version with unconstrained pt, if the DT ref hits with quality 2 are allowed
+ auto customByRefLayerAndHitQual = [&](const AlgoMuons::value_type& a, const AlgoMuons::value_type& b) -> bool {
+ if (!a->isValid()) {
+ return true;
+ }
+ if (!b->isValid()) {
+ return false;
+ }
+
+ int aRefLayerLogicNum = omtfConfig->getRefToLogicNumber()[a->getRefLayer()];
+ int aRefHitQual = 0;
+ //MB1 or MB2, i.e. the station for which extrapolation is done
+ if (aRefLayerLogicNum == 0 || aRefLayerLogicNum == 2) {
+ aRefHitQual = a->getStubResult(aRefLayerLogicNum).getMuonStub()->qualityHw;
+ aRefHitQual = aRefHitQual >= 4 ? 1 : 0;
+ }
+
+ int bRefLayerLogicNum = omtfConfig->getRefToLogicNumber()[b->getRefLayer()];
+ int bRefHitQual = 0;
+ if (bRefLayerLogicNum == 0 || bRefLayerLogicNum == 2) {
+ bRefHitQual = b->getStubResult(bRefLayerLogicNum).getMuonStub()->qualityHw;
+ bRefHitQual = bRefHitQual >= 4 ? 1 : 0;
+ }
+
+ if (aRefHitQual > bRefHitQual)
+ return false;
+ else if (aRefHitQual == bRefHitQual && aRefLayerLogicNum < bRefLayerLogicNum)
+ return false;
+ else if (aRefHitQual == bRefHitQual && aRefLayerLogicNum == bRefLayerLogicNum && a->getPdfSum() > b->getPdfSum())
+ return false;
+ else if (aRefHitQual == bRefHitQual && aRefLayerLogicNum == bRefLayerLogicNum && a->getPdfSum() == b->getPdfSum() &&
+ a->getPatternNumConstr() > b->getPatternNumConstr())
+ //should be rather getPatternNum(), but for FW getPatternNumConstr() is easier
+ return false;
+ else if (aRefHitQual == bRefHitQual && aRefLayerLogicNum == bRefLayerLogicNum && a->getPdfSum() == b->getPdfSum() &&
+ a->getPatternNumConstr() == b->getPatternNumConstr())
+ return false;
+ else
+ return true;
+ };
+
if (omtfConfig->getGhostBusterType() == "byLLH")
std::sort(muonsIN.rbegin(), muonsIN.rend(), customLessByLLH);
else if (omtfConfig->getGhostBusterType() == "byFPLLH")
std::sort(muonsIN.rbegin(), muonsIN.rend(), customLessByFPLLH);
else if (omtfConfig->getGhostBusterType() == "byRefLayer")
std::sort(muonsIN.rbegin(), muonsIN.rend(), customByRefLayer);
+ else if (omtfConfig->getGhostBusterType() == "byRefLayerAndHitQual")
+ std::sort(muonsIN.rbegin(), muonsIN.rend(), customByRefLayerAndHitQual);
else
std::sort(muonsIN.rbegin(), muonsIN.rend(), customLess);
@@ -139,8 +182,8 @@ AlgoMuons GhostBusterPreferRefDt::select(AlgoMuons muonsIN, int charge) {
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) {
+ if (muIN2->isValid() && std::abs(omtfConfig->procPhiToGmtPhase1Phi(muIN1->getPhi()) -
+ omtfConfig->procPhiToGmtPhase1Phi(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);
@@ -152,9 +195,10 @@ AlgoMuons GhostBusterPreferRefDt::select(AlgoMuons muonsIN, int charge) {
//The condition abs(muIN2->getEtaHw()) != 121 was added in the FW in 2024
//TODO add 95 meaning no DT segment was found, or don't use 95 in OmtfAngleConverter::getGlobalEta
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 &&
- abs(muIN2->getEtaHw()) != 121)) {
+ (abs(muIN1->getEtaHw()) == omtfConfig->mb1W2Eta() || abs(muIN1->getEtaHw()) == omtfConfig->mb2W2Eta() ||
+ abs(muIN1->getEtaHw()) == omtfConfig->mb3W2Eta()) &&
+ (abs(muIN2->getEtaHw()) != omtfConfig->mb1W2Eta() && abs(muIN2->getEtaHw()) != omtfConfig->mb2W2Eta() &&
+ abs(muIN2->getEtaHw()) != omtfConfig->mb3W2Eta() && abs(muIN2->getEtaHw()) != 121)) {
muIN1->setEta(muIN2->getEtaHw());
}
}
diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPattern.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPattern.cc
index 180d08735ca39..40aa39514ab4b 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPattern.cc
+++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPattern.cc
@@ -11,8 +11,7 @@ int GoldenPattern::meanDistPhiValue(unsigned int iLayer, unsigned int iRefLayer,
////////////////////////////////////////////////////
////////////////////////////////////////////////////
-int GoldenPattern::propagateRefPhi(int phiRef, int etaRef, unsigned int iRefLayer) {
- unsigned int iLayer = 2; //MB2
+int GoldenPattern::propagateRefPhi(int phiRef, int etaRef, unsigned int iRefLayer, unsigned int iLayer) {
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
diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPatternBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPatternBase.cc
index ef381e721267e..da5a335185c46 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPatternBase.cc
+++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPatternBase.cc
@@ -51,6 +51,7 @@ StubResult GoldenPatternBase::process1Layer1RefLayer(unsigned int iRefLayer,
int phiMean = this->meanDistPhiValue(iLayer, iRefLayer, refStub->phiBHw);
int phiDistMin = myOmtfConfig->nPhiBins();
+ int deltaPhiSel = myOmtfConfig->nPhiBins();
///Select hit closest to the mean of probability
///distribution in given layer
@@ -78,7 +79,8 @@ 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 - extrapolatedPhi[iStub] - phiMean - phiRefHit);
+ int deltaPhi = hitPhi - extrapolatedPhi[iStub] - phiRefHit;
+ int phiDist = deltaPhi - phiMean;
/*LogTrace("l1tOmtfEventPrint") <<"\n"<<__FUNCTION__<<":"<<__LINE__<<" "<myOmtfConfig->isNoHitValueInPdf())
pdfVal = this->pdfValue(iLayer, iRefLayer, 0);
- return StubResult(pdfVal, false, myOmtfConfig->nPhiBins(), iLayer, selectedStub);
+ return StubResult(pdfVal, false, myOmtfConfig->nPhiBins(), myOmtfConfig->nPhiBins(), iLayer, selectedStub);
}
int pdfMiddle = 1 << (myOmtfConfig->nPdfAddrBits() - 1);
@@ -113,7 +116,7 @@ StubResult GoldenPatternBase::process1Layer1RefLayer(unsigned int iRefLayer,
///Check if phiDistMin is within pdf range -63 +63
///in firmware here the arithmetic "value and sign" is used, therefore the range is -63 +63, and not -64 +63
if (std::abs(phiDistMin) > ((1 << (myOmtfConfig->nPdfAddrBits() - 1)) - 1)) {
- return StubResult(0, false, phiDistMin + pdfMiddle, iLayer, selectedStub);
+ return StubResult(0, false, phiDistMin + pdfMiddle, deltaPhiSel, iLayer, selectedStub);
//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
@@ -124,9 +127,9 @@ StubResult GoldenPatternBase::process1Layer1RefLayer(unsigned int iRefLayer,
//if (this->getDistPhiBitShift(iLayer, iRefLayer) != 0) LogTrace("l1tOmtfEventPrint")<<__FUNCTION__<<":"<<__LINE__<<" phiDistMin "<pdfValue(iLayer, iRefLayer, phiDistMin);
if (pdfVal <= 0) {
- return StubResult(0, false, phiDistMin, iLayer, selectedStub);
+ return StubResult(0, false, phiDistMin, deltaPhiSel, iLayer, selectedStub);
}
- return StubResult(pdfVal, true, phiDistMin, iLayer, selectedStub);
+ return StubResult(pdfVal, true, phiDistMin, deltaPhiSel, iLayer, selectedStub);
}
////////////////////////////////////////////////////
diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPatternResult.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPatternResult.cc
index 5577c55e38f84..21b94c60dc70b 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPatternResult.cc
+++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GoldenPatternResult.cc
@@ -35,16 +35,6 @@ void GoldenPatternResult::set(int refLayer_, int phi, int eta, int refHitPhi) {
this->refHitPhi = refHitPhi;
}
-void GoldenPatternResult::setStubResult(float pdfVal, bool valid, int pdfBin, int layer, MuonStubPtr stub) {
- if (valid) {
- //pdfSum and firedLayerBits is calculated in finaliseX()
- firedLayerBits |= (1 << layer);
- }
- stubResults[layer] = StubResult(pdfVal, valid, pdfBin, layer, stub);
-
- //stub result is added even thought it is not valid since this might be needed for debugging or optimization
-}
-
void GoldenPatternResult::setStubResult(int layer, StubResult& stubResult) {
if (stubResult.getValid()) {
//pdfSum and firedLayerBits is calculated in finaliseX()
@@ -364,8 +354,8 @@ void GoldenPatternResult::finalise10() {
//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 pdfS
- //but this cut has sometimes side effect: there can be a muon which has has pdfSum = 0 for every pattern,
+ //hard cut for the contstrainedPt - the phiB of the refHit must fit to the pdf
+ //but this cut has sometimes side effect: it can result in a muon which 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.
diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc
index 4e870e55e6c30..da71aed27105f 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc
+++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc
@@ -299,6 +299,19 @@ void OMTFConfiguration::configureFromEdmParameterSet(const edm::ParameterSet &ed
if (edmParameterSet.exists("cleanStubs")) {
cleanStubs_ = edmParameterSet.getParameter("cleanStubs");
}
+
+ if (edmParameterSet.exists("usePhase2DTPrimitives")) {
+ usePhase2DTPrimitives_ = edmParameterSet.getParameter("usePhase2DTPrimitives");
+ }
+
+ //phase-2
+ if (getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::valueP2Scale) {
+ //in DataFormats/L1TMuonPhase2/interface/Constants.h BITSETA = 13
+ //for OMTF we reduce the precision
+ const int BITSETA = 13 - 2;
+ const float LSBeta = 2. * M_PI / pow(2, BITSETA);
+ etaUnit_ = LSBeta;
+ }
}
///////////////////////////////////////////////
@@ -363,7 +376,7 @@ uint32_t OMTFConfiguration::getLayerNumber(uint32_t rawId) const {
DetId detId(rawId);
if (detId.det() != DetId::Muon) {
- std::cout << "PROBLEM: hit in unknown Det, detID: " << detId.det() << std::endl;
+ edm::LogError("OMTFReconstruction") << "PROBLEM: hit in unknown Det, detID: " << detId.det() << std::endl;
return rawId;
}
@@ -399,15 +412,6 @@ 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;
@@ -524,36 +528,27 @@ int OMTFConfiguration::etaBit2Code(unsigned int bit) {
///////////////////////////////////////////////
// phiRad should be in the range [-pi,pi]
int OMTFConfiguration::getProcScalePhi(unsigned int iProcessor, double phiRad) const {
- double phi15deg =
- M_PI / 3. * (iProcessor) + M_PI / 12.; // "0" is 15degree moved cyclically to each processor, note [0,2pi]
+ // "0" is 15degree moved cyclically to each processor, note [0,2pi]
+ double phi15deg = 2 * M_PI / nProcessors() * (iProcessor) + M_PI / 12.;
const double phiUnit = 2 * M_PI / nPhiBins(); //rad/unit
// adjust [0,2pi] and [-pi,pi] to get deltaPhi difference properly
- switch (iProcessor + 1) {
- case 1:
- break;
- case 6: {
- phi15deg -= 2 * M_PI;
- break;
- }
- default: {
- if (phiRad < 0)
- phiRad += 2 * M_PI;
- break;
- }
- }
+ if ((iProcessor + 1) == nProcessors())
+ phi15deg -= 2 * M_PI;
+ else if (phiRad < 0)
+ phiRad += 2 * M_PI;
// local angle in CSC halfStrip usnits
return lround((phiRad - phi15deg) / phiUnit); //FIXME lround or floor ???
}
-///////////////////////////////////////////////
-///////////////////////////////////////////////
-double OMTFConfiguration::procHwPhiToGlobalPhi(int procHwPhi, int procHwPhi0) const {
- int globalHwPhi = foldPhi(procHwPhi + procHwPhi0);
- const double phiUnit = 2 * M_PI / nPhiBins(); //rad/unit
- return globalHwPhi * phiUnit;
+//returns the global phi in the OMTF scale
+int OMTFConfiguration::procPhiOmtfToGlobalPhiOmtf(unsigned int iProcessor, int procHwPhi) const {
+ //24 is 360 deg / 15 deg, 15 deg is the offset of the processor internal scale versus CMS phi = 0 rad
+ int globalPhi = iProcessor * nPhiBins() / nProcessors() + procHwPhi + nPhiBins() / 24;
+ globalPhi = foldPhi(globalPhi);
+ return globalPhi;
}
///////////////////////////////////////////////
@@ -606,5 +601,7 @@ void OMTFConfiguration::printConfig() const {
edm::LogVerbatim("OMTFReconstruction") << "useEndcapStubsRInExtr " << useEndcapStubsRInExtr_ << std::endl;
edm::LogVerbatim("OMTFReconstruction") << "dtRefHitMinQuality " << dtRefHitMinQuality << std::endl;
+ edm::LogVerbatim("OMTFReconstruction") << "etaUnit_ " << etaUnit_ << 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 cc54c465a2201..441f1ff00ee6f 100644
--- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc
+++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc
@@ -28,6 +28,7 @@
#include
#include
+#include
///////////////////////////////////////////////
///////////////////////////////////////////////
@@ -62,7 +63,8 @@ void OMTFProcessor::init(const edm::ParameterSet& edmCfg, edm
if (this->myOmtfConfig->getGhostBusterType() == "GhostBusterPreferRefDt" ||
this->myOmtfConfig->getGhostBusterType() == "byLLH" || this->myOmtfConfig->getGhostBusterType() == "byFPLLH" ||
- this->myOmtfConfig->getGhostBusterType() == "byRefLayer") {
+ this->myOmtfConfig->getGhostBusterType() == "byRefLayer" ||
+ this->myOmtfConfig->getGhostBusterType() == "byRefLayerAndHitQual") {
setGhostBuster(new GhostBusterPreferRefDt(this->myOmtfConfig));
edm::LogVerbatim("OMTFReconstruction") << "setting " << this->myOmtfConfig->getGhostBusterType() << std::endl;
} else {
@@ -84,8 +86,12 @@ void OMTFProcessor::init(const edm::ParameterSet& edmCfg, edm
}
if (this->myOmtfConfig->usePhiBExtrapolationMB1() || this->myOmtfConfig->usePhiBExtrapolationMB2()) {
- extrapolFactors.resize(2, std::vector >(this->myOmtfConfig->nLayers()));
- extrapolFactorsNorm.resize(2, std::vector >(this->myOmtfConfig->nLayers()));
+ extrapolFactors.resize(
+ 2 * 3,
+ std::vector >(
+ this->myOmtfConfig
+ ->nLayers())); // 2 * 3 because there are two reference layers and three possible quality values for a hit in the layers
+ extrapolFactorsNorm.resize(2 * 3, std::vector >(this->myOmtfConfig->nLayers()));
//when useFloatingPointExtrapolation is true the extrapolFactors are not used,
//all calculations are done in the extrapolateDtPhiBFloatPoint
@@ -98,211 +104,261 @@ void OMTFProcessor::init(const edm::ParameterSet& edmCfg, edm
}
template
-std::vector OMTFProcessor::getFinalcandidates(unsigned int iProcessor,
- l1t::tftype mtfType,
- const AlgoMuons& algoCands) {
- std::vector result;
+void OMTFProcessor::assignQuality(AlgoMuons::value_type& algoMuon) {
+ unsigned int quality = 12;
+ if (this->myOmtfConfig->fwVersion() <= 6)
+ quality = checkHitPatternValidity(algoMuon->getFiredLayerBits()) ? 0 | (1 << 2) | (1 << 3) : 0 | (1 << 2); //12 : 4
+ unsigned int firedLayerBits = static_cast(algoMuon->getFiredLayerBits());
+ if (abs(algoMuon->getEtaHw()) == 115 && //115 is eta 1.25 rrrrrrrrccccdddddd
+ (firedLayerBits == std::bitset<18>("100000001110000000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000001110000000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("100000000110000000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("100000001100000000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("100000001010000000").to_ulong())) {
+ if (this->myOmtfConfig->fwVersion() <= 6)
+ quality = 4;
+ else
+ quality = 1;
+ }
- for (auto& myCand : algoCands) {
- l1t::RegionalMuonCand candidate;
+ if (this->myOmtfConfig->fwVersion() >= 5 && this->myOmtfConfig->fwVersion() <= 6) {
+ if (firedLayerBits == std::bitset<18>("000000010000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000100000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001000000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000010000000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000100000000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000000000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("010000000000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("100000000000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000010000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000100000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001000000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000010000000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000100000000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000000000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("010000000000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("100000000000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000010000110000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000100000110000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001000000110000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000010000000110000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000100000000110000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000000000110000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("010000000000110000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("100000000000110000").to_ulong())
+ quality = 1;
+ } else if (this->myOmtfConfig->fwVersion() >= 8) { //TODO fix the fwVersion rrrrrrrrccccdddddd
+ if (firedLayerBits == std::bitset<18>("000000110000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000100000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000010000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000110000000001").to_ulong() ||
+
+ firedLayerBits == std::bitset<18>("000001000000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000011000000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000010000000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000011000000000100").to_ulong() ||
+
+ firedLayerBits == std::bitset<18>("000000011000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000010000000001").to_ulong())
+ quality = 1;
+ else if (firedLayerBits == std::bitset<18>("000000010000000101").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000010001000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000011000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000011000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000011100000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000100000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000100001000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000100100000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000110100000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000111000000000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000111000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000111000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001000001000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001010000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001010000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001010000000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001100000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001100000000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001100000000111").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001100001000000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001110000000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001110000000101").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000010000000000101").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000010010000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000010010000000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000010010000000101").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000010100000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000010100000000101").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000011110000000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000011110000000101").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000101000000010101").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000010000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000011000000000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000011000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000100000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000110000000000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001001000000000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001001100000000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001010000000000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("010000000010000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("010000000011000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("010000010000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("010000100000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("100000011000000000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000110000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000010000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000110000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000011000000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000011000000000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000010010000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000010000000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001001000001000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001100000000101").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000100000000101").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001100000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001110000000111").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000110001000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001110000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000000001000100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000110001000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001000000000101").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001010000001000000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001100000001000000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("100000010000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("010000010010000000").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000010100000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000110000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001000000001100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000000000000111101").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000001100000110001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000100000000010100").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000100000000011").to_ulong() ||
+ firedLayerBits == std::bitset<18>("001000110000000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("010000100010000001").to_ulong() ||
+ firedLayerBits == std::bitset<18>("000100000000110000").to_ulong())
+ quality = 8;
+ } // if (abs(myCand->getEta()) == 121) quality = 4;
+ if (abs(algoMuon->getEtaHw()) >= 121)
+ quality = 0; // changed from 4 on request from HI
+
+ algoMuon->setQuality(quality);
+}
- //the charge is only for the constrained measurement. The constrained measurement is always defined for a valid candidate
- if (ptAssignment) {
- if (myCand->getPdfSumConstr() > 0 && myCand->getFiredLayerCntConstr() >= 3)
- candidate.setHwPt(myCand->getPtNNConstr());
- else if (myCand->getPtUnconstr() > 0)
- candidate.setHwPt(1);
- else
- candidate.setHwPt(0);
+template
+FinalMuons OMTFProcessor::getFinalMuons(unsigned int iProcessor,
+ l1t::tftype mtfType,
+ const AlgoMuons& gbCandidates) {
+ LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " gbCandidates.size() " << gbCandidates.size()
+ << std::endl;
+ FinalMuons finalMuons;
+
+ for (auto& algoMuon : gbCandidates) {
+ auto finalMuon = std::make_shared(algoMuon);
- candidate.setHwSign(myCand->getChargeNNConstr() < 0 ? 1 : 0);
+ //the charge is only for the constrained measurement. The constrained measurement is always defined for a valid candidate
+ if (algoMuon->getPdfSumConstr() > 0) {
+ finalMuon->setPtGev(this->myOmtfConfig->hwPtToGev(algoMuon->getPtConstr()));
+ } else if (algoMuon->getPtUnconstr() > 0) {
+ //if myCand->getPdfSumConstr() == 0, the myCand->getPtConstr() might not be 0, see the end of GhostBusterPreferRefDt::select
+ //pT is set to 0 here, i.e. as in convertToGmtScalesPhase1, pt=1 in GMT scale means 0 GeV
+ finalMuon->setPtGev(0.0);
} else {
- if (myCand->getPdfSumConstr() > 0 && myCand->getFiredLayerCntConstr() >= 3)
- candidate.setHwPt(myCand->getPtConstr());
- else if (myCand->getPtUnconstr() > 0)
- //if myCand->getPdfSumConstr() == 0, the myCand->getPtConstr() might not be 0, see the end of GhostBusterPreferRefDt::select
- //but 0 means empty candidate, 1 means pt=0, therefore here we set HwPt to 1, as the PtUnconstr > 0
- candidate.setHwPt(1);
- else
- candidate.setHwPt(0);
+ //empty candidates are not added to the finalMuons
+ continue;
+ }
+
+ finalMuon->setPtUnconstrGev(this->myOmtfConfig->hwPtToGev(algoMuon->getPtUnconstr()));
+
+ finalMuon->setSign(algoMuon->getChargeConstr() < 0 ? 1 : 0);
- candidate.setHwSign(myCand->getChargeConstr() < 0 ? 1 : 0);
+ if (mtfType == l1t::omtf_pos) {
+ finalMuon->setEtaRad(this->myOmtfConfig->hwEtaToEta(algoMuon->getEtaHw()));
+ } else {
+ finalMuon->setEtaRad((-1) * this->myOmtfConfig->hwEtaToEta(algoMuon->getEtaHw()));
}
- if (mtfType == l1t::omtf_pos)
- candidate.setHwEta(myCand->getEtaHw());
- else
- candidate.setHwEta((-1) * myCand->getEtaHw());
+ finalMuon->setPhiRad(this->myOmtfConfig->procPhiOmtfToPhiRad(iProcessor, algoMuon->getPhi()));
- int phiValue = myCand->getPhi();
- if (phiValue >= int(this->myOmtfConfig->nPhiBins()))
- phiValue -= this->myOmtfConfig->nPhiBins();
- phiValue = this->myOmtfConfig->procPhiToGmtPhi(phiValue);
- candidate.setHwPhi(phiValue);
+ //finalMuon->setFiredLayerCnt(algoMuon->getFiredLayerCnt());
+ finalMuon->setProcessor(iProcessor);
+ finalMuon->setTrackFinderType(mtfType);
- candidate.setHwSignValid(1);
+ finalMuons.emplace_back(finalMuon);
+ }
+ return finalMuons;
+}
- 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);
+template
+void OMTFProcessor::convertToGmtScalesPhase1(unsigned int iProcessor,
+ l1t::tftype mtfType,
+ FinalMuonPtr& finalMuon) {
+ //the charge is only for the constrained measurement. The constrained result is always defined for a valid candidate
+ if (finalMuon->getAlgoMuon()->getPdfSumConstr() > 0 && finalMuon->getAlgoMuon()->getFiredLayerCntConstr() >= 3)
+ finalMuon->setPtGmt(finalMuon->getAlgoMuon()->getPtConstr());
+ else if (finalMuon->getAlgoMuon()->getPtUnconstr() > 0)
+ //if myCand->getPdfSumConstr() == 0, the myCand->getPtConstr() might not be 0, see the end of GhostBusterPreferRefDt::select
+ //but 0 means empty candidate, 1 means pt=0, therefore here we set HwPt to 1, as the PtUnconstr > 0
+ finalMuon->setPtGmt(1);
+ else
+ finalMuon->setPtGmt(0);
+
+ //N.B. the phase-1 GMT upt has different hardware scale than the pt, the upt unit is 1 GeV
+ if (finalMuon->getAlgoMuon()->getPtUnconstr() == 0)
+ finalMuon->setPtUnconstrGmt(0);
+ else
+ finalMuon->setPtUnconstrGmt((finalMuon->getAlgoMuon()->getPtUnconstr() - 1) / 2 + 1);
+
+ if (mtfType == l1t::omtf_pos) {
+ finalMuon->setEtaGmt(finalMuon->getAlgoMuon()->getEtaHw());
+ } else {
+ finalMuon->setEtaGmt((-1) * finalMuon->getAlgoMuon()->getEtaHw());
+ }
- unsigned int quality = 12;
- if (this->myOmtfConfig->fwVersion() <= 6)
- quality = checkHitPatternValidity(myCand->getFiredLayerBits()) ? 0 | (1 << 2) | (1 << 3) : 0 | (1 << 2); //12 : 4
-
- 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() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("100000001100000000").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("100000001010000000").to_ulong())) {
- if (this->myOmtfConfig->fwVersion() <= 6)
- quality = 4;
- else
- quality = 1;
- }
+ //TODO why it is needed?
+ int phiValue = finalMuon->getAlgoMuon()->getPhi();
+ if (phiValue >= int(this->myOmtfConfig->nPhiBins()))
+ phiValue -= this->myOmtfConfig->nPhiBins();
+ phiValue = this->myOmtfConfig->procPhiToGmtPhase1Phi(phiValue);
+ finalMuon->setPhiGmt(phiValue);
+ //finalMuon.setHwSignValid(1);
+}
+///////////////////////////////////////////////////////
+///////////////////////////////////////////////////////
+template
+std::vector OMTFProcessor::getRegionalMuonCands(unsigned int iProcessor,
+ l1t::tftype mtfType,
+ FinalMuons& finalMuons) {
+ std::vector result;
+
+ for (auto& finalMuon : finalMuons) {
+ l1t::RegionalMuonCand candidate;
+
+ candidate.setHwPt(finalMuon->getPtGmt());
+ candidate.setHwPtUnconstrained(finalMuon->getPtUnconstrGmt());
+
+ candidate.setHwPhi(finalMuon->getPhiGmt());
+ candidate.setHwEta(finalMuon->getEtaGmt());
+
+ candidate.setHwSign(finalMuon->getSign());
+ candidate.setHwSignValid(1);
- if (this->myOmtfConfig->fwVersion() >= 5 && this->myOmtfConfig->fwVersion() <= 6) {
- if (static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000010000000011").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000100000000011").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001000000000011").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000010000000000011").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000100000000000011").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000000000000011").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("010000000000000011").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("100000000000000011").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000010000001100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000100000001100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001000000001100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000010000000001100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000100000000001100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000000000001100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("010000000000001100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("100000000000001100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000010000110000").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000100000110000").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001000000110000").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000010000000110000").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000100000000110000").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000000000110000").to_ulong() ||
- 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 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() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000110000000001").to_ulong() ||
-
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001000000001100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000011000000001100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000010000000001100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000011000000000100").to_ulong() ||
-
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000011000000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000010000000001").to_ulong())
- quality = 1;
- else if (
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000010000000101").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000010001000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000011000000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000011000000011").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000011100000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000100000000011").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000100001000100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000100100000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000110100000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000111000000000").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000111000000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000111000000011").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001000001000100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001010000000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001010000000011").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001010000000100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001100000000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001100000000100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001100000000111").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001100001000000").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001110000000100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001110000000101").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000010000000000101").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000010010000000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000010010000000100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000010010000000101").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000010100000000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000010100000000101").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000011110000000100").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000011110000000101").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000101000000010101").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000010000000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000011000000000").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000011000000001").to_ulong() ||
- static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000100000000001").to_ulong() ||
- static_cast