From cdf567d61596468267d96f2efe2264c47a34f778 Mon Sep 17 00:00:00 2001 From: Karol Bunkowski Date: Wed, 22 Oct 2025 16:23:43 +0200 Subject: [PATCH 01/12] Many updates related to phase2, no changes to phase1 algorithm Changes from https://github.com/kbunkow/cmssw/tree/from-CMSSW_14_2_0_pre2_KB_v1/L1Trigger/L1TMuonOverlapPhase1 Merged changes from the CMSSW master L1TMuonOverlapPhase1: OMTFConfiguration.h Renaming and modifying several methods (e.g. for eta and phi conversions), new methods, mb1W2Eta(), mb2W2Eta(), etc. Added parameter usePhase2DTPrimitives. AlgoMuon added quality, dxyNN and nnOutputs Added class FinalMuon that stores the candidate parameters in the output format. IOMTFEmulationObserver::observeProcesorEmulation FinalMuons instead of RegionalMuonCands in the argument list OMTFProcessor: run() returns now FinalMuons instead of RegionalMuonCands. Added std::function assignQuality, which is set to assignQualityPhase1 or assignQualityPhase2 Methods OMTFProcessor::convertToGmtScalesPhase1 and OmtfEmulation::convertToGmtScalesPhase2 set the values in the finalMuon, then the values from the finalMuon are set in l1t::RegionalMuonCand (in getRegionalMuonCands) or SAMuon (in OmtfEmulation::run), respectively. Added method OMTFProcessor::assignQualityPhase1 assignQuality is called in OMTFProcessor::run. Adde option useStubQualInExtr - it refers to the ref hit quality. targetStubR is used in extrapolateDtPhiBFixedPoint, instead of targetStubEta CscDigiToStubsConverter::makeStubs Dumping cscDigis to xml. GhostBusterPreferRefDt.cc: added customByRefLayerAndHitQual sorting function, for which the quality of the DT ref hit is the first criterion, not used a.t.m.eicihdebihcfnvlecdgjbekcdnekdlegevvbevejrguf GoldenPatternBase and GoldenPattern::propagateRefPhi adedd iLayer as an argument StubResult.h - added field deltaPhi that stores: deltaPhi = hitPhi - extrapolatedPhi[iStub] - phiRefHit in GoldenPatternBase::process1Layer1RefLayer and is dumped in DataROOTDumper2::observeEventEnd as hit.phiDist . CandidateSimMuonMatcher Removing OMTFConfiguration so that it can be used in the analyzer outside the OMTF package. Added MatchingType enum. reworked CandidateSimMuonMatcher::match. MatchingType::simplePropagation is now propagating the muon to the muon station with the use of the provided histogram of medianDelta, minDelta, and maxDelta. Added method CandidateSimMuonMatcher::propagate which does both propagation withPropagator and simplePropagation. CandidateSimMuonMatcher::propagate: when propagation fails, doSimplePropagation is called for muonRho < 40 added CandidateSimMuonMatcher::collectMuonCands - no matching, just collecting the MuonCands, useful e..g. in minBIas sample, when there is no gen info. match(const l1t::RegionalMuonCand* omtfCand, const AlgoMuonPtr& procMuon, MatchingResult& result, TrajectoryStateOnSurface& tsof) - is used both for the simeTrack and trackingParticle. Added method atStation1. Deleting deltaPhiPropCandMean and deltaPhiPropCandStdDev in destructor. ghostBust - increasing deltaPhi margin from 8 to 10, to reduce the ghost for the displaced muons. match - result.matchingLikelihood = 1. / ( std::abs(result.deltaPhi) + 0.001) as normal_pdf geves nan for low pt muons. mean set to 0 setting result.propagatedPhi and propagatedEta. DataROOTDumper2 Setting omtfEvent.muonEvent = -2 when ResultType::propagationFailed. Fixed setting of omtfEvent.omtfPt. Added rootTree->Write() in DataROOTDumper2::endJob() as it seems it fixes the job crashes. Added vertexEta and vertexPhi. Dumping hit.etaHw instead of hit.z, deltaR insted of eta L1TMuonOverlapPhase2: InputMakerPhase2.h: using L1Phase2MuDTThDigi in the OMTF phase2 algorithm merged from https://github.com/folguera/cmssw/tree/omtf_dtphase2theta_cmssw14_0_0_pre3 DtPhase2DigiToStubsConverterOmtf::addDTphiDigi: R is set for the DT segments. implemented OmtfPhase2AngleConverter::getGlobalEta(). OMTFReconstruction Constructor - using edmParameterSet.copyForModify, as it was suspected that ordinary copying of parameterSet was sometimes causing crashes. FinalMuons are used in reconstruct() PtAssignmentBase Renamed getPts to run. EmulationObserverBase.h changing ParameterSet to reference L1TMuonOverlapPhase2TrackProducer::produce - produces SAMuonCollection OmtfEmulation: Added OmtfEmulation::getQualityFromFiredLayers with firedLayersToQuality tuned for the phase2 OMTF patterns. Added OmtfEmulation::convertToGmtScalesPhase2(). Added OmtfEmulation::getSAMuons(). LutNetworkFixedPointRegressionMultipleOutputs - the new version of the neural network, with multiple outputs. The neurons of the last layer are not fully connected to the last-but-one layer. PtAssignmentNNRegression adapted to the LutNetworkFixedPointRegressionMultipleOutputs with lutNN_omtfRegression_v430_FP.xml omtfHitWithQualAndRToEventInput, OmtfHit now has r instead of eta, no pt calibration, the second pt returned by the NN is not used yet hit.z is not used in OmtfHit deltaR instad of r LutNeuronLayerFixedPoint.h - in floorlog2 and ceillog2 removed throw cms::Exception as it should be const expressions, so runtime throws have no sense. Added template parameter output_F --- L1Trigger/L1TMuonOverlapPhase1/BuildFile.xml | 1 - .../interface/MuonStubMakerBase.h | 1 - .../interface/Omtf/AlgoMuon.h | 35 +- .../interface/Omtf/FinalMuon.h | 158 ++++ .../interface/Omtf/GoldenPattern.h | 5 +- .../interface/Omtf/GoldenPatternBase.h | 6 +- .../interface/Omtf/GoldenPatternResult.h | 2 - .../interface/Omtf/IOMTFEmulationObserver.h | 6 +- .../interface/Omtf/IProcessorEmulator.h | 20 +- .../interface/Omtf/OMTFConfiguration.h | 61 +- .../interface/Omtf/OMTFProcessor.h | 36 +- .../interface/Omtf/PtAssignmentBase.h | 4 +- .../interface/Omtf/XMLEventWriter.h | 5 +- .../interface/ProcConfigurationBase.h | 22 +- .../interface/StubResult.h | 9 +- .../interface/Tools/CandidateSimMuonMatcher.h | 105 ++- .../interface/Tools/DataROOTDumper2.h | 18 +- .../interface/Tools/EmulationObserverBase.h | 6 +- .../interface/Tools/EventCapture.h | 5 +- .../interface/Tools/PatternGenerator.h | 3 +- .../interface/Tools/PatternOptimizerBase.h | 3 +- .../interface/Tools/StubsSimHitsMatcher.h | 4 +- .../src/MuonStubMakerBase.cc | 21 + .../src/Omtf/GhostBuster.cc | 2 +- .../src/Omtf/GhostBusterPreferRefDt.cc | 45 +- .../src/Omtf/GoldenPattern.cc | 3 +- .../src/Omtf/GoldenPatternBase.cc | 14 +- .../src/Omtf/GoldenPatternResult.cc | 14 +- .../src/Omtf/OMTFConfiguration.cc | 57 +- .../src/Omtf/OMTFProcessor.cc | 530 +++++++----- .../src/Omtf/OMTFReconstruction.cc | 24 +- .../src/Omtf/OMTFinputMaker.cc | 12 + .../src/Omtf/XMLEventWriter.cc | 36 +- .../src/Tools/CandidateSimMuonMatcher.cc | 818 ++++++++++-------- .../src/Tools/DataROOTDumper2.cc | 207 +++-- .../src/Tools/EmulationObserverBase.cc | 4 +- .../src/Tools/EventCapture.cc | 120 +-- .../src/Tools/PatternGenerator.cc | 33 +- .../src/Tools/PatternOptimizerBase.cc | 3 +- .../src/Tools/StubsSimHitsMatching.cc | 20 +- .../interface/InputMakerPhase2.h | 30 +- .../LutNetworkFixedPointRegression2Outputs.h | 88 +- ...tworkFixedPointRegressionMultipleOutputs.h | 289 +++++++ .../interface/LutNeuronLayerFixedPoint.h | 92 +- .../interface/OmtfEmulation.h | 29 +- .../interface/OmtfPhase2AngleConverter.h | 6 +- .../interface/PtAssignmentNNRegression.h | 5 +- .../L1TMuonOverlapPhase2TrackProducer.cc | 26 +- .../L1TMuonOverlapPhase2TrackProducer.h | 1 + .../python/simOmtfPhase2Digis_DT_2_2_2_cff.py | 14 + .../python/simOmtfPhase2Digis_cfi.py | 15 +- .../src/InputMakerPhase2.cc | 90 +- .../L1TMuonOverlapPhase2/src/OmtfEmulation.cc | 305 ++++++- .../src/OmtfPhase2AngleConverter.cc | 54 +- .../src/PtAssignmentNNRegression.cc | 409 ++++++--- ...OverlapPatternGeneratorClassProb_phase2.py | 91 +- ...uonOverlapPatternGenerator_displ_phase2.py | 2 +- .../runMuonOverlapPatternGenerator_phase2.py | 66 +- .../expert/runMuonOverlap_NN_Regression_FP.py | 4 +- .../test/runMuonOverlap.py | 2 +- 60 files changed, 2798 insertions(+), 1298 deletions(-) create mode 100644 L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h create mode 100644 L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegressionMultipleOutputs.h create mode 100644 L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_DT_2_2_2_cff.py 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/MuonStubMakerBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStubMakerBase.h index 4cd2efb411c37..6911279655133 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" diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h index ab005a8b9e254..27c2653f390e2 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h @@ -42,9 +42,9 @@ 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 + //hardware upt, in the pattens scale, not in the GMT scale int getPtUnconstr() const { - return goldenPaternUnconstr == nullptr ? 0 : (goldenPaternUnconstr->key().thePt - 1) / 2 + 1; + return goldenPaternUnconstr == nullptr ? 0 : goldenPaternUnconstr->key().thePt; } int getChargeConstr() const { return goldenPaternConstr == nullptr ? -1 : goldenPaternConstr->key().theCharge; } @@ -125,21 +125,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; } + + float getPtNNUnconstr() const { return ptNNUnconstr; } - void setPtNNConstr(int ptNn = 0) { ptNNConstr = ptNn; } + void setPtNNUnconstr(float ptNnUnconstr) { ptNNUnconstr = ptNnUnconstr; } - int getChargeNNUnconstr() const { return chargeNNUnconstr; } + int getDxyNn() const { return dxyNN; } - void setChargeNNUnconstr(int chargeNnUnconstr = 0) { chargeNNUnconstr = chargeNnUnconstr; } + void setDxyNn(int dxyNn = 0) { dxyNN = dxyNn; } - int getPtNNUnconstr() const { return ptNNUnconstr; } + const std::vector& getNnOutputs() const { return nnOutputs; } - void setPtNNUnconstr(int ptNnUnconstr = 0) { ptNNUnconstr = ptNnUnconstr; } + 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 +173,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..4a2308893d564 --- /dev/null +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h @@ -0,0 +1,158 @@ +/* + * 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" + +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; + } + +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..4f685110ad287 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h @@ -33,17 +33,19 @@ class IProcessorEmulator { virtual AlgoMuons ghostBust(AlgoMuons refHitCands, int charge = 0) = 0; - virtual bool checkHitPatternValidity(unsigned int hits) = 0; + virtual std::vector getRegionalMuonCands(unsigned int iProcessor, + l1t::tftype mtfType, + FinalMuons& finalMuons) = 0; - virtual std::vector getFinalcandidates(unsigned int iProcessor, - l1t::tftype mtfType, - const AlgoMuons& algoCands) = 0; + virtual FinalMuons run(unsigned int iProcessor, + l1t::tftype mtfType, + int bx, + OMTFinputMaker* inputMaker, + std::vector >& observers) = 0; - virtual std::vector run(unsigned int iProcessor, - l1t::tftype mtfType, - int bx, - OMTFinputMaker* inputMaker, - std::vector >& observers) = 0; + + virtual void setAssignQualityFunction( + std::function asignQuality) = 0; virtual void printInfo() const = 0; }; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h index 475ae3a3392c4..a2342416a0c21 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h @@ -136,23 +136,46 @@ class OMTFConfiguration : public ProcConfigurationBase { const vector4D& getMeasurements4D() const { return measurements4D; } const vector4D& getMeasurements4Dref() const { return measurements4Dref; } + //pt unit of the OMTF patrterns, the same as in the phase-1 uGMT + //TODO refactor to omtfPtUnit double ptUnit = 0.5; // GeV/unit ///uGMT pt scale conversion + //TODO refactor to omtfPtToGev double hwPtToGev(int hwPt) const override { return (hwPt - 1.) * ptUnit; } - double uptUnit = 1; // GeV/unit - double hwUPtToGev(int hwPt) const override { return (hwPt - 1.) * uptUnit; } - ///uGMT pt scale conversion: [0GeV, 0.5GeV) = 1 [0.5GeV, 1 Gev) = 2 int ptGevToHw(double ptGev) const override { return (ptGev / ptUnit + 1); } - int calcGlobalPhi(int locPhi, int proc) const; - - double etaUnit = 0.010875; //=2.61/240 TODO value taken from the interface note, should be defined somewhere globally ///center of eta bin - virtual double hwEtaToEta(int hwEta) const { return (hwEta * etaUnit); } + 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 +183,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; } + 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 +194,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 +310,8 @@ class OMTFConfiguration : public ProcConfigurationBase { bool cleanStubs() const { return cleanStubs_; } + bool usePhase2DTPrimitives() const { return usePhase2DTPrimitives_; } + private: L1TMuonOverlapParams rawParams; @@ -366,6 +393,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..46f377da913d1 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" @@ -61,6 +62,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 +74,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 +100,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 assignQualityPhase1(AlgoMuons::value_type& algoMuon); + + FinalMuons getFinalMuons(unsigned int iProcessor, l1t::tftype mtfType, const AlgoMuons& gbCandidates); + + void convertToGmtScalesPhase1(unsigned int iProcessor, l1t::tftype mtfType, FinalMuonPtr& finalMuon); + + std::vector getRegionalMuonCands(unsigned int iProcessor, + l1t::tftype mtfType, + FinalMuons& finalMuons); ///allows to use other sorter implementation than the default one virtual void setSorter(SorterBase* sorter) { this->sorter.reset(sorter); } @@ -110,11 +118,17 @@ class OMTFProcessor : public ProcessorBase, public IProcessor 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; + + void setAssignQualityFunction( + std::function assignQuality) override { + this->assignQuality = assignQuality; + } + + FinalMuons run(unsigned int iProcessor, + l1t::tftype mtfType, + int bx, + OMTFinputMaker* inputMaker, + std::vector >& observers) override; void printInfo() const override; @@ -130,12 +144,14 @@ 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; + std::function assignQuality; + //ptAssignment should be destroyed where it is created, i.e. by OmtfEmulation or OMTFReconstruction PtAssignmentBase* ptAssignment = nullptr; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h index 83b098918f3ce..a961fc4e0b4f1 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h @@ -20,8 +20,8 @@ class PtAssignmentBase { PtAssignmentBase(const OMTFConfiguration* omtfConfig) : omtfConfig(omtfConfig) {} virtual ~PtAssignmentBase(); - virtual std::vector getPts(AlgoMuons::value_type& algoMuon, - std::vector >& observers) = 0; + virtual void run(AlgoMuons::value_type& algoMuon, + std::vector >& observers) = 0; protected: const OMTFConfiguration* omtfConfig = nullptr; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLEventWriter.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/XMLEventWriter.h index 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..05567f8e3c66a 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; } @@ -100,6 +112,12 @@ 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; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/StubResult.h b/L1Trigger/L1TMuonOverlapPhase1/interface/StubResult.h index 9260297345b2d..eade5a406c714 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; } @@ -47,6 +49,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..8c4f6d041ccea 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,14 +66,21 @@ 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; @@ -97,7 +94,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 +108,78 @@ 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); + + void match(const FinalMuons& finalMuons, + MatchingResult& result, + std::vector& matchingResults); - MatchingResult match(const l1t::RegionalMuonCand* omtfCand, - const AlgoMuonPtr& procMuon, - const TrackingParticle& trackingParticle, - TrajectoryStateOnSurface& tsof); + void match(const FinalMuonPtr& finalMuon3, MatchingResult& result); std::vector cleanMatching(std::vector matchingResults, - std::vector& muonCands, - AlgoMuons& ghostBustedProcMuons); + const FinalMuons& finalMuons); - std::vector match(std::vector& muonCands, - AlgoMuons& ghostBustedProcMuons, + 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; + //const OMTFConfiguration* omtfConfig; + + int nProcessors = 6; const edm::ParameterSet& edmCfg; @@ -189,10 +192,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..8bb362e78fb9c 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h @@ -35,11 +35,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 +67,9 @@ struct OmtfEvent { struct { char layer; char quality; - char z; + char etaHw; char valid; - short eta; + short deltaR; short phiDist; }; }; @@ -88,10 +93,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 +113,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/src/MuonStubMakerBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/MuonStubMakerBase.cc index 459a1d9c0b953..304c83b642b23 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,33 @@ 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/GhostBuster.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBuster.cc index 7cc8378a4ab76..46a81cf14a64a 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBuster.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBuster.cc @@ -40,7 +40,7 @@ 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..aaf5ae5d56e92 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); @@ -140,7 +183,7 @@ 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) { + 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); 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..e03c7f2c3c43b 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,9 @@ 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; + //int phiDist = this->myOmtfConfig->foldPhi(hitPhi - extrapolatedPhi[iStub] - phiMean - phiRefHit); /*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 +117,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 +128,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..e649971b493bf 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc @@ -214,6 +214,14 @@ void OMTFConfiguration::configure(const L1TMuonOverlapParams *omtfParams) { setGhostBusterType("byRefLayer"); } + + //phase-2 + if (fwVersion() >= 0x0210) { + //like in DataFormats/L1TMuonPhase2/interface/Constants.h + const int BITSETA = 13; + const float LSBeta = 2. * M_PI / pow(2, BITSETA); + etaUnit_ = LSBeta; + } } void OMTFConfiguration::configureFromEdmParameterSet(const edm::ParameterSet &edmParameterSet) { @@ -299,6 +307,10 @@ void OMTFConfiguration::configureFromEdmParameterSet(const edm::ParameterSet &ed if (edmParameterSet.exists("cleanStubs")) { cleanStubs_ = edmParameterSet.getParameter("cleanStubs"); } + + if (edmParameterSet.exists("usePhase2DTPrimitives")) { + usePhase2DTPrimitives_ = edmParameterSet.getParameter("usePhase2DTPrimitives"); + } } /////////////////////////////////////////////// @@ -399,15 +411,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 +527,30 @@ 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; + // Handle wrap-around with %. Add nPhiBins to make sure the number is positive + globalPhi = (globalPhi + nPhiBins()) % nPhiBins(); + + return globalPhi; } /////////////////////////////////////////////// diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc index cc54c465a2201..8e1ac7ef3fecd 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 { @@ -70,6 +72,10 @@ void OMTFProcessor::init(const edm::ParameterSet& edmCfg, edm edm::LogVerbatim("OMTFReconstruction") << "setting GhostBuster" << std::endl; } + assignQuality = [&](AlgoMuons::value_type& algoMuon) { + return this->assignQualityPhase1(algoMuon); + }; + edm::LogVerbatim("OMTFReconstruction") << "fwVersion 0x" << hex << this->myOmtfConfig->fwVersion() << std::endl; useStubQualInExtr = this->myOmtfConfig->useStubQualInExtr(); @@ -84,8 +90,8 @@ 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())); + 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,269 @@ 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::assignQualityPhase1(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); +} + +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); + //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); + 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 { + finalMuon->setPtGev(0); + continue; + } - candidate.setHwSign(myCand->getChargeNNConstr() < 0 ? 1 : 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); + finalMuon->setPtUnconstrGev(this->myOmtfConfig->hwPtToGev(algoMuon->getPtUnconstr())); - candidate.setHwSign(myCand->getChargeConstr() < 0 ? 1 : 0); + finalMuon->setSign(algoMuon->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()); + finalMuon->setPhiRad(this->myOmtfConfig->procPhiOmtfToPhiRad(iProcessor, algoMuon->getPhi())); + + //finalMuon->setFiredLayerCnt(algoMuon->getFiredLayerCnt()); + finalMuon->setProcessor(iProcessor); + finalMuon->setTrackFinderType(mtfType); + + finalMuons.emplace_back(finalMuon); + } + return finalMuons; +} + +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->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 - candidate.setHwEta((-1) * myCand->getEtaHw()); + finalMuon->setPtGmt(0); - int phiValue = myCand->getPhi(); + //N.B. the pahse-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()); + } + + //TODO why it is needed? + int phiValue = finalMuon->getAlgoMuon()->getPhi(); if (phiValue >= int(this->myOmtfConfig->nPhiBins())) phiValue -= this->myOmtfConfig->nPhiBins(); - phiValue = this->myOmtfConfig->procPhiToGmtPhi(phiValue); - candidate.setHwPhi(phiValue); + 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; - candidate.setHwSignValid(1); + for (auto& finalMuon : finalMuons) { + convertToGmtScalesPhase1(iProcessor, mtfType, finalMuon); - 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); + l1t::RegionalMuonCand candidate; - 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; - } + candidate.setHwPt(finalMuon->getPtGmt()); + candidate.setHwPtUnconstrained(finalMuon->getPtUnconstrGmt()); - 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(myCand->getFiredLayerBits()) == std::bitset<18>("001000110000000000").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001001000000000100").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001001100000000100").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001010000000000100").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("010000000010000001").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("010000000011000100").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("010000010000000001").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("010000100000000001").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("100000011000000000").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000110000000001").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000010000000011").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000110000000011").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000011000000001100").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000011000000000100").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000010010000001").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000010000000001100").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001001000001000100").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001100000000101").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000100000000101").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001100000000011").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001110000000111").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000110001000001").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001110000000011").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000000001000100").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000110001000001").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001000000000101").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001010000001000000").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001100000001000000").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("100000010000000001").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("010000010010000000").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000010100000001100").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000110000000011").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001000000001100").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000000000000111101").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000001100000110001").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000100000000010100").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000100000000011").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("001000110000000001").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("010000100010000001").to_ulong() || - static_cast(myCand->getFiredLayerBits()) == std::bitset<18>("000100000000110000").to_ulong()) - quality = 8; - } // if (abs(myCand->getEta()) == 121) quality = 4; - if (abs(myCand->getEtaHw()) >= 121) - quality = 0; // changed from 4 on request from HI - - candidate.setHwQual(quality); + candidate.setHwPhi(finalMuon->getPhiGmt()); + candidate.setHwEta(finalMuon->getEtaGmt()); + + candidate.setHwSign(finalMuon->getSign()); + candidate.setHwSignValid(1); + + candidate.setHwQual(finalMuon->getQuality()); std::map trackAddr; - trackAddr[0] = myCand->getFiredLayerBits(); + trackAddr[0] = finalMuon->getAlgoMuon()->getFiredLayerBits(); //TODO in the hardware, the uPt is sent to the uGMT at the trackAddr = (uPt << 18) + trackAddr; //check if it matters if it needs to be here as well - trackAddr[1] = myCand->getRefLayer(); - trackAddr[2] = myCand->getDisc(); + trackAddr[1] = finalMuon->getAlgoMuon()->getRefLayer(); + trackAddr[2] = finalMuon->getAlgoMuon()->getDisc(); if (candidate.hwPt() > 0 || candidate.hwPtUnconstrained() > 0) { candidate.setTrackAddress(trackAddr); candidate.setTFIdentifiers(iProcessor, mtfType); result.push_back(candidate); } } + return result; } -/////////////////////////////////////////////////////// -/////////////////////////////////////////////////////// /////////////////////////////////////////////////////// /////////////////////////////////////////////////////// @@ -349,6 +413,7 @@ template int OMTFProcessor::extrapolateDtPhiBFloatPoint(const int& refLogicLayer, const int& refPhi, const int& refPhiB, + const int& refHitSuperLayer, unsigned int targetLayer, const int& targetStubPhi, const int& targetStubQuality, @@ -357,7 +422,8 @@ int OMTFProcessor::extrapolateDtPhiBFloatPoint(const int& ref const OMTFConfiguration* omtfConfig) { LogTrace("l1tOmtfEventPrint") << "\n" << __FUNCTION__ << ":" << __LINE__ << " refLogicLayer " << refLogicLayer - << " targetLayer " << targetLayer << std::endl; + << " refHitSuperLayer " << refHitSuperLayer << " targetLayer " << targetLayer + << std::endl; LogTrace("l1tOmtfEventPrint") << "refPhi " << refPhi << " refPhiB " << refPhiB << " targetStubPhi " << targetStubPhi << " targetStubQuality " << targetStubQuality << std::endl; @@ -372,15 +438,32 @@ int OMTFProcessor::extrapolateDtPhiBFloatPoint(const int& ref } int reflLayerIndex = refLogicLayer == 0 ? 0 : 1; + if (useStubQualInExtr) { + //the phase-2 DT Trigger Primitives, since CMSSW_14_2_0_pre1 define phi always in "the middle of the chamber" + //also for the uncorrelated stubs + //so the below correction has sense only for the phase-1 + if (refHitSuperLayer == 1) { + rRefLayer = rRefLayer - 23.5 / 2; //inner superlayer + } else if (refHitSuperLayer == 3) { //using refHitSuperLayer = 3 here as in the L1Phase2MuDTPhDigi::slNum() + rRefLayer = rRefLayer + 23.5 / 2; //inner superlayer + } + + reflLayerIndex = (refHitSuperLayer << 1) | reflLayerIndex; + } if (targetLayer == 0 || targetLayer == 2 || targetLayer == 4 || (targetLayer >= 10 && targetLayer <= 14)) { //all units are cm. Values from the CMS geometry - float rTargetLayer = 512.401; //MB2 + float rTargetLayer = 512.475; //MB2 if (targetLayer == 0) - rTargetLayer = 431.133; //MB1 - else if (targetLayer == 4) - rTargetLayer = 617.946; //MB3 + rTargetLayer = 431.175; //MB1 + else if (targetLayer == 4) { //MB3 + //it is different than in the phase-1, as in the phase-2 it is a middle of the DT chamber, not muon station + if (omtfConfig->usePhase2DTPrimitives()) + rTargetLayer = 619.675; + else + rTargetLayer = 617.946; + } else if (targetLayer == 10) rTargetLayer = 413.675; //RB1in @@ -505,6 +588,7 @@ template int OMTFProcessor::extrapolateDtPhiBFixedPoint(const int& refLogicLayer, const int& refPhi, const int& refPhiB, + const int& refHitSuperLayer, unsigned int targetLayer, const int& targetStubPhi, const int& targetStubQuality, @@ -514,6 +598,10 @@ int OMTFProcessor::extrapolateDtPhiBFixedPoint(const int& ref int phiExtr = 0; //delta phi extrapolated int reflLayerIndex = refLogicLayer == 0 ? 0 : 1; + + if (useStubQualInExtr) + reflLayerIndex = (refHitSuperLayer << 1) | reflLayerIndex; + int extrFactor = 0; if (targetLayer == 0 || targetLayer == 2 || targetLayer == 4) { @@ -539,8 +627,8 @@ int OMTFProcessor::extrapolateDtPhiBFixedPoint(const int& ref //if given abs(targetStubEta) value is not present in the map, it is added with default value of 0 //so it should be good. The only problem is that the map can grow... //TODO change to targetStubR when it is implemented in the FW - extrFactor = extrapolFactors[reflLayerIndex][targetLayer][abs(targetStubEta)]; - //extrFactor = extrapolFactors[reflLayerIndex][targetLayer][abs(targetStubR)]; + //extrFactor = extrapolFactors[reflLayerIndex][targetLayer][abs(targetStubEta)]; + extrFactor = extrapolFactors[reflLayerIndex][targetLayer][abs(targetStubR)]; } else { extrFactor = extrapolFactors[reflLayerIndex][targetLayer][0]; } @@ -565,10 +653,20 @@ int OMTFProcessor::extrapolateDtPhiB(const MuonStubPtr& refSt const MuonStubPtr& targetStub, unsigned int targetLayer, const OMTFConfiguration* omtfConfig) { + //0 is correlated segment, so middle of the chamber + // 1 is inner SL, 2 is outer. + //N.B. that in L1Phase2MuDTPhDigi::slNum() out SL is 3 + int refHitSuperLayer = 0; + if (refStub->qualityHw == 2 || refStub->qualityHw == 0) + refHitSuperLayer = 1; + else if (refStub->qualityHw == 3 || refStub->qualityHw == 1) + refHitSuperLayer = 2; + if (useFloatingPointExtrapolation) return OMTFProcessor::extrapolateDtPhiBFloatPoint(refStub->logicLayer, refStub->phiHw, refStub->phiBHw, + refHitSuperLayer, targetLayer, targetStub->phiHw, targetStub->qualityHw, @@ -578,6 +676,7 @@ int OMTFProcessor::extrapolateDtPhiB(const MuonStubPtr& refSt return OMTFProcessor::extrapolateDtPhiBFixedPoint(refStub->logicLayer, refStub->phiHw, refStub->phiBHw, + refHitSuperLayer, targetLayer, targetStub->phiHw, targetStub->qualityHw, @@ -625,7 +724,7 @@ void OMTFProcessor::processInput(unsigned int iProcessor, } boost::property_tree::ptree procDataTree; - LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << " " << __LINE__; + LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << " " << __LINE__ << std::endl; for (unsigned int iLayer = 0; iLayer < this->myOmtfConfig->nLayers(); ++iLayer) { //debug /*for(auto& h : layerHits) { @@ -713,25 +812,29 @@ void OMTFProcessor::processInput(unsigned int iProcessor, int etaRef = refStub->etaHw; //calculating the phiExtrp in the case the RefLayer is MB1, to include it in the candidate phi of candidate + unsigned int layerPhiOut = 2; //the layer at which the candidate output phi is defined + unsigned int extrRefLayer = layerPhiOut == 0 ? 2 : 0; + //N.B. is seems that using layer 0 (MB1) as the layer where the phi is defined gives much worse results - worse phi and more ghosts + int phiExtrp = 0; - if ((this->myOmtfConfig->usePhiBExtrapolationMB1() && aRefHitDef.iRefLayer == 0)) { + if ((this->myOmtfConfig->usePhiBExtrapolationMB1() && aRefHitDef.iRefLayer == extrRefLayer)) { //||(this->myOmtfConfig->getUsePhiBExtrapolationMB2() && aRefHitDef.iRefLayer == 2) ) { //the extrapolation from the layer 2 to the layer 2 has no sense, so phiExtrp is 0 LogTrace("l1tOmtfEventPrint") << "\n" << __FUNCTION__ << ":" << __LINE__ << "extrapolating ref hit to get the phi of the candidate" << std::endl; if (useFloatingPointExtrapolation) phiExtrp = extrapolateDtPhiBFloatPoint( - aRefHitDef.iRefLayer, phiRef, refStub->phiBHw, 2, 0, 6, 0, 0, this->myOmtfConfig); + aRefHitDef.iRefLayer, phiRef, refStub->phiBHw, 0, layerPhiOut, 0, 6, 0, 0, this->myOmtfConfig); else phiExtrp = extrapolateDtPhiBFixedPoint( - aRefHitDef.iRefLayer, phiRef, refStub->phiBHw, 2, 0, 6, 0, 0, this->myOmtfConfig); + aRefHitDef.iRefLayer, phiRef, refStub->phiBHw, 0, layerPhiOut, 0, 6, 0, 0, this->myOmtfConfig); } for (auto& itGP : this->theGPs) { if (itGP->key().thePt == 0) //empty pattern continue; - int phiRefSt2 = itGP->propagateRefPhi(phiRef + phiExtrp, etaRef, aRefHitDef.iRefLayer); + int phiRefSt2 = itGP->propagateRefPhi(phiRef + phiExtrp, etaRef, aRefHitDef.iRefLayer, layerPhiOut); itGP->getResults()[procIndx][iRefHit].set(aRefHitDef.iRefLayer, phiRefSt2, etaRef, phiRef); } } @@ -759,12 +862,11 @@ void OMTFProcessor::processInput(unsigned int iProcessor, /////////////////////////////////////////////////////// template -std::vector OMTFProcessor::run( - unsigned int iProcessor, - l1t::tftype mtfType, - int bx, - OMTFinputMaker* inputMaker, - std::vector >& observers) { +FinalMuons OMTFProcessor::run(unsigned int iProcessor, + l1t::tftype mtfType, + int bx, + OMTFinputMaker* inputMaker, + std::vector >& observers) { //uncomment if you want to check execution time of each method //boost::timer::auto_cpu_timer t("%ws wall, %us user in getProcessorCandidates\n"); @@ -797,13 +899,14 @@ std::vector OMTFProcessor::run( //LogTrace("l1tOmtfEventPrint")<<"processInput "; t.report(); AlgoMuons algoCandidates = sortResults(iProcessor, mtfType); + for (auto& algoMuon : algoCandidates) { + assignQuality(algoMuon); + } + if (ptAssignment) { - for (auto& myCand : algoCandidates) { - if (myCand->isValid()) { - auto pts = ptAssignment->getPts(myCand, observers); - /*for (unsigned int i = 0; i < pts.size(); i++) { - trackAddr[10 + i] = this->myOmtfConfig->ptGevToHw(pts[i]); - }*/ + for (auto& algoMuon : algoCandidates) { + if (algoMuon->isValid()) { + ptAssignment->run(algoMuon, observers); } } } @@ -814,20 +917,21 @@ std::vector OMTFProcessor::run( AlgoMuons gbCandidates = ghostBust(algoCandidates); //LogTrace("l1tOmtfEventPrint")<<"ghostBust"; t.report(); - // fill RegionalMuonCand colleciton - std::vector candMuons = getFinalcandidates(iProcessor, mtfType, gbCandidates); - //LogTrace("l1tOmtfEventPrint")<<"getFinalcandidates "; t.report(); - //fill outgoing collection - for (auto& candMuon : candMuons) { - candMuon.setHwQual(candMuon.hwQual()); + FinalMuons finalMuons = getFinalMuons(iProcessor, mtfType, gbCandidates); + + for(auto& finalMuon : finalMuons) { + finalMuon->setBx(bx); } + // fill RegionalMuonCand colleciton + //std::vector candMuons = getFinalcandidates(iProcessor, mtfType, gbCandidates); + for (auto& obs : observers) { - obs->observeProcesorEmulation(iProcessor, mtfType, input, algoCandidates, gbCandidates, candMuons); + obs->observeProcesorEmulation(iProcessor, mtfType, input, algoCandidates, gbCandidates, finalMuons); } - return candMuons; + return finalMuons; } template diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc index dffb0e26e679d..14cd72a00a4e0 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc @@ -27,11 +27,12 @@ ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// OMTFReconstruction::OMTFReconstruction(const edm::ParameterSet& parameterSet, MuStubsInputTokens& muStubsInputTokens) - : edmParameterSet(parameterSet), - muStubsInputTokens(muStubsInputTokens), + : muStubsInputTokens(muStubsInputTokens), omtfConfig(new OMTFConfiguration()), omtfProc(nullptr), m_OMTFConfigMaker(nullptr) { + edmParameterSet.copyForModify(parameterSet); //why edmParameterSet is not reference? + bxMin = edmParameterSet.exists("bxMin") ? edmParameterSet.getParameter("bxMin") : 0; bxMax = edmParameterSet.exists("bxMax") ? edmParameterSet.getParameter("bxMax") : 0; @@ -222,7 +223,7 @@ void OMTFReconstruction::addObservers( if (edmParameterSet.exists("candidateSimMuonMatcher")) { if (edmParameterSet.getParameter("candidateSimMuonMatcher")) { observers.emplace_back(std::make_unique( - edmParameterSet, omtfConfig.get(), magneticFieldEsToken, propagatorEsToken)); + edmParameterSet, omtfConfig->nProcessors(), magneticFieldEsToken, propagatorEsToken)); candidateSimMuonMatcher = static_cast(observers.back().get()); } } @@ -282,33 +283,42 @@ std::unique_ptr OMTFReconstruction::reconstru std::unique_ptr candidates = std::make_unique(); candidates->setBXRange(bxMin, bxMax); + FinalMuons allFinalMuons; + ///The order is important: first put omtf_pos candidates, then omtf_neg. for (int bx = bxMin; bx <= bxMax; bx++) { for (unsigned int iProcessor = 0; iProcessor < omtfConfig->nProcessors(); ++iProcessor) { + FinalMuons finalMuons = omtfProc->run(iProcessor, l1t::tftype::omtf_pos, bx, inputMaker.get(), observers); + std::vector candMuons = - omtfProc->run(iProcessor, l1t::tftype::omtf_pos, bx, inputMaker.get(), observers); + omtfProc->getRegionalMuonCands(iProcessor, l1t::tftype::omtf_pos, finalMuons); //fill outgoing collection for (auto& candMuon : candMuons) { candidates->push_back(bx, candMuon); } + + allFinalMuons.insert(allFinalMuons.end(), finalMuons.begin(), finalMuons.end()); } for (unsigned int iProcessor = 0; iProcessor < omtfConfig->nProcessors(); ++iProcessor) { - std::vector candMuons = - omtfProc->run(iProcessor, l1t::tftype::omtf_neg, bx, inputMaker.get(), observers); + FinalMuons finalMuons = omtfProc->run(iProcessor, l1t::tftype::omtf_neg, bx, inputMaker.get(), observers); + std::vector candMuons = + omtfProc->getRegionalMuonCands(iProcessor, l1t::tftype::omtf_neg, finalMuons); //fill outgoing collection for (auto& candMuon : candMuons) { candidates->push_back(bx, candMuon); } + + allFinalMuons.insert(allFinalMuons.end(), finalMuons.begin(), finalMuons.end()); } //edm::LogInfo("OMTFReconstruction") <<"OMTF: Number of candidates in BX="<size(bx) << std::endl;; } for (auto& obs : observers) { - obs->observeEventEnd(iEvent, candidates); + obs->observeEventEnd(iEvent, allFinalMuons); } return candidates; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinputMaker.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinputMaker.cc index a1fd384f8a1bc..7922b988989b4 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinputMaker.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinputMaker.cc @@ -178,6 +178,18 @@ void RpcDigiToStubsConverterOmtf::addRPCstub(MuonStubPtrs2D& muonStubsInLayers, float r = 0; stub.etaHw = angleConverter->getGlobalEtaRpc(rawid, cluster.firstStrip, r); + + if (iLayer == 10) + r = 413.675; //RB1in + else if (iLayer == 11) + r = 448.675; //RB1out + else if (iLayer == 12) + r = 494.975; //RB2in + else if (iLayer == 13) + r = 529.975; //RB2out + else if (iLayer == 14) + r = 602.150; //RB3 + stub.r = round(r); stub.qualityHw = cluster.size(); diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/XMLEventWriter.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/XMLEventWriter.cc index c68b1853bd58d..63d1d4ef3ea85 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/XMLEventWriter.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/XMLEventWriter.cc @@ -55,11 +55,11 @@ void XMLEventWriter::observeProcesorEmulation(unsigned int iProcessor, const std::shared_ptr& input, const AlgoMuons& algoCandidates, const AlgoMuons& gbCandidates, - const std::vector& candMuons) { + const FinalMuons& finalMuons) { int endcap = (mtfType == l1t::omtf_neg) ? -1 : ((mtfType == l1t::omtf_pos) ? +1 : 0); OmtfName board(iProcessor, endcap, omtfConfig); - if (candMuons.empty()) + if (finalMuons.empty()) return; for (unsigned int iLayer = 0; iLayer < omtfConfig->nLayers(); ++iLayer) { @@ -168,26 +168,25 @@ void XMLEventWriter::observeProcesorEmulation(unsigned int iProcessor, } } - for (auto& candMuon : candMuons) { + for (auto& finalMuon : finalMuons) { auto& candMuonTree = procTree.add("CandMuon", ""); - candMuonTree.add(".hwEta", candMuon.hwEta()); - candMuonTree.add(".hwPhi", candMuon.hwPhi()); - candMuonTree.add(".hwPt", candMuon.hwPt()); - candMuonTree.add(".hwUPt", candMuon.hwPtUnconstrained()); - candMuonTree.add(".hwQual", candMuon.hwQual()); - candMuonTree.add(".hwSign", candMuon.hwSign()); - candMuonTree.add(".hwSignValid", candMuon.hwSignValid()); - candMuonTree.add(".hwTrackAddress", std::bitset<29>(candMuon.trackAddress().at(0))); - candMuonTree.add(".link", candMuon.link()); - candMuonTree.add(".processor", candMuon.processor()); + candMuonTree.add(".hwEta", finalMuon->getEtaGmt()); + candMuonTree.add(".hwPhi", finalMuon->getPhiGmt()); + candMuonTree.add(".hwPt", finalMuon->getPtGmt()); + candMuonTree.add(".hwUPt", finalMuon->getPtUnconstrGmt()); + candMuonTree.add(".hwQual", finalMuon->getQuality()); + candMuonTree.add(".hwSign", finalMuon->getSign()); + candMuonTree.add(".hwSignValid", 1); + candMuonTree.add(".hwTrackAddress", std::bitset<29>(finalMuon->getAlgoMuon()->getFiredLayerBits())); + candMuonTree.add(".link", (mtfType == l1t::omtf_neg ? 60 + iProcessor : 42 + iProcessor)); + candMuonTree.add(".processor", iProcessor); std::ostringstream stringStr; - if (candMuon.trackFinderType() == l1t::omtf_neg) + if (mtfType == l1t::omtf_neg) stringStr << "OMTF_NEG"; - else if (candMuon.trackFinderType() == l1t::omtf_pos) + else if (mtfType == l1t::omtf_pos) stringStr << "OMTF_POS"; - else - stringStr << candMuon.trackFinderType(); + candMuonTree.add(".trackFinderType", stringStr.str()); } @@ -206,8 +205,7 @@ void XMLEventWriter::observeEventBegin(const edm::Event& iEvent) { eventTree->add(".iBx", 2 * eventId); } -void XMLEventWriter::observeEventEnd(const edm::Event& iEvent, - std::unique_ptr& finalCandidates) {} +void XMLEventWriter::observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMuons) {} void XMLEventWriter::endJob() { edm::LogInfo("l1tOmtfEventPrint") << "XMLEventWriter::endJob() - writing the data to the xml - starting"; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc index 0d62407de2c2f..0574d14381c3d 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc @@ -24,11 +24,16 @@ #include "TFile.h" #include "TH1D.h" - +/* double hwGmtPhiToGlobalPhi(int phi) { double phiGmtUnit = 2. * M_PI / 576.; - return phi * phiGmtUnit; -} + double globalPhi = phi * phiGmtUnit; + + if (globalPhi > M_PI) + globalPhi = globalPhi - (2. * M_PI); + + return globalPhi; +}*/ double foldPhi(double phi) { if (phi > M_PI) @@ -39,38 +44,113 @@ double foldPhi(double phi) { return phi; } +MatchingResult::MatchingResult(const SimTrack& simTrack, const SimVertex* simVertex) + : simTrack(&simTrack), simVertex(simVertex) { + pdgId = simTrack.type(); + genPt = simTrack.momentum().pt(); + genEta = simTrack.momentum().eta(); + genPhi = simTrack.momentum().phi(); + genCharge = simTrack.charge(); + + const math::XYZTLorentzVectorD& vtxPos = this->simVertex->position(); + muonDxy = (-vtxPos.X() * this->simTrack->momentum().py() + vtxPos.Y() * this->simTrack->momentum().px()) / + this->simTrack->momentum().pt(); + muonRho = vtxPos.Rho(); + + vertexEta = vtxPos.eta(); + vertexPhi = vtxPos.phi(); + + //parentPdgId = 0; TODO +} + +MatchingResult::MatchingResult(const TrackingParticle& trackingParticle) : trackingParticle(&trackingParticle) { + pdgId = trackingParticle.pdgId(); + genPt = trackingParticle.pt(); + genEta = trackingParticle.momentum().eta(); + genPhi = trackingParticle.momentum().phi(); + genCharge = trackingParticle.charge(); + + muonDxy = this->trackingParticle->dxy(); + muonRho = this->trackingParticle->parentVertex()->position().Rho(); + + vertexEta = this->trackingParticle->parentVertex()->position().eta(); + vertexPhi = this->trackingParticle->parentVertex()->position().phi(); +} + +int CandidateSimMuonMatcher::calcGlobalPhi(int locPhi, int proc) { + 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 + 24 + 576) % 576; + return globPhi; +} + CandidateSimMuonMatcher::CandidateSimMuonMatcher( const edm::ParameterSet& edmCfg, - const OMTFConfiguration* omtfConfig, + //const OMTFConfiguration* omtfConfig, + int nProcessors, const edm::ESGetToken& magneticFieldEsToken, const edm::ESGetToken& propagatorEsToken) - : omtfConfig(omtfConfig), + : //omtfConfig(omtfConfig), + nProcessors(nProcessors), edmCfg(edmCfg), magneticFieldEsToken(magneticFieldEsToken), propagatorEsToken(propagatorEsToken) { + //needed when CandidateSimMuonMatcher is used outside the OMTF package, where the omtfConfig is not available + if (edmCfg.exists("phase")) { + if (edmCfg.getParameter("phase") == 2) + this->nProcessors = 3; + } + std::string muonMatcherFileName = edmCfg.getParameter("muonMatcherFile").fullPath(); - TFile inFile(muonMatcherFileName.c_str()); + TFile muonMatcherFile(muonMatcherFileName.c_str()); edm::LogImportant("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: using muonMatcherFileName " << muonMatcherFileName << std::endl; if (edmCfg.exists("candidateSimMuonMatcherType")) { - if (edmCfg.getParameter("candidateSimMuonMatcherType") == "propagation") - usePropagation = true; - else if (edmCfg.getParameter("candidateSimMuonMatcherType") == "matchSimple") - usePropagation = false; + if (edmCfg.getParameter("candidateSimMuonMatcherType") == "withPropagator") + matchingType = MatchingType::withPropagator; + else if (edmCfg.getParameter("candidateSimMuonMatcherType") == "simplePropagation") + matchingType = MatchingType::simplePropagation; + else if (edmCfg.getParameter("candidateSimMuonMatcherType") == "simpleMatching") + matchingType = MatchingType::simpleMatching; + else if (edmCfg.getParameter("candidateSimMuonMatcherType") == "collectMuonCands") + matchingType = MatchingType::collectMuonCands; edm::LogImportant("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: candidateSimMuonMatcherType " << edmCfg.getParameter("candidateSimMuonMatcherType") << std::endl; } - edm::LogImportant("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: usePropagation " << usePropagation << std::endl; + edm::LogImportant("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: matchingType " + << static_cast(matchingType) << std::endl; - deltaPhiPropCandMean = (TH1D*)inFile.Get("deltaPhiPropCandMean"); - deltaPhiPropCandStdDev = (TH1D*)inFile.Get("deltaPhiPropCandStdDev"); + minDelta_pos = (TH1F*)muonMatcherFile.Get("minDelta_pos"); + maxDelta_pos = (TH1F*)muonMatcherFile.Get("maxDelta_pos"); + medianDelta_pos = (TH1F*)muonMatcherFile.Get("medianDelta_pos"); + + minDelta_neg = (TH1F*)muonMatcherFile.Get("minDelta_neg"); + maxDelta_neg = (TH1F*)muonMatcherFile.Get("maxDelta_neg"); + medianDelta_neg = (TH1F*)muonMatcherFile.Get("medianDelta_neg"); + + //detaching the histograms from the file + minDelta_pos->SetDirectory(nullptr); + maxDelta_pos->SetDirectory(nullptr); + medianDelta_pos->SetDirectory(nullptr); + minDelta_neg->SetDirectory(nullptr); + maxDelta_neg->SetDirectory(nullptr); + medianDelta_neg->SetDirectory(nullptr); } -CandidateSimMuonMatcher::~CandidateSimMuonMatcher() {} +CandidateSimMuonMatcher::~CandidateSimMuonMatcher() { + delete minDelta_pos; + delete maxDelta_pos; + delete medianDelta_pos; + delete minDelta_neg; + delete maxDelta_neg; + delete medianDelta_neg; +} void CandidateSimMuonMatcher::beginRun(const edm::EventSetup& eventSetup) { //TODO use edm::ESWatcher magneticFieldRecordWatcher; @@ -85,21 +165,20 @@ void CandidateSimMuonMatcher::observeProcesorEmulation(unsigned int iProcessor, const std::shared_ptr& input, const AlgoMuons& algoCandidates, const AlgoMuons& gbCandidates, - const std::vector& candMuons) { + const FinalMuons& finalMuons) { //debug - unsigned int procIndx = omtfConfig->getProcIndx(iProcessor, mtfType); + //unsigned int procIndx = omtfConfig->getProcIndx(iProcessor, mtfType); for (auto& gbCandidate : gbCandidates) { if (gbCandidate->getPtConstr() > 0) { - LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::observeProcesorEmulation procIndx" << procIndx << " " - << *gbCandidate << std::endl; + LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::observeProcesorEmulation iProcessor " << iProcessor + << " mtfType " << mtfType << *gbCandidate << std::endl; this->gbCandidates.emplace_back(gbCandidate); } } } bool simTrackIsMuonInOmtf(const SimTrack& simTrack) { - if (std::abs(simTrack.type()) == 13 || - std::abs(simTrack.type()) == 1000015) { // 1000015 is stau, todo use other selection (e.g. pt>20) if needed + if (std::abs(simTrack.type()) == 13 || std::abs(simTrack.type()) == 1000015) { // 1000015 is stau //only muons } else return false; @@ -116,7 +195,7 @@ bool simTrackIsMuonInOmtf(const SimTrack& simTrack) { //some margin for matching must be used on top of actual OMTF region, //i.e. (0.82-1.24)=>(0.72-1.3), //otherwise many candidates are marked as ghosts - if ((std::abs(simTrack.momentum().eta()) >= 0.72) && (std::abs(simTrack.momentum().eta()) <= 1.3)) { + if ((std::abs(simTrack.momentum().eta()) >= 0.7) && (std::abs(simTrack.momentum().eta()) <= 1.31)) { LogTrace("l1tOmtfEventPrint") << "simTrackIsMuonInOmtf: is in OMTF"; } else { LogTrace("l1tOmtfEventPrint") << "simTrackIsMuonInOmtf: not in OMTF"; @@ -134,8 +213,10 @@ bool simTrackIsMuonInOmtfBx0(const SimTrack& simTrack) { } bool simTrackIsMuonInBx0(const SimTrack& simTrack) { - if (std::abs(simTrack.type()) == 13 || - std::abs(simTrack.type()) == 1000015) { // 1000015 is stau, todo use other selection (e.g. pt>20) if needed + if (std::abs(simTrack.type()) == 13 || std::abs(simTrack.type()) == 1000015) { // 1000015 is stau + if (simTrack.momentum().pt() < 2.5) //TODO muons with pt < 2.5 GeV do not reach the OMTF + return false; + //only muons if (simTrack.eventId().bunchCrossing() == 0) return true; @@ -147,6 +228,36 @@ bool trackingParticleIsMuonInBx0(const TrackingParticle& trackingParticle) { if (std::abs(trackingParticle.pdgId()) == 13 || std::abs(trackingParticle.pdgId()) == 1000015) { // 1000015 is stau, todo use other selection (e.g. pt>20) if needed + + //in the overlap, the propagation of muons with pt less then ~3.2 fails - the actual threshold depends slightly on eta, + if (trackingParticle.pt() < 2.5) + return false; + + //only muons + if (trackingParticle.eventId().bunchCrossing() == 0) + return true; + } + return false; +} + +bool trackingParticleIsMuonInBx0Displ(const TrackingParticle& trackingParticle) { + if (std::abs(trackingParticle.pdgId()) == 13 || + std::abs(trackingParticle.pdgId()) == + 1000015) { // 1000015 is stau, todo use other selection (e.g. pt>20) if needed + + //in the overlap, the propagation of muons with pt less then ~3.2 fails - the actual threshold depends slightly on eta, + if (trackingParticle.pt() < 2.) + return false; + + if (trackingParticle.dxy() < 30) { + if ((std::abs(trackingParticle.momentum().eta()) < 0.7) || (std::abs(trackingParticle.momentum().eta()) > 1.31)) + return false; + } else { + if ((std::abs(trackingParticle.parentVertex()->position().eta()) < 0.7) || + (std::abs(trackingParticle.parentVertex()->position().eta()) > 1.4)) + return false; + } + //only muons if (trackingParticle.eventId().bunchCrossing() == 0) return true; @@ -188,7 +299,7 @@ bool trackingParticleIsMuonInOmtfBx0(const TrackingParticle& trackingParticle) { //some margin for matching must be used on top of actual OMTF region, //i.e. (0.82-1.24)=>(0.72-1.3), //otherwise many candidates are marked as ghosts - if ((std::abs(trackingParticle.momentum().eta()) >= 0.72) && (std::abs(trackingParticle.momentum().eta()) <= 1.3)) { + if ((std::abs(trackingParticle.momentum().eta()) >= 0.7) && (std::abs(trackingParticle.momentum().eta()) <= 1.31)) { } else return false; @@ -202,12 +313,9 @@ bool trackingParticleIsMuonInOmtfEvent0(const TrackingParticle& trackingParticle return trackingParticleIsMuonInOmtfBx0(trackingParticle); } -void CandidateSimMuonMatcher::observeEventEnd(const edm::Event& event, - std::unique_ptr& finalCandidates) { +void CandidateSimMuonMatcher::observeEventEnd(const edm::Event& event, FinalMuons& finalMuons) { LogTrace("l1tOmtfEventPrint") << "\nCandidateSimMuonMatcher::observeEventEnd" << std::endl; - AlgoMuons ghostBustedProcMuons; - std::vector ghostBustedRegionalCands = - CandidateSimMuonMatcher::ghostBust(finalCandidates.get(), gbCandidates, ghostBustedProcMuons); + FinalMuons ghostBustedFinalMuons = CandidateSimMuonMatcher::ghostBust(finalMuons); matchingResults.clear(); if (edmCfg.exists("simTracksTag")) { @@ -220,27 +328,28 @@ void CandidateSimMuonMatcher::observeEventEnd(const edm::Event& event, LogTrace("l1tOmtfEventPrint") << "simTraksHandle size " << simTraksHandle.product()->size() << std::endl; LogTrace("l1tOmtfEventPrint") << "simVertices size " << simVertices.product()->size() << std::endl; - if (usePropagation) { - //TODO use other simTrackFilter if needed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - //we dont want to check the eta of the generated muon, as it is on the vertex, - //instead inside match, we check the eta of the propagated track to the second muons station - std::function const& simTrackFilter = simTrackIsMuonInBx0; //simTrackIsMuonInOmtfBx0; - - matchingResults = match(ghostBustedRegionalCands, - ghostBustedProcMuons, - simTraksHandle.product(), - simVertices.product(), - simTrackFilter); - } else { + if (matchingType == MatchingType::simpleMatching) { std::function const& simTrackFilter = simTrackIsMuonInOmtfBx0; //simTrackIsMuonInOmtfBx0 provides appropriate eta cut - matchingResults = matchSimple(ghostBustedRegionalCands, - ghostBustedProcMuons, + matchingResults = matchSimple(ghostBustedFinalMuons, simTraksHandle.product(), simVertices.product(), simTrackFilter); + } else if (matchingType == MatchingType::withPropagator || matchingType == MatchingType::simplePropagation) { + //TODO use other simTrackFilter if needed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + //withPropagator, we dont want to check the eta of the generated muon, as it is on the vertex, + //instead inside match, we check the eta of the propagated track to the second muons station + std::function const& simTrackFilter = + (matchingType == MatchingType::withPropagator) ? simTrackIsMuonInBx0 : simTrackIsMuonInOmtfBx0; + //withPropagator : simplePropagation + + matchingResults = match(ghostBustedFinalMuons, + simTraksHandle.product(), + simVertices.product(), + simTrackFilter); } + //todo something when noMatcher } else if (edmCfg.exists("trackingParticleTag")) { edm::Handle trackingParticleHandle; @@ -249,86 +358,75 @@ void CandidateSimMuonMatcher::observeEventEnd(const edm::Event& event, << trackingParticleHandle.product()->size() << std::endl; //TODO use other trackParticleFilter if needed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - std::function trackParticleFilter = - trackingParticleIsMuonInBx0; //trackingParticleIsMuonInOmtfBx0; + //TrackingParticle is used for minBias sample. There we should do propagation to match pions and kaons + std::function trackParticleFilter = trackingParticleIsMuonInBx0Displ; + //trackingParticleIsMuonInBx0; if propagation is used, use trackingParticleIsMuonInOmtfBx0 matchingResults = - match(ghostBustedRegionalCands, ghostBustedProcMuons, trackingParticleHandle.product(), trackParticleFilter); + match(finalMuons, trackingParticleHandle.product(), trackParticleFilter); + } else if (matchingType == MatchingType::collectMuonCands) { + matchingResults = collectMuonCands(finalMuons); } } void CandidateSimMuonMatcher::endJob() {} -std::vector CandidateSimMuonMatcher::ghostBust( - const l1t::RegionalMuonCandBxCollection* mtfCands, const AlgoMuons& gbCandidates, AlgoMuons& ghostBustedProcMuons) { - if (gbCandidates.size() != mtfCands->size(0)) { - edm::LogError("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::ghostBust(): gbCandidates.size() " - << gbCandidates.size() << " != mtfCands.size() " << mtfCands->size(); - } - - boost::dynamic_bitset<> isKilled(mtfCands->size(0), false); +FinalMuons CandidateSimMuonMatcher::ghostBust(const FinalMuons& finalMuons) { + boost::dynamic_bitset<> isKilled(finalMuons.size(), false); - for (unsigned int i1 = 0; i1 < mtfCands->size(0); ++i1) { - if (mtfCands->at(0, i1).hwPt() == 0) - continue; + for (unsigned int i1 = 0; i1 < finalMuons.size(); ++i1) { + if (finalMuons[i1]->getPtGmt() == 0) + continue; LogTrace("l1tOmtfEventPrint") << "\nCandidateSimMuonMatcher::ghostBust regionalCand pt " << std::setw(3) - << mtfCands->at(0, i1).hwPt() << " qual " << std::setw(2) - << mtfCands->at(0, i1).hwQual() << " proc " << std::setw(2) - << mtfCands->at(0, i1).processor(); - for (unsigned int i2 = i1 + 1; i2 < mtfCands->size(0); ++i2) { - auto& mtfCand1 = mtfCands->at(0, i1); - auto& mtfCand2 = mtfCands->at(0, i2); - if (mtfCand2.hwPt() == 0) - continue; - - if (std::abs(mtfCand1.hwEta() - mtfCand2.hwEta()) < (0.3 / 0.010875)) { - int gloablHwPhi1 = omtfConfig->calcGlobalPhi(mtfCand1.hwPhi(), mtfCand1.processor()); - int gloablHwPhi2 = omtfConfig->calcGlobalPhi(mtfCand2.hwPhi(), mtfCand2.processor()); - + << finalMuons[i1]->getPtGmt() << " qual " << std::setw(2) + << finalMuons[i1]->getQuality() << " proc " << std::setw(2) + << finalMuons[i1]->getProcessor() << " PhiRad " << finalMuons[i1]->getPhiRad() << " etaRad " << finalMuons[i1]->getEtaRad(); + for (unsigned int i2 = i1 + 1; i2 < finalMuons.size(); ++i2) { + auto& mtfCand1 = finalMuons[i1]; + auto& mtfCand2 = finalMuons[i2]; + //if (mtfCand2->getPt() == 0) + // continue; + + if (std::abs(mtfCand1->getEtaRad() - mtfCand2->getEtaRad()) < 0.3) { //folding phi - int deltaPhi = std::abs(gloablHwPhi1 - gloablHwPhi2); - if (deltaPhi > 576 / 2) - deltaPhi = std::abs(deltaPhi - 576); - - //one can use the phi in radians like that: - //double globalPhi1 = hwGmtPhiToGlobalPhi(omtfConfig->calcGlobalPhi( mtfCand1.hwPhi(), mtfCand1.processor() ) ); - //double globalPhi2 = hwGmtPhiToGlobalPhi(omtfConfig->calcGlobalPhi( mtfCand2.hwPhi(), mtfCand2.processor() ) ); - - //0.0872664626 = 5 deg, i.e. the same window as in the OMTF ghost buster - if (deltaPhi < 8) { - //if (mtfCand1.hwQual() > mtfCand2.hwQual()) //TODO this is used in the uGMT - //but this should be better - but probably the difference is not big - if (gbCandidates[i1]->getFiredLayerCnt() > gbCandidates[i2]->getFiredLayerCnt()) { + double deltaPhi = std::abs(mtfCand1->getPhiRad() - mtfCand2->getPhiRad() ); + if (deltaPhi > M_PI) + deltaPhi = std::abs(deltaPhi - 2 * M_PI); + + //0.116355283466 is 10 units of the phase1 + if (deltaPhi < 10 * 2 * M_PI / 576) { + if (mtfCand1->getFiredLayerCnt() > mtfCand2->getFiredLayerCnt()) { // isKilled[i2] = true; } else isKilled[i1] = true; } + LogTrace("l1tOmtfEventPrint") <<" mtfCand2 PhiRad " << mtfCand2->getPhiRad() << " etaRad " << mtfCand2->getEtaRad() << " deltaPhi "<< deltaPhi + << " isKilled[i2] " << isKilled[i2] << " isKilled[i1] " << isKilled[i1]; } } } - std::vector resultCands; + FinalMuons resultCands; - for (unsigned int i1 = 0; i1 < mtfCands->size(0); ++i1) { - //dropping candidates with quality 0 !!!!!!!!!!!!!!!!!!!! fixme if not needed - if (!isKilled[i1] && mtfCands->at(0, i1).hwPt()) { - resultCands.push_back(&(mtfCands->at(0, i1))); - ghostBustedProcMuons.push_back(gbCandidates.at(i1)); + for (unsigned int i1 = 0; i1 < finalMuons.size(); ++i1) { + //dropping candidates with quality 0 and 1 !!!!!!!!!!!!!!!!!!!! fixme if not needed + if (!isKilled[i1] && finalMuons[i1]->getQuality() > 1) { + resultCands.push_back(finalMuons[i1]); } - if (mtfCands->at(0, i1).hwPt()) { - LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::ghostBust\n regionalCand pt " << std::setw(3) - << mtfCands->at(0, i1).hwPt() << " qual " << std::setw(2) - << mtfCands->at(0, i1).hwQual() << " proc " << std::setw(2) - << mtfCands->at(0, i1).processor() << " eta " << std::setw(4) - << mtfCands->at(0, i1).hwEta() << " gloablEta " << std::setw(8) - << mtfCands->at(0, i1).hwEta() * 0.010875 << " hwPhi " << std::setw(3) - << mtfCands->at(0, i1).hwPhi() << " globalPhi " << std::setw(8) - << hwGmtPhiToGlobalPhi(omtfConfig->calcGlobalPhi(mtfCands->at(0, i1).hwPhi(), - mtfCands->at(0, i1).processor())) - << " fireadLayers " << std::bitset<18>(mtfCands->at(0, i1).trackAddress().at(0)) + if (finalMuons[i1]->getPtGmt() > 0) { + LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::ghostBust\n" + << "finalMuon pt " << std::setw(3) << finalMuons[i1]->getPtGmt() + << " qual " << std::setw(2) << finalMuons[i1]->getQuality() + << " proc " << std::setw(2) << finalMuons[i1]->getProcessor() + //<< " eta " << std::setw(4) << finalMuons[i1]->getEta() + << " gloablEta " << std::setw(8) << finalMuons[i1]->getEtaRad() + << " globalPhi " << std::setw(8) << finalMuons[i1]->getPhiRad() + //<< " fireaLayers " << std::bitset<18>(mtfCands->at(0, i1).trackAddress().at(0)) << " gb isKilled " << isKilled.test(i1) << std::endl; - LogTrace("l1tOmtfEventPrint") << *(gbCandidates.at(i1)) << std::endl; + //LogTrace("l1tOmtfEventPrint") << *(gbCandidates.at(i1)) << std::endl; + if (finalMuons[i1]->getAlgoMuon()) + LogTrace("l1tOmtfEventPrint") << *(finalMuons[i1]->getAlgoMuon()) << std::endl; } } @@ -339,18 +437,27 @@ std::vector CandidateSimMuonMatcher::ghostBust( return resultCands; } -TrajectoryStateOnSurface CandidateSimMuonMatcher::atStation2(const FreeTrajectoryState& ftsStart) const { +TrajectoryStateOnSurface CandidateSimMuonMatcher::atStation1(const FreeTrajectoryState& ftsStart) const { // propagate to MB1, which defines the OMTF region (W+-2 MB1 is connected only to the OMTF) // 415 cm is R of RB1in, 660.5cm is |z| of the edge of MB2 (B field on) - ReferenceCountingPointer rpc = ReferenceCountingPointer( - new BoundCylinder(GlobalPoint(0., 0., 0.), TkRotation(), SimpleCylinderBounds(415., 415., -660.5, 660.5))); + ReferenceCountingPointer rpc = ReferenceCountingPointer(new BoundCylinder( + GlobalPoint(0., 0., 0.), TkRotation(), SimpleCylinderBounds(431.133, 431.133, -660.5, 660.5))); + //N.B. zMin and zMax do not matter for the propagator->propagate, i.e. there is not cut on them TrajectoryStateOnSurface trackAtRPC = propagator->propagate(ftsStart, *rpc); return trackAtRPC; } +TrajectoryStateOnSurface CandidateSimMuonMatcher::atStation2(const FreeTrajectoryState& ftsStart) const { + ReferenceCountingPointer surface = ReferenceCountingPointer(new BoundCylinder( + GlobalPoint(0., 0., 0.), TkRotation(), SimpleCylinderBounds(512.401, 512.401, -900, 900))); + + TrajectoryStateOnSurface tsof = propagator->propagate(ftsStart, *surface); + return tsof; +} + FreeTrajectoryState CandidateSimMuonMatcher::simTrackToFts(const SimTrack& simTrackPtr, const SimVertex& simVertex) { - int charge = simTrackPtr.type() > 0 ? -1 : 1; //works for muons + int charge = simTrackPtr.charge(); //simTrackPtr.type() > 0 ? -1 : 1; //works for muons GlobalVector p3GV(simTrackPtr.momentum().x(), simTrackPtr.momentum().y(), simTrackPtr.momentum().z()); GlobalPoint r3GP(simVertex.position().x(), simVertex.position().y(), simVertex.position().z()); @@ -361,7 +468,7 @@ FreeTrajectoryState CandidateSimMuonMatcher::simTrackToFts(const SimTrack& simTr } FreeTrajectoryState CandidateSimMuonMatcher::simTrackToFts(const TrackingParticle& trackingParticle) { - int charge = trackingParticle.pdgId() > 0 ? -1 : 1; //works for muons + int charge = trackingParticle.charge(); //trackingParticle.pdgId() > 0 ? -1 : 1; //works for muons GlobalVector p3GV(trackingParticle.momentum().x(), trackingParticle.momentum().y(), trackingParticle.momentum().z()); GlobalPoint r3GP(trackingParticle.vx(), trackingParticle.vy(), trackingParticle.vz()); @@ -407,132 +514,83 @@ float normal_pdf(float x, float m, float s) { return inv_sqrt_2pi / s * std::exp(-0.5 * a * a); } -MatchingResult CandidateSimMuonMatcher::match(const l1t::RegionalMuonCand* muonCand, - const AlgoMuonPtr& procMuon, - const SimTrack& simTrack, - TrajectoryStateOnSurface& tsof) { - MatchingResult result(simTrack); +void CandidateSimMuonMatcher::match(const FinalMuonPtr& finalMuon, MatchingResult& result) { + double trackPt = result.genPt; - double candGloablEta = muonCand->hwEta() * 0.010875; //if (std::abs(simTrack.momentum().eta() - candGloablEta) < 0.3) //has no sense for displaced muons { - double candGlobalPhi = omtfConfig->calcGlobalPhi(muonCand->hwPhi(), muonCand->processor()); - candGlobalPhi = hwGmtPhiToGlobalPhi(candGlobalPhi); + result.muonCand = finalMuon; - if (candGlobalPhi > M_PI) - candGlobalPhi = candGlobalPhi - (2. * M_PI); + if (matchingType == MatchingType::simplePropagation) { + //int charge = result.pdgId > 0 ? -1 : 1; //works for muons - result.deltaPhi = foldPhi(tsof.globalPosition().phi() - candGlobalPhi); - result.deltaEta = tsof.globalPosition().eta() - candGloablEta; + TH1* medianDelta = nullptr; + TH1* minDelta = nullptr; + TH1* maxDelta = nullptr; - result.propagatedPhi = tsof.globalPosition().phi(); - result.propagatedEta = tsof.globalPosition().eta(); + if (result.genCharge == 1) { + medianDelta = medianDelta_pos; + minDelta = minDelta_pos; + maxDelta = maxDelta_pos; + } else { + medianDelta = medianDelta_neg; + minDelta = minDelta_neg; + maxDelta = maxDelta_neg; + } - double mean = 0; - double sigma = 1; - //if(!fillMean) - { - auto ptBin = deltaPhiPropCandMean->FindBin(simTrack.momentum().pt()); - mean = deltaPhiPropCandMean->GetBinContent(ptBin); - sigma = deltaPhiPropCandStdDev->GetBinContent(ptBin); - } - result.matchingLikelihood = normal_pdf(result.deltaPhi, mean, sigma); //TODO temporary solution - - result.muonCand = muonCand; - result.procMuon = procMuon; - - //for displaced muons in H2ll - double treshold = 0.15; //pt > 30 - if (simTrack.momentum().pt() < - 10) //TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! tune the threshold!!!!!! - treshold = 0.3; - else if (simTrack.momentum().pt() < - 30) //TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! tune the threshold!!!!!! - treshold = 0.22; - - if (std::abs(result.deltaPhi - mean) < treshold && std::abs(result.deltaEta) < 0.3) - result.result = MatchingResult::ResultType::matched; - - LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match: simTrack type " << simTrack.type() << " pt " - << std::setw(8) << simTrack.momentum().pt() << " eta " << std::setw(8) - << simTrack.momentum().eta() << " phi " << std::setw(8) << simTrack.momentum().phi() - << " propagation eta " << std::setw(8) << tsof.globalPosition().eta() << " phi " - << tsof.globalPosition().phi() << "\n muonCand pt " << std::setw(8) - << muonCand->hwPt() << " candGloablEta " << std::setw(8) << candGloablEta - << " candGlobalPhi " << std::setw(8) << candGlobalPhi << " hwQual " - << muonCand->hwQual() << " deltaEta " << std::setw(8) << result.deltaEta - << " deltaPhi " << std::setw(8) << result.deltaPhi << " sigma " << std::setw(8) - << sigma << " Likelihood " << std::setw(8) << result.matchingLikelihood << " result " - << (short)result.result << std::endl; - } + auto ptBin = medianDelta->FindBin(trackPt); + auto min = minDelta->GetBinContent(ptBin); + auto max = maxDelta->GetBinContent(ptBin); - return result; -} + result.propagatedPhi = foldPhi(result.genPhi + medianDelta->GetBinContent(ptBin)); -MatchingResult CandidateSimMuonMatcher::match(const l1t::RegionalMuonCand* muonCand, - const AlgoMuonPtr& procMuon, - const TrackingParticle& trackingParticle, - TrajectoryStateOnSurface& tsof) { - MatchingResult result(trackingParticle); + result.deltaPhi = foldPhi(result.genPhi - finalMuon->getPhiRad()); + result.deltaEta = result.propagatedEta - finalMuon->getEtaRad(); - double candGloablEta = muonCand->hwEta() * 0.010875; - //if (std::abs(trackingParticle.momentum().eta() - candGloablEta) < 0.3) //has no sense for displaced muons - { - double candGlobalPhi = omtfConfig->calcGlobalPhi(muonCand->hwPhi(), muonCand->processor()); - candGlobalPhi = hwGmtPhiToGlobalPhi(candGlobalPhi); + result.matchingLikelihood = 1. / (std::abs(result.deltaPhi) + 0.001); - if (candGlobalPhi > M_PI) - candGlobalPhi = candGlobalPhi - (2. * M_PI); + if (result.deltaPhi > min && result.deltaPhi < max && std::abs(result.deltaEta) < 0.4) + result.result = MatchingResult::ResultType::matched; + } else if (matchingType == MatchingType::withPropagator) { + result.deltaPhi = foldPhi(result.propagatedPhi - finalMuon->getPhiRad()); + result.deltaEta = result.propagatedEta - finalMuon->getEtaRad(); //propagatedEta is set in propagate - result.deltaPhi = foldPhi(tsof.globalPosition().phi() - candGlobalPhi); - result.deltaEta = tsof.globalPosition().eta() - candGloablEta; + result.matchingLikelihood = 1. / (std::abs(result.deltaPhi) + 0.001); - result.propagatedPhi = tsof.globalPosition().phi(); - result.propagatedEta = tsof.globalPosition().eta(); + double mean = 0; + double treshold = 0; - double mean = 0; - double sigma = 1; - //if(!fillMean) - { - auto ptBin = deltaPhiPropCandMean->FindBin(trackingParticle.pt()); + //for displaced muons in H2ll + //here a coarse threshold are used, as for dispalced muons + treshold = 0.15; //pt > 30 + if (trackPt < 10) //TODO!!!!!!!!!!!!!!!!!!!!! tune the threshold!!!!!! + treshold = 0.4; + else if (trackPt < 30) //TODO!!!!!!!!!!!!!!! tune the threshold!!!!!! + treshold = 0.22; + + mean = 0; - mean = deltaPhiPropCandMean->GetBinContent(ptBin); - sigma = deltaPhiPropCandStdDev->GetBinContent(ptBin); + if (std::abs(result.deltaPhi - mean) < treshold && std::abs(result.deltaEta) < 0.4) + result.result = MatchingResult::ResultType::matched; } - result.matchingLikelihood = normal_pdf(result.deltaPhi, mean, sigma); //TODO temporary solution - - result.muonCand = muonCand; - result.procMuon = procMuon; - - double treshold = 6. * sigma; - if (trackingParticle.pt() > 20) - treshold = 7. * sigma; - if (trackingParticle.pt() > 100) - treshold = 20. * sigma; - - if (std::abs(result.deltaPhi - mean) < treshold && std::abs(result.deltaEta) < 0.3) - result.result = MatchingResult::ResultType::matched; - - LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match: trackingParticle type " - << trackingParticle.pdgId() << " pt " << std::setw(8) << trackingParticle.pt() - << " eta " << std::setw(8) << trackingParticle.momentum().eta() << " phi " - << std::setw(8) << trackingParticle.momentum().phi() << " propagation eta " - << std::setw(8) << tsof.globalPosition().eta() << " phi " - << tsof.globalPosition().phi() << " muonCand pt " << std::setw(8) << muonCand->hwPt() - << " candGloablEta " << std::setw(8) << candGloablEta << " candGlobalPhi " - << std::setw(8) << candGlobalPhi << " hwQual " << muonCand->hwQual() << " deltaEta " - << std::setw(8) << result.deltaEta << " deltaPhi " << std::setw(8) << result.deltaPhi + LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match: simTrack type " << result.pdgId << " pt " + << std::setw(8) << trackPt << " eta " << std::setw(8) << result.genEta << " phi " + << std::setw(8) << result.genPhi << " propagatedEta " << std::setw(8) + << result.propagatedEta << " propagatedPhi " << result.propagatedPhi + << "\n muonCand pt " << std::setw(8) << finalMuon->getPtGmt() + << " candGloablEta " << std::setw(8) << finalMuon->getEtaGmt() + << " candGlobalPhi " << std::setw(8) << finalMuon->getPhiGmt() + //<< " hwPhi " << muonCand->hwPhi() + << " hwQual " << finalMuon->getQuality() << " processor " << finalMuon->getProcessor() + << " deltaEta " << std::setw(8) << result.deltaEta << " deltaPhi " << std::setw(8) << result.deltaPhi << " Likelihood " << std::setw(8) << result.matchingLikelihood << " result " << (short)result.result << std::endl; } - - return result; } std::vector CandidateSimMuonMatcher::cleanMatching(std::vector matchingResults, - std::vector& muonCands, - AlgoMuons& ghostBustedProcMuons) { + const FinalMuons& finalMuons) { //Cleaning the matching std::sort( matchingResults.begin(), matchingResults.end(), [](const MatchingResult& a, const MatchingResult& b) -> bool { @@ -558,19 +616,13 @@ std::vector CandidateSimMuonMatcher::cleanMatching(std::vectorFill(ptGen, matchingResult.deltaPhi); //filling overflow is ok here - deltaPhiPropCandStdDev->Fill(ptGen, matchingResult.deltaPhi * matchingResult.deltaPhi); - }*/ - } } - //adding the muonCand-s that were not matched, i.e. in order to analyze them later - unsigned int iCand = 0; - for (auto& muonCand : muonCands) { + //adding the muonCand-s that were not matched, e.g. in order to analyze them later + for (auto& muonCand : finalMuons) { + if(muonCand->getPtGmt() == 0 || muonCand->getQuality() == 0) + continue; + bool isMatched = false; for (auto& matchingResult : cleanedMatchingResults) { if (matchingResult.muonCand == muonCand) { @@ -582,13 +634,11 @@ std::vector CandidateSimMuonMatcher::cleanMatching(std::vector CandidateSimMuonMatcher::cleanMatching(std::vectorhwPt() << " hwQual " - << result.muonCand->hwQual() << " hwEta " << result.muonCand->hwEta() + LogTrace("l1tOmtfEventPrint") << " muonCand pt " << std::setw(8) << result.muonCand->getPtGmt() << " hwQual " + << result.muonCand->getQuality() << " eta " << result.muonCand->getEtaRad() << " deltaEta " << std::setw(8) << result.deltaEta << " deltaPhi " << std::setw(8) << result.deltaPhi << " Likelihood " << std::setw(8) << result.matchingLikelihood << " result " << (short)result.result; - LogTrace("l1tOmtfEventPrint") << " procMuon " << *(result.procMuon) << std::endl; + //LogTrace("l1tOmtfEventPrint") << " procMuon " << *(result.procMuon) << std::endl; } else LogTrace("l1tOmtfEventPrint") << " no muonCand " << " result " << (short)result.result << std::endl; @@ -614,8 +664,102 @@ std::vector CandidateSimMuonMatcher::cleanMatching(std::vector CandidateSimMuonMatcher::match(std::vector& muonCands, - AlgoMuons& ghostBustedProcMuons, +void CandidateSimMuonMatcher::propagate(MatchingResult& result) { + auto doSimplePropagation = [&]() { + TH1* medianDelta = result.genCharge == 1 ? medianDelta_pos : medianDelta_neg; + auto ptBin = medianDelta->FindBin(result.genPt); + result.propagatedPhi = foldPhi(result.genPhi + medianDelta->GetBinContent(ptBin)); + result.propagatedEta = result.genEta; + }; + + if (matchingType == MatchingType::withPropagator) { + //TODO if result.simVertex is null it will crash - add a protection + FreeTrajectoryState ftsTrack = result.simTrack ? simTrackToFts(*(result.simTrack), *(result.simVertex)) + : simTrackToFts(*result.trackingParticle); + + TrajectoryStateOnSurface tsof = atStation2(ftsTrack); //propagation + + if (!tsof.isValid()) { + if (result.genPt > 2.5 && result.trackingParticle && result.trackingParticle->parentVertex().isNonnull()) { + if (result.muonRho < 40) { + doSimplePropagation(); + } + } else { + result.result = MatchingResult::ResultType::propagationFailed; + //result.propagatedEta = 0 in this case + } + } else { + result.propagatedPhi = tsof.globalPosition().phi(); + result.propagatedEta = tsof.globalPosition().eta(); + } + } else if (matchingType == MatchingType::simplePropagation) { + doSimplePropagation(); + } +} + +void CandidateSimMuonMatcher::match(const FinalMuons& finalMuons, + MatchingResult& result, + std::vector& matchingResults) { + propagate(result); + if (result.result == MatchingResult::ResultType::propagationFailed) { //no sense to do matching + + //TODO For the displaced muons adding the muons for which the propagation failed in principle has no sense + //as matching with candidates is not possible then. + //For prompt muons this can be useful, to have the full pt spectrum of gen muons. + //However, using them in the denominator of the efficiency biases the efficiency, because for these muons matching to the candidates is not possible. + //In any case these results are marked in the DataROOTDumper2 omtfEvent.muonEvent = -2. + LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " propagation failed: genPt " << result.genPt + << " genEta " << result.genEta << " eventId " //<< simTrack.eventId().event() + << std::endl; + + //matchingResults.push_back(result); + } else { + //checking if the propagated track is inside the OMTF range, TODO - tune the range!!!!!!!!!!!!!!!!! + //eta 0.7 is the beginning of the MB2, + //the eta range wider than the nominal OMTF region is needed, as in any case muons outside this region are seen by the OMTF + //so it is better to match them to simMuon, otherwise they look like ghosts. + //Besides, it better to train the nn suich that is able to measure its pt, as it may affect the rate + if ((std::abs(result.propagatedEta) >= 0.7) && (std::abs(result.propagatedEta) <= 1.31)) { + LogTrace("l1tOmtfEventPrint") + << "CandidateSimMuonMatcher::match simTrack IS in OMTF region, matching to the omtfCands, propagatedEta: " + << result.propagatedEta; + } else { + LogTrace("l1tOmtfEventPrint") << "simTrack NOT in OMTF region "; + return; + } + + /* TODO fix if filling of the deltaPhiPropCandMean and deltaPhiPropCandStdDev is needed + double ptGen = simTrack.momentum().pt(); + if(ptGen >= deltaPhiVertexProp->GetXaxis()->GetXmax()) + ptGen = deltaPhiVertexProp->GetXaxis()->GetXmax() - 0.01; + + deltaPhiVertexProp->Fill(ptGen, simTrack.momentum().phi() - tsof.globalPosition().phi());*/ + + unsigned int iCand = 0; + bool matched = false; + for (auto& muonCand : finalMuons) { + //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive + if (muonCand->getQuality() > 1) { + MatchingResult resultCopy = result; + + match(muonCand, resultCopy); + + if (resultCopy.result == MatchingResult::ResultType::matched) { + matchingResults.push_back(resultCopy); + matched = true; + } + } + iCand++; + } + + if (!matched) { //we are adding also if it was not matching to any candidate + matchingResults.push_back(result); + LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " no matching candidate found" << std::endl; + } + } +} + +std::vector CandidateSimMuonMatcher::match(const FinalMuons& finalMuons, const edm::SimTrackContainer* simTracks, const edm::SimVertexContainer* simVertices, std::function const& simTrackFilter) { @@ -625,78 +769,36 @@ std::vector CandidateSimMuonMatcher::match(std::vector= 0 ? simVertices->at(simTrack.vertIndex()).position().Rho() + : -99) << std::endl; - bool matched = false; - - TrajectoryStateOnSurface tsof = propagate(simTrack, simVertices); - if (!tsof.isValid()) { //no sense to do matching - MatchingResult result(simTrack); - result.result = MatchingResult::ResultType::propagationFailed; - LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " propagation failed: genPt " << result.genPt - << " genEta " << result.genEta << " eventId " << simTrack.eventId().event() - << std::endl; - - matchingResults.push_back(result); + SimVertex simVertex; + int vtxInd = simTrack.vertIndex(); + if (vtxInd < 0) { + edm::LogImportant("l1tOmtfEventPrint") << "Track with no vertex, defaulting to (0,0,0)"; } else { - //checking if the propagated track is inside the OMTF range, TODO - tune the range!!!!!!!!!!!!!!!!! - //eta 0.7 is the beginning of the MB2, - //the eta range wider than the nominal OMTF region is needed, as in any case muons outside this region are seen by the OMTF - //so it better to train the nn suich that is able to measure its pt, as it may affect the rate - if ((std::abs(tsof.globalPosition().eta()) >= 0.7) && (std::abs(tsof.globalPosition().eta()) <= 1.31)) { - LogTrace("l1tOmtfEventPrint") - << "CandidateSimMuonMatcher::match simTrack IS in OMTF region, matching to the omtfCands"; - } else { - LogTrace("l1tOmtfEventPrint") << "simTrack NOT in OMTF region "; - continue; + simVertex = simVertices->at(vtxInd); + if (((int)simVertex.vertexId()) != vtxInd) { + edm::LogImportant("l1tOmtfEventPrint") << "simVertex.vertexId() != vtxInd. simVertex.vertexId() " + << simVertex.vertexId() << " vtxInd " << vtxInd << " !!!!!!!!!!!!!!!!!"; } + } - /* TODO fix if filling of the deltaPhiPropCandMean and deltaPhiPropCandStdDev is needed - double ptGen = simTrack.momentum().pt(); - if(ptGen >= deltaPhiVertexProp->GetXaxis()->GetXmax()) - ptGen = deltaPhiVertexProp->GetXaxis()->GetXmax() - 0.01; - - deltaPhiVertexProp->Fill(ptGen, simTrack.momentum().phi() - tsof.globalPosition().phi());*/ - - unsigned int iCand = 0; - for (auto& muonCand : muonCands) { - //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive - //if(muonCand->hwQual() > 1) - { - MatchingResult result; - if (tsof.isValid()) { - result = match(muonCand, ghostBustedProcMuons.at(iCand), simTrack, tsof); - } - int vtxInd = simTrack.vertIndex(); - if (vtxInd >= 0) { - result.simVertex = &(simVertices->at( - vtxInd)); //TODO ?????? something strange is here, was commented in the previous version - } - if (result.result == MatchingResult::ResultType::matched) { - matchingResults.push_back(result); - matched = true; - } - } - iCand++; - } + MatchingResult result(simTrack, simTrack.vertIndex() >= 0 ? &(simVertices->at(simTrack.vertIndex())) : nullptr); - if (!matched) { //we are adding also if it was not matching to any candidate - MatchingResult result(simTrack); - matchingResults.push_back(result); - LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " no matching candidate found" << std::endl; - } - } + match(finalMuons, result, matchingResults); } - return cleanMatching(matchingResults, muonCands, ghostBustedProcMuons); + return cleanMatching(matchingResults, finalMuons); } std::vector CandidateSimMuonMatcher::match( - std::vector& muonCands, - AlgoMuons& ghostBustedProcMuons, + const FinalMuons& finalMuons, const TrackingParticleCollection* trackingParticles, std::function const& simTrackFilter) { std::vector matchingResults; @@ -714,69 +816,16 @@ std::vector CandidateSimMuonMatcher::match( << " eta " << std::setw(9) << trackingParticle.momentum().eta() << " phi " << std::setw(9) << trackingParticle.momentum().phi() << std::endl; - bool matched = false; + MatchingResult result(trackingParticle); - TrajectoryStateOnSurface tsof = propagate(trackingParticle); - if (!tsof.isValid()) { - LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match:" << __LINE__ << " propagation failed" - << std::endl; - MatchingResult result; - result.result = MatchingResult::ResultType::propagationFailed; - continue; //no sense to do matching - } - - LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match, tsof.globalPosition().eta() " - << tsof.globalPosition().eta(); - - //checking if the propagated track is inside the OMTF range, TODO - tune the range!!!!!!!!!!!!!!!!! - //eta 0.7 is the beginning of the MB2, while 1.31 is mid of RE2 + some margin - if ((std::abs(tsof.globalPosition().eta()) >= 0.7) && (std::abs(tsof.globalPosition().eta()) <= 1.31)) { - LogTrace("l1tOmtfEventPrint") - << "CandidateSimMuonMatcher::match trackingParticle IS in OMTF region, matching to the omtfCands"; - } else { - LogTrace("l1tOmtfEventPrint") << "trackingParticle NOT in OMTF region "; - continue; - } - - /* TODO fix if filling of the deltaPhiPropCandMean and deltaPhiPropCandStdDev is needed - double ptGen = trackingParticle.pt(); - if(ptGen >= deltaPhiVertexProp->GetXaxis()->GetXmax()) - ptGen = deltaPhiVertexProp->GetXaxis()->GetXmax() - 0.01; - - deltaPhiVertexProp->Fill(ptGen, trackingParticle.momentum().phi() - tsof.globalPosition().phi()); - */ - - unsigned int iCand = 0; - for (auto& muonCand : muonCands) { - //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive then - /*if(muonCand->hwQual() <= 1) - continue; */ - - MatchingResult result; - if (tsof.isValid()) { - result = match(muonCand, ghostBustedProcMuons.at(iCand), trackingParticle, tsof); - } - iCand++; - - if (result.result == MatchingResult::ResultType::matched) { - matchingResults.push_back(result); - matched = true; - } - } - - if (!matched) { //we are adding result also if it there was no matching to any candidate - MatchingResult result(trackingParticle); - matchingResults.push_back(result); - LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " no matching candidate found" << std::endl; - } + match(finalMuons, result, matchingResults); } - return cleanMatching(matchingResults, muonCands, ghostBustedProcMuons); + return cleanMatching(matchingResults, finalMuons); } std::vector CandidateSimMuonMatcher::matchSimple( - std::vector& muonCands, - AlgoMuons& ghostBustedProcMuons, + const FinalMuons& finalMuons, const edm::SimTrackContainer* simTracks, const edm::SimVertexContainer* simVertices, std::function const& simTrackFilter) { @@ -793,28 +842,20 @@ std::vector CandidateSimMuonMatcher::matchSimple( bool matched = false; - unsigned int iCand = 0; - for (auto& muonCand : muonCands) { + for (auto& finalMuon : finalMuons) { //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive //if(muonCand->hwQual() > 1) + if (finalMuon->getPtGev() > 0) { - MatchingResult result(simTrack); + MatchingResult result(simTrack, simTrack.vertIndex() >= 0 ? &(simVertices->at(simTrack.vertIndex())) : nullptr); - double candGloablEta = muonCand->hwEta() * 0.010875; - double candGlobalPhi = omtfConfig->calcGlobalPhi(muonCand->hwPhi(), muonCand->processor()); - candGlobalPhi = hwGmtPhiToGlobalPhi(candGlobalPhi); + result.deltaPhi = foldPhi(result.genPhi - finalMuon->getPhiRad()); + result.deltaEta = result.genEta - finalMuon->getEtaRad(); - if (candGlobalPhi > M_PI) - candGlobalPhi = candGlobalPhi - (2. * M_PI); + result.propagatedPhi = result.genPhi; + result.propagatedEta = result.genEta; - result.deltaPhi = foldPhi(result.genPhi - candGlobalPhi); - result.deltaEta = result.genEta - candGloablEta; - - result.propagatedPhi = 0; - result.propagatedEta = 0; - - result.muonCand = muonCand; - result.procMuon = ghostBustedProcMuons.at(iCand); + result.muonCand = finalMuon; //TODO histogram can be used, like in the usercode/L1MuonAnalyzer MuonMatcher::matchWithoutPorpagation //for prompt muons @@ -828,53 +869,70 @@ std::vector CandidateSimMuonMatcher::matchSimple( else if (simTrack.momentum().pt() < 20) treshold = 0.5;*/ - //for displaced muons - double treshold = 0.7; + double treshold = 0.5; if (simTrack.momentum().pt() < 5) treshold = 1.5; else if (simTrack.momentum().pt() < 10) treshold = 1.0; - else if (simTrack.momentum().pt() < 20) + else if (simTrack.momentum().pt() < 25) treshold = 0.7; if (std::abs(result.deltaPhi) < treshold && std::abs(result.deltaEta) < 0.5) { result.result = MatchingResult::ResultType::matched; //matchingLikelihood is needed in the cleanMatching, so we put something - if (std::abs(result.deltaPhi) < 0.001) - result.matchingLikelihood = 1. / 0.001; - else - result.matchingLikelihood = 1. / std::abs(result.deltaPhi); + result.matchingLikelihood = 1. / (std::abs(result.deltaPhi) + 0.001); } LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::matchSimple: simTrack type " << simTrack.type() << " pt " << std::setw(8) << simTrack.momentum().pt() << " eta " << std::setw(8) << simTrack.momentum().eta() << " phi " << std::setw(8) << simTrack.momentum().phi() << "\n muonCand pt " << std::setw(8) - << muonCand->hwPt() << " candGloablEta " << std::setw(8) << candGloablEta - << " candGlobalPhi " << std::setw(8) << candGlobalPhi << " hwQual " - << muonCand->hwQual() << " deltaEta " << std::setw(8) << result.deltaEta + << finalMuon->getPtGmt() << " candGloablEta " << std::setw(8) << finalMuon->getEtaRad() + << " candGlobalPhi " << std::setw(8) << finalMuon->getPhiRad() << " hwQual " + << finalMuon->getQuality() << " deltaEta " << std::setw(8) << result.deltaEta << " deltaPhi " << std::setw(8) << result.deltaPhi << " matchingLikelihood " << result.matchingLikelihood << " result " << (short)result.result << std::endl; - int vtxInd = simTrack.vertIndex(); - if (vtxInd >= 0) { - result.simVertex = &( - simVertices->at(vtxInd)); //TODO ?????? something strange is here, was commented in the previous version - } if (result.result == MatchingResult::ResultType::matched) { matchingResults.push_back(result); matched = true; } } - iCand++; } if (!matched) { //we are adding also if it was not matched to any candidate - MatchingResult result(simTrack); + MatchingResult result(simTrack, simTrack.vertIndex() >= 0 ? &(simVertices->at(simTrack.vertIndex())) : nullptr); + result.propagatedPhi = result.genPhi; + result.propagatedEta = result.genEta; matchingResults.push_back(result); LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " no matching candidate found" << std::endl; } } - return cleanMatching(matchingResults, muonCands, ghostBustedProcMuons); + return cleanMatching(matchingResults, finalMuons); +} + +std::vector CandidateSimMuonMatcher::collectMuonCands(const FinalMuons& finalMuons) { + std::vector matchingResults; + unsigned int iCand = 0; + for (auto& muonCand : finalMuons) { + //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive + //if(muonCand->hwQual() > 1) + { + MatchingResult result; + + result.muonCand = muonCand; + + LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::collectMuonCands: muonCand pt " << std::setw(8) + << muonCand->getPtGmt() << " candGloablEta " << std::setw(8) << muonCand->getEtaRad() + << " candGlobalPhi " << std::setw(8) << muonCand->getPhiRad() << " hwQual " + << muonCand->getQuality() << " deltaEta " << std::setw(8) << result.deltaEta + << " deltaPhi " << std::setw(8) << result.deltaPhi << " matchingLikelihood " + << result.matchingLikelihood << " result " << (short)result.result << std::endl; + + matchingResults.push_back(result); + } + iCand++; + } + return matchingResults; } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc index c5d0b6f040a7e..2d73a99bf7ac7 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc @@ -31,17 +31,6 @@ DataROOTDumper2::DataROOTDumper2(const edm::ParameterSet& edmCfg, if (edmCfg.getParameter("dumpKilledOmtfCands")) dumpKilledOmtfCands = true; - if (edmCfg.exists("candidateSimMuonMatcherType")) { - if (edmCfg.getParameter("candidateSimMuonMatcherType") == "propagation") - usePropagation = true; - else if (edmCfg.getParameter("candidateSimMuonMatcherType") == "matchSimple") - usePropagation = false; - - edm::LogImportant("l1tOmtfEventPrint") - << " CandidateSimMuonMatcher: candidateSimMuonMatcherType " - << edmCfg.getParameter("candidateSimMuonMatcherType") << std::endl; - } - edm::LogVerbatim("l1tOmtfEventPrint") << " DataROOTDumper2 created. dumpKilledOmtfCands " << dumpKilledOmtfCands << std::endl; } @@ -65,6 +54,9 @@ void DataROOTDumper2::initializeTTree() { rootTree->Branch("muonDxy", &omtfEvent.muonDxy); rootTree->Branch("muonRho", &omtfEvent.muonRho); + rootTree->Branch("parentPdgId", &omtfEvent.parentPdgId); + rootTree->Branch("vertexEta", &omtfEvent.vertexEta); + rootTree->Branch("vertexPhi", &omtfEvent.vertexPhi); rootTree->Branch("omtfPt", &omtfEvent.omtfPt); rootTree->Branch("omtfUPt", &omtfEvent.omtfUPt); @@ -79,6 +71,7 @@ void DataROOTDumper2::initializeTTree() { rootTree->Branch("omtfQuality", &omtfEvent.omtfQuality); rootTree->Branch("omtfRefLayer", &omtfEvent.omtfRefLayer); rootTree->Branch("omtfRefHitNum", &omtfEvent.omtfRefHitNum); + rootTree->Branch("omtfRefHitPhi", &omtfEvent.omtfRefHitPhi); rootTree->Branch("omtfFiredLayers", &omtfEvent.omtfFiredLayers); //<<<<<<<<<<<<<<<<<<<<<&, const AlgoMuons& algoCandidates, const AlgoMuons& gbCandidates, - const std::vector& candMuons) {} + const FinalMuons& finalMuons) {} -void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, - std::unique_ptr& finalCandidates) { +void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMuons) { /* int muonCharge = 0; if (simMuon) { @@ -137,18 +129,23 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, //for some events there are more than one matchingResults, //Usually at least one them has genPt 0, which means no simMuon was matched, so candidate is ghost (or fake) - //so better is to to drop such event, as it is not sue if the correct simMuon was matched to the candidate. + //so better is to to drop such event, as it is not sure if the correct simMuon was matched to the candidate. //So we assume here that when the propagation is not used it is a single mu sample and this filter has sense - //the propagation is used for multi-muon sample, so then this fitler cannot be used + //the propagation is used for multi-muon sample, so then this filter cannot be used //TODO add a flag to enable this filter? Disable it if not needed - if (!usePropagation && matchingResults.size() > 1) { //omtfConfig->cleanStubs() && + //in the single Mu sample, if there are two matchingResults, and the second has genPt 0, so it is easy to fitler it out when reading the dump. + //so better would be to remove this condition, as it may be activated unintentionly + if (candidateSimMuonMatcher->getMatchingType() == CandidateSimMuonMatcher::MatchingType::simpleMatching && + matchingResults.size() > 1) { //omtfConfig->cleanStubs() && edm::LogVerbatim("l1tOmtfEventPrint") << "\nDataROOTDumper2::observeEventEnd matchingResults.size() " << matchingResults.size() << std::endl; for (auto& matchingResult : matchingResults) { edm::LogVerbatim("l1tOmtfEventPrint") << "matchingResult: genPt " << matchingResult.genPt; - if (matchingResult.procMuon) - edm::LogVerbatim("l1tOmtfEventPrint") << " procMuon.PtConstr " << matchingResult.procMuon->getPtConstr(); + if (matchingResult.muonCand) + edm::LogVerbatim("l1tOmtfEventPrint") + << " procMuon.PtConstr " << matchingResult.muonCand->getAlgoMuon()->getPtConstr() << " processor " + << matchingResult.muonCand->getProcessor() << " hwPhi " << matchingResult.muonCand->getAlgoMuon()->getPhi(); else edm::LogVerbatim("l1tOmtfEventPrint") << " no procMuon" << std::endl; } @@ -162,7 +159,10 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, if (matchingResult.trackingParticle) { auto trackingParticle = matchingResult.trackingParticle; - omtfEvent.muonEvent = trackingParticle->eventId().event(); + if (matchingResult.result == MatchingResult::ResultType::propagationFailed) + omtfEvent.muonEvent = -2; + else + omtfEvent.muonEvent = trackingParticle->eventId().event(); omtfEvent.muonPt = trackingParticle->pt(); omtfEvent.muonEta = trackingParticle->momentum().eta(); @@ -170,12 +170,21 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, omtfEvent.muonPropEta = matchingResult.propagatedEta; omtfEvent.muonPropPhi = matchingResult.propagatedPhi; omtfEvent.muonCharge = (std::abs(trackingParticle->pdgId()) == 13) ? trackingParticle->pdgId() / -13 : 0; + omtfEvent.muonCharge = trackingParticle->charge(); if (trackingParticle->parentVertex().isNonnull()) { omtfEvent.muonDxy = trackingParticle->dxy(); omtfEvent.muonRho = trackingParticle->parentVertex()->position().Rho(); + + for (auto& parentTrack : trackingParticle->parentVertex()->sourceTracks()) { + omtfEvent.parentPdgId = parentTrack->pdgId(); + LogTrace("l1MuonAnalyzerOmtf") << " DataROOTDumper2 parentTrackPdgId " << omtfEvent.parentPdgId << std::endl; + } } + omtfEvent.vertexPhi = matchingResult.vertexPhi; + omtfEvent.vertexEta = matchingResult.vertexEta; + omtfEvent.deltaEta = matchingResult.deltaEta; omtfEvent.deltaPhi = matchingResult.deltaPhi; @@ -195,8 +204,10 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, } } else if (matchingResult.simTrack) { auto simTrack = matchingResult.simTrack; - - omtfEvent.muonEvent = simTrack->eventId().event(); + if (matchingResult.result == MatchingResult::ResultType::propagationFailed) + omtfEvent.muonEvent = -2; + else + omtfEvent.muonEvent = simTrack->eventId().event(); omtfEvent.muonPt = simTrack->momentum().pt(); omtfEvent.muonEta = simTrack->momentum().eta(); @@ -205,12 +216,18 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, omtfEvent.muonPropPhi = matchingResult.propagatedPhi; omtfEvent.muonCharge = simTrack->charge(); - if (!simTrack->noVertex() && matchingResult.simVertex) { + /*if (!simTrack->noVertex() && matchingResult.simVertex) { const math::XYZTLorentzVectorD& vtxPos = matchingResult.simVertex->position(); omtfEvent.muonDxy = (-vtxPos.X() * simTrack->momentum().py() + vtxPos.Y() * simTrack->momentum().px()) / simTrack->momentum().pt(); omtfEvent.muonRho = vtxPos.Rho(); - } + }*/ + + omtfEvent.muonDxy = matchingResult.muonDxy; + omtfEvent.muonRho = matchingResult.muonRho; + + omtfEvent.vertexPhi = matchingResult.vertexPhi; + omtfEvent.vertexEta = matchingResult.vertexEta; omtfEvent.deltaEta = matchingResult.deltaEta; omtfEvent.deltaPhi = matchingResult.deltaPhi; @@ -246,27 +263,44 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, omtfEvent.muonRho = 0; } - auto addOmtfCand = [&](AlgoMuonPtr& procMuon) { - omtfEvent.omtfPt = omtfConfig->hwPtToGev(procMuon->getPtConstr()); - omtfEvent.omtfUPt = omtfConfig->hwUPtToGev(procMuon->getPtUnconstr()); - omtfEvent.omtfEta = omtfConfig->hwEtaToEta(procMuon->getEtaHw()); - omtfEvent.omtfPhi = procMuon->getPhi(); - omtfEvent.omtfCharge = procMuon->getChargeConstr(); - omtfEvent.omtfScore = procMuon->getPdfSum(); + auto addOmtfCand = [&](FinalMuonPtr muonCand) { + //the charge is only for the constrained measurement. The constrained measurement is always defined for a valid candidate + if (muonCand->getAlgoMuon()->getPdfSumConstr() > 0 && muonCand->getAlgoMuon()->getFiredLayerCntConstr() >= 3) + omtfEvent.omtfPt = muonCand->getPtGev(); + else if (muonCand->getAlgoMuon()->getPtUnconstr() > 0) + //if myCand->getPdfSumConstr() == 0, the myCand->getPtConstr() might not be 0, see the end of GhostBusterPreferRefDt::select + //but hwPt=0 means empty candidate, hwPt=1 means pt=0, + //but omtfPt = 0 means empty candidate + //therefore here we set omtfPt=0.5 GeV, if the PtUnconstr > 0 + //N.B it is different than in the OMTFProcessor::convertToOuputScalesPhase1, where hwPt=1 + omtfEvent.omtfPt = 0.5; + else + omtfEvent.omtfPt = omtfConfig->hwPtToGev(0); + + //for candidate with no unconstrained measurement, hardware upt = 0 + //so then omtfEvent.omtfUPt is -1 + omtfEvent.omtfUPt = muonCand->getPtUnconstrGev(); + //omtfEvent.omtfEta = omtfConfig->hwEtaToEta(procMuon->getEtaHw()); + omtfEvent.omtfEta = muonCand->getEtaRad(); + omtfEvent.omtfPhi = muonCand->getPhiRad(); + omtfEvent.omtfCharge = muonCand->getAlgoMuon()->getChargeConstr(); + omtfEvent.omtfScore = muonCand->getAlgoMuon()->getPdfSum(); - omtfEvent.omtfHwEta = procMuon->getEtaHw(); + omtfEvent.omtfHwEta = muonCand->getAlgoMuon()->getEtaHw(); - omtfEvent.omtfFiredLayers = procMuon->getFiredLayerBits(); - omtfEvent.omtfRefLayer = procMuon->getRefLayer(); - omtfEvent.omtfRefHitNum = procMuon->getRefHitNumber(); + omtfEvent.omtfFiredLayers = muonCand->getAlgoMuon()->getFiredLayerBits(); + omtfEvent.omtfRefLayer = muonCand->getAlgoMuon()->getRefLayer(); + omtfEvent.omtfRefHitNum = muonCand->getAlgoMuon()->getRefHitNumber(); omtfEvent.hits.clear(); //TODO choose, which gpResult should be dumped //auto& gpResult = procMuon->getGpResultConstr(); - auto& gpResult = (procMuon->getGpResultUnconstr().getPdfSumUnconstr() > procMuon->getGpResultConstr().getPdfSum()) - ? procMuon->getGpResultUnconstr() - : procMuon->getGpResultConstr(); + auto& gpResult = (muonCand->getAlgoMuon()->getGpResultUnconstr().getPdfSumUnconstr() > muonCand->getAlgoMuon()->getGpResultConstr().getPdfSum()) + ? muonCand->getAlgoMuon()->getGpResultUnconstr() + : muonCand->getAlgoMuon()->getGpResultConstr(); + + omtfEvent.omtfRefHitPhi = gpResult.getRefHitPhi(); /* edm::LogVerbatim("l1tOmtfEventPrint")<<"DataROOTDumper2:;observeEventEnd muonPt "<qualityHw; - hit.eta = stubResult.getMuonStub()->etaHw; //in which scale? + //hit.eta = stubResult.getMuonStub()->etaHw; //replaced by deltaR hit.valid = stubResult.getValid(); - int hitPhi = stubResult.getMuonStub()->phiHw; - unsigned int refLayerLogicNum = omtfConfig->getRefToLogicNumber()[procMuon->getRefLayer()]; - int phiRefHit = gpResult.getStubResults()[refLayerLogicNum].getMuonStub()->phiHw; - - if (omtfConfig->isBendingLayer(iLogicLayer)) { - hitPhi = stubResult.getMuonStub()->phiBHw; - phiRefHit = 0; //phi ref hit for the bending layer set to 0, since it should not be included in the phiDist - } + unsigned int refLayerLogicNum = omtfConfig->getRefToLogicNumber()[muonCand->getAlgoMuon()->getRefLayer()]; - //phiDist = hitPhi - phiRefHit; - hit.phiDist = hitPhi - phiRefHit; + if (false) { //choose what to dump in hit.phiDist: "hitPhi - phiRefHit" or stubResult.getDeltaPhi() + int hitPhi = stubResult.getMuonStub()->phiHw; + int phiRefHit = gpResult.getStubResults()[refLayerLogicNum].getMuonStub()->phiHw; + hit.phiDist = hitPhi - phiRefHit; - /* LogTrace("l1tOmtfEventPrint")<<" muonPt "<getGoldenPatern()->getDistPhiBitShift(iLogicLayer, procMuon->getRefLayer()) - <<" meanDistPhiValue "<getGoldenPatern()->meanDistPhiValue(iLogicLayer, procMuon->getRefLayer())//<<(phiDist != hit.phiDist? "!!!!!!!<<<<<" : "") - <isBendingLayer(iLogicLayer)) { + hit.phiDist = stubResult.getMuonStub()->phiBHw; + } + } else { + //stubResult.getDeltaPhi() includes the extrapolated phi + hit.phiDist = stubResult.getDeltaPhi(); + } - /*if (hit.phiDist > 504 || hit.phiDist < -512) { - edm::LogVerbatim("l1tOmtfEventPrint") + if (refLayerLogicNum == iLogicLayer) + hit.deltaR = stubResult.getMuonStub()->r - 413; //r of the ref hit - r of RB1in + else + hit.deltaR = stubResult.getMuonStub()->r - gpResult.getStubResults()[refLayerLogicNum].getMuonStub()->r; + + LogTrace("l1tOmtfEventPrint") + << " muonPt " << omtfEvent.muonPt << " omtfPt " << omtfEvent.omtfPt << " RefLayer " + << int(omtfEvent.omtfRefLayer) << " layer " << int(hit.layer) << " PdfBin " << stubResult.getPdfBin() + << " hit.phiDist " << hit.phiDist << " valid " << int(hit.valid) << " " //<<" phiDist "<getGoldenPatern()->getDistPhiBitShift(iLogicLayer, procMuon->getRefLayer()) + //<<" meanDistPhiValue "<getGoldenPatern()->meanDistPhiValue(iLogicLayer, procMuon->getRefLayer())//<<(phiDist != hit.phiDist? "!!!!!!!<<<<<" : "") + << endl; + + if (hit.phiDist > 504 || hit.phiDist < -512) { + LogTrace("l1tOmtfEventPrint") << " muonPt " << omtfEvent.muonPt << " omtfPt " << omtfEvent.omtfPt << " RefLayer " << (int)omtfEvent.omtfRefLayer << " layer " << int(hit.layer) << " hit.phiDist " << hit.phiDist << " valid " << stubResult.getValid() << " !!!!!!!!!!!!!!!!!!!!!!!!" << endl; - }*/ + } - DetId detId(stubResult.getMuonStub()->detId); + /*DetId detId(stubResult.getMuonStub()->detId); if (detId.subdetId() == MuonSubdetId::CSC) { CSCDetId cscId(detId); hit.z = cscId.chamber() % 2; - } + }*/ + + //hit.etaHw is char, so we must limit the value being assigned + //it char range is ok with valueP1Scale + //for the phase2 scale something will have to be done TODO + if (stubResult.getMuonStub()->etaHw > 127) + hit.etaHw = 127; + else if (stubResult.getMuonStub()->etaHw < -127) + hit.etaHw = -127; + else + hit.etaHw = stubResult.getMuonStub()->etaHw; omtfEvent.hits.push_back(hit.rawData); + //edm::LogVerbatim("l1tOmtfEventPrint")<<" hit.layer "<<(int)hit.layer<<" hit.phiDist "<hwPt() << " hwSign " << finalCandidate->hwSign() - << " hwQual " << finalCandidate->hwQual() << " hwEta " << std::setw(4) - << finalCandidate->hwEta() << std::setw(4) << " hwPhi " << finalCandidate->hwPhi() - << " eta " << std::setw(9) << (finalCandidate->hwEta() * 0.010875) - << " isKilled " << procMuon->isKilled() << " tRefLayer " << procMuon->getRefLayer() - << " RefHitNumber " << procMuon->getRefHitNumber() << std::endl; + + LogTrace("l1tOmtfEventPrint") << " hwPt " << matchingResult.muonCand->getAlgoMuon()->getPtConstr() << " hwSign " << matchingResult.muonCand->getAlgoMuon()->getChargeConstr() + << " hwQual " << matchingResult.muonCand->getQuality() << " hwEta " << std::setw(4) + << matchingResult.muonCand->getAlgoMuon()->getEtaHw() << std::setw(4) << " hwPhi " << matchingResult.muonCand->getAlgoMuon()->getPhi() + << " eta " << std::setw(9) << matchingResult.muonCand->getEtaRad() + << " isKilled " << matchingResult.muonCand->getAlgoMuon()->isKilled() << " tRefLayer " << matchingResult.muonCand->getAlgoMuon()->getRefLayer() + << " RefHitNumber " << matchingResult.muonCand->getAlgoMuon()->getRefHitNumber() << std::endl; }; - if (matchingResult.muonCand && matchingResult.procMuon->getPtConstr() > 0 && - matchingResult.muonCand->hwQual() >= 1) { + if (matchingResult.muonCand && matchingResult.muonCand->getAlgoMuon()->getPtConstr() > 0 && + matchingResult.muonCand->getQuality() >= 1) { //TODO set the quality, quality 0 has the candidates with eta > 1.3(?) EtaHw >= 121 //&& matchingResult.genPt < 20 - omtfEvent.omtfQuality = matchingResult.muonCand->hwQual(); //procMuon->getQ(); + omtfEvent.omtfQuality = matchingResult.muonCand->getQuality(); //procMuon->getQ(); omtfEvent.killed = false; - omtfEvent.omtfProcessor = matchingResult.muonCand->processor(); + omtfEvent.omtfProcessor = matchingResult.muonCand->getProcessor(); if (matchingResult.muonCand->trackFinderType() == l1t::omtf_neg) { omtfEvent.omtfProcessor *= -1; } - addOmtfCand(matchingResult.procMuon); + addOmtfCand(matchingResult.muonCand); rootTree->Fill(); + /* TODO there are a few problems with dumping the killed muons: there is no procMuon for them, so the global eta and omtfProcessor are not available if (dumpKilledOmtfCands) { for (auto& killedCand : matchingResult.procMuon->getKilledMuons()) { omtfEvent.omtfQuality = 0; @@ -359,7 +417,7 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, addOmtfCand(killedCand); rootTree->Fill(); } - } + }*/ } else if (omtfEvent.muonPt > 0) { //checking if there was a simMuon LogTrace("l1tOmtfEventPrint") << "DataROOTDumper2::observeEventEnd no matching omtfCand" << std::endl; @@ -388,4 +446,7 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, evntCnt++; } -void DataROOTDumper2::endJob() { edm::LogVerbatim("l1tOmtfEventPrint") << " evntCnt " << evntCnt << endl; } +void DataROOTDumper2::endJob() { + edm::LogVerbatim("l1tOmtfEventPrint") << " evntCnt " << evntCnt << endl; + rootTree->Write(); +} diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EmulationObserverBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EmulationObserverBase.cc index 107321f386eac..94a4ef4090066 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EmulationObserverBase.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EmulationObserverBase.cc @@ -24,7 +24,7 @@ void EmulationObserverBase::observeProcesorEmulation(unsigned int iProcessor, const std::shared_ptr& input, const AlgoMuons& algoCandidates, const AlgoMuons& gbCandidates, - const std::vector& candMuons) { + const FinalMuons& finalMuons) { unsigned int procIndx = omtfConfig->getProcIndx(iProcessor, mtfType); unsigned int i = 0; @@ -37,7 +37,7 @@ void EmulationObserverBase::observeProcesorEmulation(unsigned int iProcessor, candProcIndx = procIndx; //should be good, as the regionalMuonCand is created for every gbCandidate in OMTFProcessor::getFinalcandidates - regionalMuonCand = candMuons.at(i); + finalMuon = finalMuons.at(i); //this->algoCandidates = algoCandidates; //TODO uncomment if needed } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EventCapture.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EventCapture.cc index e777e7e05037a..1b08243a17bb6 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EventCapture.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EventCapture.cc @@ -37,8 +37,8 @@ EventCapture::EventCapture(const edm::ParameterSet& edmCfg, << "EventCapture::EventCapture: no InputTag simTracksTag found" << std::endl; //stubsSimHitsMatcher works only with the trackingParticle, because only them are stored in the pilup events - if (this->candidateSimMuonMatcher && edmCfg.exists("trackingParticleTag")) - stubsSimHitsMatcher = std::make_unique(edmCfg, omtfConfig, muonGeometryTokens); + //if (this->candidateSimMuonMatcher && edmCfg.exists("trackingParticleTag")) + // stubsSimHitsMatcher = std::make_unique(edmCfg, omtfConfig, muonGeometryTokens); } EventCapture::~EventCapture() { @@ -51,6 +51,8 @@ void EventCapture::beginRun(edm::EventSetup const& eventSetup) { } void EventCapture::observeEventBegin(const edm::Event& event) { + edm::LogImportant("l1tOmtfEventPrint") << "EventCapture::observeEventBegin event " << event.id() + << "*************************" << std::endl; simMuons.clear(); if (!simTracksTag.label().empty()) { @@ -78,7 +80,7 @@ void EventCapture::observeProcesorEmulation(unsigned int iProcessor, const std::shared_ptr& input, const AlgoMuons& algoCandidates, const AlgoMuons& gbCandidates, - const std::vector& candMuons) { + const FinalMuons& finalMuons) { unsigned int procIndx = omtfConfig->getProcIndx(iProcessor, mtfType); edm::LogImportant("l1tOmtfEventPrint") << "EventCapture::observeProcesorEmulation : iProcessor" << iProcessor << " mtfType " << mtfType << " procIndx " << procIndx << " OmtfName(procIndx) " @@ -90,8 +92,7 @@ void EventCapture::observeProcesorEmulation(unsigned int iProcessor, gbCandidatesInProcs[procIndx] = gbCandidates; } -void EventCapture::observeEventEnd(const edm::Event& iEvent, - std::unique_ptr& finalCandidates) { +void EventCapture::observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMuons) { std::ostringstream ostr; //filtering @@ -106,7 +107,6 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, //TODO choose a condition, to print the desired candidates if (matchingResult.muonCand) { dump = true; - bool runStubsSimHitsMatcher = false; if (matchingResult.trackingParticle) { auto trackingParticle = matchingResult.trackingParticle; @@ -122,19 +122,32 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, << matchingResult.simTrack->momentum().pt() //<<" Beta "<momentum().Beta() << " eta " << std::setw(9) << matchingResult.simTrack->momentum().eta() << " phi " << std::setw(9) << matchingResult.simTrack->momentum().phi() << std::endl; + //TODO choose a condition, to print the desired candidates + if (matchingResult.simTrack->eventId().event() == 0 && + std::abs(matchingResult.simTrack->momentum().eta()) > 0.82 && + std::abs(matchingResult.simTrack->momentum().eta()) < 1.24) { + //&& matchingResult.simTrack->momentum().pt() >= 22. && + //matchingResult.muonCand != nullptr && matchingResult.muonCand->hwPt() < 47) { + dump = true; + } } else { ostr << "no simMuon "; runStubsSimHitsMatcher = true; } ostr << "matched to: " << std::endl; auto finalCandidate = matchingResult.muonCand; - ostr << " hwPt " << finalCandidate->hwPt() << " hwUPt " << finalCandidate->hwPtUnconstrained() << " hwSign " - << finalCandidate->hwSign() << " hwQual " << finalCandidate->hwQual() << " hwEta " << std::setw(4) - << finalCandidate->hwEta() << std::setw(4) << " hwPhi " << finalCandidate->hwPhi() << " eta " - << std::setw(9) << (finalCandidate->hwEta() * 0.010875) << " phi " << std::endl; + ostr << " hwPt " << matchingResult.muonCand->getAlgoMuon()->getPtConstr() + //<< " hwUPt " << matchingResult.muonCand->getAlgoMuon()->getPtUnconstr() + << " hwUPt " << matchingResult.muonCand->getPtUnconstrGmt() + //<< " hwSign " << matchingResult.muonCand->getAlgoMuon()->getChargeConstr() + << " hwSign " << matchingResult.muonCand->getSign() + << " hwQual " << matchingResult.muonCand->getQuality() << " hwEta " << std::setw(4) + //<< matchingResult.muonCand->getAlgoMuon()->getEtaHw() << std::setw(4) << " hwPhi " << matchingResult.muonCand->getAlgoMuon()->getPhi() + << matchingResult.muonCand->getEtaGmt() << std::setw(4) << " hwPhi " << matchingResult.muonCand->getPhiGmt() + << " eta " << std::setw(9) << matchingResult.muonCand->getEtaRad() << " phi "<< std::endl;// << matchingResult.muonCand->getPhiRad() << std::endl; if (stubsSimHitsMatcher && runStubsSimHitsMatcher) - stubsSimHitsMatcher->match(iEvent, matchingResult.muonCand, matchingResult.procMuon, ostr); + stubsSimHitsMatcher->match(iEvent, matchingResult.muonCand, ostr); } } } else if (!simTracksTag.label().empty()) { @@ -143,8 +156,9 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, bool wasSimMuInOmtfNeg = false; for (auto& simMuon : simMuons) { //TODO choose a condition, to print the desired events - if (simMuon->eventId().event() == 0 && std::abs(simMuon->momentum().eta()) > 0.82 && - std::abs(simMuon->momentum().eta()) < 1.24 && simMuon->momentum().pt() >= 3.) { + if (simMuon->eventId().event() == 0 && std::abs(simMuon->momentum().eta()) > 0.82) + //&& std::abs(simMuon->momentum().eta()) < 1.24 && simMuon->momentum().pt() >= 22.) + { ostr << "SimMuon: eventId " << simMuon->eventId().event() << " pdgId " << std::setw(3) << simMuon->type() << " pt " << std::setw(9) << simMuon->momentum().pt() //<<" Beta "<momentum().Beta() << " eta " << std::setw(9) << simMuon->momentum().eta() << " phi " << std::setw(9) @@ -160,14 +174,14 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, bool wasCandInNeg = false; bool wasCandInPos = false; - for (auto& finalCandidate : *finalCandidates) { + for (auto& finalMuon : finalMuons) { //TODO choose a condition, to print the desired candidates - if (finalCandidate.trackFinderType() == l1t::tftype::omtf_neg && finalCandidate.hwQual() >= 12 && - finalCandidate.hwPt() > 20) + if ( //finalCandidate.trackFinderType() == l1t::tftype::omtf_neg && finalCandidate.hwQual() >= 12 && + finalMuon->getAlgoMuon()->getPtConstr() < 47) wasCandInNeg = true; - if (finalCandidate.trackFinderType() == l1t::tftype::omtf_pos && finalCandidate.hwQual() >= 12 && - finalCandidate.hwPt() > 20) + if ( //finalCandidate.trackFinderType() == l1t::tftype::omtf_pos && finalCandidate.hwQual() >= 12 && + finalMuon->getAlgoMuon()->getPtConstr() < 47) wasCandInPos = true; } @@ -201,35 +215,25 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, edm::LogVerbatim("l1tOmtfEventPrint") << ostr.str() << endl; //printing sim muons edm::LogVerbatim("l1tOmtfEventPrint") << "finalCandidates " << std::endl; - for (int bx = finalCandidates->getFirstBX(); bx <= finalCandidates->getLastBX(); bx++) { - for (auto finalCandidateIt = finalCandidates->begin(bx); finalCandidateIt != finalCandidates->end(bx); - finalCandidateIt++) { - auto& finalCandidate = *finalCandidateIt; - int globHwPhi = (finalCandidate.processor()) * 96 + finalCandidate.hwPhi(); - // first processor starts at CMS phi = 15 degrees (24 in int)... Handle wrap-around with %. Add 576 to make sure the number is positive - globHwPhi = (globHwPhi + 600) % 576; - - double globalPhi = globHwPhi * 2. * M_PI / 576; - if (globalPhi > M_PI) - globalPhi = globalPhi - (2. * M_PI); - - int layerHits = (int)finalCandidate.trackAddress().at(0); + //for (int bx = finalCandidates->getFirstBX(); bx <= finalCandidates->getLastBX(); bx++) + { + for (auto& finalMuon : finalMuons) { + int layerHits = finalMuon->getAlgoMuon()->getFiredLayerBits(); std::bitset<18> layerHitBits(layerHits); edm::LogVerbatim("l1tOmtfEventPrint") - << " bx " << bx << " hwPt " << finalCandidate.hwPt() << " hwUPt " << finalCandidate.hwPtUnconstrained() - << " hwSign " << finalCandidate.hwSign() << " hwQual " << finalCandidate.hwQual() << " hwEta " << std::setw(4) - << finalCandidate.hwEta() << std::setw(4) << " hwPhi " << finalCandidate.hwPhi() << " eta " << std::setw(9) - << (finalCandidate.hwEta() * 0.010875) << " phi " << std::setw(9) << globalPhi << " " << layerHitBits - << " processor " << OmtfName(finalCandidate.processor(), finalCandidate.trackFinderType(), omtfConfig) + << " bx " << finalMuon->getBx() << " hwPt " << finalMuon->getAlgoMuon()->getPtConstr() + //<< " hwUPt " << finalMuon->getAlgoMuon()->getPtUnconstr() + << " hwUPt " << finalMuon->getPtUnconstrGmt() + << " hwSign " << finalMuon->getAlgoMuon()->getChargeConstr() << " hwQual " << finalMuon->getQuality() + //<< " hwEta " << std::setw(4) << finalMuon->getAlgoMuon()->getEtaHw() + << " hwEta " << std::setw(4) << finalMuon->getEtaGmt() ////////////////////////////////////////////// + //<< std::setw(4) << " hwPhi " << finalMuon->getAlgoMuon()->getPhi() + << std::setw(4) << " hwPhi " << finalMuon->getPhiGmt() ///////////////////////////////////////////// + << " eta " << std::setw(9) << finalMuon->getEtaRad() /////////////////////////////////////////// + << " phi " << std::setw(9) << finalMuon->getPhiRad() << " " << layerHitBits + << " processor " << OmtfName(finalMuon->getProcessor(), finalMuon->trackFinderType(), omtfConfig) << std::endl; - - for (auto& trackAddr : finalCandidate.trackAddress()) { - if (trackAddr.first >= 10) - edm::LogVerbatim("l1tOmtfEventPrint") - << "trackAddr first " << trackAddr.first << " second " << trackAddr.second << " ptGeV " - << omtfConfig->hwPtToGev(trackAddr.second); - } } } edm::LogVerbatim("l1tOmtfEventPrint") << std::endl; @@ -247,8 +251,7 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, if (stub && (stub->type != MuonStub::Type::EMPTY)) { layerFired = true; - auto globalPhiRad = omtfConfig->procHwPhiToGlobalPhi( - stub->phiHw, OMTFinputMaker::getProcessorPhiZero(omtfConfig, iProc % omtfConfig->nProcessors())); + auto globalPhiRad = omtfConfig->procPhiOmtfToPhiRad(iProc, stub->phiHw); ostrInput << (*stub) << " globalPhiRad " << globalPhiRad << std::endl; } if (layerFired) @@ -348,7 +351,8 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, for (auto& gbCandidate : gbCandidatesInProcs[iProc]) edm::LogVerbatim("l1tOmtfEventPrint") << " (" << std::setw(5) << gbCandidate->getPtConstr() << "," << std::setw(5) - << gbCandidate->getPtUnconstr() << "," + //<< ( (gbCandidate->getPtUnconstr() - 1) / 2 + 1 )<< "," //GMT scale + << ( gbCandidate->getPtUnconstr() == 0 ? 0 : ( (gbCandidate->getPtUnconstr() - 1) / 2 + 1 ) )<< "," //GMT scale << std::setw(5) << gbCandidate->getGpResultConstr().getFiredLayerCnt() << "," << std::setw(5) << gbCandidate->getGpResultUnconstr().getFiredLayerCnt() @@ -379,30 +383,28 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, edm::LogVerbatim("l1tOmtfEventPrint") << "finalCandidates " << std::endl; std::ostringstream ostr; - if (finalCandidates->size(0) > 0) { + //if (finalCandidates->size(0) > 0) + { int iMu = 1; - for (auto finalCandidateIt = finalCandidates->begin(0); finalCandidateIt != finalCandidates->end(0); - finalCandidateIt++) { - auto& finalCandidate = *finalCandidateIt; - - auto omtfName = OmtfName(finalCandidate.processor(), finalCandidate.trackFinderType(), omtfConfig); + for (auto& finalMuon : finalMuons) { + auto omtfName = OmtfName(finalMuon->getProcessor(), finalMuon->trackFinderType(), omtfConfig); if (omtfName == board.name()) { - int layerHits = (int)finalCandidate.trackAddress().at(0); + int layerHits = finalMuon->getAlgoMuon()->getFiredLayerBits(); std::bitset<18> layerHitBits(layerHits); - unsigned int trackAddr = finalCandidate.trackAddress().at(0); - unsigned int uPt = finalCandidate.hwPtUnconstrained(); + unsigned int trackAddr = finalMuon->getAlgoMuon()->getFiredLayerBits(); + unsigned int uPt = finalMuon->getPtUnconstrGmt(); //if(uPt == 0) uPt = 5; //TODO remove when fixed in the FW trackAddr = (uPt << 18) + trackAddr; - ostr << "M" << iMu << ":" << std::setw(4) << finalCandidate.hwPt() << "," << std::setw(4) - << finalCandidate.hwQual() << "," << std::setw(4) << finalCandidate.hwPhi() << "," << std::setw(4) - << std::abs(finalCandidate.hwEta()) + ostr << "M" << iMu << ":" << std::setw(4) << finalMuon->getPtGmt() << "," << std::setw(4) + << finalMuon->getQuality() << "," << std::setw(4) << finalMuon->getPhiGmt() << "," << std::setw(4) + << std::abs(finalMuon->getEtaGmt()) << "," //<getSign() << "," << std::setw(4) << 1 << "; "; //ChValid //<< " -- uPt " << std::setw(10) << uPt << " firedLayers " << finalCandidate.trackAddress().at(0); //<Fill(simMuon->momentum().eta()); - candEta->Fill(omtfConfig->hwEtaToEta(regionalMuonCand.hwEta())); + candEta->Fill(finalMuon->getEtaRad()); double ptSim = simMuon->momentum().pt(); int chargeSim = (abs(simMuon->type()) == 13) ? simMuon->type() / -13 : 0; @@ -159,11 +159,7 @@ void PatternGenerator::updateStat() { bool fired = false; if (gpResult.getStubResults()[iLayer].getMuonStub()) { - if (omtfConfig->isBendingLayer(iLayer)) { - if (gpResult.getStubResults()[iLayer].getMuonStub()->qualityHw >= 4) //TODO change quality cut if needed - fired = true; - } else - fired = true; + fired = true; } if (fired) { //the result is not empty @@ -208,7 +204,7 @@ void PatternGenerator::updateStatUsingMatcher2() { //&& matchingResult.muonCand->hwQual() >= 12 && //matchingResult.muonCand->hwPt() > 38 - AlgoMuon* algoMuon = matchingResult.procMuon.get(); + AlgoMuon* algoMuon = matchingResult.muonCand->getAlgoMuon().get(); if (!algoMuon) { edm::LogImportant("l1tOmtfEventPrint") << ":" << __LINE__ << " algoMuon is null" << std::endl; throw runtime_error("algoMuon is null"); @@ -232,7 +228,7 @@ void PatternGenerator::updateStatUsingMatcher2() { eventCntPerGp[exptPatNum]++; candProcIndx = - omtfConfig->getProcIndx(matchingResult.muonCand->processor(), matchingResult.muonCand->trackFinderType()); + omtfConfig->getProcIndx(matchingResult.muonCand->getProcessor(), matchingResult.muonCand->trackFinderType()); //edm::LogImportant("l1tOmtfEventPrint")<<"\n" <<__FUNCTION__<<": "<<__LINE__<<" exptCandGp "<key()<<" candProcIndx "<& finalCandidates) { +void PatternGenerator::observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMuons) { if (simMuon == nullptr || omtfCand->getGoldenPatern() == nullptr) //no sim muon or empty candidate return; if (abs(simMuon->momentum().eta()) < 0.8 || abs(simMuon->momentum().eta()) > 1.24) return; - PatternOptimizerBase::observeEventEnd(iEvent, finalCandidates); + PatternOptimizerBase::observeEventEnd(iEvent, finalMuons); //updateStat(); //updateStatUsingMatcher2(); @@ -452,7 +447,7 @@ void PatternGenerator::upadatePdfs() { //the shift for given pattern and layer should be the same same for all refLayers //otherwise the firmware does not compile - at least the phase-1 //for phase2 - /*if ((gp->key().thePt <= 10) && + if ((gp->key().thePt <= 10) && (iLayer == 1 || iLayer == 3 || iLayer == 5)) { //iRefLayer: MB2, iLayer: MB1 and MB2 phiB gp->setDistPhiBitShift(2, iLayer, iRefLayer); } else if ((gp->key().thePt <= 10) && (iLayer == 10)) { //iRefLayer: MB2, iLayer: RB1_in @@ -466,10 +461,10 @@ void PatternGenerator::upadatePdfs() { //so the shift must be increased (or the group should be divided into to 2 groups, but it will increase fw occupancy gp->setDistPhiBitShift(1, iLayer, iRefLayer); } else - gp->setDistPhiBitShift(0, iLayer, iRefLayer);*/ + gp->setDistPhiBitShift(0, iLayer, iRefLayer); //for phase1 - if ((gp->key().thePt <= 8) && + /*if ((gp->key().thePt <= 8) && (iLayer == 1 || iLayer == 3 || iLayer == 5)) { //iRefLayer: MB2, iLayer: MB1 and MB2 phiB gp->setDistPhiBitShift(2, iLayer, iRefLayer); } else if ((gp->key().thePt <= 10) && (iLayer == 10)) { //iRefLayer: MB2, iLayer: RB1_in @@ -486,7 +481,7 @@ void PatternGenerator::upadatePdfs() { //so the shift must be increased (or the group should be divided into to 2 groups, but it will increase fw occupancy gp->setDistPhiBitShift(0, iLayer, iRefLayer); } else - gp->setDistPhiBitShift(0, iLayer, iRefLayer); + gp->setDistPhiBitShift(0, iLayer, iRefLayer);*/ } } } @@ -738,10 +733,10 @@ void PatternGenerator::modifyClassProb(double step) { //if (ptFrom == 20) //pattern Key_13 // newPdfVal += 1; - if (ptFrom >= 22 && ptFrom <= 26) - newPdfVal += 2; - if (ptFrom == 28) //pattern Key_17 - newPdfVal += 1; + //if (ptFrom >= 22 && ptFrom <= 26) + // newPdfVal += 2; + //if (ptFrom == 28) //pattern Key_17 + // newPdfVal += 1; if (ptFrom == 100) newPdfVal = 16; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/PatternOptimizerBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/PatternOptimizerBase.cc index 459cc767684b5..3f5faf9daf56c 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/PatternOptimizerBase.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/PatternOptimizerBase.cc @@ -105,8 +105,7 @@ void PatternOptimizerBase::printPatterns() { } } -void PatternOptimizerBase::observeEventEnd(const edm::Event& iEvent, - std::unique_ptr& finalCandidates) { +void PatternOptimizerBase::observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMuons) { if (simMuon == nullptr || omtfCand->getGoldenPatern() == nullptr) //no sim muon or empty candidate return; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc index 3343ab331546a..284363bbf40d5 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc @@ -5,6 +5,7 @@ * Author: kbunkow */ +#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Tools/StubsSimHitsMatcher.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfName.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinputMaker.h" @@ -92,8 +93,7 @@ void StubsSimHitsMatcher::beginRun(edm::EventSetup const& eventSetup) { } void StubsSimHitsMatcher::match(const edm::Event& iEvent, - const l1t::RegionalMuonCand* omtfCand, - const AlgoMuonPtr& procMuon, + const FinalMuonPtr& finalMuon, std::ostringstream& ostr) { ostr << "stubsSimHitsMatching ---------------" << std::endl; @@ -124,14 +124,14 @@ void StubsSimHitsMatcher::match(const edm::Event& iEvent, edm::Handle trackingParticleHandle; iEvent.getByLabel(trackingParticleTag, trackingParticleHandle); - if (procMuon->isValid() && omtfCand) { - OmtfName board(omtfCand->processor(), omtfCand->trackFinderType(), omtfConfig); - auto processorPhiZero = OMTFinputMaker::getProcessorPhiZero(omtfConfig, omtfCand->processor()); + if (finalMuon->getAlgoMuon()->isValid()) { + OmtfName board(finalMuon->getProcessor(), finalMuon->trackFinderType(), omtfConfig); + auto processorPhiZero = OMTFinputMaker::getProcessorPhiZero(omtfConfig, finalMuon->getProcessor()); std::set matchedTrackInfos; - ostr << board.name() << " " << *procMuon << std::endl; + ostr << board.name() << " " << *finalMuon->getAlgoMuon() << std::endl; - auto& gpResult = procMuon->getGpResultConstr(); + auto& gpResult = finalMuon->getAlgoMuon()->getGpResultConstr(); for (unsigned int iLogicLayer = 0; iLogicLayer < gpResult.getStubResults().size(); ++iLogicLayer) { auto& stub = gpResult.getStubResults()[iLogicLayer].getMuonStub(); if (stub && gpResult.isLayerFired(iLogicLayer)) { @@ -145,7 +145,7 @@ void StubsSimHitsMatcher::match(const edm::Event& iEvent, continue; } - auto stubGlobalPhi = omtfConfig->procHwPhiToGlobalPhi(stub->phiHw, processorPhiZero); + auto stubGlobalPhi = omtfConfig->procPhiOmtfToPhiRad(stub->phiHw, processorPhiZero); ostr << (*stub) << "\nstubGlobalPhi " << stubGlobalPhi << std::endl; switch (stubDetId.subdetId()) { @@ -350,8 +350,8 @@ void StubsSimHitsMatcher::match(const edm::Event& iEvent, } } - ostr << board.name() << " " << *procMuon << std::endl; - ostr << procMuon->getGpResultConstr() << std::endl << std::endl; + ostr << board.name() << " " << *finalMuon->getAlgoMuon() << std::endl; + ostr << finalMuon->getAlgoMuon()->getGpResultConstr() << std::endl << std::endl; int maxMatchedStubs = 0; const TrackingParticle* bestMatchedPart = nullptr; diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h b/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h index 92f112f4672f0..35a71b2cf2feb 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h @@ -9,9 +9,8 @@ #define L1Trigger_L1TMuonOverlapPhase2_InputMakerPhase2_h #include "DataFormats/Common/interface/Handle.h" -#include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThContainer.h" #include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhContainer.h" -#include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThContainer.h" #include "DataFormats/MuonDetId/interface/DTChamberId.h" #include "FWCore/Utilities/interface/EDGetToken.h" @@ -21,10 +20,15 @@ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinputMaker.h" #include "L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h" +struct MuStubsPhase2InputTokens { + edm::EDGetTokenT inputTokenDtPh; + edm::EDGetTokenT inputTokenDtTh; +}; + class DtPhase2DigiToStubsConverter : public DigiToStubsConverterBase { public: DtPhase2DigiToStubsConverter(edm::EDGetTokenT inputTokenDtPh, - edm::EDGetTokenT inputTokenDtTh) + edm::EDGetTokenT inputTokenDtTh) : inputTokenDtPh(inputTokenDtPh), inputTokenDtTh(inputTokenDtTh) {} ~DtPhase2DigiToStubsConverter() override {} @@ -41,12 +45,12 @@ class DtPhase2DigiToStubsConverter : public DigiToStubsConverterBase { //dtThDigis is provided as argument, because in the OMTF implementation the phi and eta digis are merged (even thought it is artificial) virtual void addDTphiDigi(MuonStubPtrs2D& muonStubsInLayers, const L1Phase2MuDTPhDigi& digi, - const L1MuDTChambThContainer* dtThDigis, + const L1Phase2MuDTThContainer* dtThDigis, unsigned int iProcessor, l1t::tftype procTyp) = 0; virtual void addDTetaStubs(MuonStubPtrs2D& muonStubsInLayers, - const L1MuDTChambThDigi& thetaDigi, + const L1Phase2MuDTThDigi& thetaDigi, unsigned int iProcessor, l1t::tftype procTyp) = 0; @@ -58,18 +62,18 @@ class DtPhase2DigiToStubsConverter : public DigiToStubsConverterBase { bool mergePhiAndTheta = true; edm::EDGetTokenT inputTokenDtPh; - edm::EDGetTokenT inputTokenDtTh; + edm::EDGetTokenT inputTokenDtTh; edm::Handle dtPhDigis; - edm::Handle dtThDigis; + edm::Handle dtThDigis; }; class DtPhase2DigiToStubsConverterOmtf : public DtPhase2DigiToStubsConverter { public: DtPhase2DigiToStubsConverterOmtf(const OMTFConfiguration* config, - const OmtfAngleConverter* angleConverter, + const OmtfPhase2AngleConverter* angleConverter, edm::EDGetTokenT inputTokenDtPh, - edm::EDGetTokenT inputTokenDtTh) + edm::EDGetTokenT inputTokenDtTh) : DtPhase2DigiToStubsConverter(inputTokenDtPh, inputTokenDtTh), config(*config), angleConverter(*angleConverter) {} @@ -79,12 +83,12 @@ class DtPhase2DigiToStubsConverterOmtf : public DtPhase2DigiToStubsConverter { //dtThDigis is provided as argument, because in the OMTF implementation the phi and eta digis are merged (even thought it is artificial) void addDTphiDigi(MuonStubPtrs2D& muonStubsInLayers, const L1Phase2MuDTPhDigi& digi, - const L1MuDTChambThContainer* dtThDigis, + const L1Phase2MuDTThContainer* dtThDigis, unsigned int iProcessor, l1t::tftype procTyp) override; void addDTetaStubs(MuonStubPtrs2D& muonStubsInLayers, - const L1MuDTChambThDigi& thetaDigi, + const L1Phase2MuDTThDigi& thetaDigi, unsigned int iProcessor, l1t::tftype procTyp) override; @@ -92,14 +96,14 @@ class DtPhase2DigiToStubsConverterOmtf : public DtPhase2DigiToStubsConverter { private: const OMTFConfiguration& config; - const OmtfAngleConverter& angleConverter; + const OmtfPhase2AngleConverter& angleConverter; }; class InputMakerPhase2 : public OMTFinputMaker { public: InputMakerPhase2(const edm::ParameterSet& edmParameterSet, MuStubsInputTokens& muStubsInputTokens, - edm::EDGetTokenT inputTokenDTPhPhase2, + MuStubsPhase2InputTokens& muStubsPhase2InputTokens, const OMTFConfiguration* config, std::unique_ptr angleConverter); diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegression2Outputs.h b/L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegression2Outputs.h index 6880acd14ce70..7471a1df4505b 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegression2Outputs.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegression2Outputs.h @@ -20,31 +20,33 @@ #include namespace lutNN { - //_I - number of integer bits in the ap_ufixed, _F - number of fractional bits in the ap_ufixed //the network has two outputs, and since each output can have different range, the LUTs in the last layer have different I and F - template + template < + int input_I, + int input_F, + std::size_t inputSize, + int layer1_lut_I, + int layer1_lut_F, + int layer1_neurons, + int layer1_output_I, //to the layer1 output the bias is added to make the layer2 input, therefore the layer1_output_I and layer2_lut_I are different + int layer1_output_F, + int layer2_input_I, + int layer2_lut_I, + int layer2_lut_F, + int layer2_neurons, + int layer3_input_I, + int layer3_input_F, + int layer3_0_inputCnt, + int layer3_0_lut_I, + int layer3_0_lut_F, + int output0_I, + int output0_F, + int layer3_1_inputCnt, + int layer3_1_lut_I, + int layer3_1_lut_F, + int output1_I, + int output1_F> class LutNetworkFixedPointRegression2Outputs : public LutNetworkFixedPointRegressionBase { public: LutNetworkFixedPointRegression2Outputs() { @@ -57,15 +59,22 @@ namespace lutNN { lutLayer3_1.setName("lutLayer3_1"); }; - ~LutNetworkFixedPointRegression2Outputs() override {} + ~LutNetworkFixedPointRegression2Outputs() override {}; - typedef LutNeuronLayerFixedPoint + typedef LutNeuronLayerFixedPoint LutLayer1; LutLayer1 lutLayer1; static constexpr unsigned int noHitCntShift = layer1_output_I; //FIXME should be layer1_output_I ??? - static constexpr int layer2_input_F = layer1_lut_F; + static constexpr int layer2_input_F = layer1_output_F; typedef LutNeuronLayerFixedPoint + layer3_input_I, + layer3_input_F> LutLayer2; LutLayer2 lutLayer2; - static constexpr int layer3_input_F = layer2_lut_F; - typedef LutNeuronLayerFixedPoint + output0_I, + output0_F> LutLayer3_0; LutLayer3_0 lutLayer3_0; //"lutLayer3_0" @@ -95,7 +104,8 @@ namespace lutNN { layer3_1_lut_I, layer3_1_lut_F, 1, - output1_I> + output1_I, + output1_F> LutLayer3_1; LutLayer3_1 lutLayer3_1; //"lutLayer3_1" @@ -130,6 +140,12 @@ namespace lutNN { noHitsCnt++; } + //the minimum required number of hits for a good candidate is 3, + //and the total number of possible hits is 18 (number of OMTF layers) + //so the maximum noHitsCnt is 15. It must be constrained here, otherwise address for the the next layer would be out of LUT range + if (noHitsCnt > 15) + noHitsCnt = 15; + unsigned int bias = (noHitsCnt << noHitCntShift); //layer1Bias switches the input of the layer2 (i.e. output of the layer1) do different regions in the LUTs @@ -152,11 +168,13 @@ namespace lutNN { //pt in the hardware scale, ptGeV = (ptHw -1) / 2 int getCalibratedHwPt() override { - auto lutAddr = ap_ufixed( - lutLayer3_0.getLutOutSum()[0]); - lutAddr = lutAddr << output0_F; + //auto lutAddr = ap_ufixed(lutLayer3_0.getLutOutSum()[0]); + //lutAddr = lutAddr< scale * lut[x] + offset for the last layer } void save(const std::string& filename) override { diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegressionMultipleOutputs.h b/L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegressionMultipleOutputs.h new file mode 100644 index 0000000000000..7206c0d18e551 --- /dev/null +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegressionMultipleOutputs.h @@ -0,0 +1,289 @@ +/* + * LutNetworkFixedPointRegressionMultipleOutputs.h + * + * Created on: April 13, 2021 + * Author: Karol Bunkowski, kbunkow@cern.ch + */ + +#ifndef L1Trigger_L1TMuonOverlapPhase2_LutNetworkFixedPointRegressionMultipleOutputs_h +#define L1Trigger_L1TMuonOverlapPhase2_LutNetworkFixedPointRegressionMultipleOutputs_h + +#include "L1Trigger/L1TMuonOverlapPhase2/interface/LutNeuronLayerFixedPoint.h" + +#include "ap_int.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include + +#include +#include + +namespace lutNN { + + //_I - number of integer bits in the ap_ufixed, _F - number of fractional bits in the ap_ufixed + //the network has two outputs, and since each output can have different range, the LUTs in the last layer have different I and F + template < + int input_I, + int input_F, + std::size_t inputSize, + int layer1_lut_I, + int layer1_lut_F, + int layer1_neurons, + int layer1_output_I, //to the layer1 output the bias is added to make the layer2 input, therefore the layer1_output_I and layer2_lut_I are different + int layer1_output_F, + int layer2_input_I, + int layer2_lut_I, + int layer2_lut_F, + int layer2_neurons, + int layer3_input_I, + int layer3_input_F, + int layer3_0_inputCnt, + int layer3_0_lut_I, + int layer3_0_lut_F, + int output0_I, + int output0_F, + int layer3_0_multiplicity, + int layer3_1_inputCnt, + int layer3_1_lut_I, + int layer3_1_lut_F, + int output1_I, + int output1_F, + int layer3_1_multiplicity> + class LutNetworkFixedPointRegressionMultipleOutputs : public LutNetworkFixedPointRegressionBase { + public: + LutNetworkFixedPointRegressionMultipleOutputs() { + static_assert(layer2_neurons == + (layer3_0_inputCnt * layer3_0_multiplicity + layer3_1_inputCnt * layer3_1_multiplicity)); + + //std::cout << "LutNetworkFixedPoint" << std::endl; + lutLayer1.setName("lutLayer1"); + lutLayer2.setName("lutLayer2"); + for (unsigned int iSubLayer = 0; iSubLayer < lutLayer3_0.size(); iSubLayer++) { + lutLayer3_0[iSubLayer].setName("lutLayer3_0_" + std::to_string(iSubLayer)); + } + for (unsigned int iSubLayer = 0; iSubLayer < lutLayer3_1.size(); iSubLayer++) { + lutLayer3_1[iSubLayer].setName("lutLayer3_1_" + std::to_string(iSubLayer)); + } + }; + + ~LutNetworkFixedPointRegressionMultipleOutputs() override {}; + + typedef LutNeuronLayerFixedPoint + LutLayer1; + LutLayer1 lutLayer1; + + static constexpr unsigned int noHitCntShift = layer1_output_I; //FIXME should be layer1_output_I ??? + + static constexpr int layer2_input_F = layer1_output_F; + + typedef LutNeuronLayerFixedPoint + LutLayer2; + LutLayer2 lutLayer2; + + typedef LutNeuronLayerFixedPoint + LutLayer3_0; + std::array lutLayer3_0; + + typedef LutNeuronLayerFixedPoint + LutLayer3_1; + std::array lutLayer3_1; + + void runWithInterpolation() { + lutLayer1.runWithInterpolation(inputArray); + auto& layer1Out = lutLayer1.getOutWithOffset(); + + std::array, layer1_neurons> + layer1OutWithBias; + for (unsigned int i = 0; i < layer1Out.size(); i++) { + layer1OutWithBias[i] = layer1Out[i] + layer1Bias; + } + + lutLayer2.runWithInterpolation(layer1OutWithBias); + auto& layer2Out = lutLayer2.getOutWithOffset(); + + for (unsigned int iSubLayer = 0; iSubLayer < lutLayer3_0.size(); iSubLayer++) { + typename LutLayer3_0::inputArrayType lutLayer3_0_input; + std::copy(layer2Out.begin() + lutLayer3_0_input.size() * iSubLayer, //from + layer2Out.begin() + lutLayer3_0_input.size() * (iSubLayer + 1), + lutLayer3_0_input.begin()); + + lutLayer3_0[iSubLayer].runWithInterpolation(lutLayer3_0_input); + } + + for (unsigned int iSubLayer = 0; iSubLayer < lutLayer3_1.size(); iSubLayer++) { + typename LutLayer3_1::inputArrayType lutLayer3_1_input; + std::copy( + layer2Out.begin() + lutLayer3_1_input.size() * iSubLayer + + layer3_0_inputCnt * layer3_0_multiplicity, //from + layer2Out.begin() + lutLayer3_1_input.size() * (iSubLayer + 1) + layer3_0_inputCnt * layer3_0_multiplicity, + lutLayer3_1_input.begin()); + + lutLayer3_1[iSubLayer].runWithInterpolation(lutLayer3_1_input); + } + } + + void run(std::vector& inputs, float noHitVal, std::vector& nnResult) override { + unsigned int noHitsCnt = 0; + for (unsigned int iInput = 0; iInput < inputs.size(); iInput++) { + inputArray[iInput] = inputs[iInput]; + if (inputs[iInput] == noHitVal) + noHitsCnt++; + } + + //the minimum required number of hits for a good candidate is 3, + //and the total number of possible hits is 18 (number of OMTF layers) + //so the maximum noHitsCnt is 15. It must be constrained here, otherwise address for the the next layer would be out of LUT range + if (noHitsCnt > 15) + noHitsCnt = 15; + + unsigned int bias = (noHitsCnt << noHitCntShift); + + //layer1Bias switches the input of the layer2 (i.e. output of the layer1) do different regions in the LUTs + //depending on the number of layers without hits + layer1Bias = bias; + + runWithInterpolation(); + + //output0_I goes to the declaration of the lutLayer3_0, but it does not matter, as it is used only for the outputArray + //auto layer3_0_out = ap_ufixed(lutLayer3_0.getLutOutSum()[0]); //TODO should be AP_RND_CONV rather, but it affect the rate + //auto layer3_1_out = ap_fixed (lutLayer3_1.getLutOutSum()[0]); //here layer3_0_out has size 1 + + for (unsigned int iSubLayer = 0; iSubLayer < lutLayer3_0.size(); iSubLayer++) { + nnResult[iSubLayer] = lutLayer3_0[iSubLayer].getLutOutSum()[0].to_float(); //here layer3_0_out has size 1 + //std::cout<<"nnResult["<(lutLayer3_0.getLutOutSum()[0]); + //lutAddr = lutAddr< scale * lut[x] + offset for the last layer + } + + void save(const std::string& filename) override { + // Create an empty property tree object. + boost::property_tree::ptree tree; + + PUT_VAR(tree, name, output0_I) + PUT_VAR(tree, name, output0_F) + PUT_VAR(tree, name, output1_I) + PUT_VAR(tree, name, output1_F) + + lutLayer1.save(tree, name); + lutLayer2.save(tree, name); + for (unsigned int iSubLayer = 0; iSubLayer < lutLayer3_0.size(); iSubLayer++) { + lutLayer3_0[iSubLayer].save(tree, name); + } + for (unsigned int iSubLayer = 0; iSubLayer < lutLayer3_1.size(); iSubLayer++) { + lutLayer3_1[iSubLayer].save(tree, name); + } + + int size = ptCalibrationArray.size(); + std::string key = "LutNetworkFixedPointRegressionMultipleOutputs.ptCalibrationArray"; + PUT_VAR(tree, key, size) + std::ostringstream ostr; + for (auto& a : ptCalibrationArray) { + ostr << a.to_uint() << ", "; + } + tree.put(key + ".values", ostr.str()); + + boost::property_tree::write_xml(filename, + tree, + std::locale(), + boost::property_tree::xml_parser::xml_writer_make_settings(' ', 2)); + } + + void load(const std::string& filename) override { + // Create an empty property tree object. + boost::property_tree::ptree tree; + + boost::property_tree::read_xml(filename, tree); + + CHECK_VAR(tree, name, output0_I) + CHECK_VAR(tree, name, output0_F) + CHECK_VAR(tree, name, output1_I) + CHECK_VAR(tree, name, output1_F) + + lutLayer1.load(tree, name); + lutLayer2.load(tree, name); + for (unsigned int iSubLayer = 0; iSubLayer < lutLayer3_0.size(); iSubLayer++) { + lutLayer3_0[iSubLayer].load(tree, name); + } + for (unsigned int iSubLayer = 0; iSubLayer < lutLayer3_1.size(); iSubLayer++) { + lutLayer3_1[iSubLayer].load(tree, name); + } + + std::string key = "LutNetworkFixedPointRegressionMultipleOutputs.ptCalibrationArray"; + int size = ptCalibrationArray.size(); + CHECK_VAR(tree, key, size) + + auto str = tree.get(key + ".values"); + + std::stringstream ss(str); + std::string item; + + for (auto& a : ptCalibrationArray) { + if (std::getline(ss, item, ',')) { + a = std::stoul(item, nullptr, 10); + } else { + throw std::runtime_error( + "LutNetworkFixedPointRegressionMultipleOutputs::read: number of items get from file is smaller than lut " + "size"); + } + } + } + + auto& getPtCalibrationArray() { return ptCalibrationArray; } + + private: + std::array, inputSize> inputArray; + ap_uint layer1Bias; + + //ptCalibrationArray size should be 1024, the LSB of the input 0.25 GeV, + //the output is int, with range 0...511, the LSB of output 0.5 GeV + std::array, 1 << (output0_I + output0_F)> ptCalibrationArray; + + std::string name = "LutNetworkFixedPointRegressionMultipleOutputs"; + }; + +} /* namespace lutNN */ + +#endif /* L1Trigger_L1TMuonOverlapPhase2_LutNetworkFixedPointRegressionMultipleOutputs_h */ diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/LutNeuronLayerFixedPoint.h b/L1Trigger/L1TMuonOverlapPhase2/interface/LutNeuronLayerFixedPoint.h index 62cfcb70c3ae2..39143db85dcdd 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/LutNeuronLayerFixedPoint.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/LutNeuronLayerFixedPoint.h @@ -25,65 +25,51 @@ namespace lutNN { // constexpr for ceil(log2) from stackoverflow - constexpr size_t floorlog2(size_t i) { - if (!(i > 0)) - throw cms::Exception("Incorrect input") - << "Argument of floorlog2 must be grater than 0, while " << i << " used.\n"; - return i == 1 ? 0 : 1 + floorlog2(i >> 1); - } - constexpr size_t ceillog2(size_t i) { - if (!(i > 0)) - throw cms::Exception("Incorrect input") - << "Argument of ceillog2 must be grater than 0, while " << i << " used.\n"; - return i == 1 ? 0 : floorlog2(i - 1) + 1; - } - - template + constexpr size_t floorlog2(size_t i) { return i == 1 ? 0 : 1 + floorlog2(i >> 1); } + constexpr size_t ceillog2(size_t i) { return i == 1 ? 0 : floorlog2(i - 1) + 1; } + + template class LutNeuronLayerFixedPoint { public: static constexpr int input_W = input_I + input_F; static constexpr int lut_W = lut_I + lut_F; //the lut out values sum - //static const int lutOutSum_I = lut_I + ceil(log2(inputSize)); //MB: ceil(log2(inputSize)) is not constexpr which makes issue for code-checks + //static const int lutOutSum_I = lut_I + ceil(log2(inputSize)); //ceil(log2(inputSize)) is not constexpr which makes issue for code-checks + static_assert(inputSize > 0); static constexpr int lutOutSum_I = lut_I + ceillog2(inputSize); - static constexpr int lutOutSum_W = lutOutSum_I + lut_F; + static constexpr int lutOutSum_W = lutOutSum_I + output_F; - static constexpr int output_W = output_I + lut_F; + static constexpr int output_W = output_I + output_F; //static_assert( (1<, inputSize> inputArrayType; + //the lutSumArrayType lutOutSum_I is such that no overflow in summation is possible typedef std::array, neurons> lutSumArrayType; LutNeuronLayerFixedPoint() { //FIXME initialise name(name) //static_assert(lut_I <= (output_I - ceil(log2(inputSize)) ), "not correct lut_I, output_I and inputSize"); //TODO - LogTrace("l1tOmtfEventPrint") << "Constructing LutNeuronLayerFixedPoint " << name << "\n input_I " - << std::setw(2) << input_I << " input_F " << std::setw(2) << input_F - << " input_W " << std::setw(2) << input_W << " inputSize " << std::setw(2) - << inputSize << "\n lut_I " << std::setw(2) << lut_I << " lut_F " - << std::setw(2) << lut_F << " lut_W " << std::setw(2) << lut_W << " lutSize " - << std::setw(2) << lutSize << "\n lutOutSum_I " << std::setw(2) << lutOutSum_I - << " lutOutSum_W " << std::setw(2) << lutOutSum_W << "\n output_I " - << std::setw(2) << output_I << " output_W " << std::setw(2) << output_W - << "\n neurons " << std::setw(2) << neurons << "\n outOffset " << outOffset << " = " - << std::hex << outOffset << " width " << outOffset.width << std::dec; + LogTrace("l1tOmtfEventPrint") << name << "\n input_I " << std::setw(2) << input_I << " input_F " + << std::setw(2) << input_F << " input_W " << std::setw(2) << input_W + << " inputSize " << std::setw(2) << inputSize << "\n lut_I " << std::setw(2) + << lut_I << " lut_F " << std::setw(2) << lut_F << " lut_W " + << std::setw(2) << lut_W << " lutSize " << std::setw(2) << lutSize + << "\n lutOutSum_I " << std::setw(2) << lutOutSum_I << " lutOutSum_F " + << std::setw(2) << lut_F << " lutOutSum_W " << std::setw(2) << lutOutSum_W + << "\n output_I " << std::setw(2) << output_I << " output_F " << std::setw(2) + << output_F << " output_W " << std::setw(2) << output_W << "\n neurons " + << std::setw(2) << neurons << "\n outOffset " << outOffset << " = " << std::hex + << outOffset << " width " << outOffset.width << std::dec << std::endl; } virtual ~LutNeuronLayerFixedPoint() {} void setName(std::string name) { this->name = name; } - auto& getLutArray() { return lutArray; } - - void setLutArray( - const std::array, lutSize>, neurons>, inputSize>& lutArray) { - this->lutArray = lutArray; - } - void save(boost::property_tree::ptree& tree, std::string keyPath) { PUT_VAR(tree, keyPath + "." + name, input_I) PUT_VAR(tree, keyPath + "." + name, input_F) @@ -92,6 +78,7 @@ namespace lutNN { PUT_VAR(tree, keyPath + "." + name, lut_F) PUT_VAR(tree, keyPath + "." + name, neurons) PUT_VAR(tree, keyPath + "." + name, output_I) + PUT_VAR(tree, keyPath + "." + name, output_F) for (unsigned int iInput = 0; iInput < lutArray.size(); iInput++) { for (unsigned int iNeuron = 0; iNeuron < lutArray[iInput].size(); iNeuron++) { @@ -114,6 +101,7 @@ namespace lutNN { CHECK_VAR(tree, keyPath + "." + name, lut_F) CHECK_VAR(tree, keyPath + "." + name, neurons) CHECK_VAR(tree, keyPath + "." + name, output_I) + CHECK_VAR(tree, keyPath + "." + name, output_F) for (unsigned int iInput = 0; iInput < lutArray.size(); iInput++) { for (unsigned int iNeuron = 0; iNeuron < lutArray[iInput].size(); iNeuron++) { @@ -144,33 +132,51 @@ namespace lutNN { auto address = inputArray.at(iInput).to_uint(); //address in principle is unsigned auto& lut = lutArray.at(iInput).at(iNeuron); - auto addresPlus1 = address + 1; - if (addresPlus1 >= lut.size()) - addresPlus1 = address; + auto addresPlus1 = address; + //there is a protection is in getOutWithOffset() + //but it does not include the bias node, and the noHit value, so the address == lut.size()-1 is still possible + //so this protection is needed here + if (addresPlus1 < (lut.size() - 1)) { + addresPlus1 = address + 1; + } auto derivative = lut.at(addresPlus1) - lut.at(address); // must be signed //N.B. the address and fractionalPart is the same for all neurons, what matters for the firmware ap_ufixed fractionalPart = inputArray.at(iInput); + //the W of derivative is (lut_W + 1) + //the W of (fractionalPart * derivative) is (input_W - input_I) + (lut_W + 1), the F is input_W-input_I + lut_F + //so the F of result is the F of the multiplication, so input_W-input_I + lut_F + //the F of lutOutSum is lut_F,so it is implicitly truncated auto result = lut.at(address) + fractionalPart * derivative; lutOutSum += result; } - - lutOutSumArray.at(iNeuron) = lutOutSum; } return lutOutSumArray; } //Output without offset - auto& getLutOutSum() { return lutOutSumArray; } + lutSumArrayType& getLutOutSum() { return lutOutSumArray; } //converts the output values from signed to unsigned by adding the offset = 1 << (output_I-1) //these values can be then directly used as inputs of the next LUT layer auto& getOutWithOffset() { for (unsigned int iOut = 0; iOut < lutOutSumArray.size(); iOut++) { + //the integer part of the outputArray is usually smaller than inte case of the lutOutSumArray + //therefore the outputArray has AP_SAT to avoid overflow outputArray[iOut] = lutOutSumArray[iOut] + outOffset; + //in the next layer, in runWithInterpolation the addresPlus1 is calculated, so outputArray[iOut] must be smaller the max_ap_fixed() -1 + //std::cout<<__FUNCTION__<<":"<<__LINE__<<" "< (max_ap_ufixed() - 1)) { + edm::LogVerbatim("l1tOmtfEventPrint") + << __FUNCTION__ << ":" << __LINE__ << " " << name << " " + << "iOut " << iOut << " lutOutSumArray[i] " << lutOutSumArray[iOut] << " outputArray[i] " + << outputArray[iOut] << " max_ap_ufixed " << max_ap_ufixed() << " <<<<<<<<<<<<<<<" + << std::endl; + outputArray[iOut] = max_ap_ufixed() - 1; + } } return outputArray; @@ -184,8 +190,8 @@ namespace lutNN { ap_uint outOffset = 1 << (output_I - 1); - std::array, lutSize>, neurons>, inputSize> - lutArray; //[inputNum][outputNum = neuronNum][address] + //[inputNum][outputNum = neuronNum][address] + std::array, lutSize>, neurons>, inputSize> lutArray; std::string name; }; diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h index 22ebd502496a6..6921160371964 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h @@ -9,15 +9,17 @@ #define L1Trigger_L1TMuonOverlapPhase2_OmtfEmulation_h #include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhContainer.h" +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" #include "FWCore/Utilities/interface/EDGetToken.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h" #include "L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h" +#include "L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h" class OmtfEmulation : public OMTFReconstruction { public: OmtfEmulation(const edm::ParameterSet& edmParameterSet, MuStubsInputTokens& muStubsInputTokens, - edm::EDGetTokenT inputTokenDTPhPhase2); + MuStubsPhase2InputTokens& muStubsPhase2InputTokens); void beginJob(); @@ -27,10 +29,31 @@ class OmtfEmulation : public OMTFReconstruction { const edm::ESGetToken& magneticFieldEsToken, const edm::ESGetToken& propagatorEsToken) override; -private: - edm::EDGetTokenT inputTokenDTPhPhase2; + //RegionalMuonCandBxCollection is filled for backward compatibility of analyzers etc. + + struct OmtfOutptuCollections { + std::unique_ptr constrSaMuons; //ip constrained candidates + std::unique_ptr unConstrSaMuons; //ip unconstrained candidates + std::unique_ptr regionalCandidates; //for backward compatibility of analyzers etc. + }; + OmtfOutptuCollections run(const edm::Event& iEvent, + const edm::EventSetup& evSetup); + +private: + MuStubsPhase2InputTokens& muStubsPhase2InputTokens; unique_ptr ptAssignment; + + std::map firedLayersToQuality; + + void assignQualityPhase2(AlgoMuons::value_type& algoMuon); + + void convertToGmtScalesPhase2(unsigned int iProcessor, l1t::tftype mtfType, FinalMuonPtr& finalMuon); + + l1t::SAMuonCollection getSAMuons(unsigned int iProcessor, + l1t::tftype mtfType, + FinalMuons& finalMuons, + bool costrainedPt); }; #endif /* L1Trigger_L1TMuonOverlapPhase2_OmtfEmulation_h */ diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h index 77ba206e079b3..8f15bff3f4514 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h @@ -2,14 +2,18 @@ #define OmtfPhase2AngleConverter_h #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTThContainer.h" +#include "DataFormats/MuonDetId/interface/DTChamberId.h" class OmtfPhase2AngleConverter : public OmtfAngleConverter { public: - OmtfPhase2AngleConverter() {} + OmtfPhase2AngleConverter() : OmtfAngleConverter() {} ~OmtfPhase2AngleConverter() override = default; // Convert DT phi to OMTF coordinate system. int getProcessorPhi(int phiZero, l1t::tftype part, int dtScNum, int dtPhi) const override; + + int getGlobalEta(DTChamberId dTChamberId, const L1Phase2MuDTThContainer *dtThDigis, int bxNum) const; }; #endif diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/PtAssignmentNNRegression.h b/L1Trigger/L1TMuonOverlapPhase2/interface/PtAssignmentNNRegression.h index 0db72c7b01b78..5fa0441f8ba8d 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/PtAssignmentNNRegression.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/PtAssignmentNNRegression.h @@ -9,7 +9,7 @@ #define L1Trigger_L1TMuonOverlapPhase2_PtAssigmentNNRegression_h #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h" -#include "L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegression2Outputs.h" +#include "L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointCommon.h" class PtAssignmentNNRegression : public PtAssignmentBase { public: @@ -18,8 +18,7 @@ class PtAssignmentNNRegression : public PtAssignmentBase { std::string networkFile); ~PtAssignmentNNRegression() override = default; - std::vector getPts(AlgoMuons::value_type& algoMuon, - std::vector >& observers) override; + void run(AlgoMuons::value_type& algoMuon, std::vector >& observers) override; private: unique_ptr lutNetworkFP; diff --git a/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.cc b/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.cc index e332d7cf525b6..cad7f239fdd63 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.cc @@ -6,12 +6,14 @@ #include "DataFormats/RPCDigi/interface/RPCDigiCollection.h" #include "SimDataFormats/Track/interface/SimTrackContainer.h" #include "SimDataFormats/Vertex/interface/SimVertexContainer.h" +#include "SimDataFormats/TrackingAnalysis/interface/TrackingParticleFwd.h" #include "FWCore/Framework/interface/EDConsumerBase.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/ProductRegistryHelper.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/PluginManager/interface/PluginFactory.h" #include "FWCore/Utilities/interface/InputTag.h" +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" #include #include @@ -19,10 +21,13 @@ L1TMuonOverlapPhase2TrackProducer::L1TMuonOverlapPhase2TrackProducer(const edm::ParameterSet& edmParameterSet) : muStubsInputTokens( - {consumes(edmParameterSet.getParameter("srcDTPh")), - consumes(edmParameterSet.getParameter("srcDTTh")), + {mayConsume(edmParameterSet.getParameter("srcDTPh")), + mayConsume(edmParameterSet.getParameter("srcDTTh")), consumes(edmParameterSet.getParameter("srcCSC")), consumes(edmParameterSet.getParameter("srcRPC"))}), + muStubsPhase2InputTokens( + {consumes(edmParameterSet.getParameter("srcDTPhPhase2")), + consumes(edmParameterSet.getParameter("srcDTThPhase2"))}), omtfParamsEsToken(esConsumes()), muonGeometryTokens({esConsumes(), esConsumes(), @@ -31,16 +36,19 @@ L1TMuonOverlapPhase2TrackProducer::L1TMuonOverlapPhase2TrackProducer(const edm:: magneticFieldEsToken(esConsumes()), propagatorEsToken(esConsumes( edm::ESInputTag("", "SteppingHelixPropagatorAlong"))), - omtfEmulation(edmParameterSet, - muStubsInputTokens, - consumes(edmParameterSet.getParameter("srcDTPhPhase2"))) { - produces("OMTF"); + omtfEmulation(edmParameterSet, muStubsInputTokens, muStubsPhase2InputTokens) { + + produces("OMTF"); //phase-1 collection + produces("OMTFconstr"); + produces("OMTFunconstr"); //it is needed for pattern generation and RootDataDumper if (edmParameterSet.exists("simTracksTag")) mayConsume(edmParameterSet.getParameter("simTracksTag")); if (edmParameterSet.exists("simVertexesTag")) mayConsume(edmParameterSet.getParameter("simVertexesTag")); + if (edmParameterSet.exists("trackingParticleTag")) + mayConsume(edmParameterSet.getParameter("trackingParticleTag")); } ///////////////////////////////////////////////////// @@ -59,9 +67,11 @@ void L1TMuonOverlapPhase2TrackProducer::beginRun(edm::Run const& run, edm::Event void L1TMuonOverlapPhase2TrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& evSetup) { std::ostringstream str; - std::unique_ptr candidates = omtfEmulation.reconstruct(iEvent, evSetup); + auto outptuCollections = omtfEmulation.run(iEvent, evSetup); - iEvent.put(std::move(candidates), "OMTF"); + iEvent.put(std::move(outptuCollections.regionalCandidates), "OMTF"); + iEvent.put(std::move(outptuCollections.constrSaMuons), "OMTFconstr"); + iEvent.put(std::move(outptuCollections.unConstrSaMuons), "OMTFunconstr"); } ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// diff --git a/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.h b/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.h index b15974950dec0..0596d194ec333 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.h +++ b/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.h @@ -25,6 +25,7 @@ class L1TMuonOverlapPhase2TrackProducer : public edm::one::EDProducer omtfParamsEsToken; diff --git a/L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_DT_2_2_2_cff.py b/L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_DT_2_2_2_cff.py new file mode 100644 index 0000000000000..ca857f43606f7 --- /dev/null +++ b/L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_DT_2_2_2_cff.py @@ -0,0 +1,14 @@ +import FWCore.ParameterSet.Config as cms + +from L1Trigger.L1TMuonOverlapPhase2.simOmtfPhase2Digis_cfi import simOmtfPhase2Digis + +#these patterns were gnerated with dtRefHitMinQuality = 4 +#simOmtfPhase2Digis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_ExtraplMB1nadMB2DTQualAndRFixedP_DT_2_2_t30__classProb17_recalib2.xml") + +#these patterns were gnerated with dtRefHitMinQuality = 2, so some pdfs are wider, but the performance is very similar as in the Patterns_ExtraplMB1nadMB2DTQualAndRFixedP_DT_2_2_t30__classProb17_recalib2.xml +#simOmtfPhase2Digis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_ExtraplMB1nadMB2DTQualAndRFixedP_DT_2_2_2_t31__classProb17_recalib2.xml") + +# the patterns t30 and t31 had rpcDropAllClustersIfMoreThanMax = 0, but also cleanStubs = 1, so then its like rpcDropAllClustersIfMoreThanMax = 1, so are OK + +simOmtfPhase2Digis.dtRefHitMinQuality = cms.int32(2) +simOmtfPhase2Digis.ghostBusterType = cms.string("byRefLayerAndHitQual") \ No newline at end of file diff --git a/L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_cfi.py b/L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_cfi.py index c27335f7bf28b..a88f8422474dc 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_cfi.py +++ b/L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_cfi.py @@ -5,14 +5,15 @@ srcDTPh = cms.InputTag('simDtTriggerPrimitiveDigis'), srcDTTh = cms.InputTag('simDtTriggerPrimitiveDigis'), srcCSC = cms.InputTag('simCscTriggerPrimitiveDigis','MPCSORTED'), + #srcCSC = cms.InputTag('simCscTriggerPrimitiveDigis'), srcRPC = cms.InputTag('simMuonRPCDigis'), srcDTPhPhase2 = cms.InputTag('dtTriggerPhase2PrimitiveDigis'), srcDTThPhase2 = cms.InputTag('dtTriggerPhase2PrimitiveDigis'), ## XML / PATTERNS file: configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0209.xml"), - patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_ExtraplMB1nadMB2DTQualAndEtaFixedP_ValueP1Scale_t20_v1_SingleMu_iPt_and_OneOverPt_classProb17_recalib2_minDP0.xml"), - extrapolFactorsFilename = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/ExtrapolationFactors_ExtraplMB1nadMB2DTQual_ValueP1Scale_t20.xml"), + extrapolFactorsFilename = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/ExtrapolationFactors_ExtraplMB1nadMB2_R_EtaValueP1Scale_t35.xml"), + patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_ExtraplMB1andMB2RFixedP_ValueP1Scale_DT_2_2_2_t35__classProb17_recalib2.xml"), dumpResultToXML = cms.bool(False), dumpDetailedResultToXML = cms.bool(False), @@ -37,7 +38,7 @@ noHitValueInPdf = cms.bool(True), minDtPhiQuality = cms.int32(2), - minDtPhiBQuality = cms.int32(4), + minDtPhiBQuality = cms.int32(2), dtRefHitMinQuality = cms.int32(4), @@ -45,9 +46,15 @@ stubEtaEncoding = cms.string("valueP1Scale"), #TODO change to valueP1Scale when InputMakerPhase2 is modifiwed + rpcMaxClusterSize = cms.int32(3), + rpcMaxClusterCnt = cms.int32(2), + rpcDropAllClustersIfMoreThanMax = cms.bool(True), + usePhiBExtrapolationFromMB1 = cms.bool(True), usePhiBExtrapolationFromMB2 = cms.bool(True), - useStubQualInExtr = cms.bool(True), + #in the DTTriggerPhase2 in PR44924 the phi is defined always in the middle of the chamber, even for the uncorelated stubs + #so the qulaity doeas not maater in the extrapolation + useStubQualInExtr = cms.bool(False), useEndcapStubsRInExtr = cms.bool(True), useFloatingPointExtrapolation = cms.bool(False), diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc b/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc index db9952a549664..c7f2d05cfc776 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc @@ -24,11 +24,10 @@ void DtPhase2DigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers, int bxFrom, int bxTo, std::vector >& observers) { - if (!dtPhDigis) - return; - boost::property_tree::ptree procDataTree; + std::map chamberTrees; + for (const auto& digiIt : *dtPhDigis->getContainer()) { DTChamberId detid(digiIt.whNum(), digiIt.stNum(), digiIt.scNum() + 1); @@ -40,34 +39,56 @@ void DtPhase2DigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers, if (digiIt.bxNum() - 20 >= bxFrom && digiIt.bxNum() - 20 <= bxTo) { addDTphiDigi(muonStubsInLayers, digiIt, dtThDigis.product(), iProcessor, procTyp); - auto& dtP2Digi = procDataTree.add_child("dtP2Digi", boost::property_tree::ptree()); - dtP2Digi.add(".whNum", digiIt.whNum()); - dtP2Digi.add(".scNum", digiIt.scNum()); - dtP2Digi.add(".stNum", digiIt.stNum()); - dtP2Digi.add(".slNum", digiIt.slNum()); - dtP2Digi.add(".quality", digiIt.quality()); - dtP2Digi.add(".rpcFlag", digiIt.rpcFlag()); - dtP2Digi.add(".phi", digiIt.phi()); - dtP2Digi.add(".phiBend", digiIt.phiBend()); + std::ostringstream chamberName; + //chamberName<.whNum", digiIt.whNum()); + dtP2PhiDigi.add(".scNum", digiIt.scNum()); + dtP2PhiDigi.add(".stNum", digiIt.stNum()); + dtP2PhiDigi.add(".slNum", digiIt.slNum()); + dtP2PhiDigi.add(".quality", digiIt.quality()); + dtP2PhiDigi.add(".rpcFlag", digiIt.rpcFlag()); + dtP2PhiDigi.add(".phi", digiIt.phi()); + dtP2PhiDigi.add(".phiBend", digiIt.phiBend()); } } - if (!mergePhiAndTheta) { - for (auto& thetaDigi : (*(dtThDigis->getContainer()))) { - if (thetaDigi.bxNum() >= bxFrom && thetaDigi.bxNum() <= bxTo) { + for (auto& thetaDigi : (*(dtThDigis->getContainer()))) { + if (thetaDigi.bxNum() - 20 >= bxFrom && thetaDigi.bxNum() - 20 <= bxTo) { + if (!mergePhiAndTheta) { addDTetaStubs(muonStubsInLayers, thetaDigi, iProcessor, procTyp); } + + std::ostringstream chamberName; + //chamberName<.whNum", thetaDigi.whNum()); + dtP2ThDigi.add(".scNum", thetaDigi.scNum()); + dtP2ThDigi.add(".stNum", thetaDigi.stNum()); + dtP2ThDigi.add(".quality", thetaDigi.quality()); + dtP2ThDigi.add(".rpcFlag", thetaDigi.rpcFlag()); + dtP2ThDigi.add(".k", thetaDigi.k()); + dtP2ThDigi.add(".z", thetaDigi.z()); } } + for(auto& chamberTree : chamberTrees) { + chamberTree.second.add(".name", chamberTree.first); + procDataTree.add_child("dtChamber", chamberTree.second); + } + for (auto& obs : observers) - obs->addProcesorData("linkData", procDataTree); + obs->addProcesorData("dtData", procDataTree); } //dtThDigis is provided as argument, because in the OMTF implementation the phi and eta digis are merged (even thought it is artificial) void DtPhase2DigiToStubsConverterOmtf::addDTphiDigi(MuonStubPtrs2D& muonStubsInLayers, const L1Phase2MuDTPhDigi& digi, - const L1MuDTChambThContainer* dtThDigis, + const L1Phase2MuDTThContainer* dtThDigis, unsigned int iProcessor, l1t::tftype procTyp) { DTChamberId detid(digi.whNum(), digi.stNum(), digi.scNum() + 1); @@ -75,14 +96,14 @@ void DtPhase2DigiToStubsConverterOmtf::addDTphiDigi(MuonStubPtrs2D& muonStubsInL MuonStub stub; //converting the quality to the same encoding as in phase-1, as it is important for extrapolation - if (digi.quality() >= 6) + if (digi.quality() >= 6) // correlated stub stub.qualityHw = digi.quality() - 2; - else if (digi.quality() >= 3) { + else if (digi.quality() >= 3) { // 4 hit uncorrelated stub if (digi.slNum() == 3) stub.qualityHw = 3; else if (digi.slNum() == 1) stub.qualityHw = 2; - } else { + } else { //quality 1 (3 hits) or 2 (3+2 hits) if (digi.slNum() == 3) stub.qualityHw = 1; else if (digi.slNum() == 1) @@ -106,11 +127,17 @@ void DtPhase2DigiToStubsConverterOmtf::addDTphiDigi(MuonStubPtrs2D& muonStubsInL stub.phiHw = angleConverter.getProcessorPhi( OMTFinputMaker::getProcessorPhiZero(&config, iProcessor), procTyp, digi.scNum(), digi.phi()); - //TODO the dtThDigis are not good yet,so passing an empty container to the angleConverter - //then it should return middle of chambers - //remove when the dtThDigis are fixed on the DT side - L1MuDTChambThContainer dtThDigisEmpty; - stub.etaHw = angleConverter.getGlobalEta(detid, &dtThDigisEmpty, digi.bxNum() - 20); + stub.etaHw = angleConverter.getGlobalEta(detid, dtThDigis, digi.bxNum() - 20); + + if (iLayer == 0) + stub.r = 431.175; //MB1 + else if (iLayer == 2) { + stub.r = 512.475; //MB2 + } else if (iLayer == 4) { + stub.r = 620; //round(619.675); + //MB3, it is different than in the phase-1, as in the phase-2 it is a middle of the DT chamber, not muon station + } + //in phase2, the phiB is 13 bits, and range is [-2, 2 rad] so 4 rad, 2^13 units/(4 rad) = 1^11/rad. //need to convert them to 512units==1rad (to use OLD PATTERNS...) stub.phiBHw = digi.phiBend() * config.dtPhiBUnitsRad() / 2048; @@ -130,11 +157,14 @@ void DtPhase2DigiToStubsConverterOmtf::addDTphiDigi(MuonStubPtrs2D& muonStubsInL << " slNum " << digi.slNum() << " quality " << digi.quality() << " rpcFlag " << digi.rpcFlag() << " phi " << digi.phi() << " phiBend " << digi.phiBend() << std::endl; + LogTrace("l1tOmtfEventPrint") << board.name() << " stub: detid " << detid << " phi " << stub.phiHw << " eta " + << stub.etaHw << " phiB " << stub.phiBHw << " bx " << stub.bx << " quality " + << stub.qualityHw << " logicLayer " << stub.logicLayer << std::endl; OMTFinputMaker::addStub(&config, muonStubsInLayers, iLayer, iInput, stub); } void DtPhase2DigiToStubsConverterOmtf::addDTetaStubs(MuonStubPtrs2D& muonStubsInLayers, - const L1MuDTChambThDigi& thetaDigi, + const L1Phase2MuDTThDigi& thetaDigi, unsigned int iProcessor, l1t::tftype procTyp) { //in the Phase1 omtf the theta stubs are merged with the phi in the addDTphiDigi @@ -149,7 +179,7 @@ bool DtPhase2DigiToStubsConverterOmtf::acceptDigi(const DTChamberId& dTChamberId InputMakerPhase2::InputMakerPhase2(const edm::ParameterSet& edmParameterSet, MuStubsInputTokens& muStubsInputTokens, - edm::EDGetTokenT inputTokenDTPhPhase2, + MuStubsPhase2InputTokens& muStubsPhase2InputTokens, const OMTFConfiguration* config, std::unique_ptr angleConverter) : OMTFinputMaker(edmParameterSet, muStubsInputTokens, config, std::move(angleConverter)) { @@ -162,7 +192,11 @@ InputMakerPhase2::InputMakerPhase2(const edm::ParameterSet& edmParameterSet, "is not true"); //if the Phase2DTPrimitives are used, then the phase1 DT primitives should be dropped edm::LogImportant("OMTFReconstruction") << " using Phase2 DT trigger primitives" << std::endl; + digiToStubsConverters.emplace_back(std::make_unique( - config, this->angleConverter.get(), inputTokenDTPhPhase2, muStubsInputTokens.inputTokenDtTh)); + config, + dynamic_cast(this->angleConverter.get()), + muStubsPhase2InputTokens.inputTokenDtPh, + muStubsPhase2InputTokens.inputTokenDtTh)); } } diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfEmulation.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfEmulation.cc index 3ae8d20b79d4d..20ffb11c6f1f0 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfEmulation.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfEmulation.cc @@ -11,26 +11,131 @@ #include "L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h" #include "L1Trigger/L1TMuonOverlapPhase2/interface/PtAssignmentNNRegression.h" +#include "DataFormats/L1TMuonPhase2/interface/Constants.h" + #include "FWCore/MessageLogger/interface/MessageLogger.h" #include OmtfEmulation::OmtfEmulation(const edm::ParameterSet& edmParameterSet, MuStubsInputTokens& muStubsInputTokens, - edm::EDGetTokenT inputTokenDTPhPhase2) - : OMTFReconstruction(edmParameterSet, muStubsInputTokens), inputTokenDTPhPhase2(inputTokenDTPhPhase2) {} + MuStubsPhase2InputTokens& muStubsPhase2InputTokens) + : OMTFReconstruction(edmParameterSet, muStubsInputTokens), muStubsPhase2InputTokens(muStubsPhase2InputTokens) {} void OmtfEmulation::beginJob() { if (edmParameterSet.exists("usePhase2DTPrimitives") && edmParameterSet.getParameter("usePhase2DTPrimitives")) { inputMaker = std::make_unique(edmParameterSet, muStubsInputTokens, - inputTokenDTPhPhase2, + muStubsPhase2InputTokens, omtfConfig.get(), std::make_unique()); } else { inputMaker = std::make_unique( edmParameterSet, muStubsInputTokens, omtfConfig.get(), std::make_unique()); } + + //.....................rrrrrrrrccccdddddd + //.....................765432109876543210 + firedLayersToQuality[0b000000110000000011] = 1; + firedLayersToQuality[0b000000100000000011] = 1; + firedLayersToQuality[0b000000010000000011] = 1; + firedLayersToQuality[0b000000110000000001] = 1; + firedLayersToQuality[0b000001000000001100] = 1; + firedLayersToQuality[0b000011000000001100] = 1; + firedLayersToQuality[0b000010000000001100] = 1; + firedLayersToQuality[0b000011000000000100] = 1; + firedLayersToQuality[0b000000011000000001] = 1; + firedLayersToQuality[0b001000010000000001] = 1; + + firedLayersToQuality[0b000100000000110000] = 1; + firedLayersToQuality[0b001100000000010000] = 1; + + firedLayersToQuality[0b010000110000000001] = 8; + firedLayersToQuality[0b000000111110000001] = 8; + firedLayersToQuality[0b000000001000000011] = 8; + firedLayersToQuality[0b000000111000000001] = 8; + firedLayersToQuality[0b000000101000000001] = 8; + firedLayersToQuality[0b010000011000000001] = 8; + firedLayersToQuality[0b010000100000000001] = 8; + firedLayersToQuality[0b000000110100000001] = 8; + firedLayersToQuality[0b000000100100000001] = 8; + firedLayersToQuality[0b001000100000000001] = 8; + firedLayersToQuality[0b010000010000000001] = 8; + firedLayersToQuality[0b001000110000000001] = 8; + firedLayersToQuality[0b001000110000000000] = 8; + firedLayersToQuality[0b000000010100000001] = 8; + firedLayersToQuality[0b000010100000000001] = 8; + firedLayersToQuality[0b000000100010000001] = 8; + firedLayersToQuality[0b001010010000000101] = 8; + firedLayersToQuality[0b100000000000000011] = 8; + firedLayersToQuality[0b011011000000000000] = 8; + firedLayersToQuality[0b000010110000000001] = 8; + firedLayersToQuality[0b001001110000000001] = 8; + firedLayersToQuality[0b000010100000000101] = 8; + firedLayersToQuality[0b000011110000000001] = 8; + firedLayersToQuality[0b000011110000001101] = 8; + firedLayersToQuality[0b000011100000000101] = 8; + firedLayersToQuality[0b000011110000000101] = 8; + firedLayersToQuality[0b000100000001110000] = 8; + firedLayersToQuality[0b000001110000001101] = 8; + firedLayersToQuality[0b000000110110000001] = 8; + firedLayersToQuality[0b000001110000000001] = 8; + firedLayersToQuality[0b001000010001000001] = 8; + firedLayersToQuality[0b000001100000000101] = 8; + firedLayersToQuality[0b000001100000000001] = 8; + firedLayersToQuality[0b000001110000000101] = 8; + firedLayersToQuality[0b001001110001000001] = 8; + firedLayersToQuality[0b000010110000000101] = 8; + firedLayersToQuality[0b000000010001000001] = 8; + firedLayersToQuality[0b000000100110000001] = 8; + firedLayersToQuality[0b001001100000001100] = 8; + firedLayersToQuality[0b000001010000000001] = 8; + firedLayersToQuality[0b000010100000000011] = 8; + firedLayersToQuality[0b000000100001000001] = 8; + firedLayersToQuality[0b001000110001000001] = 8; + firedLayersToQuality[0b000000010010000001] = 8; + firedLayersToQuality[0b000001010000000101] = 8; + firedLayersToQuality[0b100000100110000001] = 8; + firedLayersToQuality[0b000010010000000101] = 8; + firedLayersToQuality[0b000000110010000001] = 8; + firedLayersToQuality[0b000000000000110100] = 8; + firedLayersToQuality[0b000000010000000101] = 8; + firedLayersToQuality[0b000000110001000001] = 8; + firedLayersToQuality[0b000000010000001100] = 8; + firedLayersToQuality[0b000010110000001101] = 8; + firedLayersToQuality[0b000011010000001101] = 8; + firedLayersToQuality[0b000000100000010001] = 8; + firedLayersToQuality[0b000000110000000101] = 8; + firedLayersToQuality[0b000001100000000111] = 8; + firedLayersToQuality[0b000000100000000101] = 8; + firedLayersToQuality[0b010000010010000001] = 8; + firedLayersToQuality[0b000001100000001101] = 8; + firedLayersToQuality[0b000011100000000111] = 8; + firedLayersToQuality[0b000000010110000001] = 8; + firedLayersToQuality[0b000011110000000111] = 8; + firedLayersToQuality[0b000000011100000000] = 8; + firedLayersToQuality[0b001000010000000011] = 8; + firedLayersToQuality[0b000001110000000011] = 8; + firedLayersToQuality[0b000100000000110000] = 8; + firedLayersToQuality[0b000111100000110100] = 8; + firedLayersToQuality[0b010000010010000000] = 8; + firedLayersToQuality[0b100000010100000000] = 8; + firedLayersToQuality[0b001000100000000011] = 8; + firedLayersToQuality[0b000011100000001101] = 8; + firedLayersToQuality[0b100000011100000000] = 8; + firedLayersToQuality[0b110000011110000001] = 8; + //firedLayersToQuality[0b000000000000110011] = 8; + //firedLayersToQuality[0b000000100110000011] = 8; + //firedLayersToQuality[0b110000000100000000] = 8; + //firedLayersToQuality[0b001011110001001101] = 8; + //firedLayersToQuality[0b010000100001000011] = 8; + //firedLayersToQuality[0b000001100000001100] = 8; + //firedLayersToQuality[0b000001110001000011] = 8; + //firedLayersToQuality[0b011000000010000000] = 8; + //firedLayersToQuality[0b001000110100000011] = 8; + //firedLayersToQuality[0b010001000011000000] = 8; + //firedLayersToQuality[0b100000000110000000] = 8; + //firedLayersToQuality[0b000000000000111100] = 8; } void OmtfEmulation::addObservers(const MuonGeometryTokens& muonGeometryTokens, @@ -44,6 +149,7 @@ void OmtfEmulation::addObservers(const MuonGeometryTokens& muonGeometryTokens, }*/ } + //addObservers is called in OMTFReconstruction::beginRun after the omtfProc is constructed, therefore here we can ptAssignment in omtfProc if (edmParameterSet.exists("neuralNetworkFile") && !ptAssignment) { edm::LogImportant("OMTFReconstruction") << "constructing PtAssignmentNNRegression" << std::endl; std::string neuralNetworkFile = edmParameterSet.getParameter("neuralNetworkFile").fullPath(); @@ -55,4 +161,197 @@ void OmtfEmulation::addObservers(const MuonGeometryTokens& muonGeometryTokens, omtfProcGoldenPat->setPtAssignment(ptAssignment.get()); //omtfProcGoldenPat can be constructed from scratch each run, so ptAssignment is set herer every run } + + omtfProc->setAssignQualityFunction( + [&](AlgoMuons::value_type& algoMuon) { this->assignQualityPhase2(algoMuon); }); +} + +void OmtfEmulation::assignQualityPhase2(AlgoMuons::value_type& algoMuon) { + if (abs(algoMuon->getEtaHw()) >= 121) { //TODO take into account the eta scale + algoMuon->setQuality(0); // changed from 4 on request from HI + return; + } + + auto it = firedLayersToQuality.find(algoMuon->getFiredLayerBits()); + if (algoMuon->getPtConstr() == 0) { + algoMuon->setQuality(0); //default value + return; + } + + if (it != firedLayersToQuality.end()) { + algoMuon->setQuality(it->second); + } else { + algoMuon->setQuality(12); //default value + } +}; + +void OmtfEmulation::convertToGmtScalesPhase2(unsigned int iProcessor, l1t::tftype mtfType, FinalMuonPtr& finalMuon) { + //ptAssignment (NN) is used only if there was valid candidate from pattern logic + //it overrides the pt from the pattern logic + if (ptAssignment) { + //PtNNConstr should be in GeV + finalMuon->setPtGev(finalMuon->getAlgoMuon()->getPtNNConstr()); + + //TODO use getPtNNUnconstr when the network with upt is trained to set setPtUnconstrGev() + } + + //in getFinalMuons the PtGeV is set to 0 in this case, as it is like that for the phase-1. + //but it is better to set non-0 pt in this case, so we set 1 GeV + if (finalMuon->getAlgoMuon()->getPdfSumConstr() == 0 && finalMuon->getAlgoMuon()->getPtUnconstr() > 0) + finalMuon->setPtGev(1.0); //set to 1 GeV to be able to distinguish from pt=0, which means no candidate + + int maxPtHw = (1 << Phase2L1GMT::BITSPT) - 1; + + int ptHwConstr = (finalMuon->getPtGev() * (1. / Phase2L1GMT::LSBpt)); + + if (ptHwConstr >= maxPtHw) + ptHwConstr = maxPtHw; + + finalMuon->setPtGmt(ptHwConstr); + + + int ptHwUnConstr = finalMuon->getPtUnconstrGev() * (1. / Phase2L1GMT::LSBpt); + + if (ptHwUnConstr >= maxPtHw) + ptHwUnConstr = maxPtHw; + + finalMuon->setPtUnconstrGmt(ptHwUnConstr); + + + if (mtfType == l1t::omtf_pos) { + finalMuon->setEtaGmt(finalMuon->getAlgoMuon()->getEtaHw()); + } + else { + finalMuon->setEtaGmt((-1) * finalMuon->getAlgoMuon()->getEtaHw()); + } + + int globPhi = omtfConfig->procPhiOmtfToGlobalPhiOmtf(iProcessor, finalMuon->getAlgoMuon()->getPhi()); + int gmtPhiBins = 1 << Phase2L1GMT::BITSPHI; + int omtfToGmtFactorPhi = std::lround(gmtPhiBins * (1 << 12) / double(omtfConfig->nPhiBins()) ) ; + int gmtPhi = (globPhi * omtfToGmtFactorPhi) >> 12; + finalMuon->setPhiGmt(gmtPhi); + + int omtfToGmtFactorEta = std::lround(omtfConfig->etaUnit() * (1 << 12) / Phase2L1GMT::LSBeta ) ; + int gmtEta = (finalMuon->getAlgoMuon()->getEtaHw() * omtfToGmtFactorEta) >> 12; + if (mtfType == l1t::omtf_neg) + gmtEta = -gmtEta; + finalMuon->setEtaGmt(gmtEta); + + //finalMuon.setHwSignValid(1); +} + +l1t::SAMuonCollection OmtfEmulation::getSAMuons(unsigned int iProcessor, + l1t::tftype mtfType, + FinalMuons& finalMuons, + bool costrainedPt) { + l1t::SAMuonCollection saMuons; + for (auto& finalMuon : finalMuons) { + convertToGmtScalesPhase2(iProcessor, mtfType, finalMuon); + + int charge = finalMuon->getSign(); + + unsigned int pt = costrainedPt ? finalMuon->getPtGmt() : finalMuon->getPtUnconstrGmt(); + + LogTrace("OMTFReconstruction") << "OmtfEmulation::getSAMuons finalMuon->getPtGmt(): " + << finalMuon->getPtGmt() << " finalMuon->getPtUnconstrGmt() "<< finalMuon->getPtUnconstrGmt() << std::endl; + + int phi = finalMuon->getPhiGmt(); + int eta = finalMuon->getEtaGmt(); + + int z0 = 0; + // Use 2 bits with LSB = 30cm for BMTF and 25cm for EMTF currently, but subjet to change + int d0 = 0; //finalMuon->getHwD0(); + + unsigned int qual = finalMuon->getQuality(); + + //TODO FIX + //Here do not use the word format to GT but use the word format expected by GMT + /* + int bstart = 0; + wordtype word(0); + bstart = wordconcat(word, bstart, 1, 1); + bstart = wordconcat(word, bstart, charge, 1); + bstart = wordconcat(word, bstart, pt, BITSPT); + bstart = wordconcat(word, bstart, phi, BITSPHI); + bstart = wordconcat(word, bstart, eta, BITSETA); + // bstart = wordconcat(word, bstart, z0, BITSSAZ0); NOT YET SUPPORTED BY GMT + bstart = wordconcat(word, bstart, d0, BITSSAD0); + bstart = wordconcat( + word, bstart, qual, 8); //FOR NOW 8 bits to be efficienct with Ghost busting. THIS IS ***NOT*** THE FINAL QUALITY +*/ + + // Calculate Lorentz Vector + //TODO for the vertex constrained muon, the z0 and d0 by definition should be 0 - then why give it? + math::PtEtaPhiMLorentzVector p4Constr(pt * Phase2L1GMT::LSBpt, eta * Phase2L1GMT::LSBeta, phi * Phase2L1GMT::LSBphi, 0.0); + l1t::SAMuon saMuonConstr(p4Constr, charge, pt, eta, phi, z0, d0, qual); + saMuonConstr.setTF(mtfType); + //samuon.setWord(word); + + if (saMuonConstr.hwPt() > 0) { + saMuons.push_back(saMuonConstr); + } + } + + return saMuons; +} + +OmtfEmulation::OmtfOutptuCollections OmtfEmulation::run( + const edm::Event& iEvent, + const edm::EventSetup& evSetup) { + LogTrace("l1tOmtfEventPrint") << "\n" << __FUNCTION__ << ":" << __LINE__ << " iEvent " << iEvent.id().event() << endl; + inputMaker->loadAndFilterDigis(iEvent); + + for (auto& obs : observers) { + obs->observeEventBegin(iEvent); + } + + OmtfOutptuCollections outptuCollections; + outptuCollections.constrSaMuons = std::make_unique(); + outptuCollections.unConstrSaMuons = std::make_unique(); + outptuCollections.regionalCandidates = std::make_unique(); + outptuCollections.regionalCandidates->setBXRange(bxMin, bxMax); + + FinalMuons allFinalMuons; + + ///The order is important: first put omtf_pos candidates, then omtf_neg. + for (int bx = bxMin; bx <= bxMax; bx++) { + for(unsigned int iSide = 0; iSide < 2; ++iSide) { + l1t::tftype mtfType = (iSide == 0) ? l1t::tftype::omtf_pos : l1t::tftype::omtf_neg; + for (unsigned int iProcessor = 0; iProcessor < omtfConfig->nProcessors(); ++iProcessor) { + FinalMuons finalMuons = omtfProc->run(iProcessor, mtfType, bx, inputMaker.get(), observers); + + //getRegionalMuonCands calls convertToGmtScalesPhase1, it sets value eta, phi, pt finalMuons + //so regionalCandidates have values in phase-1 scales + std::vector candMuons = + omtfProc->getRegionalMuonCands(iProcessor, mtfType, finalMuons); + for (auto& candMuon : candMuons) { + outptuCollections.regionalCandidates->push_back(bx, candMuon); + } + + for (auto& finalMuon : finalMuons) { + convertToGmtScalesPhase2(iProcessor, mtfType, finalMuon); + } + + l1t::SAMuonCollection constrSAMuons = getSAMuons(iProcessor, mtfType, finalMuons, true); + for (auto& saMuon : constrSAMuons) { + outptuCollections.unConstrSaMuons->push_back(saMuon); + } + + l1t::SAMuonCollection unconstrSAMuons = getSAMuons(iProcessor, mtfType, finalMuons, false); + for (auto& saMuon : unconstrSAMuons) { + outptuCollections.unConstrSaMuons->push_back(saMuon); + } + + allFinalMuons.insert(allFinalMuons.end(), finalMuons.begin(), finalMuons.end()); + } + } + + //edm::LogInfo("OMTFReconstruction") <<"OMTF: Number of candidates in BX="<size(bx) << std::endl;; + } + + for (auto& obs : observers) { + obs->observeEventEnd(iEvent, allFinalMuons); + } + + return outptuCollections; } diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc index 26bbbc46e4477..1ca36c89c0386 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc @@ -20,12 +20,56 @@ int OmtfPhase2AngleConverter::getProcessorPhi(int phiZero, l1t::tftype part, int return config->foldPhi(phiConverted); } -/* TODO implement the etat for the phase2 stubs -int getGlobalEta(const DTChamberId dTChamberId, const L1Phase2MuDTThContainer *dtThDigis, int bxNum) const { +int OmtfPhase2AngleConverter::getGlobalEta(DTChamberId dTChamberId, + const L1Phase2MuDTThContainer* dtThDigis, + int bxNum) const { + int dtThBins = 65536; //65536. for [-6.3,6.3] + float kconv = 1 / (dtThBins / 2.); - //const DTChamberId dTChamberId(aDigi.whNum(),aDigi.stNum(),aDigi.scNum()+1); - DTTrigGeom trig_geom(_geodt->chamber(dTChamberId), false); + float eta = -999; + // get the theta digi + bool foundeta = false; + int thetaDigiCnt = 0; + for (const auto& thetaDigi : (*(dtThDigis->getContainer()))) { + if (thetaDigi.whNum() == dTChamberId.wheel() && thetaDigi.stNum() == dTChamberId.station() && + thetaDigi.scNum() == (dTChamberId.sector() - 1) && (thetaDigi.bxNum() - 20) == bxNum) { + // get the theta digi + float k = thetaDigi.k() * kconv; //-pow(-1.,z<0)*log(tan(atan(1/k)/2.)); + eta = -1. * std::copysign( log(fabs(tan(atan(1 / k) / 2.))), thetaDigi.z() ); + LogTrace("OMTFReconstruction") << "OmtfPhase2AngleConverter::getGlobalEta(" << dTChamberId << ") eta: " << eta + << " k: " << k << " thetaDigi.k(): " << thetaDigi.k(); + thetaDigiCnt++; + //checking if the obtained eta has reasonable range - temporary fix + if ((dTChamberId.station() == 1 && (std::abs(eta) < 0.85 || std::abs(eta) > 1.20)) || + (dTChamberId.station() == 2 && (std::abs(eta) < 0.75 || std::abs(eta) > 1.04)) || + (dTChamberId.station() == 3 && (std::abs(eta) < 0.63 || std::abs(eta) > 0.92))) { + foundeta = false; + /*edm::LogVerbatim("OMTFReconstruction") + << "OmtfPhase2AngleConverter::getGlobalEta(" << dTChamberId << ") wrong output eta: " << eta << " k: " << k + << " thetaDigi.k(): " << thetaDigi.k() << " quality " << thetaDigi.quality();*/ + } else + foundeta = true; + } + } + //if more than 1 thetaDigi per given chamber - we don't use them, as they are ambiguous and we have no way to match them to the phi digis + if (thetaDigiCnt > 1) + foundeta = false; + + if (foundeta) { + //return std::abs(config->etaToHwEta(eta)); TODO use this version + return std::abs(std::lround(eta * 92)); + } else { + //Returning eta of the chamber middle + if (dTChamberId.station() == 1) + eta = config->mb1W2Eta(); + else if (dTChamberId.station() == 2) + eta = config->mb2W2Eta(); + else if (dTChamberId.station() == 3) + eta = config->mb3W2Eta(); + + return eta; + } + return 95; } -*/ diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/PtAssignmentNNRegression.cc b/L1Trigger/L1TMuonOverlapPhase2/src/PtAssignmentNNRegression.cc index ce3cdb6972343..501b4ba69efaf 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/PtAssignmentNNRegression.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/PtAssignmentNNRegression.cc @@ -12,6 +12,9 @@ #include "DataFormats/MuonDetId/interface/CSCDetId.h" #include "L1Trigger/L1TMuonOverlapPhase2/interface/PtAssignmentNNRegression.h" +#include "L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegressionMultipleOutputs.h" +#include "DataFormats/L1TMuonPhase2/interface/Constants.h" +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" #include #include @@ -21,58 +24,68 @@ #include namespace lutNN { - static constexpr int input_I = 10; - static constexpr int input_F = 4; - static constexpr std::size_t networkInputSize = 18; + const int input_I = 10; + const int input_F = 7; + const std::size_t networkInputSize = 18; - static constexpr int layer1_neurons = 16; - static constexpr int layer1_lut_I = 3; - static constexpr int layer1_lut_F = 13; + const int layer1_neurons = 16; + const int layer1_lut_I = 3; + const int layer1_lut_F = 9; + + const int layer1_output_I = 4; + const int layer1_output_F = layer1_lut_F + 2; - static constexpr int layer1_output_I = 4; //4 bits are for the count of the noHit layers which goes to the input of the layer2 - static constexpr int layer2_input_I = 8; - - static constexpr int layer2_neurons = 9; - static constexpr int layer2_lut_I = 5; - static constexpr int layer2_lut_F = 11; - - static constexpr int layer3_input_I = 5; - - static constexpr int layer3_0_inputCnt = 8; - static constexpr int layer3_0_lut_I = 5; - static constexpr int layer3_0_lut_F = 11; - static constexpr int output0_I = 8; - static constexpr int output0_F = 2; - - static constexpr int layer3_1_inputCnt = 1; - static constexpr int layer3_1_lut_I = 4; - static constexpr int layer3_1_lut_F = 11; - static constexpr int output1_I = 8; - static constexpr int output1_F = 0; //Does not matter in principle - it is not used - - typedef LutNetworkFixedPointRegression2Outputs + const int layer2_input_I = layer1_output_I + 4; + + const int layer2_neurons = 8 * 2 + 1 + 3; //8 neurons for pt0, pt1 (each), 1 for charge, 3s for p_displ + const int layer2_lut_I = 5; + const int layer2_lut_F = 7; + + const int layer3_input_I = 5; + const int layer3_input_F = layer2_lut_F + 2; + + const int layer3_0_inputCnt = 8; + const int layer3_0_lut_I = 8; + const int layer3_0_lut_F = 5 + 5; + const int output0_I = 8; + const int output0_F = 5 + 5; //layer3_0_lut_F + 2; + const int layer3_0_multiplicity = 2; + + const int layer3_1_inputCnt = 1; + const int layer3_1_lut_I = 8; //TODO it should be smaller than 4 bits + const int layer3_1_lut_F = 5 + 5; + + const int output1_I = 8; + const int output1_F = 5 + 5; + const int layer3_1_multiplicity = 4; + + typedef LutNetworkFixedPointRegressionMultipleOutputs LutNetworkFP; } // namespace lutNN @@ -99,7 +112,7 @@ struct OmtfHit { char quality; char z; char valid; - short eta; + short deltaR; short phiDist; }; }; @@ -107,6 +120,187 @@ struct OmtfHit { OmtfHit(unsigned long rawData) : rawData(rawData) {} }; +bool omtfHitWithQualAndRToEventInput(OmtfHit& hit, std::vector& inputs, unsigned int omtfRefLayer, bool print) { + int lustSize = 1024; //TODO change it if needed + int refLayers = 8; + float rangeSize = lustSize / (refLayers * 2); + //float offset = (omtfRefLayer<<7) + rangeMiddle; + + //two ranges for each omtfRefLayer, so that two qualites can be used for each omtfRefLayer + float offset = omtfRefLayer * rangeSize * 2 + rangeSize / 2; + int rangeFactor = 2; //rangeFactor scales the hit.phiDist such that the event->inputs is smaller then 63 + + //if(!hit.valid) + // return false; ///TODO <<<<<<<<<<<<<<<<<<<<<<<<<<<<< + if (hit.layer <= 5) { //DT hits + rangeFactor = 2; //rangeFactor scales the hit.phiDist such that the event->inputs is smaller then 63 + //two ranges for each omtfRefLayer, so that two qualites can be used for each omtfRefLayer + offset = omtfRefLayer * rangeSize * 2 + rangeSize / 2; + if ((hit.layer == 1 || hit.layer == 3 || hit.layer == 5)) { //phiB + //if(!hit.valid) + // return false; ///TODO <<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + if (hit.quality < 2) ///TODO <<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return false; + + if (hit.layer == 1) { + rangeFactor = 8 * 2; + } else if (hit.layer == 3) { + rangeFactor = 8 * 2; + } + + else if (hit.layer == 5) { + rangeFactor = 8 * 2; + } + } else { //phi + rangeFactor *= 4; + } + + if (hit.quality >= 4) { + offset += rangeSize; + //rangeFactor *= 4; + } + + } else if ((hit.layer >= 6 && hit.layer <= 9) || (hit.layer >= 15)) { //CSC hits and RPCe hits + int rBins = 16; + rangeSize = lustSize / (refLayers * rBins); + rangeFactor = 4; + int rBin = std::abs(hit.deltaR) >> 4; + if (rBin >= rBins) { + //cout<<"rBin "<= 10 || hit.layer <= 14) { //RPCb hits + rangeFactor *= 4; + } + + rangeFactor *= 2; //TODO !!!!!!!!!!!!!!!!!!! + + if (abs(hit.phiDist) >= ((rangeSize / 2 - 1) * rangeFactor)) { + if (hit.valid) + cout //<<" muonPt "<= lustSize - 2) + inputs.at(hit.layer) = lustSize - 2; + + if (print || inputs.at(hit.layer) < 0) { + cout //<<"rawData "<inputs.at(hit.layer) < 0 !!!!!!!!!!!!!!!!!" << endl; + cout << endl; + } + + if (inputs[hit.layer] >= lustSize) { //TODO should be the size of the LUT of the first layer + cout << " event->inputs[hit.layer] >= " << lustSize << " !!!!!!!!!!!!!!!!!" << endl; + } + return true; +} + +bool omtfHitWithQualToEventInput(OmtfHit& hit, std::vector& inputs, unsigned int omtfRefLayer, bool print) { + float rangeMiddle = 64 / 2; + float offset = (omtfRefLayer << 7) + rangeMiddle; + + int rangeFactor = 2; //rangeFactor scales the hit.phiDist such that the event->inputs is smaller then 63 + + if ((hit.layer == 1 || hit.layer == 3 || hit.layer == 5)) { + //if (!hit.valid) + // return false; + + if (hit.quality < 2) ///TODO <<<<<<<<<<<<<<<<<<<<<<<<<<<<< + return false; + + if (hit.layer == 1) { + rangeFactor = 8; + } else if (hit.layer == 3) { + rangeFactor = 8; + } else if (hit.layer == 5) { + rangeFactor = 8; + } + + if (hit.quality >= 4) { + offset += (1 << 6); + //rangeFactor *= 4; + } + } else { + //if (!hit.valid) + // return false; + + if ((hit.layer == 0 || hit.layer == 2 || hit.layer == 3)) { + if (hit.quality >= 4) { + offset += (1 << 6); + //rangeFactor *= 4; + } + } + + /*else if(hit.layer == 8 || hit.layer == 17) { + rangeFactor = 4; + }*/ + if (hit.layer == 9) { + rangeFactor = 1; + } + /*else { + rangeFactor = 2; + }*/ + + /*if(hit.valid) { + offset += (1 << 6); + rangeFactor *= 4; + }*/ + } + + rangeFactor *= 4; //TODO !!!!!!!!!!!!!!!!!!! + + if (abs(hit.phiDist) >= ((rangeMiddle - 1) * rangeFactor)) { + cout //<<" muonPt "<= + 1022) //the last address i.e. 1023 is reserved for the no-hit value, so interpolation between the 1022 and 1023 has no sense + inputs.at(hit.layer) = 1022; + + if (print || inputs.at(hit.layer) < 0) { + cout //<<"rawData "<inputs.at(hit.layer) < 0 !!!!!!!!!!!!!!!!!" << endl; + cout << endl; + } + + if (inputs[hit.layer] >= 1024) { //TODO should be the size of the LUT of the first layer + cout << " event->inputs[hit.layer] >= 1024 !!!!!!!!!!!!!!!!!" << endl; + } + return true; +} + bool omtfHitToEventInput(OmtfHit& hit, std::vector& inputs, unsigned int omtfRefLayer, bool print) { float offset = (omtfRefLayer << 7) + 64; @@ -117,19 +311,13 @@ bool omtfHitToEventInput(OmtfHit& hit, std::vector& inputs, unsigned int int rangeFactor = 2; //rangeFactor scales the hit.phiDist such that the event->inputs is smaller then 63 if (hit.layer == 1) { rangeFactor = 8; - } - /*else if(hit.layer == 8 || hit.layer == 17) { - rangeFactor = 4; - }*/ - else if (hit.layer == 3) { + } else if (hit.layer == 3) { rangeFactor = 4; + } else if (hit.layer == 5) { + //rangeFactor = 4; } else if (hit.layer == 9) { rangeFactor = 1; } - /*else { - rangeFactor = 2; - } - */ rangeFactor *= 2; //TODO !!!!!!!!!!!!!!!!!!! @@ -166,8 +354,8 @@ bool omtfHitToEventInput(OmtfHit& hit, std::vector& inputs, unsigned int return false; } -std::vector PtAssignmentNNRegression::getPts(AlgoMuons::value_type& algoMuon, - std::vector>& observers) { +void PtAssignmentNNRegression::run(AlgoMuons::value_type& algoMuon, + std::vector>& observers) { LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << std::endl; auto& gpResult = algoMuon->getGpResultConstr(); //int pdfMiddle = 1<<(omtfConfig->nPdfAddrBits()-1); @@ -178,19 +366,36 @@ std::vector PtAssignmentNNRegression::getPts(AlgoMuons::value_type& algoM <<" omtfPt "< inputs(inputCnt, noHitVal); - + int hitCnt = 0; + unsigned int refLayerLogicNum = omtfConfig->getRefToLogicNumber()[algoMuon->getRefLayer()]; for (unsigned int iLogicLayer = 0; iLogicLayer < gpResult.getStubResults().size(); ++iLogicLayer) { auto& stubResult = gpResult.getStubResults()[iLogicLayer]; if (stubResult.getMuonStub()) { //&& stubResult.getValid() //TODO!!!!!!!!!!!!!!!!1 + OmtfHit hit(0); + hit.layer = iLogicLayer; + hit.quality = stubResult.getMuonStub()->qualityHw; + //hit.eta = stubResult.getMuonStub()->etaHw; //in which scale? + if (refLayerLogicNum == iLogicLayer) + hit.deltaR = stubResult.getMuonStub()->r - 413; //r of the ref hit - r of RB1in + else + hit.deltaR = stubResult.getMuonStub()->r - gpResult.getStubResults()[refLayerLogicNum].getMuonStub()->r; + + hit.valid = stubResult.getValid(); + + //TODO the hit.phiDist should be set in the same way as in DataROOTDumper2, for the root files used for the NN training + //so either hit.phiDist = hitPhi - phiRefHit; or hit.phiDist = stubResult.getDeltaPhi(); + /* int hitPhi = stubResult.getMuonStub()->phiHw; unsigned int refLayerLogicNum = omtfConfig->getRefToLogicNumber()[algoMuon->getRefLayer()]; int phiRefHit = gpResult.getStubResults()[refLayerLogicNum].getMuonStub()->phiHw; @@ -200,15 +405,9 @@ std::vector PtAssignmentNNRegression::getPts(AlgoMuons::value_type& algoM phiRefHit = 0; //phi ref hit for the banding layer set to 0, since it should not be included in the phiDist } - OmtfHit hit(0); - - hit.layer = iLogicLayer; - hit.quality = stubResult.getMuonStub()->qualityHw; - hit.eta = stubResult.getMuonStub()->etaHw; //in which scale? - hit.valid = stubResult.getValid(); + hit.phiDist = hitPhi - phiRefHit;*/ - //phiDist = hitPhi - phiRefHit; - hit.phiDist = hitPhi - phiRefHit; + hit.phiDist = stubResult.getDeltaPhi(); /* LogTrace("l1tOmtfEventPrint") <<" muonPt "< PtAssignmentNNRegression::getPts(AlgoMuons::value_type& algoM <<" meanDistPhiValue "<getGoldenPatern()->meanDistPhiValue(iLogicLayer, omtfCand->getRefLayer())//<<(phiDist != hit.phiDist? "!!!!!!!<<<<<" : "") < 504 || hit.phiDist < -512) { + /* if (hit.phiDist > 504 || hit.phiDist < -512) { edm::LogVerbatim("l1tOmtfEventPrint") //<<" muonPt "<detId); - if (detId.subdetId() == MuonSubdetId::CSC) { - CSCDetId cscId(detId); - hit.z = cscId.chamber() % 2; - } + } */ - LogTrace("l1tOmtfEventPrint") << "hit: layer " << (int)hit.layer << " quality " << (int)hit.quality << " eta " - << (int)hit.eta << " valid " << (int)hit.valid << " phiDist " << (int)hit.phiDist - << " z " << (int)hit.z << std::endl; - - omtfHitToEventInput(hit, inputs, algoMuon->getRefLayer(), false); + hitCnt += omtfHitWithQualAndRToEventInput(hit, inputs, algoMuon->getRefLayer(), false); } } - LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << std::endl; + //noHitCnt input is calculated in the LutNetworkFixedPointRegression2Outputs::run + //so here hitCnt is used only for debug + LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << " hitCnt " << hitCnt << std::endl; std::vector nnResult(outputCnt); lutNetworkFP->run(inputs, noHitVal, nnResult); LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << std::endl; - double pt = std::copysign(nnResult.at(0), nnResult.at(1)); + int charge = nnResult[2] >= 0 ? 1 : -1; + double pt = std::copysign(nnResult.at(0), charge); LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << " nnResult.at(0) " << nnResult.at(0) << " nnResult.at(1) " << nnResult.at(1) << " pt " << pt << std::endl; - std::vector pts; - pts.emplace_back(pt); - //algoMuon->setPtNN(omtfConfig->ptGevToHw(nnResult.at(0))); - auto calibratedHwPt = lutNetworkFP->getCalibratedHwPt(); - algoMuon->setPtNNConstr(calibratedHwPt); + //auto calibratedHwPt = lutNetworkFP->getCalibratedHwPt(); + //pt in the hardware scale, ptGeV = (ptHw -1) / 2 + + //algoMuon->setPtNNConstr(omtfConfig->ptGevToHw(calibratedHwPt)); + + + //here the pts are GeV + double omtfPt = omtfConfig->hwPtToGev(algoMuon->getPtConstr()); + double combinedPt = nnResult.at(0); + if( (nnResult.at(0) - omtfPt) > 0.75 * omtfPt) + combinedPt = omtfPt; + + algoMuon->setPtNNConstr(combinedPt); + + algoMuon->setChargeNNConstr(charge); - algoMuon->setChargeNNConstr(nnResult[1] >= 0 ? 1 : -1); + //TODOO uncomment when NN with upt is ready + //int ptHwUnconstr = round(nnResult.at(??) ); + //algoMuon->setPtNNUnconstr(ptHwUnconstr); + + algoMuon->setNnOutputs(nnResult); //TODO add some if here, such that the property_tree is filled only when needed boost::property_tree::ptree procDataTree; @@ -268,22 +474,23 @@ std::vector PtAssignmentNNRegression::getPts(AlgoMuons::value_type& algoM } std::ostringstream ostr; - ostr << std::fixed << std::setprecision(19) << nnResult.at(0); - procDataTree.add("output0..val", ostr.str()); - ostr.str(""); - ostr << std::fixed << std::setprecision(19) << nnResult.at(1); - procDataTree.add("output1..val", ostr.str()); + for (unsigned int i = 0; i < nnResult.size(); i++) { + auto& inputTree = procDataTree.add("output", ""); + ostr.str(""); + ostr << std::fixed << std::setprecision(19) << nnResult.at(i); - procDataTree.add("calibratedHwPt..val", calibratedHwPt); + inputTree.add(".num", i); + inputTree.add(".val", ostr.str()); + } + + //procDataTree.add("calibratedHwPt..val", calibratedHwPt); procDataTree.add("hwSign..val", algoMuon->getChargeNNConstr() < 0 ? 1 : 0); for (auto& obs : observers) obs->addProcesorData("regressionNN", procDataTree); - return pts; - //event.print(); /* std::vector pts(classifierToRegressions.size(), 0); diff --git a/L1Trigger/L1TMuonOverlapPhase2/test/expert/runMuonOverlapPatternGeneratorClassProb_phase2.py b/L1Trigger/L1TMuonOverlapPhase2/test/expert/runMuonOverlapPatternGeneratorClassProb_phase2.py index 9c95e5e6ac909..39efa7df57228 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/test/expert/runMuonOverlapPatternGeneratorClassProb_phase2.py +++ b/L1Trigger/L1TMuonOverlapPhase2/test/expert/runMuonOverlapPatternGeneratorClassProb_phase2.py @@ -10,15 +10,15 @@ process.load("FWCore.MessageLogger.MessageLogger_cfi") verbose = True +versionIn = "ExtraplMB1andMB2RFixedP_ValueP1Scale_DT_2_2_2_t35_mcWaw2023_OneOverPt_and_iPt2" -versionIn = "ExtraplMB1nadMB2DTQualAndRFixedP_ValueP1Scale_t25c__mcWaw2023_OneOverPt_and_iPt2_mcWaw2023_OneOverPt_and_iPt2" #versionIn = "ExtraplMB1nadMB2DTQualAndEtaFixedP_ValueP1Scale_t20_SingleMu_mcWaw2023_OneOverPt" #versionIn = "ExtraplMB1nadMB2DTQualAndEtaValueP1Scale_t18" #versionIn = "0x00011_oldSample_3_30Files" #versionOut = versionIn + "_classProb17_recalib2" #_classProb17_recalib2_minDP0 -versionOut = "ExtraplMB1nadMB2DTQualAndRFixedP_ValueP1Scale_t25c_" + "_classProb17_recalib2" +versionOut = "ExtraplMB1andMB2RFixedP_ValueP1Scale_DT_2_2_2_t35_" + "_classProb17_recalib2" if verbose: process.MessageLogger = cms.Service("MessageLogger", @@ -41,7 +41,7 @@ l1tOmtfEventPrint = cms.untracked.PSet( limit = cms.untracked.int32(1000000000) ), OMTFReconstruction = cms.untracked.PSet( limit = cms.untracked.int32(1000000000) ) ), - debugModules = cms.untracked.vstring('simOmtfDigis') + debugModules = cms.untracked.vstring('simOmtfPhase2Digis') #debugModules = cms.untracked.vstring('*') ) @@ -52,22 +52,24 @@ #SkipEvent = cms.untracked.vstring('ProductNotFound') ) -process.load('Configuration.Geometry.GeometryExtendedRun4D49Reco_cff') -process.load('Configuration.Geometry.GeometryExtendedRun4D49_cff') - # import of standard configurations process.load('Configuration.StandardSequences.Services_cff') -process.load('SimGeneral.HepPDTESSource.pythiapdt_cfi') -process.load('Configuration.EventContent.EventContent_cff') -process.load('SimGeneral.MixingModule.mixNoPU_cfi') - +#process.load('SimGeneral.HepPDTESSource.pythiapdt_cfi') +#process.load('FWCore.MessageService.MessageLogger_cfi') +#process.load('Configuration.EventContent.EventContent_cff') +#process.load('SimGeneral.MixingModule.mixNoPU_cfi') +process.load('Configuration.Geometry.GeometryExtendedRun4D110Reco_cff') process.load('Configuration.StandardSequences.MagneticField_cff') +#process.load('Configuration.StandardSequences.RawToDigi_cff') #process.load('Configuration.StandardSequences.SimL1Emulator_cff') +#process.load('Configuration.StandardSequences.SimPhase2L1GlobalTriggerEmulator_cff') +#process.load('L1Trigger.Configuration.Phase2GTMenus.SeedDefinitions.prototypeSeeds') process.load('Configuration.StandardSequences.EndOfProcess_cff') process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') from Configuration.AlCa.GlobalTag import GlobalTag -process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') +process.GlobalTag = GlobalTag(process.GlobalTag, '131X_mcRun4_realistic_v9', '') +#process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') path = '/eos/user/k/kbunkow/cms_data/SingleMuFullEta/721_FullEta_v4/' #old sample, but very big #path = '/eos/user/a/akalinow/Data/SingleMu/9_3_14_FullEta_v2/' #new sample, but small and more noisy @@ -114,56 +116,57 @@ #process.TFileService = cms.Service("TFileService", fileName = cms.string('omtfAnalysis1_1.root'), closeFileFast = cms.untracked.bool(True) ) ####OMTF Emulator -process.load('L1Trigger.L1TMuonOverlapPhase1.simOmtfDigis_cfi') +#process.load('L1Trigger.L1TMuonOverlapPhase1.simOmtfPhase2Digis_cfi') +process.load('L1Trigger.L1TMuonOverlapPhase2.simOmtfPhase2Digis_cfi') -process.simOmtfDigis.bxMin = cms.int32(0) -process.simOmtfDigis.bxMax = cms.int32(0) +process.simOmtfPhase2Digis.bxMin = cms.int32(0) +process.simOmtfPhase2Digis.bxMax = cms.int32(0) -process.simOmtfDigis.dumpResultToXML = cms.bool(False) -process.simOmtfDigis.eventCaptureDebug = cms.bool(False) +process.simOmtfPhase2Digis.dumpResultToXML = cms.bool(False) +process.simOmtfPhase2Digis.eventCaptureDebug = cms.bool(False) -process.simOmtfDigis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_template.xml") -#process.simOmtfDigis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_0x00012_oldSample_3_30Files_grouped1_classProb1_recalib.xml") -#process.simOmtfDigis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_0x00012_oldSample_3_30Files_grouped1_classProb11_recalib2.xml") -#process.simOmtfDigis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x0009_oldSample_3_10Files_classProb2.xml") -#process.simOmtfDigis.patternsXMLFiles = cms.VPSet(cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/GPs_parametrised_plus_v1.xml")), +process.simOmtfPhase2Digis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_template.xml") +#process.simOmtfPhase2Digis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_0x00012_oldSample_3_30Files_grouped1_classProb1_recalib.xml") +#process.simOmtfPhase2Digis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_0x00012_oldSample_3_30Files_grouped1_classProb11_recalib2.xml") +#process.simOmtfPhase2Digis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x0009_oldSample_3_10Files_classProb2.xml") +#process.simOmtfPhase2Digis.patternsXMLFiles = cms.VPSet(cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/GPs_parametrised_plus_v1.xml")), # cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/GPs_parametrised_minus_v1.xml")) ) -#process.simOmtfDigis.patternsXMLFiles = cms.VPSet(#cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/PatternsDisplaced_0x0007_minus.xml")), +#process.simOmtfPhase2Digis.patternsXMLFiles = cms.VPSet(#cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/PatternsDisplaced_0x0007_minus.xml")), # cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/PatternsDisplaced_0x0007_plus.xml")) # ) -#process.simOmtfDigis.patternGenerator = cms.string("modifyClassProb") -#process.simOmtfDigis.patternGenerator = cms.string("groupPatterns") -process.simOmtfDigis.patternGenerator = cms.string("patternGenFromStat") -#process.simOmtfDigis.patternGenerator = cms.string("") #does nothing except storing the patterns in the root file -#process.simOmtfDigis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_0x00011_oldSample_3_30Files_layerStat.root") -#process.simOmtfDigis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_layerStat_ExtraplMB1nadMB2_t14.root") -#process.simOmtfDigis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_layerStat_ExtraplMB1nadMB2FullAlgo_t16.root") -process.simOmtfDigis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_layerStat_" + versionIn + ".root") +#process.simOmtfPhase2Digis.patternGenerator = cms.string("modifyClassProb") +#process.simOmtfPhase2Digis.patternGenerator = cms.string("groupPatterns") +process.simOmtfPhase2Digis.patternGenerator = cms.string("patternGenFromStat") +#process.simOmtfPhase2Digis.patternGenerator = cms.string("") #does nothing except storing the patterns in the root file +#process.simOmtfPhase2Digis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_0x00011_oldSample_3_30Files_layerStat.root") +#process.simOmtfPhase2Digis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_layerStat_ExtraplMB1nadMB2_t14.root") +#process.simOmtfPhase2Digis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuonOverlapPhase1/test/expert/omtf/Patterns_layerStat_ExtraplMB1nadMB2FullAlgo_t16.root") +process.simOmtfPhase2Digis.patternsROOTFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_layerStat_" + versionIn + ".root") -process.simOmtfDigis.patternType = cms.string("GoldenPatternWithStat") -process.simOmtfDigis.generatePatterns = cms.bool(True) -#process.simOmtfDigis.optimisedPatsXmlFile = cms.string("Patterns_0x0009_oldSample_3_10Files_classProb3.xml") -#process.simOmtfDigis.optimisedPatsXmlFile = cms.string("Patterns_0x00012_oldSample_3_30Files_grouped1_classProb17_recalib2.xml") -#process.simOmtfDigis.optimisedPatsXmlFile = cms.string("Patterns_ExtraplMB1nadMB2FullAlgo_t16_classProb17_recalib2.xml") -process.simOmtfDigis.optimisedPatsXmlFile = cms.string("Patterns_" + versionOut + ".xml") -#process.simOmtfDigis.optimisedPatsXmlFile = cms.string("PatternsDisplaced_0x0007_p.xml") +process.simOmtfPhase2Digis.patternType = cms.string("GoldenPatternWithStat") +process.simOmtfPhase2Digis.generatePatterns = cms.bool(True) +#process.simOmtfPhase2Digis.optimisedPatsXmlFile = cms.string("Patterns_0x0009_oldSample_3_10Files_classProb3.xml") +#process.simOmtfPhase2Digis.optimisedPatsXmlFile = cms.string("Patterns_0x00012_oldSample_3_30Files_grouped1_classProb17_recalib2.xml") +#process.simOmtfPhase2Digis.optimisedPatsXmlFile = cms.string("Patterns_ExtraplMB1nadMB2FullAlgo_t16_classProb17_recalib2.xml") +process.simOmtfPhase2Digis.optimisedPatsXmlFile = cms.string("Patterns_" + versionOut + ".xml") +#process.simOmtfPhase2Digis.optimisedPatsXmlFile = cms.string("PatternsDisplaced_0x0007_p.xml") -process.simOmtfDigis.rpcMaxClusterSize = cms.int32(3) -process.simOmtfDigis.rpcMaxClusterCnt = cms.int32(2) -process.simOmtfDigis.rpcDropAllClustersIfMoreThanMax = cms.bool(True) +process.simOmtfPhase2Digis.rpcMaxClusterSize = cms.int32(3) +process.simOmtfPhase2Digis.rpcMaxClusterCnt = cms.int32(2) +process.simOmtfPhase2Digis.rpcDropAllClustersIfMoreThanMax = cms.bool(True) -process.simOmtfDigis.goldenPatternResultFinalizeFunction = cms.int32(3) #valid values are 0, 1, 2, 3, 5 -process.simOmtfDigis.lctCentralBx = cms.int32(6);#<<<<<<<<<<<<<<< Date: Thu, 6 Nov 2025 14:56:33 +0100 Subject: [PATCH 02/12] Added class OmtfProcessorPhase2, implemented phase-2 eta scale for stubs added valueP2Scale i.e. option ot use the phase-2 GMT eta scale IProcessorEmulator removed setAssignQualityFunction. OMTFProcessor.h assignQualityPhase1 changed to assignQuality. Removed ptAssignment. PatternGenerator.cc removed reCalibratePt(). PtAssignmentBase renamed to MlModelBase and moved to L1Trigger/L1TMuonOverlapPhase2. PtAssignmentNNRegression.h renamed to NNRegression.h. Added class OmtfProcessorPhase2. OmtfEmulation added method beginRun. A few methods and fields moved to OmtfProcessorPhase2. L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_cfi.py hwToLogicLayer_0x0210.xml - added ref hits from the processors' overlap regions, to improve the efficiency at the processor boundaries. Patterns_ExtraplMB1andMB2RFixedP_ValueP1Scale_DT_2_2_2_t35__classProb17.xml - pattern without pt recalibration, besides the same as the previous version (i.e. Patterns_ExtraplMB1andMB2RFixedP_ValueP1Scale_DT_2_2_2_t35__classProb17_recalib2.xml). --- .../interface/Omtf/IProcessorEmulator.h | 6 +- .../interface/Omtf/OMTFConfiguration.h | 2 +- .../interface/Omtf/OMTFProcessor.h | 17 +- .../interface/Omtf/OMTFReconstruction.h | 2 +- .../interface/ProcConfigurationBase.h | 5 +- .../src/Omtf/GhostBusterPreferRefDt.cc | 4 +- .../src/Omtf/OMTFConfiguration.cc | 19 +- .../src/Omtf/OMTFProcessor.cc | 28 +- .../src/Omtf/OMTFReconstruction.cc | 1 + .../src/Omtf/OmtfAngleConverter.cc | 6 +- .../src/Omtf/PtAssignmentBase.cc | 10 - .../src/ProcConfigurationBase.cc | 2 + .../src/Tools/PatternGenerator.cc | 2 +- .../test/runMuonOverlap_run3_data.py | 73 ++-- .../interface/MlModelBase.h} | 13 +- ...ssignmentNNRegression.h => NNRegression.h} | 8 +- .../interface/OmtfEmulation.h | 24 +- .../interface/OmtfProcessorPhase2.h | 52 +++ .../python/simOmtfPhase2Digis_cfi.py | 10 +- .../L1TMuonOverlapPhase2/src/MlModelBase.cc | 10 + ...ignmentNNRegression.cc => NNRegression.cc} | 56 +-- .../L1TMuonOverlapPhase2/src/OmtfEmulation.cc | 300 ++------------ .../src/OmtfPhase2AngleConverter.cc | 5 +- .../src/OmtfProcessorPhase2.cc | 373 ++++++++++++++++++ ...OverlapPatternGeneratorClassProb_phase2.py | 2 +- 25 files changed, 592 insertions(+), 438 deletions(-) delete mode 100644 L1Trigger/L1TMuonOverlapPhase1/src/Omtf/PtAssignmentBase.cc rename L1Trigger/{L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h => L1TMuonOverlapPhase2/interface/MlModelBase.h} (63%) rename L1Trigger/L1TMuonOverlapPhase2/interface/{PtAssignmentNNRegression.h => NNRegression.h} (73%) create mode 100644 L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h create mode 100644 L1Trigger/L1TMuonOverlapPhase2/src/MlModelBase.cc rename L1Trigger/L1TMuonOverlapPhase2/src/{PtAssignmentNNRegression.cc => NNRegression.cc} (93%) create mode 100644 L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h index 4f685110ad287..0efaf399bece6 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/IProcessorEmulator.h @@ -33,6 +33,8 @@ class IProcessorEmulator { virtual AlgoMuons ghostBust(AlgoMuons refHitCands, int charge = 0) = 0; + virtual FinalMuons getFinalMuons(unsigned int iProcessor, l1t::tftype mtfType, const AlgoMuons& gbCandidates) = 0; + virtual std::vector getRegionalMuonCands(unsigned int iProcessor, l1t::tftype mtfType, FinalMuons& finalMuons) = 0; @@ -43,10 +45,6 @@ class IProcessorEmulator { OMTFinputMaker* inputMaker, std::vector >& observers) = 0; - - virtual void setAssignQualityFunction( - std::function asignQuality) = 0; - virtual void printInfo() const = 0; }; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h index a2342416a0c21..a48c8feb2ca9e 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h @@ -141,7 +141,7 @@ class OMTFConfiguration : public ProcConfigurationBase { double ptUnit = 0.5; // GeV/unit ///uGMT pt scale conversion //TODO refactor to omtfPtToGev - double hwPtToGev(int hwPt) const override { return (hwPt - 1.) * ptUnit; } + 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); } diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h index 46f377da913d1..c9a883fc5431b 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h @@ -100,9 +100,9 @@ class OMTFProcessor : public ProcessorBase, public IProcessor return ghostBuster->select(refHitCands, charge); } - void assignQualityPhase1(AlgoMuons::value_type& algoMuon); + void assignQuality(AlgoMuons::value_type& algoMuon); - FinalMuons getFinalMuons(unsigned int iProcessor, l1t::tftype mtfType, const AlgoMuons& gbCandidates); + FinalMuons getFinalMuons(unsigned int iProcessor, l1t::tftype mtfType, const AlgoMuons& gbCandidates) override; void convertToGmtScalesPhase1(unsigned int iProcessor, l1t::tftype mtfType, FinalMuonPtr& finalMuon); @@ -116,14 +116,6 @@ 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; } - - - void setAssignQualityFunction( - std::function assignQuality) override { - this->assignQuality = assignQuality; - } - FinalMuons run(unsigned int iProcessor, l1t::tftype mtfType, int bx, @@ -150,11 +142,6 @@ class OMTFProcessor : public ProcessorBase, public IProcessor std::unique_ptr ghostBuster; - std::function assignQuality; - - //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..950e9696a8252 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h @@ -43,7 +43,7 @@ class OMTFReconstruction { void endJob(); - void beginRun(edm::Run const& run, + virtual void beginRun(edm::Run const& run, edm::EventSetup const& iSetup, edm::ESGetToken& omtfParamsEsToken, const MuonGeometryTokens& muonGeometryTokens, diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h index 05567f8e3c66a..c202c142ff11e 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h @@ -97,11 +97,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; } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc index aaf5ae5d56e92..a70cdcb0d4b04 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc @@ -195,8 +195,8 @@ 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(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/OMTFConfiguration.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc index e649971b493bf..aebfa92afb7ba 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc @@ -214,14 +214,6 @@ void OMTFConfiguration::configure(const L1TMuonOverlapParams *omtfParams) { setGhostBusterType("byRefLayer"); } - - //phase-2 - if (fwVersion() >= 0x0210) { - //like in DataFormats/L1TMuonPhase2/interface/Constants.h - const int BITSETA = 13; - const float LSBeta = 2. * M_PI / pow(2, BITSETA); - etaUnit_ = LSBeta; - } } void OMTFConfiguration::configureFromEdmParameterSet(const edm::ParameterSet &edmParameterSet) { @@ -311,6 +303,15 @@ void OMTFConfiguration::configureFromEdmParameterSet(const edm::ParameterSet &ed 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; + } } /////////////////////////////////////////////// @@ -603,5 +604,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 8e1ac7ef3fecd..412385ecb11ff 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc @@ -72,10 +72,6 @@ void OMTFProcessor::init(const edm::ParameterSet& edmCfg, edm edm::LogVerbatim("OMTFReconstruction") << "setting GhostBuster" << std::endl; } - assignQuality = [&](AlgoMuons::value_type& algoMuon) { - return this->assignQualityPhase1(algoMuon); - }; - edm::LogVerbatim("OMTFReconstruction") << "fwVersion 0x" << hex << this->myOmtfConfig->fwVersion() << std::endl; useStubQualInExtr = this->myOmtfConfig->useStubQualInExtr(); @@ -104,7 +100,7 @@ void OMTFProcessor::init(const edm::ParameterSet& edmCfg, edm } template -void OMTFProcessor::assignQualityPhase1(AlgoMuons::value_type& algoMuon) { +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 @@ -761,7 +757,7 @@ void OMTFProcessor::processInput(unsigned int iProcessor, LogTrace("l1tOmtfEventPrint") << "\n" << __FUNCTION__ << ":" << __LINE__ << " extrapolating from layer " << refLayerLogicNum - << " - iRefLayer " << aRefHitDef.iRefLayer << " to layer " << iLayer << " stub " << targetStub + << " - iRefLayer " << aRefHitDef.iRefLayer << " to layer " << iLayer << " stub " << *targetStub << " value " << extrapolatedPhi[iStub] << std::endl; if (this->myOmtfConfig->getDumpResultToXML()) { @@ -899,22 +895,15 @@ FinalMuons OMTFProcessor::run(unsigned int iProcessor, //LogTrace("l1tOmtfEventPrint")<<"processInput "; t.report(); AlgoMuons algoCandidates = sortResults(iProcessor, mtfType); - for (auto& algoMuon : algoCandidates) { - assignQuality(algoMuon); - } - - if (ptAssignment) { - for (auto& algoMuon : algoCandidates) { - if (algoMuon->isValid()) { - ptAssignment->run(algoMuon, observers); - } - } - } - //LogTrace("l1tOmtfEventPrint")<<"sortResults "; t.report(); // perform GB //watch out: etaBits2HwEta is used in the ghostBust to convert the AlgoMuons eta, it affect algoCandidates as they are pointers AlgoMuons gbCandidates = ghostBust(algoCandidates); + + //assignQuality must be called after ghostBust, because eta is set there + for (auto& gbCandidate : gbCandidates) { + assignQuality(gbCandidate); + } //LogTrace("l1tOmtfEventPrint")<<"ghostBust"; t.report(); @@ -924,9 +913,6 @@ FinalMuons OMTFProcessor::run(unsigned int iProcessor, finalMuon->setBx(bx); } - // fill RegionalMuonCand colleciton - //std::vector candMuons = getFinalcandidates(iProcessor, mtfType, gbCandidates); - for (auto& obs : observers) { obs->observeProcesorEmulation(iProcessor, mtfType, input, algoCandidates, gbCandidates, finalMuons); } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc index 14cd72a00a4e0..64c23a036ac71 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc @@ -103,6 +103,7 @@ void OMTFReconstruction::beginRun(edm::Run const& run, //patterns from the edm::EventSetup are reloaded every beginRun //therefore OMTFProcessor is re-created here + //TODO would be better to just update the patterns in the existing OMTFProcessor edm::LogVerbatim("OMTFReconstruction") << "getting patterns from EventSetup" << std::endl; if (processorType == "OMTFProcessor") { omtfProc = std::make_unique >( diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc index e67b542ca1f09..e0cdb65585d04 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc @@ -149,7 +149,7 @@ int OmtfAngleConverter::getGlobalEta(const DTChamberId dTChamberId, if (config->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::bits) return OMTFConfiguration::eta2Bits(abs(iEta)); - else if (config->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::valueP1Scale) + else if (config->getStubEtaEncoding() >= ProcConfigurationBase::StubEtaEncoding::valueP1Scale) return abs(iEta); return 0; @@ -213,7 +213,7 @@ int OmtfAngleConverter::getGlobalEta(unsigned int rawid, const CSCCorrelatedLCTD if (config->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::bits) return OMTFConfiguration::eta2Bits(abs(etaKeyWG2Code(id, keyWG))); - else if (config->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::valueP1Scale) { + else if (config->getStubEtaEncoding() >= ProcConfigurationBase::StubEtaEncoding::valueP1Scale) { return config->etaToHwEta(abs(gpWg.eta())); } else { return 0; @@ -233,7 +233,7 @@ int OmtfAngleConverter::getGlobalEtaRpc(unsigned int rawid, const unsigned int & if (config->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::bits) return OMTFConfiguration::eta2Bits(abs(etaVal2Code(gp.eta()))); - else if (config->getStubEtaEncoding() == ProcConfigurationBase::StubEtaEncoding::valueP1Scale) + else if (config->getStubEtaEncoding() >= ProcConfigurationBase::StubEtaEncoding::valueP1Scale) return abs(config->etaToHwEta((gp.eta()))); return 0; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/PtAssignmentBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/PtAssignmentBase.cc deleted file mode 100644 index d732d25518d6f..0000000000000 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/PtAssignmentBase.cc +++ /dev/null @@ -1,10 +0,0 @@ -/* - * PtAssignmentBase.cc - * - * Created on: Mar 16, 2020 - * Author: kbunkow - */ - -#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h" - -PtAssignmentBase::~PtAssignmentBase() {} diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/ProcConfigurationBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/ProcConfigurationBase.cc index 8e54b3b69c2e9..9ac334df6336d 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/ProcConfigurationBase.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/ProcConfigurationBase.cc @@ -68,6 +68,8 @@ void ProcConfigurationBase::configureFromEdmParameterSet(const edm::ParameterSet stubEtaEncoding = StubEtaEncoding::bits; else if (stubEtaEncodingStr == "valueP1Scale") stubEtaEncoding = StubEtaEncoding::valueP1Scale; + else if (stubEtaEncodingStr == "valueP2Scale") + stubEtaEncoding = StubEtaEncoding::valueP2Scale; else throw cms::Exception(std::string("ProcConfigurationBase::configureFromEdmParameterSet: stubEtaEncoding ") + stubEtaEncodingStr + "is not correct"); diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/PatternGenerator.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/PatternGenerator.cc index 876d438114036..bb54762cc7eda 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/PatternGenerator.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/PatternGenerator.cc @@ -423,7 +423,7 @@ void PatternGenerator::endJob() { //groupPatterns(); IMPORTANT don't call grouping here, just set the groups above!!!! - reCalibratePt(); + //reCalibratePt(); this->writeLayerStat = true; } diff --git a/L1Trigger/L1TMuonOverlapPhase1/test/runMuonOverlap_run3_data.py b/L1Trigger/L1TMuonOverlapPhase1/test/runMuonOverlap_run3_data.py index 03b24725d5d4c..6c54577b297db 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/test/runMuonOverlap_run3_data.py +++ b/L1Trigger/L1TMuonOverlapPhase1/test/runMuonOverlap_run3_data.py @@ -1,52 +1,55 @@ # -*- coding: utf-8 -*- import FWCore.ParameterSet.Config as cms -process = cms.Process("L1TMuonEmulation") +from Configuration.Eras.Era_Run3_2025_cff import Run3_2025 +process = cms.Process("L1TMuonEmulation", Run3_2025) import os import sys -loadConfigFrom_sqlite_file = True +loadConfigFrom_sqlite_file = False -loadConfigFrom_fakeOmtfParams = False +loadConfigFrom_fakeOmtfParams = True process.load("FWCore.MessageLogger.MessageLogger_cfi") -process.MessageLogger = cms.Service("MessageLogger", - # suppressInfo = cms.untracked.vstring('AfterSource', 'PostModule'), - destinations=cms.untracked.vstring( - # 'detailedInfo', - # 'critical', +verbose = False +log_threshold = 'INFO' + +if verbose: + process.MessageLogger = cms.Service("MessageLogger", + #suppressInfo = cms.untracked.vstring('AfterSource', 'PostModule'), + destinations = cms.untracked.vstring( + #'detailedInfo', + #'critical', #'cout', #'cerr', - 'omtfEventPrint' + 'omtfEventPrint' ), - categories=cms.untracked.vstring('l1tOmtfEventPrint', 'OMTFReconstruction'), #, 'FwkReport' - # cout=cms.untracked.PSet( - # threshold=cms.untracked.string('INFO'), - # default=cms.untracked.PSet(limit=cms.untracked.int32(0)), - # # INFO = cms.untracked.int32(0), - # # DEBUG = cms.untracked.int32(0), - # l1tOmtfEventPrint=cms.untracked.PSet(limit=cms.untracked.int32(1000000000)), - # OMTFReconstruction=cms.untracked.PSet(limit=cms.untracked.int32(1000000000)), - # #FwkReport=cms.untracked.PSet(reportEvery = cms.untracked.int32(50) ), - # ), - - omtfEventPrint = cms.untracked.PSet( + categories = cms.untracked.vstring('l1tOmtfEventPrint', 'OMTFReconstruction', 'l1MuonAnalyzerOmtf'), + omtfEventPrint = cms.untracked.PSet( filename = cms.untracked.string('log_MuonOverlap_run3_data'), extension = cms.untracked.string('.txt'), - threshold = cms.untracked.string('INFO'), + threshold = cms.untracked.string(log_threshold), default = cms.untracked.PSet( limit = cms.untracked.int32(0) ), #INFO = cms.untracked.int32(0), #DEBUG = cms.untracked.int32(0), l1tOmtfEventPrint = cms.untracked.PSet( limit = cms.untracked.int32(1000000000) ), - OMTFReconstruction = cms.untracked.PSet( limit = cms.untracked.int32(1000000000) ) + OMTFReconstruction = cms.untracked.PSet( limit = cms.untracked.int32(1000000000) ), + l1MuonAnalyzerOmtf = cms.untracked.PSet( limit = cms.untracked.int32(1000000000) ) ), - debugModules=cms.untracked.vstring('simOmtfDigis') - # debugModules = cms.untracked.vstring('*') + debugModules = cms.untracked.vstring('simOmtfDigis', 'L1MuonAnalyzerOmtf', 'CalibratedDigis') + #debugModules = cms.untracked.vstring('*') ) -#process.MessageLogger.cerr.FwkReport.reportEvery = cms.untracked.int32(50) -process.options = cms.untracked.PSet(wantSummary=cms.untracked.bool(False), - # SkipEvent = cms.untracked.vstring('ProductNotFound') + #process.MessageLogger.cerr.FwkReport.reportEvery = cms.untracked.int32(100) +if not verbose: + process.MessageLogger.cerr.FwkReport.reportEvery = cms.untracked.int32(10000) + process.MessageLogger.cerr.threshold = cms.untracked.string('INFO') + process.MessageLogger.cerr.l1tOmtfEventPrint = cms.untracked.PSet( limit = cms.untracked.int32(1000000000) ) + process.MessageLogger.cerr.OMTFReconstruction = cms.untracked.PSet( limit = cms.untracked.int32(1000000000) ) + process.MessageLogger.cerr.l1MuonAnalyzerOmtf = cms.untracked.PSet( limit = cms.untracked.int32(1000000000) ) + + process.options = cms.untracked.PSet(wantSummary = cms.untracked.bool(False), + #SkipEvent = cms.untracked.vstring('ProductNotFound') ) process.source = cms.Source('PoolSource', @@ -59,9 +62,10 @@ #'/store/express/Commissioning2021/ExpressCosmics/FEVT/Express-v1/000/344/566/00000/19ef107a-4cd9-4df0-ba93-dbfbab8df1cb.root', #'/store/express/Commissioning2021/ExpressCosmics/FEVT/Express-v1/000/342/094/00000/038c179a-d2ce-45f0-a7d5-8b2d40017042.root', # only DT, fw 0x0008 - '/store/express/Commissioning2021/ExpressCosmics/FEVT/Express-v1/000/344/266/00000/db2cfbdd-5edf-4ee4-aab0-5bdba105728d.root' #DT and RPC fw 0x0008 + #'/store/express/Commissioning2021/ExpressCosmics/FEVT/Express-v1/000/344/266/00000/db2cfbdd-5edf-4ee4-aab0-5bdba105728d.root' #DT and RPC fw 0x0008 #'/store/express/Commissioning2021/ExpressCosmics/FEVT/Express-v1/000/344/566/00000/19ef107a-4cd9-4df0-ba93-dbfbab8df1cb.root' #'/store/express/Commissioning2021/ExpressCosmics/FEVT/Express-v1/000/347/053/00000/7b486245-96ea-4b7c-9fe7-76c957968785.root' #RPC noise only + 'file:/eos/home-k/kbunkow/cms_data/run3_data/Run2025G_398240_Muon0_raw.root' ), ) @@ -70,17 +74,19 @@ # import of standard configurations process.load('Configuration.StandardSequences.Services_cff') process.load('SimGeneral.HepPDTESSource.pythiapdt_cfi') -process.load('Configuration.Geometry.GeometryExtended2017Reco_cff') +#process.load('Configuration.Geometry.GeometryExtended2017Reco_cff') +process.load("Configuration.StandardSequences.GeometryRecoDB_cff") process.load('Configuration.StandardSequences.MagneticField_AutoFromDBCurrent_cff') process.load('Configuration.StandardSequences.EndOfProcess_cff') process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') +process.load("Configuration.StandardSequences.RawToDigi_Data_cff") #process.load('Configuration.StandardSequences.RawToDigi_Data_cff') #process.load('EventFilter.L1TRawToDigi.omtfStage2Digis_cfi') #unpacker #process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') from Configuration.AlCa.GlobalTag import GlobalTag -process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:run2_data', '') +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:run3_data', '') #process.GlobalTag = GlobalTag(process.GlobalTag, '113X_dataRun3_Prompt_v3', '') #process.GlobalTag = GlobalTag(process.GlobalTag, '102X_upgrade2018_realistic_v16', '') @@ -88,7 +94,7 @@ if loadConfigFrom_fakeOmtfParams : ####Event Setup Producer - process.load('L1Trigger.L1TMuonOverlapPhase1.fakeOmtfParams_cff') + process.load('L1Trigger.L1TMuonOverlapPhase1.fakeOmtfParams_extrapolSimple_cff') #process.omtfParams.configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0008.xml") process.esProd = cms.EDAnalyzer("EventSetupRecordDataGetter", @@ -172,6 +178,7 @@ #+ process.dumpED #+ process.dumpES ) + print("Loading OMTF configuration from fakeOmtfParams_cff") else : process.L1TMuonSeq = cms.Sequence( process.omtfStage2Digis + process.simOmtfDigis @@ -186,5 +193,5 @@ ) #process.output_step = cms.EndPath(process.out) -#process.schedule = cms.Schedule(process.L1TMuonPath) +process.schedule = cms.Schedule(process.L1TMuonPath) #process.schedule.extend([process.output_step]) diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h b/L1Trigger/L1TMuonOverlapPhase2/interface/MlModelBase.h similarity index 63% rename from L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h rename to L1Trigger/L1TMuonOverlapPhase2/interface/MlModelBase.h index a961fc4e0b4f1..84ccf99ea2c63 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/MlModelBase.h @@ -5,20 +5,19 @@ * Author: kbunkow */ -#ifndef L1T_OmtfP1_PTASSIGNMENTBASE_H_ -#define L1T_OmtfP1_PTASSIGNMENTBASE_H_ +#ifndef L1T_OmtfP2_MlModelBase_H_ +#define L1T_OmtfP2_MlModelBase_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 { +class MlModelBase { public: - PtAssignmentBase(const OMTFConfiguration* omtfConfig) : omtfConfig(omtfConfig) {} - virtual ~PtAssignmentBase(); + MlModelBase(const OMTFConfiguration* omtfConfig) : omtfConfig(omtfConfig) {} + virtual ~MlModelBase(); virtual void run(AlgoMuons::value_type& algoMuon, std::vector >& observers) = 0; @@ -27,4 +26,4 @@ class PtAssignmentBase { const OMTFConfiguration* omtfConfig = nullptr; }; -#endif /* L1T_OmtfP1_PTASSIGNMENTBASE_H_ */ +#endif /* L1T_OmtfP2_MlModelBase_H_ */ diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/PtAssignmentNNRegression.h b/L1Trigger/L1TMuonOverlapPhase2/interface/NNRegression.h similarity index 73% rename from L1Trigger/L1TMuonOverlapPhase2/interface/PtAssignmentNNRegression.h rename to L1Trigger/L1TMuonOverlapPhase2/interface/NNRegression.h index 5fa0441f8ba8d..5fbb83cfb2592 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/PtAssignmentNNRegression.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/NNRegression.h @@ -8,15 +8,15 @@ #ifndef L1Trigger_L1TMuonOverlapPhase2_PtAssigmentNNRegression_h #define L1Trigger_L1TMuonOverlapPhase2_PtAssigmentNNRegression_h -#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/PtAssignmentBase.h" +#include "L1Trigger/L1TMuonOverlapPhase2/interface/MlModelBase.h" #include "L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointCommon.h" -class PtAssignmentNNRegression : public PtAssignmentBase { +class NNRegression : public MlModelBase { public: - PtAssignmentNNRegression(const edm::ParameterSet& edmCfg, + NNRegression(const edm::ParameterSet& edmCfg, const OMTFConfiguration* omtfConfig, std::string networkFile); - ~PtAssignmentNNRegression() override = default; + ~NNRegression() override = default; void run(AlgoMuons::value_type& algoMuon, std::vector >& observers) override; diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h index 6921160371964..dd21ad27cea79 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h @@ -14,6 +14,7 @@ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h" #include "L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h" #include "L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h" +#include "L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h" class OmtfEmulation : public OMTFReconstruction { public: @@ -25,11 +26,12 @@ class OmtfEmulation : public OMTFReconstruction { ~OmtfEmulation() override = default; - void addObservers(const MuonGeometryTokens& muonGeometryTokens, - const edm::ESGetToken& magneticFieldEsToken, - const edm::ESGetToken& propagatorEsToken) override; - - //RegionalMuonCandBxCollection is filled for backward compatibility of analyzers etc. + void beginRun(edm::Run const& run, + edm::EventSetup const& iSetup, + edm::ESGetToken& omtfParamsEsToken, + const MuonGeometryTokens& muonGeometryTokens, + const edm::ESGetToken& magneticFieldEsToken, + const edm::ESGetToken& propagatorEsToken) override; struct OmtfOutptuCollections { std::unique_ptr constrSaMuons; //ip constrained candidates @@ -42,18 +44,8 @@ class OmtfEmulation : public OMTFReconstruction { private: MuStubsPhase2InputTokens& muStubsPhase2InputTokens; - unique_ptr ptAssignment; - - std::map firedLayersToQuality; - - void assignQualityPhase2(AlgoMuons::value_type& algoMuon); - - void convertToGmtScalesPhase2(unsigned int iProcessor, l1t::tftype mtfType, FinalMuonPtr& finalMuon); - l1t::SAMuonCollection getSAMuons(unsigned int iProcessor, - l1t::tftype mtfType, - FinalMuons& finalMuons, - bool costrainedPt); + OmtfProcessorPhase2 omtfProcPhase2; }; #endif /* L1Trigger_L1TMuonOverlapPhase2_OmtfEmulation_h */ diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h new file mode 100644 index 0000000000000..eaa8bcdfd5487 --- /dev/null +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h @@ -0,0 +1,52 @@ +/* + * OmtfProcessorPhase2.h + * + * Created on: Oct 29, 2025 + * Author: kbunkow + */ + +#ifndef L1Trigger_L1TMuonOverlapPhase2_OMTFPROCESSORPHASE2_H_ +#define L1Trigger_L1TMuonOverlapPhase2_OMTFPROCESSORPHASE2_H_ + + +#include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h" +#include "L1Trigger/L1TMuonOverlapPhase2/interface/MlModelBase.h" + +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" + +class OmtfProcessorPhase2 { +public: + //Composition is used over inheritance here, primarily because the OMTFProcessor is a template class and is constructed in OMTFReconstruction + OmtfProcessorPhase2(const OMTFConfiguration* omtfConfig, const unique_ptr& omtfProc); + + virtual ~OmtfProcessorPhase2(); + + void beginRun(const edm::ParameterSet& edmParameterSet, edm::EventSetup const& iSetup); + + FinalMuons run(unsigned int iProcessor, + l1t::tftype mtfType, + int bx, + OMTFinputMaker* inputMaker, + std::vector >& observers); + + void assignQualityPhase2(AlgoMuons::value_type& algoMuon); + + void convertToGmtScalesPhase2(unsigned int iProcessor, l1t::tftype mtfType, FinalMuonPtr& finalMuon); + + l1t::SAMuonCollection getSAMuons(unsigned int iProcessor, + l1t::tftype mtfType, + FinalMuons& finalMuons, + bool costrainedPt); + +private: + const OMTFConfiguration* omtfConfig; + + //reference to the unique_ptr is used here, because the omtfProc might be re-constructed in the OMTFReconstruction each run + const unique_ptr& omtfProc; + + unique_ptr mlModel; + + std::map firedLayersToQuality; +}; + +#endif /* L1Trigger_L1TMuonOverlapPhase2_OMTFPROCESSORPHASE2_H_ */ diff --git a/L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_cfi.py b/L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_cfi.py index a88f8422474dc..0379d2aa34d50 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_cfi.py +++ b/L1Trigger/L1TMuonOverlapPhase2/python/simOmtfPhase2Digis_cfi.py @@ -11,10 +11,12 @@ srcDTThPhase2 = cms.InputTag('dtTriggerPhase2PrimitiveDigis'), ## XML / PATTERNS file: - configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0209.xml"), + #configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0209.xml"), + configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0210.xml"), extrapolFactorsFilename = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/ExtrapolationFactors_ExtraplMB1nadMB2_R_EtaValueP1Scale_t35.xml"), - patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_ExtraplMB1andMB2RFixedP_ValueP1Scale_DT_2_2_2_t35__classProb17_recalib2.xml"), - + #patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_ExtraplMB1andMB2RFixedP_ValueP1Scale_DT_2_2_2_t35__classProb17_recalib2.xml"), #pt defined at approx 80% of the efficiency curve + patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_ExtraplMB1andMB2RFixedP_ValueP1Scale_DT_2_2_2_t35__classProb17.xml"), #pt defined at approx 50% of the efficiency curve + dumpResultToXML = cms.bool(False), dumpDetailedResultToXML = cms.bool(False), XMLDumpFileName = cms.string("TestEvents.xml"), @@ -44,7 +46,7 @@ dtPhiBUnitsRad = cms.int32(1024), #2048 is the orginal phase2 scale, 512 is the phase1 scale - stubEtaEncoding = cms.string("valueP1Scale"), #TODO change to valueP1Scale when InputMakerPhase2 is modifiwed + stubEtaEncoding = cms.string("valueP2Scale"), #TODO change to valueP1Scale when InputMakerPhase2 is modifiwed rpcMaxClusterSize = cms.int32(3), rpcMaxClusterCnt = cms.int32(2), diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/MlModelBase.cc b/L1Trigger/L1TMuonOverlapPhase2/src/MlModelBase.cc new file mode 100644 index 0000000000000..04f29f7d3fbbc --- /dev/null +++ b/L1Trigger/L1TMuonOverlapPhase2/src/MlModelBase.cc @@ -0,0 +1,10 @@ +/* + * PtAssignmentBase.cc + * + * Created on: Mar 16, 2020 + * Author: kbunkow + */ + +#include "L1Trigger/L1TMuonOverlapPhase2/interface/MlModelBase.h" + +MlModelBase::~MlModelBase() {} diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/PtAssignmentNNRegression.cc b/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc similarity index 93% rename from L1Trigger/L1TMuonOverlapPhase2/src/PtAssignmentNNRegression.cc rename to L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc index 501b4ba69efaf..e60af4bd1eda8 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/PtAssignmentNNRegression.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc @@ -11,7 +11,6 @@ #include "DataFormats/MuonDetId/interface/CSCDetId.h" -#include "L1Trigger/L1TMuonOverlapPhase2/interface/PtAssignmentNNRegression.h" #include "L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegressionMultipleOutputs.h" #include "DataFormats/L1TMuonPhase2/interface/Constants.h" #include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" @@ -19,6 +18,7 @@ #include #include #include +#include #include #include @@ -89,10 +89,10 @@ namespace lutNN { LutNetworkFP; } // namespace lutNN -PtAssignmentNNRegression::PtAssignmentNNRegression(const edm::ParameterSet& edmCfg, +NNRegression::NNRegression(const edm::ParameterSet& edmCfg, const OMTFConfiguration* omtfConfig, std::string networkFile) - : PtAssignmentBase(omtfConfig), lutNetworkFP(make_unique()) { + : MlModelBase(omtfConfig), lutNetworkFP(make_unique()) { std::ifstream ifs(networkFile); edm::LogImportant("OMTFReconstruction") @@ -354,7 +354,7 @@ bool omtfHitToEventInput(OmtfHit& hit, std::vector& inputs, unsigned int return false; } -void PtAssignmentNNRegression::run(AlgoMuons::value_type& algoMuon, +void NNRegression::run(AlgoMuons::value_type& algoMuon, std::vector>& observers) { LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << std::endl; auto& gpResult = algoMuon->getGpResultConstr(); @@ -437,10 +437,9 @@ void PtAssignmentNNRegression::run(AlgoMuons::value_type& algoMuon, LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << std::endl; int charge = nnResult[2] >= 0 ? 1 : -1; - double pt = std::copysign(nnResult.at(0), charge); LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << " nnResult.at(0) " << nnResult.at(0) - << " nnResult.at(1) " << nnResult.at(1) << " pt " << pt << std::endl; + << " nnResult.at(1) " << nnResult.at(1) << std::endl; //algoMuon->setPtNN(omtfConfig->ptGevToHw(nnResult.at(0))); //auto calibratedHwPt = lutNetworkFP->getCalibratedHwPt(); @@ -451,8 +450,9 @@ void PtAssignmentNNRegression::run(AlgoMuons::value_type& algoMuon, //here the pts are GeV double omtfPt = omtfConfig->hwPtToGev(algoMuon->getPtConstr()); - double combinedPt = nnResult.at(0); - if( (nnResult.at(0) - omtfPt) > 0.75 * omtfPt) + double nnPt = nnResult.at(0); + double combinedPt = nnPt; + if( nnPt < 2.5 || (nnResult[0] - omtfPt) > 0.75 * omtfPt) combinedPt = omtfPt; algoMuon->setPtNNConstr(combinedPt); @@ -465,31 +465,31 @@ void PtAssignmentNNRegression::run(AlgoMuons::value_type& algoMuon, algoMuon->setNnOutputs(nnResult); - //TODO add some if here, such that the property_tree is filled only when needed - boost::property_tree::ptree procDataTree; - for (unsigned int i = 0; i < inputs.size(); i++) { - auto& inputTree = procDataTree.add("input", ""); - inputTree.add(".num", i); - inputTree.add(".val", inputs[i]); - } - - std::ostringstream ostr; + if (omtfConfig->getDumpResultToXML()) { + boost::property_tree::ptree procDataTree; + for (unsigned int i = 0; i < inputs.size(); i++) { + auto& inputTree = procDataTree.add("input", ""); + inputTree.add(".num", i); + inputTree.add(".val", inputs[i]); + } - for (unsigned int i = 0; i < nnResult.size(); i++) { - auto& inputTree = procDataTree.add("output", ""); - ostr.str(""); - ostr << std::fixed << std::setprecision(19) << nnResult.at(i); + std::ostringstream ostr; - inputTree.add(".num", i); - inputTree.add(".val", ostr.str()); - } + for (unsigned int i = 0; i < nnResult.size(); i++) { + auto& inputTree = procDataTree.add("output", ""); + ostr.str(""); + ostr << std::fixed << std::setprecision(19) << nnResult.at(i); - //procDataTree.add("calibratedHwPt..val", calibratedHwPt); + inputTree.add(".num", i); + inputTree.add(".val", ostr.str()); + } + //procDataTree.add("calibratedHwPt..val", calibratedHwPt); - procDataTree.add("hwSign..val", algoMuon->getChargeNNConstr() < 0 ? 1 : 0); + procDataTree.add("hwSign..val", algoMuon->getChargeNNConstr() < 0 ? 1 : 0); - for (auto& obs : observers) - obs->addProcesorData("regressionNN", procDataTree); + for (auto& obs : observers) + obs->addProcesorData("regressionNN", procDataTree); + } //event.print(); /* diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfEmulation.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfEmulation.cc index 20ffb11c6f1f0..f4ed6eafb2416 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfEmulation.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfEmulation.cc @@ -9,7 +9,6 @@ #include "L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h" #include "L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h" -#include "L1Trigger/L1TMuonOverlapPhase2/interface/PtAssignmentNNRegression.h" #include "DataFormats/L1TMuonPhase2/interface/Constants.h" @@ -20,7 +19,7 @@ OmtfEmulation::OmtfEmulation(const edm::ParameterSet& edmParameterSet, MuStubsInputTokens& muStubsInputTokens, MuStubsPhase2InputTokens& muStubsPhase2InputTokens) - : OMTFReconstruction(edmParameterSet, muStubsInputTokens), muStubsPhase2InputTokens(muStubsPhase2InputTokens) {} + : OMTFReconstruction(edmParameterSet, muStubsInputTokens), muStubsPhase2InputTokens(muStubsPhase2InputTokens), omtfProcPhase2(omtfConfig.get(), omtfProc) {} void OmtfEmulation::beginJob() { if (edmParameterSet.exists("usePhase2DTPrimitives") && edmParameterSet.getParameter("usePhase2DTPrimitives")) { @@ -33,266 +32,18 @@ void OmtfEmulation::beginJob() { inputMaker = std::make_unique( edmParameterSet, muStubsInputTokens, omtfConfig.get(), std::make_unique()); } - - //.....................rrrrrrrrccccdddddd - //.....................765432109876543210 - firedLayersToQuality[0b000000110000000011] = 1; - firedLayersToQuality[0b000000100000000011] = 1; - firedLayersToQuality[0b000000010000000011] = 1; - firedLayersToQuality[0b000000110000000001] = 1; - firedLayersToQuality[0b000001000000001100] = 1; - firedLayersToQuality[0b000011000000001100] = 1; - firedLayersToQuality[0b000010000000001100] = 1; - firedLayersToQuality[0b000011000000000100] = 1; - firedLayersToQuality[0b000000011000000001] = 1; - firedLayersToQuality[0b001000010000000001] = 1; - - firedLayersToQuality[0b000100000000110000] = 1; - firedLayersToQuality[0b001100000000010000] = 1; - - firedLayersToQuality[0b010000110000000001] = 8; - firedLayersToQuality[0b000000111110000001] = 8; - firedLayersToQuality[0b000000001000000011] = 8; - firedLayersToQuality[0b000000111000000001] = 8; - firedLayersToQuality[0b000000101000000001] = 8; - firedLayersToQuality[0b010000011000000001] = 8; - firedLayersToQuality[0b010000100000000001] = 8; - firedLayersToQuality[0b000000110100000001] = 8; - firedLayersToQuality[0b000000100100000001] = 8; - firedLayersToQuality[0b001000100000000001] = 8; - firedLayersToQuality[0b010000010000000001] = 8; - firedLayersToQuality[0b001000110000000001] = 8; - firedLayersToQuality[0b001000110000000000] = 8; - firedLayersToQuality[0b000000010100000001] = 8; - firedLayersToQuality[0b000010100000000001] = 8; - firedLayersToQuality[0b000000100010000001] = 8; - firedLayersToQuality[0b001010010000000101] = 8; - firedLayersToQuality[0b100000000000000011] = 8; - firedLayersToQuality[0b011011000000000000] = 8; - firedLayersToQuality[0b000010110000000001] = 8; - firedLayersToQuality[0b001001110000000001] = 8; - firedLayersToQuality[0b000010100000000101] = 8; - firedLayersToQuality[0b000011110000000001] = 8; - firedLayersToQuality[0b000011110000001101] = 8; - firedLayersToQuality[0b000011100000000101] = 8; - firedLayersToQuality[0b000011110000000101] = 8; - firedLayersToQuality[0b000100000001110000] = 8; - firedLayersToQuality[0b000001110000001101] = 8; - firedLayersToQuality[0b000000110110000001] = 8; - firedLayersToQuality[0b000001110000000001] = 8; - firedLayersToQuality[0b001000010001000001] = 8; - firedLayersToQuality[0b000001100000000101] = 8; - firedLayersToQuality[0b000001100000000001] = 8; - firedLayersToQuality[0b000001110000000101] = 8; - firedLayersToQuality[0b001001110001000001] = 8; - firedLayersToQuality[0b000010110000000101] = 8; - firedLayersToQuality[0b000000010001000001] = 8; - firedLayersToQuality[0b000000100110000001] = 8; - firedLayersToQuality[0b001001100000001100] = 8; - firedLayersToQuality[0b000001010000000001] = 8; - firedLayersToQuality[0b000010100000000011] = 8; - firedLayersToQuality[0b000000100001000001] = 8; - firedLayersToQuality[0b001000110001000001] = 8; - firedLayersToQuality[0b000000010010000001] = 8; - firedLayersToQuality[0b000001010000000101] = 8; - firedLayersToQuality[0b100000100110000001] = 8; - firedLayersToQuality[0b000010010000000101] = 8; - firedLayersToQuality[0b000000110010000001] = 8; - firedLayersToQuality[0b000000000000110100] = 8; - firedLayersToQuality[0b000000010000000101] = 8; - firedLayersToQuality[0b000000110001000001] = 8; - firedLayersToQuality[0b000000010000001100] = 8; - firedLayersToQuality[0b000010110000001101] = 8; - firedLayersToQuality[0b000011010000001101] = 8; - firedLayersToQuality[0b000000100000010001] = 8; - firedLayersToQuality[0b000000110000000101] = 8; - firedLayersToQuality[0b000001100000000111] = 8; - firedLayersToQuality[0b000000100000000101] = 8; - firedLayersToQuality[0b010000010010000001] = 8; - firedLayersToQuality[0b000001100000001101] = 8; - firedLayersToQuality[0b000011100000000111] = 8; - firedLayersToQuality[0b000000010110000001] = 8; - firedLayersToQuality[0b000011110000000111] = 8; - firedLayersToQuality[0b000000011100000000] = 8; - firedLayersToQuality[0b001000010000000011] = 8; - firedLayersToQuality[0b000001110000000011] = 8; - firedLayersToQuality[0b000100000000110000] = 8; - firedLayersToQuality[0b000111100000110100] = 8; - firedLayersToQuality[0b010000010010000000] = 8; - firedLayersToQuality[0b100000010100000000] = 8; - firedLayersToQuality[0b001000100000000011] = 8; - firedLayersToQuality[0b000011100000001101] = 8; - firedLayersToQuality[0b100000011100000000] = 8; - firedLayersToQuality[0b110000011110000001] = 8; - //firedLayersToQuality[0b000000000000110011] = 8; - //firedLayersToQuality[0b000000100110000011] = 8; - //firedLayersToQuality[0b110000000100000000] = 8; - //firedLayersToQuality[0b001011110001001101] = 8; - //firedLayersToQuality[0b010000100001000011] = 8; - //firedLayersToQuality[0b000001100000001100] = 8; - //firedLayersToQuality[0b000001110001000011] = 8; - //firedLayersToQuality[0b011000000010000000] = 8; - //firedLayersToQuality[0b001000110100000011] = 8; - //firedLayersToQuality[0b010001000011000000] = 8; - //firedLayersToQuality[0b100000000110000000] = 8; - //firedLayersToQuality[0b000000000000111100] = 8; } -void OmtfEmulation::addObservers(const MuonGeometryTokens& muonGeometryTokens, - const edm::ESGetToken& magneticFieldEsToken, - const edm::ESGetToken& propagatorEsToken) { - if (observers.empty()) { //assuring it is done only at the first run - OMTFReconstruction::addObservers(muonGeometryTokens, magneticFieldEsToken, propagatorEsToken); - /* if(edmParameterSet.exists("patternsPtAssignment") && edmParameterSet.getParameter("patternsPtAssignment")) { - //std::string rootFileName = edmParameterSet.getParameter("dumpHitsFileName"); - .emplace_back(std::make_unique(edmParameterSet, omtfConfig.get(), omtfProcGoldenPat->getPatterns(), "")); - }*/ - } - - //addObservers is called in OMTFReconstruction::beginRun after the omtfProc is constructed, therefore here we can ptAssignment in omtfProc - if (edmParameterSet.exists("neuralNetworkFile") && !ptAssignment) { - edm::LogImportant("OMTFReconstruction") << "constructing PtAssignmentNNRegression" << std::endl; - std::string neuralNetworkFile = edmParameterSet.getParameter("neuralNetworkFile").fullPath(); - ptAssignment = std::make_unique(edmParameterSet, omtfConfig.get(), neuralNetworkFile); - } +void OmtfEmulation::beginRun(edm::Run const& run, + edm::EventSetup const& eventSetup, + edm::ESGetToken& omtfParamsEsToken, + const MuonGeometryTokens& muonGeometryTokens, + const edm::ESGetToken& magneticFieldEsToken, + const edm::ESGetToken& propagatorEsToken) { - auto omtfProcGoldenPat = dynamic_cast*>(omtfProc.get()); - if (omtfProcGoldenPat) { - omtfProcGoldenPat->setPtAssignment(ptAssignment.get()); - //omtfProcGoldenPat can be constructed from scratch each run, so ptAssignment is set herer every run - } + OMTFReconstruction::beginRun(run, eventSetup, omtfParamsEsToken, muonGeometryTokens, magneticFieldEsToken, propagatorEsToken); - omtfProc->setAssignQualityFunction( - [&](AlgoMuons::value_type& algoMuon) { this->assignQualityPhase2(algoMuon); }); -} - -void OmtfEmulation::assignQualityPhase2(AlgoMuons::value_type& algoMuon) { - if (abs(algoMuon->getEtaHw()) >= 121) { //TODO take into account the eta scale - algoMuon->setQuality(0); // changed from 4 on request from HI - return; - } - - auto it = firedLayersToQuality.find(algoMuon->getFiredLayerBits()); - if (algoMuon->getPtConstr() == 0) { - algoMuon->setQuality(0); //default value - return; - } - - if (it != firedLayersToQuality.end()) { - algoMuon->setQuality(it->second); - } else { - algoMuon->setQuality(12); //default value - } -}; - -void OmtfEmulation::convertToGmtScalesPhase2(unsigned int iProcessor, l1t::tftype mtfType, FinalMuonPtr& finalMuon) { - //ptAssignment (NN) is used only if there was valid candidate from pattern logic - //it overrides the pt from the pattern logic - if (ptAssignment) { - //PtNNConstr should be in GeV - finalMuon->setPtGev(finalMuon->getAlgoMuon()->getPtNNConstr()); - - //TODO use getPtNNUnconstr when the network with upt is trained to set setPtUnconstrGev() - } - - //in getFinalMuons the PtGeV is set to 0 in this case, as it is like that for the phase-1. - //but it is better to set non-0 pt in this case, so we set 1 GeV - if (finalMuon->getAlgoMuon()->getPdfSumConstr() == 0 && finalMuon->getAlgoMuon()->getPtUnconstr() > 0) - finalMuon->setPtGev(1.0); //set to 1 GeV to be able to distinguish from pt=0, which means no candidate - - int maxPtHw = (1 << Phase2L1GMT::BITSPT) - 1; - - int ptHwConstr = (finalMuon->getPtGev() * (1. / Phase2L1GMT::LSBpt)); - - if (ptHwConstr >= maxPtHw) - ptHwConstr = maxPtHw; - - finalMuon->setPtGmt(ptHwConstr); - - - int ptHwUnConstr = finalMuon->getPtUnconstrGev() * (1. / Phase2L1GMT::LSBpt); - - if (ptHwUnConstr >= maxPtHw) - ptHwUnConstr = maxPtHw; - - finalMuon->setPtUnconstrGmt(ptHwUnConstr); - - - if (mtfType == l1t::omtf_pos) { - finalMuon->setEtaGmt(finalMuon->getAlgoMuon()->getEtaHw()); - } - else { - finalMuon->setEtaGmt((-1) * finalMuon->getAlgoMuon()->getEtaHw()); - } - - int globPhi = omtfConfig->procPhiOmtfToGlobalPhiOmtf(iProcessor, finalMuon->getAlgoMuon()->getPhi()); - int gmtPhiBins = 1 << Phase2L1GMT::BITSPHI; - int omtfToGmtFactorPhi = std::lround(gmtPhiBins * (1 << 12) / double(omtfConfig->nPhiBins()) ) ; - int gmtPhi = (globPhi * omtfToGmtFactorPhi) >> 12; - finalMuon->setPhiGmt(gmtPhi); - - int omtfToGmtFactorEta = std::lround(omtfConfig->etaUnit() * (1 << 12) / Phase2L1GMT::LSBeta ) ; - int gmtEta = (finalMuon->getAlgoMuon()->getEtaHw() * omtfToGmtFactorEta) >> 12; - if (mtfType == l1t::omtf_neg) - gmtEta = -gmtEta; - finalMuon->setEtaGmt(gmtEta); - - //finalMuon.setHwSignValid(1); -} - -l1t::SAMuonCollection OmtfEmulation::getSAMuons(unsigned int iProcessor, - l1t::tftype mtfType, - FinalMuons& finalMuons, - bool costrainedPt) { - l1t::SAMuonCollection saMuons; - for (auto& finalMuon : finalMuons) { - convertToGmtScalesPhase2(iProcessor, mtfType, finalMuon); - - int charge = finalMuon->getSign(); - - unsigned int pt = costrainedPt ? finalMuon->getPtGmt() : finalMuon->getPtUnconstrGmt(); - - LogTrace("OMTFReconstruction") << "OmtfEmulation::getSAMuons finalMuon->getPtGmt(): " - << finalMuon->getPtGmt() << " finalMuon->getPtUnconstrGmt() "<< finalMuon->getPtUnconstrGmt() << std::endl; - - int phi = finalMuon->getPhiGmt(); - int eta = finalMuon->getEtaGmt(); - - int z0 = 0; - // Use 2 bits with LSB = 30cm for BMTF and 25cm for EMTF currently, but subjet to change - int d0 = 0; //finalMuon->getHwD0(); - - unsigned int qual = finalMuon->getQuality(); - - //TODO FIX - //Here do not use the word format to GT but use the word format expected by GMT - /* - int bstart = 0; - wordtype word(0); - bstart = wordconcat(word, bstart, 1, 1); - bstart = wordconcat(word, bstart, charge, 1); - bstart = wordconcat(word, bstart, pt, BITSPT); - bstart = wordconcat(word, bstart, phi, BITSPHI); - bstart = wordconcat(word, bstart, eta, BITSETA); - // bstart = wordconcat(word, bstart, z0, BITSSAZ0); NOT YET SUPPORTED BY GMT - bstart = wordconcat(word, bstart, d0, BITSSAD0); - bstart = wordconcat( - word, bstart, qual, 8); //FOR NOW 8 bits to be efficienct with Ghost busting. THIS IS ***NOT*** THE FINAL QUALITY -*/ - - // Calculate Lorentz Vector - //TODO for the vertex constrained muon, the z0 and d0 by definition should be 0 - then why give it? - math::PtEtaPhiMLorentzVector p4Constr(pt * Phase2L1GMT::LSBpt, eta * Phase2L1GMT::LSBeta, phi * Phase2L1GMT::LSBphi, 0.0); - l1t::SAMuon saMuonConstr(p4Constr, charge, pt, eta, phi, z0, d0, qual); - saMuonConstr.setTF(mtfType); - //samuon.setWord(word); - - if (saMuonConstr.hwPt() > 0) { - saMuons.push_back(saMuonConstr); - } - } - - return saMuons; + omtfProcPhase2.beginRun(edmParameterSet, eventSetup); } OmtfEmulation::OmtfOutptuCollections OmtfEmulation::run( @@ -318,30 +69,31 @@ OmtfEmulation::OmtfOutptuCollections OmtfEmulation::run( for(unsigned int iSide = 0; iSide < 2; ++iSide) { l1t::tftype mtfType = (iSide == 0) ? l1t::tftype::omtf_pos : l1t::tftype::omtf_neg; for (unsigned int iProcessor = 0; iProcessor < omtfConfig->nProcessors(); ++iProcessor) { - FinalMuons finalMuons = omtfProc->run(iProcessor, mtfType, bx, inputMaker.get(), observers); - - //getRegionalMuonCands calls convertToGmtScalesPhase1, it sets value eta, phi, pt finalMuons - //so regionalCandidates have values in phase-1 scales - std::vector candMuons = - omtfProc->getRegionalMuonCands(iProcessor, mtfType, finalMuons); - for (auto& candMuon : candMuons) { - outptuCollections.regionalCandidates->push_back(bx, candMuon); - } - - for (auto& finalMuon : finalMuons) { - convertToGmtScalesPhase2(iProcessor, mtfType, finalMuon); - } + FinalMuons finalMuons = omtfProcPhase2.run(iProcessor, mtfType, bx, inputMaker.get(), observers); - l1t::SAMuonCollection constrSAMuons = getSAMuons(iProcessor, mtfType, finalMuons, true); + l1t::SAMuonCollection constrSAMuons = omtfProcPhase2.getSAMuons(iProcessor, mtfType, finalMuons, true); for (auto& saMuon : constrSAMuons) { - outptuCollections.unConstrSaMuons->push_back(saMuon); + outptuCollections.constrSaMuons->push_back(saMuon); } - l1t::SAMuonCollection unconstrSAMuons = getSAMuons(iProcessor, mtfType, finalMuons, false); + l1t::SAMuonCollection unconstrSAMuons = omtfProcPhase2.getSAMuons(iProcessor, mtfType, finalMuons, false); for (auto& saMuon : unconstrSAMuons) { outptuCollections.unConstrSaMuons->push_back(saMuon); } + //getRegionalMuonCands calls convertToGmtScalesPhase1, it sets value ptGmt, phiGmt, etaGmt in finalMuons + //so that regionalCandidates have values in phase-1 scales + //but it will affect the finalMuons stored in allFinalMuons as they are shared pointers, + //Therefore convertToGmtScalesPhase2 is called again. + std::vector candMuons = omtfProc->getRegionalMuonCands(iProcessor, mtfType, finalMuons); + for (auto& candMuon : candMuons) { + outptuCollections.regionalCandidates->push_back(bx, candMuon); + } + //TODO remove it when RegionalCandidates are not needed anymore + for (auto& finalMuon : finalMuons) { + omtfProcPhase2.convertToGmtScalesPhase2(iProcessor, mtfType, finalMuon); + } + allFinalMuons.insert(allFinalMuons.end(), finalMuons.begin(), finalMuons.end()); } } diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc index 1ca36c89c0386..3b13eb0e0ecfe 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc @@ -58,8 +58,7 @@ int OmtfPhase2AngleConverter::getGlobalEta(DTChamberId dTChamberId, foundeta = false; if (foundeta) { - //return std::abs(config->etaToHwEta(eta)); TODO use this version - return std::abs(std::lround(eta * 92)); + return std::abs(config->etaToHwEta(eta)); } else { //Returning eta of the chamber middle if (dTChamberId.station() == 1) @@ -71,5 +70,5 @@ int OmtfPhase2AngleConverter::getGlobalEta(DTChamberId dTChamberId, return eta; } - return 95; + return 0; //should not be reached } diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc new file mode 100644 index 0000000000000..5148f72390e2f --- /dev/null +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc @@ -0,0 +1,373 @@ +/* + * OmtfProcessorPhase2.cc + * + * Created on: Oct 29, 2025 + * Author: kbunkow + */ + +#include +#include "L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h" + +OmtfProcessorPhase2::OmtfProcessorPhase2(const OMTFConfiguration* omtfConfig, const unique_ptr& omtfProc): +omtfConfig(omtfConfig), omtfProc(omtfProc) { + + //TODO read from configuration + //.....................rrrrrrrrccccdddddd + //.....................765432109876543210 + firedLayersToQuality[0b000000110000000011] = 1; + firedLayersToQuality[0b000000100000000011] = 1; + firedLayersToQuality[0b000000010000000011] = 1; + firedLayersToQuality[0b000000110000000001] = 1; + firedLayersToQuality[0b000001000000001100] = 1; + firedLayersToQuality[0b000011000000001100] = 1; + firedLayersToQuality[0b000010000000001100] = 1; + firedLayersToQuality[0b000011000000000100] = 1; + firedLayersToQuality[0b000000011000000001] = 1; + firedLayersToQuality[0b001000010000000001] = 1; + + firedLayersToQuality[0b000100000000110000] = 1; + firedLayersToQuality[0b001100000000010000] = 1; + + firedLayersToQuality[0b010000110000000001] = 8; + firedLayersToQuality[0b000000111110000001] = 8; + firedLayersToQuality[0b000000001000000011] = 8; + firedLayersToQuality[0b000000111000000001] = 8; + firedLayersToQuality[0b000000101000000001] = 8; + firedLayersToQuality[0b010000011000000001] = 8; + firedLayersToQuality[0b010000100000000001] = 8; + firedLayersToQuality[0b000000110100000001] = 8; + firedLayersToQuality[0b000000100100000001] = 8; + firedLayersToQuality[0b001000100000000001] = 8; + firedLayersToQuality[0b010000010000000001] = 8; + firedLayersToQuality[0b001000110000000001] = 8; + firedLayersToQuality[0b001000110000000000] = 8; + firedLayersToQuality[0b000000010100000001] = 8; + firedLayersToQuality[0b000010100000000001] = 8; + firedLayersToQuality[0b000000100010000001] = 8; + firedLayersToQuality[0b001010010000000101] = 8; + firedLayersToQuality[0b100000000000000011] = 8; + firedLayersToQuality[0b011011000000000000] = 8; + firedLayersToQuality[0b000010110000000001] = 8; + firedLayersToQuality[0b001001110000000001] = 8; + firedLayersToQuality[0b000010100000000101] = 8; + firedLayersToQuality[0b000011110000000001] = 8; + firedLayersToQuality[0b000011110000001101] = 8; + firedLayersToQuality[0b000011100000000101] = 8; + firedLayersToQuality[0b000011110000000101] = 8; + firedLayersToQuality[0b000100000001110000] = 8; + firedLayersToQuality[0b000001110000001101] = 8; + firedLayersToQuality[0b000000110110000001] = 8; + firedLayersToQuality[0b000001110000000001] = 8; + firedLayersToQuality[0b001000010001000001] = 8; + firedLayersToQuality[0b000001100000000101] = 8; + firedLayersToQuality[0b000001100000000001] = 8; + firedLayersToQuality[0b000001110000000101] = 8; + firedLayersToQuality[0b001001110001000001] = 8; + firedLayersToQuality[0b000010110000000101] = 8; + firedLayersToQuality[0b000000010001000001] = 8; + firedLayersToQuality[0b000000100110000001] = 8; + firedLayersToQuality[0b001001100000001100] = 8; + firedLayersToQuality[0b000001010000000001] = 8; + firedLayersToQuality[0b000010100000000011] = 8; + firedLayersToQuality[0b000000100001000001] = 8; + firedLayersToQuality[0b001000110001000001] = 8; + firedLayersToQuality[0b000000010010000001] = 8; + firedLayersToQuality[0b000001010000000101] = 8; + firedLayersToQuality[0b100000100110000001] = 8; + firedLayersToQuality[0b000010010000000101] = 8; + firedLayersToQuality[0b000000110010000001] = 8; + firedLayersToQuality[0b000000000000110100] = 8; + firedLayersToQuality[0b000000010000000101] = 8; + firedLayersToQuality[0b000000110001000001] = 8; + firedLayersToQuality[0b000000010000001100] = 8; + firedLayersToQuality[0b000010110000001101] = 8; + firedLayersToQuality[0b000011010000001101] = 8; + firedLayersToQuality[0b000000100000010001] = 8; + firedLayersToQuality[0b000000110000000101] = 8; + firedLayersToQuality[0b000001100000000111] = 8; + firedLayersToQuality[0b000000100000000101] = 8; + firedLayersToQuality[0b010000010010000001] = 8; + firedLayersToQuality[0b000001100000001101] = 8; + firedLayersToQuality[0b000011100000000111] = 8; + firedLayersToQuality[0b000000010110000001] = 8; + firedLayersToQuality[0b000011110000000111] = 8; + firedLayersToQuality[0b000000011100000000] = 8; + firedLayersToQuality[0b001000010000000011] = 8; + firedLayersToQuality[0b000001110000000011] = 8; + firedLayersToQuality[0b000100000000110000] = 8; + firedLayersToQuality[0b000111100000110100] = 8; + firedLayersToQuality[0b010000010010000000] = 8; + firedLayersToQuality[0b100000010100000000] = 8; + firedLayersToQuality[0b001000100000000011] = 8; + firedLayersToQuality[0b000011100000001101] = 8; + firedLayersToQuality[0b100000011100000000] = 8; + firedLayersToQuality[0b110000011110000001] = 8; + //firedLayersToQuality[0b000000000000110011] = 8; + //firedLayersToQuality[0b000000100110000011] = 8; + //firedLayersToQuality[0b110000000100000000] = 8; + //firedLayersToQuality[0b001011110001001101] = 8; + //firedLayersToQuality[0b010000100001000011] = 8; + //firedLayersToQuality[0b000001100000001100] = 8; + //firedLayersToQuality[0b000001110001000011] = 8; + //firedLayersToQuality[0b011000000010000000] = 8; + //firedLayersToQuality[0b001000110100000011] = 8; + //firedLayersToQuality[0b010001000011000000] = 8; + //firedLayersToQuality[0b100000000110000000] = 8; + //firedLayersToQuality[0b000000000000111100] = 8; +} + +OmtfProcessorPhase2::~OmtfProcessorPhase2() { + +} + +void OmtfProcessorPhase2::beginRun(const edm::ParameterSet& edmParameterSet, edm::EventSetup const& iSetup) { + if (edmParameterSet.exists("neuralNetworkFile") && !mlModel) { + edm::LogImportant("OMTFReconstruction") << "constructing PtAssignmentNNRegression" << std::endl; + std::string neuralNetworkFile = edmParameterSet.getParameter("neuralNetworkFile").fullPath(); + mlModel = std::make_unique(edmParameterSet, omtfConfig, neuralNetworkFile); + } +} + +void OmtfProcessorPhase2::assignQualityPhase2(AlgoMuons::value_type& algoMuon) { + if (!algoMuon->isValid()) + return; + + if (abs(algoMuon->getEtaHw()) >= omtfConfig->etaToHwEta(1.3)) { + algoMuon->setQuality(0); + return; + } + + LogTrace("OMTFReconstruction") << "OmtfEmulation::assignQualityPhase2 algoMuon->getFiredLayerBits() " + << std::bitset<18>(algoMuon->getFiredLayerBits()) + << " algoMuon->getEtaHw() " << algoMuon->getEtaHw() << " omtfConfig->etaToHwEta(1.25) "<< omtfConfig->etaToHwEta(1.25) << std::endl; + + if (abs(algoMuon->getEtaHw()) >= omtfConfig->etaToHwEta(1.25) && + (algoMuon->getFiredLayerBits() == std::bitset<18>("100000001110000000").to_ulong() || + algoMuon->getFiredLayerBits() == std::bitset<18>("000000001110000000").to_ulong() || + algoMuon->getFiredLayerBits() == std::bitset<18>("100000000110000000").to_ulong() || + algoMuon->getFiredLayerBits() == std::bitset<18>("100000001100000000").to_ulong() || + algoMuon->getFiredLayerBits() == std::bitset<18>("100000001010000000").to_ulong())) { + algoMuon->setQuality(1); + LogTrace("OMTFReconstruction") << "OmtfEmulation::assignQualityPhase2 assigned quality 1 for etaHw " + << algoMuon->getEtaHw() << std::endl; + return; + } + + auto it = firedLayersToQuality.find(algoMuon->getFiredLayerBits()); + if (algoMuon->getPtConstr() == 0) { + algoMuon->setQuality(0); //default value + return; + } + + if (it != firedLayersToQuality.end()) { + algoMuon->setQuality(it->second); + } else { + algoMuon->setQuality(12); //default value + } +}; + +void OmtfProcessorPhase2::convertToGmtScalesPhase2(unsigned int iProcessor, l1t::tftype mtfType, FinalMuonPtr& finalMuon) { + //ptAssignment (NN) is used only if there was valid candidate from pattern logic + //it overrides the pt from the pattern logic + if (mlModel) { + //PtNNConstr should be in GeV + finalMuon->setPtGev(finalMuon->getAlgoMuon()->getPtNNConstr()); + finalMuon->setSign(finalMuon->getAlgoMuon()->getChargeNNConstr() < 0 ? 1 : 0); + + + //TODO use getPtNNUnconstr when the network with upt is trained to set setPtUnconstrGev() + LogTrace("OMTFReconstruction") << "OmtfEmulation::convertToGmtScalesPhase2 using Pt from NN " + << " iProcessor " << iProcessor<<" ptNN " << finalMuon->getAlgoMuon()->getPtNNConstr() + << " ptPatterns " << finalMuon->getAlgoMuon()->getPtConstr() + << " ChargeNN " <getAlgoMuon()->getChargeNNConstr() + << " Charge " <getAlgoMuon()->getChargeConstr() << std::endl; + } + + //in getFinalMuons the PtGeV is set to 0 in this case, as it is like that for the phase-1. + //but it is better to set non-0 pt in this case, so we set 1 GeV + if (finalMuon->getAlgoMuon()->getPdfSumConstr() == 0 && finalMuon->getAlgoMuon()->getPtUnconstr() > 0) + finalMuon->setPtGev(1.0); //set to 1 GeV to be able to distinguish from pt=0, which means no candidate + + int maxPtHw = (1 << Phase2L1GMT::BITSPT) - 1; + + int ptHwConstr = finalMuon->getPtGev() * (1. / Phase2L1GMT::LSBpt); + + if (ptHwConstr >= maxPtHw) + ptHwConstr = maxPtHw; + + finalMuon->setPtGmt(ptHwConstr); + + + int ptHwUnConstr = finalMuon->getPtUnconstrGev() * (1. / Phase2L1GMT::LSBpt); + + if (ptHwUnConstr >= maxPtHw) + ptHwUnConstr = maxPtHw; + + finalMuon->setPtUnconstrGmt(ptHwUnConstr); + + LogTrace("OMTFReconstruction") << "convertToGmtScalesPhase2 finalMuon->getPtGev() iProcessor " << iProcessor + << " PtGev " << finalMuon->getPtGev()<< " PtUnconstrGev "<< finalMuon->getPtUnconstrGev() << std::endl; + + if (mtfType == l1t::omtf_pos) { + finalMuon->setEtaGmt(finalMuon->getAlgoMuon()->getEtaHw()); + } + else { + finalMuon->setEtaGmt((-1) * finalMuon->getAlgoMuon()->getEtaHw()); + } + + int globPhi = omtfConfig->procPhiOmtfToGlobalPhiOmtf(iProcessor, finalMuon->getAlgoMuon()->getPhi()); + int gmtPhiBins = 1 << Phase2L1GMT::BITSPHI; + int omtfToGmtFactorPhi = std::lround(gmtPhiBins * (1 << 12) / double(omtfConfig->nPhiBins()) ) ; + int gmtPhi = (globPhi * omtfToGmtFactorPhi) >> 12; + finalMuon->setPhiGmt(gmtPhi); + + static const int omtfToGmtFactorEta = std::lround(omtfConfig->etaUnit() / Phase2L1GMT::LSBeta ) ; //should be 2 + LogTrace("OMTFReconstruction") << "OmtfEmulation::convertToGmtScalesPhase2 omtfToGmtFactorEta " << omtfToGmtFactorEta << std::endl; + int gmtEta = (finalMuon->getAlgoMuon()->getEtaHw() * omtfToGmtFactorEta); + if (mtfType == l1t::omtf_neg) + gmtEta = -gmtEta; + finalMuon->setEtaGmt(gmtEta); + + //finalMuon.setHwSignValid(1); +} + +l1t::SAMuonCollection OmtfProcessorPhase2::getSAMuons(unsigned int iProcessor, + l1t::tftype mtfType, + FinalMuons& finalMuons, + bool costrainedPt) { + l1t::SAMuonCollection saMuons; + for (auto& finalMuon : finalMuons) { + int charge = finalMuon->getSign(); + + unsigned int pt = costrainedPt ? finalMuon->getPtGmt() : finalMuon->getPtUnconstrGmt(); + int d0 = costrainedPt ? 0 : 50 / Phase2L1GMT::LSBSAd0; //finalMuon->getHwD0(); + if(costrainedPt == false) { + //this assures the collection of constrained and unconstrained muons have the same size + //muons that are not displaced also should be in the unconstrained collection + if(finalMuon->getPtUnconstrGmt() == 0) { + pt = finalMuon->getPtGmt(); + d0 = 0; + } + } + + LogTrace("OMTFReconstruction") << "OmtfEmulation::getSAMuons finalMuon->getPtGmt(): " + << finalMuon->getPtGmt() << " finalMuon->getPtUnconstrGmt() "<< finalMuon->getPtUnconstrGmt() << std::endl; + + int phi = finalMuon->getPhiGmt(); + int eta = finalMuon->getEtaGmt(); + + int z0 = 0; + + unsigned int qual = finalMuon->getQuality(); + + //TODO FIX + //Here do not use the word format to GT but use the word format expected by GMT + /* + int bstart = 0; + wordtype word(0); + bstart = wordconcat(word, bstart, 1, 1); + bstart = wordconcat(word, bstart, charge, 1); + bstart = wordconcat(word, bstart, pt, BITSPT); + bstart = wordconcat(word, bstart, phi, BITSPHI); + bstart = wordconcat(word, bstart, eta, BITSETA); + // bstart = wordconcat(word, bstart, z0, BITSSAZ0); NOT YET SUPPORTED BY GMT + bstart = wordconcat(word, bstart, d0, BITSSAD0); + bstart = wordconcat( + word, bstart, qual, 8); //FOR NOW 8 bits to be efficienct with Ghost busting. THIS IS ***NOT*** THE FINAL QUALITY +*/ + + // Calculate Lorentz Vector + //TODO for the vertex constrained muon, the z0 and d0 by definition should be 0 - then why give it? + math::PtEtaPhiMLorentzVector p4Constr(pt * Phase2L1GMT::LSBpt, eta * Phase2L1GMT::LSBeta, phi * Phase2L1GMT::LSBphi, 0.0); + l1t::SAMuon saMuon(p4Constr, charge, pt, eta, phi, z0, d0, qual); + saMuon.setTF(mtfType); + //samuon.setWord(word); + + if (saMuon.hwPt() > 0) { + saMuons.push_back(saMuon); + } + } + + return saMuons; +} + +FinalMuons OmtfProcessorPhase2::run(unsigned int iProcessor, + l1t::tftype mtfType, + int bx, + OMTFinputMaker* inputMaker, + std::vector >& observers) { + //uncomment if you want to check execution time of each method + //boost::timer::auto_cpu_timer t("%ws wall, %us user in getProcessorCandidates\n"); + + for (auto& obs : observers) + obs->observeProcesorBegin(iProcessor, mtfType); + + //input is shared_ptr because the observers may need them after the run() method execution is finished + std::shared_ptr input = std::make_shared(omtfConfig); + inputMaker->buildInputForProcessor(input->getMuonStubs(), iProcessor, mtfType, bx, bx, observers); + + //TODO make a method cleanStubs in OMTFinput + if (omtfConfig->cleanStubs()) { + //this has sense for the pattern generation from the tracks with the secondaries + //if more than one stub is in a given layer, all stubs are removed from this layer + for (unsigned int iLayer = 0; iLayer < input->getMuonStubs().size(); ++iLayer) { + auto& layerStubs = input->getMuonStubs()[iLayer]; + int count = std::count_if(layerStubs.begin(), layerStubs.end(), [](auto& ptr) { return ptr != nullptr; }); + if (count > 1) { + for (auto& ptr : layerStubs) + ptr.reset(); + + LogTrace("OMTFReconstruction") << __FUNCTION__ << ":" << __LINE__ << "cleaning stubs in the layer " << iLayer + << " stubs count :" << count << std::endl; + } + } + } + + //LogTrace("l1tOmtfEventPrint")<<"buildInputForProce "; t.report(); + omtfProc->processInput(iProcessor, mtfType, *(input.get()), observers); + + //LogTrace("l1tOmtfEventPrint")<<"processInput "; t.report(); + AlgoMuons algoCandidates = omtfProc->sortResults(iProcessor, mtfType); + + //assignQuality must be called after ghostBust, because eta is set there + /*for (auto& algoMuon : algoCandidates) { + assignQuality(algoMuon); + }*/ + + if (mlModel) { + for (auto& algoMuon : algoCandidates) { + if (algoMuon->isValid()) { + mlModel->run(algoMuon, observers); + } + } + } + + //LogTrace("l1tOmtfEventPrint")<<"sortResults "; t.report(); + // perform GB + //watch out: etaBits2HwEta is used in the ghostBust to convert the AlgoMuons eta, it affect algoCandidates as they are pointers + AlgoMuons gbCandidates = omtfProc->ghostBust(algoCandidates); + + for (auto& gbCandidate : gbCandidates) { + assignQualityPhase2(gbCandidate); + } + + //LogTrace("l1tOmtfEventPrint")<<"ghostBust"; t.report(); + + FinalMuons finalMuons = omtfProc->getFinalMuons(iProcessor, mtfType, gbCandidates); + + for (auto& finalMuon : finalMuons) { + convertToGmtScalesPhase2(iProcessor, mtfType, finalMuon); + } + + for(auto& finalMuon : finalMuons) { + finalMuon->setBx(bx); + } + + for (auto& obs : observers) { + obs->observeProcesorEmulation(iProcessor, mtfType, input, algoCandidates, gbCandidates, finalMuons); + } + + return finalMuons; + +} + diff --git a/L1Trigger/L1TMuonOverlapPhase2/test/expert/runMuonOverlapPatternGeneratorClassProb_phase2.py b/L1Trigger/L1TMuonOverlapPhase2/test/expert/runMuonOverlapPatternGeneratorClassProb_phase2.py index 39efa7df57228..ee48af4a3bdc3 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/test/expert/runMuonOverlapPatternGeneratorClassProb_phase2.py +++ b/L1Trigger/L1TMuonOverlapPhase2/test/expert/runMuonOverlapPatternGeneratorClassProb_phase2.py @@ -18,7 +18,7 @@ #versionOut = versionIn + "_classProb17_recalib2" #_classProb17_recalib2_minDP0 -versionOut = "ExtraplMB1andMB2RFixedP_ValueP1Scale_DT_2_2_2_t35_" + "_classProb17_recalib2" +versionOut = "ExtraplMB1andMB2RFixedP_ValueP1Scale_DT_2_2_2_t35_" + "_classProb17" if verbose: process.MessageLogger = cms.Service("MessageLogger", From 6c91d078603174f3395a49adce39b9febbccfcb7 Mon Sep 17 00:00:00 2001 From: Karol Bunkowski Date: Fri, 7 Nov 2025 18:24:15 +0100 Subject: [PATCH 03/12] removed AngleConverterBase AngleConverterBase was removed, the needed methods were moved to OmtfAngleConverter. A few methods that were not used were dropped. OmtfPhase2AngleConverter method getGlobalEta renamed to getGlobalEtaPhase2, to avoid hiding OmtfAngleConverter methods getGlobalEta. --- .../interface/AngleConverterBase.h | 116 ----- .../interface/MuonStubMakerBase.h | 2 +- .../interface/Omtf/OmtfAngleConverter.h | 77 ++- .../L1TMuonOverlapPhase1TrackProducer.h | 2 +- .../src/AngleConverterBase.cc | 457 ------------------ .../src/Omtf/OmtfAngleConverter.cc | 197 +++++++- .../src/Tools/StubsSimHitsMatching.cc | 1 - .../interface/OmtfPhase2AngleConverter.h | 3 +- .../L1TMuonOverlapPhase2TrackProducer.h | 2 +- .../src/InputMakerPhase2.cc | 2 +- .../src/OmtfPhase2AngleConverter.cc | 2 +- 11 files changed, 274 insertions(+), 587 deletions(-) delete mode 100644 L1Trigger/L1TMuonOverlapPhase1/interface/AngleConverterBase.h delete mode 100644 L1Trigger/L1TMuonOverlapPhase1/src/AngleConverterBase.cc 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 6911279655133..c9b1c346df8e1 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStubMakerBase.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/MuonStubMakerBase.h @@ -166,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/OmtfAngleConverter.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h index 7c12d7aa6b6a3..0ff378d4be0bf 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h @@ -8,13 +8,61 @@ #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 "Geometry/Records/interface/MuonGeometryRecord.h" +#include "FWCore/Framework/interface/ESWatcher.h" + +#include + +class RPCGeometry; +class CSCGeometry; +class CSCLayer; +class DTGeometry; + +class L1MuDTChambPhDigi; +class L1MuDTChambThDigi; +class L1MuDTChambThContainer; +class CSCCorrelatedLCTDigi; +class RPCDigi; + +class DTChamberId; +class CSCDetId; +class RPCDetId; + +struct MuonGeometryTokens { + edm::ESGetToken rpcGeometryEsToken; + edm::ESGetToken cscGeometryEsToken; + edm::ESGetToken dtGeometryEsToken; +}; + +class OmtfAngleConverter { public: - OmtfAngleConverter() : AngleConverterBase() {} + OmtfAngleConverter() {} + + virtual ~OmtfAngleConverter(); - ~OmtfAngleConverter() override; + ///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(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 @@ -26,8 +74,25 @@ class OmtfAngleConverter : public AngleConverterBase { ///Convert local eta coordinate to global digital microGMT scale. virtual int getGlobalEtaRpc(unsigned int rawid, const unsigned int &aDigi, float &r) const; - //to avoid Clang Warnings "hides overloaded virtual functions" - using AngleConverterBase::getGlobalEta; + +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 /* L1T_OmtfP1_OMTFANGLECONVERTER_H_ */ 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/Omtf/OmtfAngleConverter.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc index e0cdb65585d04..53675b843619e 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc @@ -33,7 +33,20 @@ namespace { return (T(0) < val) - (val < T(0)); } - //DT eta bins in the wheel +2 + 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; + } + + //phase-1: DT eta bins in the wheel +2 const std::vector bounds = {1.24, 1.14353, 1.09844, 1.05168, 1.00313, 0.952728, 0.90037, 0.8}; // 0.8 -> 73 // 0.85 -> 78 @@ -99,6 +112,158 @@ namespace { } //namespace OmtfAngleConverter::~OmtfAngleConverter() {} +/////////////////////////////////////// +/////////////////////////////////////// +void OmtfAngleConverter::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 OmtfAngleConverter::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 OmtfAngleConverter::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 OmtfAngleConverter::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); +} /////////////////////////////////////// /////////////////////////////////////// @@ -241,3 +406,33 @@ int OmtfAngleConverter::getGlobalEtaRpc(unsigned int rawid, const unsigned int & /////////////////////////////////////// /////////////////////////////////////// +bool OmtfAngleConverter::isCSCCounterClockwise(const CSCLayer* layer) const { + const int nStrips = layer->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 OmtfAngleConverter::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/Tools/StubsSimHitsMatching.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc index 284363bbf40d5..296181a0ca676 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc @@ -9,7 +9,6 @@ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Tools/StubsSimHitsMatcher.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfName.h" #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFinputMaker.h" -#include "L1Trigger/L1TMuonOverlapPhase1/interface/AngleConverterBase.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h index 8f15bff3f4514..3908366a53d8b 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h @@ -13,7 +13,8 @@ class OmtfPhase2AngleConverter : public OmtfAngleConverter { // Convert DT phi to OMTF coordinate system. int getProcessorPhi(int phiZero, l1t::tftype part, int dtScNum, int dtPhi) const override; - int getGlobalEta(DTChamberId dTChamberId, const L1Phase2MuDTThContainer *dtThDigis, int bxNum) const; + //using different name of the method to avoid hiding OmtfAngleConverter methods getGlobalEta + int getGlobalEtaPhase2(DTChamberId dTChamberId, const L1Phase2MuDTThContainer *dtThDigis, int bxNum) const; }; #endif diff --git a/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.h b/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.h index 0596d194ec333..367bcaac37696 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.h +++ b/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.h @@ -29,7 +29,7 @@ class L1TMuonOverlapPhase2TrackProducer : public edm::one::EDProducer omtfParamsEsToken; - //needed for AngleConverterBase + //needed for OmtfAngleConverter MuonGeometryTokens muonGeometryTokens; ///needed by tools/CandidateSimMuonMatcher.h diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc b/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc index c7f2d05cfc776..7bea05f5e87f3 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc @@ -127,7 +127,7 @@ void DtPhase2DigiToStubsConverterOmtf::addDTphiDigi(MuonStubPtrs2D& muonStubsInL stub.phiHw = angleConverter.getProcessorPhi( OMTFinputMaker::getProcessorPhiZero(&config, iProcessor), procTyp, digi.scNum(), digi.phi()); - stub.etaHw = angleConverter.getGlobalEta(detid, dtThDigis, digi.bxNum() - 20); + stub.etaHw = angleConverter.getGlobalEtaPhase2(detid, dtThDigis, digi.bxNum() - 20); if (iLayer == 0) stub.r = 431.175; //MB1 diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc index 3b13eb0e0ecfe..aa3b7ba0a10f8 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc @@ -20,7 +20,7 @@ int OmtfPhase2AngleConverter::getProcessorPhi(int phiZero, l1t::tftype part, int return config->foldPhi(phiConverted); } -int OmtfPhase2AngleConverter::getGlobalEta(DTChamberId dTChamberId, +int OmtfPhase2AngleConverter::getGlobalEtaPhase2(DTChamberId dTChamberId, const L1Phase2MuDTThContainer* dtThDigis, int bxNum) const { int dtThBins = 65536; //65536. for [-6.3,6.3] From 2764f0c00fd6cc2e615805f9fc8e94ddb2112679 Mon Sep 17 00:00:00 2001 From: Karol Bunkowski Date: Tue, 11 Nov 2025 19:21:28 +0100 Subject: [PATCH 04/12] Fixes in CandidateSimMuonMatcher added << operator to FinalMuon and MatchingResult CandidateSimMuonMatcher.cc Added protections against null simVertex pointer. Added protections against null muonMatcherFile and histograms. Removed cuts on candidates pt and quality. Simplified LogTrace printouts. OmtfProcessorPhase2.cc A small fix in the assignQualityPhase2. --- .../interface/Omtf/FinalMuon.h | 1 + .../interface/Tools/CandidateSimMuonMatcher.h | 4 +- .../interface/Tools/DataROOTDumper2.h | 7 +- .../src/Omtf/FinalMuon.cc | 27 ++ .../src/Omtf/OMTFProcessor.cc | 4 +- .../src/Tools/CandidateSimMuonMatcher.cc | 297 ++++++++++-------- .../src/Tools/DataROOTDumper2.cc | 3 +- .../src/OmtfProcessorPhase2.cc | 14 +- 8 files changed, 221 insertions(+), 136 deletions(-) create mode 100644 L1Trigger/L1TMuonOverlapPhase1/src/Omtf/FinalMuon.cc diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h index 4a2308893d564..9258ad22bf699 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h @@ -126,6 +126,7 @@ class FinalMuon { this->firedLayerBits = firedLayerBits; } + friend std::ostream& operator<<(std::ostream& out, const FinalMuon& finalMuon); private: AlgoMuonPtr algoMuon; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h index 8c4f6d041ccea..422e1460c436f 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h @@ -86,6 +86,8 @@ class MatchingResult { const SimVertex* simVertex = nullptr; const TrackingParticle* trackingParticle = nullptr; + + friend std::ostream& operator<<(std::ostream& out, const MatchingResult& matchingResult); }; /* @@ -177,8 +179,6 @@ class CandidateSimMuonMatcher : public IOMTFEmulationObserver { MatchingType getMatchingType() const { return matchingType; } private: - //const OMTFConfiguration* omtfConfig; - int nProcessors = 6; const edm::ParameterSet& edmCfg; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h index 8bb362e78fb9c..08c308ac31930 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; @@ -77,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; }; @@ -118,4 +123,4 @@ class DataROOTDumper2 : public EmulationObserverBase { bool dumpKilledOmtfCands = false; }; -#endif /* L1T_OmtfP1_TOOLS_DATAROOTDUMPER2_H_ */ +#endif /* L1T_OmtfP1_TOOLS_DATAROOTDUMPER2_H_ */ \ No newline at end of file diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/FinalMuon.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/FinalMuon.cc new file mode 100644 index 0000000000000..aef30f7364f68 --- /dev/null +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/FinalMuon.cc @@ -0,0 +1,27 @@ +/* + * 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" + << " pt " << std::setw(8) << finalMuon.ptGev << " GeV" + << " eta " << std::setw(8) << finalMuon.etaRad + << " phi " << std::setw(8) << finalMuon.phiRad + << " sign " << std::setw(2) << finalMuon.sign + << " ptGmt " << std::setw(8) << finalMuon.getPtGmt() + << " etaGmt " << std::setw(8) << finalMuon.getEtaGmt() + << " phiGmt " << std::setw(8) << finalMuon.getPhiGmt() + //<< " hwPhi " << muonCand->hwPhi() + << " hwQual " << finalMuon.getQuality() << " processor " << finalMuon.getProcessor(); + return out; +} + + diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc index 412385ecb11ff..70360d88f72a3 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc @@ -263,7 +263,7 @@ FinalMuons OMTFProcessor::getFinalMuons(unsigned int iProcess finalMuon->setPtGev(0.0); } else { - finalMuon->setPtGev(0); + //empty candidates are not added to the finalMuons continue; } @@ -303,7 +303,7 @@ void OMTFProcessor::convertToGmtScalesPhase1(unsigned int iPr else finalMuon->setPtGmt(0); - //N.B. the pahse-1 GMT upt has different hardware scale than the pt, the upt unit is 1 GeV + //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 diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc index 0574d14381c3d..465f934216d45 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc @@ -52,13 +52,21 @@ MatchingResult::MatchingResult(const SimTrack& simTrack, const SimVertex* simVer genPhi = simTrack.momentum().phi(); genCharge = simTrack.charge(); - const math::XYZTLorentzVectorD& vtxPos = this->simVertex->position(); - muonDxy = (-vtxPos.X() * this->simTrack->momentum().py() + vtxPos.Y() * this->simTrack->momentum().px()) / - this->simTrack->momentum().pt(); - muonRho = vtxPos.Rho(); - - vertexEta = vtxPos.eta(); - vertexPhi = vtxPos.phi(); + if (this->simVertex) { + const math::XYZTLorentzVectorD& vtxPos = this->simVertex->position(); + muonDxy = (-vtxPos.X() * this->simTrack->momentum().py() + vtxPos.Y() * this->simTrack->momentum().px()) / + this->simTrack->momentum().pt(); + muonRho = vtxPos.Rho(); + + vertexEta = vtxPos.eta(); + vertexPhi = vtxPos.phi(); + } else { + // default values when no vertex information is available + muonDxy = 0; + muonRho = 0; + vertexEta = 0; + vertexPhi = 0; + } //parentPdgId = 0; TODO } @@ -71,12 +79,47 @@ MatchingResult::MatchingResult(const TrackingParticle& trackingParticle) : track genCharge = trackingParticle.charge(); muonDxy = this->trackingParticle->dxy(); - muonRho = this->trackingParticle->parentVertex()->position().Rho(); + if (this->trackingParticle->parentVertex().isNonnull()) { + muonRho = this->trackingParticle->parentVertex()->position().Rho(); + vertexEta = this->trackingParticle->parentVertex()->position().eta(); + vertexPhi = this->trackingParticle->parentVertex()->position().phi(); + } else { + muonRho = 0; + vertexEta = 0; + vertexPhi = 0; + } +} + + +std::ostream &operator<<(std::ostream &out, const MatchingResult& matchingResult) { + out << "matchingResult:\n"; + if(matchingResult.simTrack || matchingResult.trackingParticle) { + out << " simTrack type " << std::setw(5) << matchingResult.pdgId + << " pt " << std::setw(8) << matchingResult.genPt <<" GeV" + << " eta " << std::setw(8) << matchingResult.genEta + << " phi " << std::setw(8) << matchingResult.genPhi + << " charge " << std::setw(2) << matchingResult.genCharge + << " vertexEta " << std::setw(8) << matchingResult.vertexEta + << " vertexPhi " << std::setw(8) << matchingResult.vertexPhi + << " muonDxy " << std::setw(8) << matchingResult.muonDxy + << " muonRho " << std::setw(8) << matchingResult.muonRho + << " parentPdgId " << std::setw(5) << matchingResult.parentPdgId; + } else { + out << " no matched simTrack/trackingParticle"; + } + out << "\n muonCand: " ; + if(matchingResult.muonCand) + out << *(matchingResult.muonCand); + else + out << " no matched muonCand "; - vertexEta = this->trackingParticle->parentVertex()->position().eta(); - vertexPhi = this->trackingParticle->parentVertex()->position().phi(); + out << "\n deltaEta " << std::setw(8) << matchingResult.deltaEta << " deltaPhi " << std::setw(8) << matchingResult.deltaPhi + << " Likelihood " << std::setw(8) << matchingResult.matchingLikelihood << " result " + << (short)matchingResult.result << std::endl; + return out; } + int CandidateSimMuonMatcher::calcGlobalPhi(int locPhi, int proc) { int globPhi = 0; //60 degree sectors = 96 in int-scale @@ -107,7 +150,6 @@ CandidateSimMuonMatcher::CandidateSimMuonMatcher( TFile muonMatcherFile(muonMatcherFileName.c_str()); edm::LogImportant("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: using muonMatcherFileName " << muonMatcherFileName << std::endl; - if (edmCfg.exists("candidateSimMuonMatcherType")) { if (edmCfg.getParameter("candidateSimMuonMatcherType") == "withPropagator") matchingType = MatchingType::withPropagator; @@ -125,31 +167,52 @@ CandidateSimMuonMatcher::CandidateSimMuonMatcher( edm::LogImportant("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: matchingType " << static_cast(matchingType) << std::endl; + + // Try to read histograms from the file; be defensive if file/histograms are missing + if (muonMatcherFile.IsZombie()) { + edm::LogWarning("l1tOmtfEventPrint") << "CandidateSimMuonMatcher: muon matcher file could not be opened: " + << muonMatcherFileName << std::endl; + throw cms::Exception("MissingFile") << "CandidateSimMuonMatcher: muon matcher file could not be opened: " + << muonMatcherFileName << std::endl; + } else { + edm::LogImportant("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: reading histograms from file " << std::endl; + minDelta_pos = dynamic_cast(muonMatcherFile.Get("minDelta_pos")); + LogTrace("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: " << __LINE__ << std::endl; + maxDelta_pos = dynamic_cast(muonMatcherFile.Get("maxDelta_pos")); + medianDelta_pos = dynamic_cast(muonMatcherFile.Get("medianDelta_pos")); + + LogTrace("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: " << __LINE__ << std::endl; + minDelta_neg = dynamic_cast(muonMatcherFile.Get("minDelta_neg")); + maxDelta_neg = dynamic_cast(muonMatcherFile.Get("maxDelta_neg")); + medianDelta_neg = dynamic_cast(muonMatcherFile.Get("medianDelta_neg")); + + LogTrace("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: " << __LINE__ << std::endl; + if(!minDelta_pos || !maxDelta_pos || !medianDelta_pos || !minDelta_neg || !maxDelta_neg || !medianDelta_neg) { + edm::LogWarning("l1tOmtfEventPrint") << "CandidateSimMuonMatcher: one or more histograms are missing in the file: " + << muonMatcherFileName << std::endl; + throw cms::Exception("MissingHistogram") << "CandidateSimMuonMatcher: one or more histograms are missing in the file: " + << muonMatcherFileName << std::endl; + } - minDelta_pos = (TH1F*)muonMatcherFile.Get("minDelta_pos"); - maxDelta_pos = (TH1F*)muonMatcherFile.Get("maxDelta_pos"); - medianDelta_pos = (TH1F*)muonMatcherFile.Get("medianDelta_pos"); - - minDelta_neg = (TH1F*)muonMatcherFile.Get("minDelta_neg"); - maxDelta_neg = (TH1F*)muonMatcherFile.Get("maxDelta_neg"); - medianDelta_neg = (TH1F*)muonMatcherFile.Get("medianDelta_neg"); - - //detaching the histograms from the file - minDelta_pos->SetDirectory(nullptr); - maxDelta_pos->SetDirectory(nullptr); - medianDelta_pos->SetDirectory(nullptr); - minDelta_neg->SetDirectory(nullptr); - maxDelta_neg->SetDirectory(nullptr); - medianDelta_neg->SetDirectory(nullptr); + // Detach histograms from the file so they survive file close + //it must be like that to assure the histograms leave outside this scope. + //muonMatcherFile as pointer-field in the class somehow does not work. + minDelta_pos->SetDirectory(nullptr); + maxDelta_pos->SetDirectory(nullptr); + medianDelta_pos->SetDirectory(nullptr); + minDelta_neg->SetDirectory(nullptr); + maxDelta_neg->SetDirectory(nullptr); + medianDelta_neg->SetDirectory(nullptr); + } } CandidateSimMuonMatcher::~CandidateSimMuonMatcher() { - delete minDelta_pos; - delete maxDelta_pos; - delete medianDelta_pos; - delete minDelta_neg; - delete maxDelta_neg; - delete medianDelta_neg; + if(minDelta_pos) delete minDelta_pos; + if(maxDelta_pos) delete maxDelta_pos; + if(medianDelta_pos) delete medianDelta_pos; + if(minDelta_neg) delete minDelta_neg; + if(maxDelta_neg) delete maxDelta_neg; + if(medianDelta_neg) delete medianDelta_neg; } void CandidateSimMuonMatcher::beginRun(const edm::EventSetup& eventSetup) { @@ -166,10 +229,11 @@ void CandidateSimMuonMatcher::observeProcesorEmulation(unsigned int iProcessor, const AlgoMuons& algoCandidates, const AlgoMuons& gbCandidates, const FinalMuons& finalMuons) { - //debug + //debug, gbCandidate are not used outside this method //unsigned int procIndx = omtfConfig->getProcIndx(iProcessor, mtfType); for (auto& gbCandidate : gbCandidates) { - if (gbCandidate->getPtConstr() > 0) { + //if (gbCandidate->getPtConstr() > 0) + { LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::observeProcesorEmulation iProcessor " << iProcessor << " mtfType " << mtfType << *gbCandidate << std::endl; this->gbCandidates.emplace_back(gbCandidate); @@ -242,21 +306,24 @@ bool trackingParticleIsMuonInBx0(const TrackingParticle& trackingParticle) { bool trackingParticleIsMuonInBx0Displ(const TrackingParticle& trackingParticle) { if (std::abs(trackingParticle.pdgId()) == 13 || - std::abs(trackingParticle.pdgId()) == - 1000015) { // 1000015 is stau, todo use other selection (e.g. pt>20) if needed + std::abs(trackingParticle.pdgId()) == 1000015) { // 1000015 is stau //in the overlap, the propagation of muons with pt less then ~3.2 fails - the actual threshold depends slightly on eta, if (trackingParticle.pt() < 2.) return false; - if (trackingParticle.dxy() < 30) { - if ((std::abs(trackingParticle.momentum().eta()) < 0.7) || (std::abs(trackingParticle.momentum().eta()) > 1.31)) - return false; - } else { - if ((std::abs(trackingParticle.parentVertex()->position().eta()) < 0.7) || - (std::abs(trackingParticle.parentVertex()->position().eta()) > 1.4)) - return false; + if (trackingParticle.parentVertex().isNonnull()) { + if (trackingParticle.dxy() < 30) { + if ((std::abs(trackingParticle.momentum().eta()) < 0.7) || (std::abs(trackingParticle.momentum().eta()) > 1.31)) + return false; + } else { + if ((std::abs(trackingParticle.parentVertex()->position().eta()) < 0.7) || + (std::abs(trackingParticle.parentVertex()->position().eta()) > 1.4)) + return false; + } } + else + throw cms::Exception("CandidateSimMuonMatcher", "trackingParticleIsMuonInBx0Displ: trackingParticle has no parent vertex"); //only muons if (trackingParticle.eventId().bunchCrossing() == 0) @@ -372,14 +439,15 @@ void CandidateSimMuonMatcher::endJob() {} FinalMuons CandidateSimMuonMatcher::ghostBust(const FinalMuons& finalMuons) { boost::dynamic_bitset<> isKilled(finalMuons.size(), false); - + //finalMuons are nonempty for (unsigned int i1 = 0; i1 < finalMuons.size(); ++i1) { - if (finalMuons[i1]->getPtGmt() == 0) - continue; - LogTrace("l1tOmtfEventPrint") << "\nCandidateSimMuonMatcher::ghostBust regionalCand pt " << std::setw(3) - << finalMuons[i1]->getPtGmt() << " qual " << std::setw(2) - << finalMuons[i1]->getQuality() << " proc " << std::setw(2) - << finalMuons[i1]->getProcessor() << " PhiRad " << finalMuons[i1]->getPhiRad() << " etaRad " << finalMuons[i1]->getEtaRad(); + LogTrace("l1tOmtfEventPrint") << "\nCandidateSimMuonMatcher::ghostBusting\n" << *(finalMuons[i1]); + if (finalMuons[i1]->getPtGmt() <= 0) { + //PtGmt > 0 marks valid candidate both for phase1 and phase2. But it should not matter here, as all finalMuons are not empty, so it just a safety check + throw cms::Exception("CandidateSimMuonMatcher") + << "CandidateSimMuonMatcher::ghostBust finalMuons[" << i1 << "] has ptGmt <= 0, ptGmt " + << finalMuons[i1]->getPtGmt() << std::endl; + } for (unsigned int i2 = i1 + 1; i2 < finalMuons.size(); ++i2) { auto& mtfCand1 = finalMuons[i1]; auto& mtfCand2 = finalMuons[i2]; @@ -407,26 +475,21 @@ FinalMuons CandidateSimMuonMatcher::ghostBust(const FinalMuons& finalMuons) { FinalMuons resultCands; + LogTrace("l1tOmtfEventPrint") << "\nCandidateSimMuonMatcher::ghostBust - after ghostBusting:" << std::endl; for (unsigned int i1 = 0; i1 < finalMuons.size(); ++i1) { - //dropping candidates with quality 0 and 1 !!!!!!!!!!!!!!!!!!!! fixme if not needed - if (!isKilled[i1] && finalMuons[i1]->getQuality() > 1) { + //not dropping candidates with quality 0 and 1 + if (!isKilled[i1]) { //&& finalMuons[i1]->getQuality() > 1 resultCands.push_back(finalMuons[i1]); } - if (finalMuons[i1]->getPtGmt() > 0) { - LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::ghostBust\n" - << "finalMuon pt " << std::setw(3) << finalMuons[i1]->getPtGmt() - << " qual " << std::setw(2) << finalMuons[i1]->getQuality() - << " proc " << std::setw(2) << finalMuons[i1]->getProcessor() - //<< " eta " << std::setw(4) << finalMuons[i1]->getEta() - << " gloablEta " << std::setw(8) << finalMuons[i1]->getEtaRad() - << " globalPhi " << std::setw(8) << finalMuons[i1]->getPhiRad() - //<< " fireaLayers " << std::bitset<18>(mtfCands->at(0, i1).trackAddress().at(0)) - << " gb isKilled " << isKilled.test(i1) << std::endl; + //if (finalMuons[i1]->getPtGmt() > 0) checked earlier, so it is not needed here + { //PtGmt > 0 marks valid candidate both for phase1 and phase2. But it should not matter here, as all finalMuons are not empty + LogTrace("l1tOmtfEventPrint")<< *(finalMuons[i1]) << " gb isKilled " << isKilled.test(i1) << std::endl; //LogTrace("l1tOmtfEventPrint") << *(gbCandidates.at(i1)) << std::endl; if (finalMuons[i1]->getAlgoMuon()) LogTrace("l1tOmtfEventPrint") << *(finalMuons[i1]->getAlgoMuon()) << std::endl; + LogTrace("l1tOmtfEventPrint") << std::endl; } } @@ -489,6 +552,8 @@ TrajectoryStateOnSurface CandidateSimMuonMatcher::propagate(const SimTrack& simT if (((int)simVertex.vertexId()) != vtxInd) { edm::LogImportant("l1tOmtfEventPrint") << "simVertex.vertexId() != vtxInd. simVertex.vertexId() " << simVertex.vertexId() << " vtxInd " << vtxInd << " !!!!!!!!!!!!!!!!!"; + throw cms::Exception("CandidateSimMuonMatcher", + "CandidateSimMuonMatcher::propagate: simVertex.vertexId() != vtxInd"); } } @@ -574,18 +639,7 @@ void CandidateSimMuonMatcher::match(const FinalMuonPtr& finalMuon, MatchingResul result.result = MatchingResult::ResultType::matched; } - LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match: simTrack type " << result.pdgId << " pt " - << std::setw(8) << trackPt << " eta " << std::setw(8) << result.genEta << " phi " - << std::setw(8) << result.genPhi << " propagatedEta " << std::setw(8) - << result.propagatedEta << " propagatedPhi " << result.propagatedPhi - << "\n muonCand pt " << std::setw(8) << finalMuon->getPtGmt() - << " candGloablEta " << std::setw(8) << finalMuon->getEtaGmt() - << " candGlobalPhi " << std::setw(8) << finalMuon->getPhiGmt() - //<< " hwPhi " << muonCand->hwPhi() - << " hwQual " << finalMuon->getQuality() << " processor " << finalMuon->getProcessor() - << " deltaEta " << std::setw(8) << result.deltaEta << " deltaPhi " << std::setw(8) << result.deltaPhi - << " Likelihood " << std::setw(8) << result.matchingLikelihood << " result " - << (short)result.result << std::endl; + LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match::" << __LINE__ << "\n" << result << std::endl; } } @@ -620,8 +674,9 @@ std::vector CandidateSimMuonMatcher::cleanMatching(std::vectorgetPtGmt() == 0 || muonCand->getQuality() == 0) - continue; + //PtGmt > 0 marks valid candidate both for phase1 and phase2. But this check is done in ghostBust + //if(muonCand->getPtGmt() == 0) // || muonCand->getQuality() == 0 + // continue; bool isMatched = false; for (auto& matchingResult : cleanedMatchingResults) { @@ -641,23 +696,7 @@ std::vector CandidateSimMuonMatcher::cleanMatching(std::vectorgetPtGmt() << " hwQual " - << result.muonCand->getQuality() << " eta " << result.muonCand->getEtaRad() - << " deltaEta " << std::setw(8) << result.deltaEta << " deltaPhi " << std::setw(8) - << result.deltaPhi << " Likelihood " << std::setw(8) << result.matchingLikelihood - << " result " << (short)result.result; - //LogTrace("l1tOmtfEventPrint") << " procMuon " << *(result.procMuon) << std::endl; - } else - LogTrace("l1tOmtfEventPrint") << " no muonCand " - << " result " << (short)result.result << std::endl; + LogTrace("l1tOmtfEventPrint") << result<< std::endl<< std::endl; } LogTrace("l1tOmtfEventPrint") << " " << std::endl; @@ -667,21 +706,45 @@ std::vector CandidateSimMuonMatcher::cleanMatching(std::vectorFindBin(result.genPt); - result.propagatedPhi = foldPhi(result.genPhi + medianDelta->GetBinContent(ptBin)); + auto ptBin = medianDelta->FindBin(result.genPt); + result.propagatedPhi = foldPhi(result.genPhi + medianDelta->GetBinContent(ptBin)); result.propagatedEta = result.genEta; }; if (matchingType == MatchingType::withPropagator) { - //TODO if result.simVertex is null it will crash - add a protection - FreeTrajectoryState ftsTrack = result.simTrack ? simTrackToFts(*(result.simTrack), *(result.simVertex)) - : simTrackToFts(*result.trackingParticle); - + FreeTrajectoryState ftsTrack; + if (result.simTrack) { + if (result.simVertex) { + ftsTrack = simTrackToFts(*(result.simTrack), *(result.simVertex)); + } else { + throw cms::Exception("CandidateSimMuonMatcher") + << "CandidateSimMuonMatcher::propagate - simTrack exists but simVertex is missing!!!"; + //throw, to be sue that the issue is noticed. + // Alternatively, if simTrack exists but simVertex is missing, + // fall back to a default vertex at (0,0,0). Or doSimplePropagation(). + SimVertex defVtx; // default constructed vertex at origin + ftsTrack = simTrackToFts(*(result.simTrack), defVtx); + edm::LogImportant("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::propagate - simTrack has no simVertex, using default vertex" << std::endl; + } + } else if (result.trackingParticle) { + if(result.trackingParticle->parentVertex().isNonnull()) + ftsTrack = simTrackToFts(*result.trackingParticle); + else { + edm::LogImportant("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::propagate - trackingParticle has no parentVertex!!!" << std::endl; + throw cms::Exception("CandidateSimMuonMatcher") + << "CandidateSimMuonMatcher::propagate - trackingParticle has no parentVertex!!!"; + } + } else { + // Nothing to propagate + result.result = MatchingResult::ResultType::propagationFailed; + return; + } + //TODO check if the ftsTrack is valid TrajectoryStateOnSurface tsof = atStation2(ftsTrack); //propagation if (!tsof.isValid()) { if (result.genPt > 2.5 && result.trackingParticle && result.trackingParticle->parentVertex().isNonnull()) { - if (result.muonRho < 40) { + if (result.muonRho < 40) { //TODO why it is done only for trackingParticle and not for simTrack? doSimplePropagation(); } } else { @@ -739,7 +802,8 @@ void CandidateSimMuonMatcher::match(const FinalMuons& finalMuons, bool matched = false; for (auto& muonCand : finalMuons) { //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive - if (muonCand->getQuality() > 1) { + //if (muonCand->getQuality() > 1) + { //TOOD uncomment, if this condition is needed MatchingResult resultCopy = result; match(muonCand, resultCopy); @@ -752,7 +816,7 @@ void CandidateSimMuonMatcher::match(const FinalMuons& finalMuons, iCand++; } - if (!matched) { //we are adding also if it was not matching to any candidate + if (!matched) { //adding matchingResults (i.e. simMuon in this case) also if it was not matched to any candidate matchingResults.push_back(result); LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << __LINE__ << " no matching candidate found" << std::endl; } @@ -770,7 +834,7 @@ std::vector CandidateSimMuonMatcher::match(const FinalMuons& fin continue; LogTrace("l1tOmtfEventPrint") << "\nCandidateSimMuonMatcher::match, simTrack type " << std::setw(3) - << simTrack.type() << " pt " << std::setw(9) << simTrack.momentum().pt() << " eta " + << simTrack.type() << " pt " << std::setw(9) << simTrack.momentum().pt() << " GeV eta " << std::setw(9) << simTrack.momentum().eta() << " phi " << std::setw(9) << simTrack.momentum().phi() << " rho " << (simTrack.vertIndex() >= 0 ? simVertices->at(simTrack.vertIndex()).position().Rho() @@ -813,7 +877,7 @@ std::vector CandidateSimMuonMatcher::match( LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::match, trackingParticle type " << std::setw(3) << trackingParticle.pdgId() << " pt " << std::setw(9) << trackingParticle.pt() - << " eta " << std::setw(9) << trackingParticle.momentum().eta() << " phi " + << " GeV eta " << std::setw(9) << trackingParticle.momentum().eta() << " phi " << std::setw(9) << trackingParticle.momentum().phi() << std::endl; MatchingResult result(trackingParticle); @@ -836,7 +900,7 @@ std::vector CandidateSimMuonMatcher::matchSimple( continue; LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::matchSimple: simTrack type " << std::setw(3) - << simTrack.type() << " pt " << std::setw(9) << simTrack.momentum().pt() << " eta " + << simTrack.type() << " pt " << std::setw(9) << simTrack.momentum().pt() << " GeV eta " << std::setw(9) << simTrack.momentum().eta() << " phi " << std::setw(9) << simTrack.momentum().phi() << std::endl; @@ -845,7 +909,7 @@ std::vector CandidateSimMuonMatcher::matchSimple( for (auto& finalMuon : finalMuons) { //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive //if(muonCand->hwQual() > 1) - if (finalMuon->getPtGev() > 0) + //if (finalMuon->getPtGev() > 0) in phase-1 ptGeV=0 is possible for a valid candidate { MatchingResult result(simTrack, simTrack.vertIndex() >= 0 ? &(simVertices->at(simTrack.vertIndex())) : nullptr); @@ -883,15 +947,7 @@ std::vector CandidateSimMuonMatcher::matchSimple( result.matchingLikelihood = 1. / (std::abs(result.deltaPhi) + 0.001); } - LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::matchSimple: simTrack type " << simTrack.type() - << " pt " << std::setw(8) << simTrack.momentum().pt() << " eta " << std::setw(8) - << simTrack.momentum().eta() << " phi " << std::setw(8) - << simTrack.momentum().phi() << "\n muonCand pt " << std::setw(8) - << finalMuon->getPtGmt() << " candGloablEta " << std::setw(8) << finalMuon->getEtaRad() - << " candGlobalPhi " << std::setw(8) << finalMuon->getPhiRad() << " hwQual " - << finalMuon->getQuality() << " deltaEta " << std::setw(8) << result.deltaEta - << " deltaPhi " << std::setw(8) << result.deltaPhi << " matchingLikelihood " - << result.matchingLikelihood << " result " << (short)result.result << std::endl; + LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::matchSimple:\n" << result << std::endl; if (result.result == MatchingResult::ResultType::matched) { matchingResults.push_back(result); @@ -915,20 +971,15 @@ std::vector CandidateSimMuonMatcher::matchSimple( std::vector CandidateSimMuonMatcher::collectMuonCands(const FinalMuons& finalMuons) { std::vector matchingResults; unsigned int iCand = 0; - for (auto& muonCand : finalMuons) { + for (auto& finalMuon : finalMuons) { //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive //if(muonCand->hwQual() > 1) { MatchingResult result; - result.muonCand = muonCand; + result.muonCand = finalMuon; - LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::collectMuonCands: muonCand pt " << std::setw(8) - << muonCand->getPtGmt() << " candGloablEta " << std::setw(8) << muonCand->getEtaRad() - << " candGlobalPhi " << std::setw(8) << muonCand->getPhiRad() << " hwQual " - << muonCand->getQuality() << " deltaEta " << std::setw(8) << result.deltaEta - << " deltaPhi " << std::setw(8) << result.deltaPhi << " matchingLikelihood " - << result.matchingLikelihood << " result " << (short)result.result << std::endl; + LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::collectMuonCands: " << *finalMuon << std::endl; matchingResults.push_back(result); } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc index 2d73a99bf7ac7..be952a7d56eae 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc @@ -264,7 +264,7 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, FinalMuons& fina } auto addOmtfCand = [&](FinalMuonPtr muonCand) { - //the charge is only for the constrained measurement. The constrained measurement is always defined for a valid candidate + //The constrained measurement is always defined for a valid candidate. In principle here only valid candidates should be, so this check is redundant. if (muonCand->getAlgoMuon()->getPdfSumConstr() > 0 && muonCand->getAlgoMuon()->getFiredLayerCntConstr() >= 3) omtfEvent.omtfPt = muonCand->getPtGev(); else if (muonCand->getAlgoMuon()->getPtUnconstr() > 0) @@ -448,5 +448,4 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, FinalMuons& fina void DataROOTDumper2::endJob() { edm::LogVerbatim("l1tOmtfEventPrint") << " evntCnt " << evntCnt << endl; - rootTree->Write(); } diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc index 5148f72390e2f..1f1cbcf3346d3 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc @@ -132,6 +132,13 @@ void OmtfProcessorPhase2::assignQualityPhase2(AlgoMuons::value_type& algoMuon) { if (!algoMuon->isValid()) return; + //better not to assume anything about quality for pt=0 candidates + /*if (algoMuon->getPtConstr() == 0) { + algoMuon->setQuality(0); //default value + return; + }*/ + + //TODO agree on meaning of quality = 0 if (abs(algoMuon->getEtaHw()) >= omtfConfig->etaToHwEta(1.3)) { algoMuon->setQuality(0); return; @@ -154,11 +161,6 @@ void OmtfProcessorPhase2::assignQualityPhase2(AlgoMuons::value_type& algoMuon) { } auto it = firedLayersToQuality.find(algoMuon->getFiredLayerBits()); - if (algoMuon->getPtConstr() == 0) { - algoMuon->setQuality(0); //default value - return; - } - if (it != firedLayersToQuality.end()) { algoMuon->setQuality(it->second); } else { @@ -184,7 +186,7 @@ void OmtfProcessorPhase2::convertToGmtScalesPhase2(unsigned int iProcessor, l1t: } //in getFinalMuons the PtGeV is set to 0 in this case, as it is like that for the phase-1. - //but it is better to set non-0 pt in this case, so we set 1 GeV + //but for the phase-2 pt = 0 means empty candidate, so we set 1 GeV in this case if (finalMuon->getAlgoMuon()->getPdfSumConstr() == 0 && finalMuon->getAlgoMuon()->getPtUnconstr() > 0) finalMuon->setPtGev(1.0); //set to 1 GeV to be able to distinguish from pt=0, which means no candidate From ce20e99ed470cf2f586932df0eb45cbfe2af273a Mon Sep 17 00:00:00 2001 From: Karol Bunkowski Date: Tue, 11 Nov 2025 23:19:54 +0100 Subject: [PATCH 05/12] after code-checks and code-format --- .../interface/Omtf/AlgoMuon.h | 4 +- .../interface/Omtf/FinalMuon.h | 144 ++++------- .../interface/Omtf/OMTFConfiguration.h | 8 +- .../interface/Omtf/OMTFProcessor.h | 6 +- .../interface/Omtf/OMTFReconstruction.h | 10 +- .../interface/Omtf/OmtfAngleConverter.h | 7 +- .../interface/ProcConfigurationBase.h | 1 - .../interface/Tools/CandidateSimMuonMatcher.h | 7 +- .../src/MuonStubMakerBase.cc | 13 +- .../src/Omtf/FinalMuon.cc | 22 +- .../src/Omtf/GhostBuster.cc | 3 +- .../src/Omtf/GhostBusterPreferRefDt.cc | 11 +- .../src/Omtf/OMTFConfiguration.cc | 1 - .../src/Omtf/OMTFProcessor.cc | 234 +++++++++--------- .../src/Omtf/OMTFReconstruction.cc | 2 +- .../src/Omtf/OmtfAngleConverter.cc | 10 +- .../src/Tools/CandidateSimMuonMatcher.cc | 136 +++++----- .../src/Tools/DataROOTDumper2.cc | 24 +- .../src/Tools/EventCapture.cc | 49 ++-- .../src/Tools/StubsSimHitsMatching.cc | 4 +- .../interface/NNRegression.h | 4 +- .../interface/OmtfEmulation.h | 9 +- .../interface/OmtfProcessorPhase2.h | 1 - .../L1TMuonOverlapPhase2TrackProducer.cc | 1 - .../src/InputMakerPhase2.cc | 6 +- .../L1TMuonOverlapPhase2/src/NNRegression.cc | 9 +- .../L1TMuonOverlapPhase2/src/OmtfEmulation.cc | 24 +- .../src/OmtfPhase2AngleConverter.cc | 8 +- .../src/OmtfProcessorPhase2.cc | 80 +++--- 29 files changed, 390 insertions(+), 448 deletions(-) diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h index 27c2653f390e2..066b78b5c5bca 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h @@ -43,9 +43,7 @@ class AlgoMuon { int getPtConstr() const { return goldenPaternConstr == nullptr ? 0 : goldenPaternConstr->key().thePt; } //hardware upt, in the pattens scale, not in the GMT scale - int getPtUnconstr() const { - return goldenPaternUnconstr == nullptr ? 0 : goldenPaternUnconstr->key().thePt; - } + int getPtUnconstr() const { return goldenPaternUnconstr == nullptr ? 0 : goldenPaternUnconstr->key().thePt; } int getChargeConstr() const { return goldenPaternConstr == nullptr ? -1 : goldenPaternConstr->key().theCharge; } diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h index 9258ad22bf699..810d182dad740 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h @@ -13,10 +13,8 @@ class FinalMuon { public: FinalMuon() {}; - FinalMuon(const AlgoMuonPtr& algoMuon) : - algoMuon(algoMuon), - quality(algoMuon->getQuality()), - firedLayerCnt(algoMuon->getFiredLayerCnt()) {}; + FinalMuon(const AlgoMuonPtr& algoMuon) + : algoMuon(algoMuon), quality(algoMuon->getQuality()), firedLayerCnt(algoMuon->getFiredLayerCnt()) {}; virtual ~FinalMuon() {}; @@ -26,107 +24,63 @@ class FinalMuon { void setSign(int sign = 0) { this->sign = sign; } - void setBx(int bx = 0) { - this->bx = bx; - } + void setBx(int bx = 0) { this->bx = bx; } - int getBx() const { - return bx; - } + int getBx() const { return bx; } - int getProcessor() const { - return processor; - } + int getProcessor() const { return processor; } - void setProcessor(int processor = -1) { - this->processor = processor; - } + void setProcessor(int processor = -1) { this->processor = processor; } - void setTrackFinderType(l1t::tftype mtfType) { - this->mtfType = mtfType; - } - l1t::tftype trackFinderType() const { - return mtfType; - } + 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; - } + 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; @@ -137,7 +91,7 @@ class FinalMuon { int quality = 0; int sign = 0; - + float ptGev = -1; float ptUnconstrGev = -1; float phiRad = -10; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h index a48c8feb2ca9e..1ff8423146831 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h @@ -141,7 +141,7 @@ class OMTFConfiguration : public ProcConfigurationBase { double ptUnit = 0.5; // GeV/unit ///uGMT pt scale conversion //TODO refactor to omtfPtToGev - double hwPtToGev(int hwPt) const override { return (hwPt == 0 ? 0 : (hwPt - 1.) * ptUnit);} + 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); } @@ -149,7 +149,7 @@ class OMTFConfiguration : public ProcConfigurationBase { ///center of eta bin virtual double hwEtaToEta(int hwEta) const { return (hwEta * etaUnit_); } - //TODO use version with round + //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_); } @@ -173,9 +173,7 @@ class OMTFConfiguration : public ProcConfigurationBase { } //eta of the middle DT Wheel 2 MB4, in the OMTF scale - int mb4W2Eta() const override { - return etaToHwEta(0.67); - } + int mb4W2Eta() const override { return etaToHwEta(0.67); } static unsigned int eta2Bits(unsigned int eta); diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h index c9a883fc5431b..c060a620b608d 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h @@ -101,14 +101,14 @@ class OMTFProcessor : public ProcessorBase, public IProcessor } 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); + FinalMuons& finalMuons) override; ///allows to use other sorter implementation than the default one virtual void setSorter(SorterBase* sorter) { this->sorter.reset(sorter); } diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h index 950e9696a8252..19e2152ee0090 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h @@ -44,11 +44,11 @@ class OMTFReconstruction { void endJob(); 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); + 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&); diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h index 0ff378d4be0bf..934f59f302a23 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h @@ -66,14 +66,13 @@ class OmtfAngleConverter { ///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& aDigi, float& r) const; protected: ///Check orientation of strips in given CSC chamber diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h index c202c142ff11e..c287790893eaf 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h @@ -116,7 +116,6 @@ class ProcConfigurationBase { double etaUnit() const { return etaUnit_; } protected: - double etaUnit_ = 0.010875; //=2.61/240 - value from the phase1 interface note private: diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h index 422e1460c436f..8cb869fa57d24 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/CandidateSimMuonMatcher.h @@ -137,14 +137,11 @@ class CandidateSimMuonMatcher : public IOMTFEmulationObserver { void propagate(MatchingResult& result); - void match(const FinalMuons& finalMuons, - MatchingResult& result, - std::vector& matchingResults); + void match(const FinalMuons& finalMuons, MatchingResult& result, std::vector& matchingResults); void match(const FinalMuonPtr& finalMuon3, MatchingResult& result); - std::vector cleanMatching(std::vector matchingResults, - const FinalMuons& finalMuons); + std::vector cleanMatching(std::vector matchingResults, const FinalMuons& finalMuons); std::vector match(const FinalMuons& finalMuons, const edm::SimTrackContainer* simTracks, diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/MuonStubMakerBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/MuonStubMakerBase.cc index 304c83b642b23..41200216c4d5c 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/MuonStubMakerBase.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/MuonStubMakerBase.cc @@ -79,16 +79,15 @@ void CscDigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers, 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(".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())); - } } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/FinalMuon.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/FinalMuon.cc index aef30f7364f68..823c873efdabb 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/FinalMuon.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/FinalMuon.cc @@ -11,17 +11,15 @@ #include std::ostream &operator<<(std::ostream &out, const FinalMuon &finalMuon) { - out << "finalMuon" - << " pt " << std::setw(8) << finalMuon.ptGev << " GeV" - << " eta " << std::setw(8) << finalMuon.etaRad - << " phi " << std::setw(8) << finalMuon.phiRad - << " sign " << std::setw(2) << finalMuon.sign - << " ptGmt " << std::setw(8) << finalMuon.getPtGmt() - << " etaGmt " << std::setw(8) << finalMuon.getEtaGmt() - << " phiGmt " << std::setw(8) << finalMuon.getPhiGmt() - //<< " hwPhi " << muonCand->hwPhi() - << " hwQual " << finalMuon.getQuality() << " processor " << finalMuon.getProcessor(); + 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 46a81cf14a64a..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->procPhiToGmtPhase1Phi((*it1)->getPhi()) - omtfConfig->procPhiToGmtPhase1Phi((*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 a70cdcb0d4b04..9040241b231cf 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/GhostBusterPreferRefDt.cc @@ -182,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->procPhiToGmtPhase1Phi(muIN1->getPhi()) - omtfConfig->procPhiToGmtPhase1Phi(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); @@ -195,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()) == 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)) { + (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/OMTFConfiguration.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc index aebfa92afb7ba..ea1cde892c7e4 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc @@ -543,7 +543,6 @@ int OMTFConfiguration::getProcScalePhi(unsigned int iProcessor, double phiRad) c return lround((phiRad - phi15deg) / phiUnit); //FIXME lround or floor ??? } - //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 diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc index 70360d88f72a3..e849f9f12ad02 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc @@ -104,7 +104,7 @@ void OMTFProcessor::assignQuality(AlgoMuons::value_type& algo 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()); + 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() || @@ -157,82 +157,81 @@ void OMTFProcessor::assignQuality(AlgoMuons::value_type& algo 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()) + 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) @@ -243,26 +242,23 @@ void OMTFProcessor::assignQuality(AlgoMuons::value_type& algo template FinalMuons OMTFProcessor::getFinalMuons(unsigned int iProcessor, - l1t::tftype mtfType, - const AlgoMuons& gbCandidates) { + 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); - + //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) { + } 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 { + } else { //empty candidates are not added to the finalMuons continue; } @@ -273,8 +269,7 @@ FinalMuons OMTFProcessor::getFinalMuons(unsigned int iProcess if (mtfType == l1t::omtf_pos) { finalMuon->setEtaRad(this->myOmtfConfig->hwEtaToEta(algoMuon->getEtaHw())); - } - else { + } else { finalMuon->setEtaRad((-1) * this->myOmtfConfig->hwEtaToEta(algoMuon->getEtaHw())); } @@ -291,38 +286,37 @@ FinalMuons OMTFProcessor::getFinalMuons(unsigned int iProcess 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->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()); - } + 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->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()); + } - //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); + //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); } /////////////////////////////////////////////////////// /////////////////////////////////////////////////////// @@ -899,7 +893,7 @@ FinalMuons OMTFProcessor::run(unsigned int iProcessor, // perform GB //watch out: etaBits2HwEta is used in the ghostBust to convert the AlgoMuons eta, it affect algoCandidates as they are pointers AlgoMuons gbCandidates = ghostBust(algoCandidates); - + //assignQuality must be called after ghostBust, because eta is set there for (auto& gbCandidate : gbCandidates) { assignQuality(gbCandidate); @@ -909,7 +903,7 @@ FinalMuons OMTFProcessor::run(unsigned int iProcessor, FinalMuons finalMuons = getFinalMuons(iProcessor, mtfType, gbCandidates); - for(auto& finalMuon : finalMuons) { + for (auto& finalMuon : finalMuons) { finalMuon->setBx(bx); } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc index 64c23a036ac71..2c16a02fe44f6 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc @@ -31,7 +31,7 @@ OMTFReconstruction::OMTFReconstruction(const edm::ParameterSet& parameterSet, Mu omtfConfig(new OMTFConfiguration()), omtfProc(nullptr), m_OMTFConfigMaker(nullptr) { - edmParameterSet.copyForModify(parameterSet); //why edmParameterSet is not reference? + edmParameterSet.copyForModify(parameterSet); //why edmParameterSet is not reference? bxMin = edmParameterSet.exists("bxMin") ? edmParameterSet.getParameter("bxMin") : 0; bxMax = edmParameterSet.exists("bxMax") ? edmParameterSet.getParameter("bxMax") : 0; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc index 53675b843619e..f08e8759bc872 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc @@ -69,7 +69,7 @@ namespace { return sign * code; } - int etaKeyWG2Code(const CSCDetId &detId, uint16_t keyWG) { + int etaKeyWG2Code(const CSCDetId& detId, uint16_t keyWG) { signed int etaCode = 121; if (detId.station() == 1 && detId.ring() == 2) { if (keyWG < 49) @@ -268,7 +268,7 @@ int OmtfAngleConverter::getProcessorPhi( /////////////////////////////////////// /////////////////////////////////////// int OmtfAngleConverter::getGlobalEta(const DTChamberId dTChamberId, - const L1MuDTChambThContainer *dtThDigis, + const L1MuDTChambThContainer* dtThDigis, int bxNum) const { //const DTChamberId dTChamberId(aDigi.whNum(),aDigi.stNum(),aDigi.scNum()+1); DTTrigGeom trig_geom(_geodt->chamber(dTChamberId), false); @@ -281,7 +281,7 @@ int OmtfAngleConverter::getGlobalEta(const DTChamberId dTChamberId, // TODO:::::>>> need to make sure this ordering doesn't flip under wheel sign const int NBTI_theta = ((dTChamberId.station() != 4) ? trig_geom.nCell(2) : trig_geom.nCell(3)); - const L1MuDTChambThDigi *theta_segm = + const L1MuDTChambThDigi* theta_segm = dtThDigis->chThetaSegm(dTChamberId.wheel(), dTChamberId.station(), dTChamberId.sector() - 1, bxNum); int bti_group = -1; @@ -322,7 +322,7 @@ int OmtfAngleConverter::getGlobalEta(const DTChamberId dTChamberId, /////////////////////////////////////// /////////////////////////////////////// -int OmtfAngleConverter::getGlobalEta(unsigned int rawid, const CSCCorrelatedLCTDigi &aDigi, float &r) const { +int OmtfAngleConverter::getGlobalEta(unsigned int rawid, const CSCCorrelatedLCTDigi& aDigi, float& r) const { ///Code taken from GeometryTranslator. ///Will be replaced by direct CSC phi local to global scale ///transformation as used in FPGA implementation @@ -386,7 +386,7 @@ int OmtfAngleConverter::getGlobalEta(unsigned int rawid, const CSCCorrelatedLCTD } /////////////////////////////////////// /////////////////////////////////////// -int OmtfAngleConverter::getGlobalEtaRpc(unsigned int rawid, const unsigned int &strip, float &r) const { +int OmtfAngleConverter::getGlobalEtaRpc(unsigned int rawid, const unsigned int& strip, float& r) const { const RPCDetId id(rawid); auto roll = _georpc->roll(id); const LocalPoint lp = roll->centreOfStrip((int)strip); diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc index 465f934216d45..1f6a03f2a4c9b 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc @@ -90,36 +90,34 @@ MatchingResult::MatchingResult(const TrackingParticle& trackingParticle) : track } } - -std::ostream &operator<<(std::ostream &out, const MatchingResult& matchingResult) { +std::ostream& operator<<(std::ostream& out, const MatchingResult& matchingResult) { out << "matchingResult:\n"; - if(matchingResult.simTrack || matchingResult.trackingParticle) { - out << " simTrack type " << std::setw(5) << matchingResult.pdgId - << " pt " << std::setw(8) << matchingResult.genPt <<" GeV" - << " eta " << std::setw(8) << matchingResult.genEta - << " phi " << std::setw(8) << matchingResult.genPhi - << " charge " << std::setw(2) << matchingResult.genCharge - << " vertexEta " << std::setw(8) << matchingResult.vertexEta - << " vertexPhi " << std::setw(8) << matchingResult.vertexPhi - << " muonDxy " << std::setw(8) << matchingResult.muonDxy - << " muonRho " << std::setw(8) << matchingResult.muonRho - << " parentPdgId " << std::setw(5) << matchingResult.parentPdgId; + if (matchingResult.simTrack || matchingResult.trackingParticle) { + out << " simTrack type " << std::setw(5) << matchingResult.pdgId; + out << " pt " << std::setw(8) << matchingResult.genPt << " GeV"; + out << " eta " << std::setw(8) << matchingResult.genEta; + out << " phi " << std::setw(8) << matchingResult.genPhi; + out << " charge " << std::setw(2) << matchingResult.genCharge; + out << " vertexEta " << std::setw(8) << matchingResult.vertexEta; + out << " vertexPhi " << std::setw(8) << matchingResult.vertexPhi; + out << " muonDxy " << std::setw(8) << matchingResult.muonDxy; + out << " muonRho " << std::setw(8) << matchingResult.muonRho; + out << " parentPdgId " << std::setw(5) << matchingResult.parentPdgId; } else { out << " no matched simTrack/trackingParticle"; } - out << "\n muonCand: " ; - if(matchingResult.muonCand) + out << "\n muonCand: "; + if (matchingResult.muonCand) out << *(matchingResult.muonCand); else out << " no matched muonCand "; - out << "\n deltaEta " << std::setw(8) << matchingResult.deltaEta << " deltaPhi " << std::setw(8) << matchingResult.deltaPhi - << " Likelihood " << std::setw(8) << matchingResult.matchingLikelihood << " result " - << (short)matchingResult.result << std::endl; + out << "\n deltaEta " << std::setw(8) << matchingResult.deltaEta << " deltaPhi " << std::setw(8) + << matchingResult.deltaPhi << " Likelihood " << std::setw(8) << matchingResult.matchingLikelihood << " result " + << (short)matchingResult.result << std::endl; return out; } - int CandidateSimMuonMatcher::calcGlobalPhi(int locPhi, int proc) { int globPhi = 0; //60 degree sectors = 96 in int-scale @@ -167,11 +165,11 @@ CandidateSimMuonMatcher::CandidateSimMuonMatcher( edm::LogImportant("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: matchingType " << static_cast(matchingType) << std::endl; - + // Try to read histograms from the file; be defensive if file/histograms are missing if (muonMatcherFile.IsZombie()) { edm::LogWarning("l1tOmtfEventPrint") << "CandidateSimMuonMatcher: muon matcher file could not be opened: " - << muonMatcherFileName << std::endl; + << muonMatcherFileName << std::endl; throw cms::Exception("MissingFile") << "CandidateSimMuonMatcher: muon matcher file could not be opened: " << muonMatcherFileName << std::endl; } else { @@ -187,11 +185,13 @@ CandidateSimMuonMatcher::CandidateSimMuonMatcher( medianDelta_neg = dynamic_cast(muonMatcherFile.Get("medianDelta_neg")); LogTrace("l1tOmtfEventPrint") << " CandidateSimMuonMatcher: " << __LINE__ << std::endl; - if(!minDelta_pos || !maxDelta_pos || !medianDelta_pos || !minDelta_neg || !maxDelta_neg || !medianDelta_neg) { - edm::LogWarning("l1tOmtfEventPrint") << "CandidateSimMuonMatcher: one or more histograms are missing in the file: " - << muonMatcherFileName << std::endl; - throw cms::Exception("MissingHistogram") << "CandidateSimMuonMatcher: one or more histograms are missing in the file: " - << muonMatcherFileName << std::endl; + if (!minDelta_pos || !maxDelta_pos || !medianDelta_pos || !minDelta_neg || !maxDelta_neg || !medianDelta_neg) { + edm::LogWarning("l1tOmtfEventPrint") + << "CandidateSimMuonMatcher: one or more histograms are missing in the file: " << muonMatcherFileName + << std::endl; + throw cms::Exception("MissingHistogram") + << "CandidateSimMuonMatcher: one or more histograms are missing in the file: " << muonMatcherFileName + << std::endl; } // Detach histograms from the file so they survive file close @@ -207,12 +207,18 @@ CandidateSimMuonMatcher::CandidateSimMuonMatcher( } CandidateSimMuonMatcher::~CandidateSimMuonMatcher() { - if(minDelta_pos) delete minDelta_pos; - if(maxDelta_pos) delete maxDelta_pos; - if(medianDelta_pos) delete medianDelta_pos; - if(minDelta_neg) delete minDelta_neg; - if(maxDelta_neg) delete maxDelta_neg; - if(medianDelta_neg) delete medianDelta_neg; + if (minDelta_pos) + delete minDelta_pos; + if (maxDelta_pos) + delete maxDelta_pos; + if (medianDelta_pos) + delete medianDelta_pos; + if (minDelta_neg) + delete minDelta_neg; + if (maxDelta_neg) + delete maxDelta_neg; + if (medianDelta_neg) + delete medianDelta_neg; } void CandidateSimMuonMatcher::beginRun(const edm::EventSetup& eventSetup) { @@ -305,8 +311,7 @@ bool trackingParticleIsMuonInBx0(const TrackingParticle& trackingParticle) { } bool trackingParticleIsMuonInBx0Displ(const TrackingParticle& trackingParticle) { - if (std::abs(trackingParticle.pdgId()) == 13 || - std::abs(trackingParticle.pdgId()) == 1000015) { // 1000015 is stau + if (std::abs(trackingParticle.pdgId()) == 13 || std::abs(trackingParticle.pdgId()) == 1000015) { // 1000015 is stau //in the overlap, the propagation of muons with pt less then ~3.2 fails - the actual threshold depends slightly on eta, if (trackingParticle.pt() < 2.) @@ -321,9 +326,9 @@ bool trackingParticleIsMuonInBx0Displ(const TrackingParticle& trackingParticle) (std::abs(trackingParticle.parentVertex()->position().eta()) > 1.4)) return false; } - } - else - throw cms::Exception("CandidateSimMuonMatcher", "trackingParticleIsMuonInBx0Displ: trackingParticle has no parent vertex"); + } else + throw cms::Exception("CandidateSimMuonMatcher", + "trackingParticleIsMuonInBx0Displ: trackingParticle has no parent vertex"); //only muons if (trackingParticle.eventId().bunchCrossing() == 0) @@ -399,10 +404,8 @@ void CandidateSimMuonMatcher::observeEventEnd(const edm::Event& event, FinalMuon std::function const& simTrackFilter = simTrackIsMuonInOmtfBx0; //simTrackIsMuonInOmtfBx0 provides appropriate eta cut - matchingResults = matchSimple(ghostBustedFinalMuons, - simTraksHandle.product(), - simVertices.product(), - simTrackFilter); + matchingResults = + matchSimple(ghostBustedFinalMuons, simTraksHandle.product(), simVertices.product(), simTrackFilter); } else if (matchingType == MatchingType::withPropagator || matchingType == MatchingType::simplePropagation) { //TODO use other simTrackFilter if needed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //withPropagator, we dont want to check the eta of the generated muon, as it is on the vertex, @@ -411,10 +414,7 @@ void CandidateSimMuonMatcher::observeEventEnd(const edm::Event& event, FinalMuon (matchingType == MatchingType::withPropagator) ? simTrackIsMuonInBx0 : simTrackIsMuonInOmtfBx0; //withPropagator : simplePropagation - matchingResults = match(ghostBustedFinalMuons, - simTraksHandle.product(), - simVertices.product(), - simTrackFilter); + matchingResults = match(ghostBustedFinalMuons, simTraksHandle.product(), simVertices.product(), simTrackFilter); } //todo something when noMatcher @@ -428,8 +428,7 @@ void CandidateSimMuonMatcher::observeEventEnd(const edm::Event& event, FinalMuon //TrackingParticle is used for minBias sample. There we should do propagation to match pions and kaons std::function trackParticleFilter = trackingParticleIsMuonInBx0Displ; //trackingParticleIsMuonInBx0; if propagation is used, use trackingParticleIsMuonInOmtfBx0 - matchingResults = - match(finalMuons, trackingParticleHandle.product(), trackParticleFilter); + matchingResults = match(finalMuons, trackingParticleHandle.product(), trackParticleFilter); } else if (matchingType == MatchingType::collectMuonCands) { matchingResults = collectMuonCands(finalMuons); } @@ -456,19 +455,20 @@ FinalMuons CandidateSimMuonMatcher::ghostBust(const FinalMuons& finalMuons) { if (std::abs(mtfCand1->getEtaRad() - mtfCand2->getEtaRad()) < 0.3) { //folding phi - double deltaPhi = std::abs(mtfCand1->getPhiRad() - mtfCand2->getPhiRad() ); + double deltaPhi = std::abs(mtfCand1->getPhiRad() - mtfCand2->getPhiRad()); if (deltaPhi > M_PI) deltaPhi = std::abs(deltaPhi - 2 * M_PI); //0.116355283466 is 10 units of the phase1 if (deltaPhi < 10 * 2 * M_PI / 576) { - if (mtfCand1->getFiredLayerCnt() > mtfCand2->getFiredLayerCnt()) { // + if (mtfCand1->getFiredLayerCnt() > mtfCand2->getFiredLayerCnt()) { isKilled[i2] = true; } else isKilled[i1] = true; } - LogTrace("l1tOmtfEventPrint") <<" mtfCand2 PhiRad " << mtfCand2->getPhiRad() << " etaRad " << mtfCand2->getEtaRad() << " deltaPhi "<< deltaPhi - << " isKilled[i2] " << isKilled[i2] << " isKilled[i1] " << isKilled[i1]; + LogTrace("l1tOmtfEventPrint") << " mtfCand2 PhiRad " << mtfCand2->getPhiRad() << " etaRad " + << mtfCand2->getEtaRad() << " deltaPhi " << deltaPhi << " isKilled[i2] " + << isKilled[i2] << " isKilled[i1] " << isKilled[i1]; } } } @@ -478,14 +478,14 @@ FinalMuons CandidateSimMuonMatcher::ghostBust(const FinalMuons& finalMuons) { LogTrace("l1tOmtfEventPrint") << "\nCandidateSimMuonMatcher::ghostBust - after ghostBusting:" << std::endl; for (unsigned int i1 = 0; i1 < finalMuons.size(); ++i1) { //not dropping candidates with quality 0 and 1 - if (!isKilled[i1]) { //&& finalMuons[i1]->getQuality() > 1 + if (!isKilled[i1]) { //&& finalMuons[i1]->getQuality() > 1 resultCands.push_back(finalMuons[i1]); } //if (finalMuons[i1]->getPtGmt() > 0) checked earlier, so it is not needed here - { //PtGmt > 0 marks valid candidate both for phase1 and phase2. But it should not matter here, as all finalMuons are not empty + { //PtGmt > 0 marks valid candidate both for phase1 and phase2. But it should not matter here, as all finalMuons are not empty - LogTrace("l1tOmtfEventPrint")<< *(finalMuons[i1]) << " gb isKilled " << isKilled.test(i1) << std::endl; + LogTrace("l1tOmtfEventPrint") << *(finalMuons[i1]) << " gb isKilled " << isKilled.test(i1) << std::endl; //LogTrace("l1tOmtfEventPrint") << *(gbCandidates.at(i1)) << std::endl; if (finalMuons[i1]->getAlgoMuon()) LogTrace("l1tOmtfEventPrint") << *(finalMuons[i1]->getAlgoMuon()) << std::endl; @@ -553,7 +553,7 @@ TrajectoryStateOnSurface CandidateSimMuonMatcher::propagate(const SimTrack& simT edm::LogImportant("l1tOmtfEventPrint") << "simVertex.vertexId() != vtxInd. simVertex.vertexId() " << simVertex.vertexId() << " vtxInd " << vtxInd << " !!!!!!!!!!!!!!!!!"; throw cms::Exception("CandidateSimMuonMatcher", - "CandidateSimMuonMatcher::propagate: simVertex.vertexId() != vtxInd"); + "CandidateSimMuonMatcher::propagate: simVertex.vertexId() != vtxInd"); } } @@ -696,7 +696,7 @@ std::vector CandidateSimMuonMatcher::cleanMatching(std::vector CandidateSimMuonMatcher::cleanMatching(std::vectorFindBin(result.genPt); - result.propagatedPhi = foldPhi(result.genPhi + medianDelta->GetBinContent(ptBin)); + auto ptBin = medianDelta->FindBin(result.genPt); + result.propagatedPhi = foldPhi(result.genPhi + medianDelta->GetBinContent(ptBin)); result.propagatedEta = result.genEta; }; @@ -724,13 +724,15 @@ void CandidateSimMuonMatcher::propagate(MatchingResult& result) { // fall back to a default vertex at (0,0,0). Or doSimplePropagation(). SimVertex defVtx; // default constructed vertex at origin ftsTrack = simTrackToFts(*(result.simTrack), defVtx); - edm::LogImportant("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::propagate - simTrack has no simVertex, using default vertex" << std::endl; + edm::LogImportant("l1tOmtfEventPrint") + << "CandidateSimMuonMatcher::propagate - simTrack has no simVertex, using default vertex" << std::endl; } } else if (result.trackingParticle) { - if(result.trackingParticle->parentVertex().isNonnull()) + if (result.trackingParticle->parentVertex().isNonnull()) ftsTrack = simTrackToFts(*result.trackingParticle); else { - edm::LogImportant("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::propagate - trackingParticle has no parentVertex!!!" << std::endl; + edm::LogImportant("l1tOmtfEventPrint") + << "CandidateSimMuonMatcher::propagate - trackingParticle has no parentVertex!!!" << std::endl; throw cms::Exception("CandidateSimMuonMatcher") << "CandidateSimMuonMatcher::propagate - trackingParticle has no parentVertex!!!"; } @@ -744,7 +746,7 @@ void CandidateSimMuonMatcher::propagate(MatchingResult& result) { if (!tsof.isValid()) { if (result.genPt > 2.5 && result.trackingParticle && result.trackingParticle->parentVertex().isNonnull()) { - if (result.muonRho < 40) { //TODO why it is done only for trackingParticle and not for simTrack? + if (result.muonRho < 40) { //TODO why it is done only for trackingParticle and not for simTrack? doSimplePropagation(); } } else { @@ -803,7 +805,7 @@ void CandidateSimMuonMatcher::match(const FinalMuons& finalMuons, for (auto& muonCand : finalMuons) { //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive //if (muonCand->getQuality() > 1) - { //TOOD uncomment, if this condition is needed + { //TOOD uncomment, if this condition is needed MatchingResult resultCopy = result; match(muonCand, resultCopy); @@ -834,8 +836,8 @@ std::vector CandidateSimMuonMatcher::match(const FinalMuons& fin continue; LogTrace("l1tOmtfEventPrint") << "\nCandidateSimMuonMatcher::match, simTrack type " << std::setw(3) - << simTrack.type() << " pt " << std::setw(9) << simTrack.momentum().pt() << " GeV eta " - << std::setw(9) << simTrack.momentum().eta() << " phi " << std::setw(9) + << simTrack.type() << " pt " << std::setw(9) << simTrack.momentum().pt() + << " GeV eta " << std::setw(9) << simTrack.momentum().eta() << " phi " << std::setw(9) << simTrack.momentum().phi() << " rho " << (simTrack.vertIndex() >= 0 ? simVertices->at(simTrack.vertIndex()).position().Rho() : -99) @@ -900,8 +902,8 @@ std::vector CandidateSimMuonMatcher::matchSimple( continue; LogTrace("l1tOmtfEventPrint") << "CandidateSimMuonMatcher::matchSimple: simTrack type " << std::setw(3) - << simTrack.type() << " pt " << std::setw(9) << simTrack.momentum().pt() << " GeV eta " - << std::setw(9) << simTrack.momentum().eta() << " phi " << std::setw(9) + << simTrack.type() << " pt " << std::setw(9) << simTrack.momentum().pt() + << " GeV eta " << std::setw(9) << simTrack.momentum().eta() << " phi " << std::setw(9) << simTrack.momentum().phi() << std::endl; bool matched = false; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc index be952a7d56eae..db362b701ad23 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc @@ -296,7 +296,8 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, FinalMuons& fina //TODO choose, which gpResult should be dumped //auto& gpResult = procMuon->getGpResultConstr(); - auto& gpResult = (muonCand->getAlgoMuon()->getGpResultUnconstr().getPdfSumUnconstr() > muonCand->getAlgoMuon()->getGpResultConstr().getPdfSum()) + auto& gpResult = (muonCand->getAlgoMuon()->getGpResultUnconstr().getPdfSumUnconstr() > + muonCand->getAlgoMuon()->getGpResultConstr().getPdfSum()) ? muonCand->getAlgoMuon()->getGpResultUnconstr() : muonCand->getAlgoMuon()->getGpResultConstr(); @@ -381,13 +382,16 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, FinalMuons& fina } LogTrace("l1tOmtfEventPrint") << "DataROOTDumper2::observeEventEnd adding omtfCand : " << std::endl; - - LogTrace("l1tOmtfEventPrint") << " hwPt " << matchingResult.muonCand->getAlgoMuon()->getPtConstr() << " hwSign " << matchingResult.muonCand->getAlgoMuon()->getChargeConstr() - << " hwQual " << matchingResult.muonCand->getQuality() << " hwEta " << std::setw(4) - << matchingResult.muonCand->getAlgoMuon()->getEtaHw() << std::setw(4) << " hwPhi " << matchingResult.muonCand->getAlgoMuon()->getPhi() - << " eta " << std::setw(9) << matchingResult.muonCand->getEtaRad() - << " isKilled " << matchingResult.muonCand->getAlgoMuon()->isKilled() << " tRefLayer " << matchingResult.muonCand->getAlgoMuon()->getRefLayer() - << " RefHitNumber " << matchingResult.muonCand->getAlgoMuon()->getRefHitNumber() << std::endl; + + LogTrace("l1tOmtfEventPrint") << " hwPt " << matchingResult.muonCand->getAlgoMuon()->getPtConstr() << " hwSign " + << matchingResult.muonCand->getAlgoMuon()->getChargeConstr() << " hwQual " + << matchingResult.muonCand->getQuality() << " hwEta " << std::setw(4) + << matchingResult.muonCand->getAlgoMuon()->getEtaHw() << std::setw(4) << " hwPhi " + << matchingResult.muonCand->getAlgoMuon()->getPhi() << " eta " << std::setw(9) + << matchingResult.muonCand->getEtaRad() << " isKilled " + << matchingResult.muonCand->getAlgoMuon()->isKilled() << " tRefLayer " + << matchingResult.muonCand->getAlgoMuon()->getRefLayer() << " RefHitNumber " + << matchingResult.muonCand->getAlgoMuon()->getRefHitNumber() << std::endl; }; if (matchingResult.muonCand && matchingResult.muonCand->getAlgoMuon()->getPtConstr() > 0 && @@ -446,6 +450,4 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, FinalMuons& fina evntCnt++; } -void DataROOTDumper2::endJob() { - edm::LogVerbatim("l1tOmtfEventPrint") << " evntCnt " << evntCnt << endl; -} +void DataROOTDumper2::endJob() { edm::LogVerbatim("l1tOmtfEventPrint") << " evntCnt " << evntCnt << endl; } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EventCapture.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EventCapture.cc index 1b08243a17bb6..f9c84cfb80458 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EventCapture.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EventCapture.cc @@ -136,15 +136,20 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMu } ostr << "matched to: " << std::endl; auto finalCandidate = matchingResult.muonCand; - ostr << " hwPt " << matchingResult.muonCand->getAlgoMuon()->getPtConstr() + ostr << " hwPt " + << matchingResult.muonCand->getAlgoMuon()->getPtConstr() //<< " hwUPt " << matchingResult.muonCand->getAlgoMuon()->getPtUnconstr() - << " hwUPt " << matchingResult.muonCand->getPtUnconstrGmt() + << " hwUPt " + << matchingResult.muonCand->getPtUnconstrGmt() //<< " hwSign " << matchingResult.muonCand->getAlgoMuon()->getChargeConstr() - << " hwSign " << matchingResult.muonCand->getSign() - << " hwQual " << matchingResult.muonCand->getQuality() << " hwEta " << std::setw(4) + << " hwSign " << matchingResult.muonCand->getSign() << " hwQual " << matchingResult.muonCand->getQuality() + << " hwEta " + << std::setw(4) //<< matchingResult.muonCand->getAlgoMuon()->getEtaHw() << std::setw(4) << " hwPhi " << matchingResult.muonCand->getAlgoMuon()->getPhi() - << matchingResult.muonCand->getEtaGmt() << std::setw(4) << " hwPhi " << matchingResult.muonCand->getPhiGmt() - << " eta " << std::setw(9) << matchingResult.muonCand->getEtaRad() << " phi "<< std::endl;// << matchingResult.muonCand->getPhiRad() << std::endl; + << matchingResult.muonCand->getEtaGmt() << std::setw(4) << " hwPhi " + << matchingResult.muonCand->getPhiGmt() << " eta " << std::setw(9) + << matchingResult.muonCand->getEtaRad() << " phi " + << std::endl; // << matchingResult.muonCand->getPhiRad() << std::endl; if (stubsSimHitsMatcher && runStubsSimHitsMatcher) stubsSimHitsMatcher->match(iEvent, matchingResult.muonCand, ostr); @@ -215,25 +220,27 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMu edm::LogVerbatim("l1tOmtfEventPrint") << ostr.str() << endl; //printing sim muons edm::LogVerbatim("l1tOmtfEventPrint") << "finalCandidates " << std::endl; - //for (int bx = finalCandidates->getFirstBX(); bx <= finalCandidates->getLastBX(); bx++) + //for (int bx = finalCandidates->getFirstBX(); bx <= finalCandidates->getLastBX(); bx++) { for (auto& finalMuon : finalMuons) { int layerHits = finalMuon->getAlgoMuon()->getFiredLayerBits(); std::bitset<18> layerHitBits(layerHits); edm::LogVerbatim("l1tOmtfEventPrint") - << " bx " << finalMuon->getBx() << " hwPt " << finalMuon->getAlgoMuon()->getPtConstr() + << " bx " << finalMuon->getBx() << " hwPt " + << finalMuon->getAlgoMuon()->getPtConstr() //<< " hwUPt " << finalMuon->getAlgoMuon()->getPtUnconstr() - << " hwUPt " << finalMuon->getPtUnconstrGmt() - << " hwSign " << finalMuon->getAlgoMuon()->getChargeConstr() << " hwQual " << finalMuon->getQuality() + << " hwUPt " << finalMuon->getPtUnconstrGmt() << " hwSign " << finalMuon->getAlgoMuon()->getChargeConstr() + << " hwQual " + << finalMuon->getQuality() //<< " hwEta " << std::setw(4) << finalMuon->getAlgoMuon()->getEtaHw() - << " hwEta " << std::setw(4) << finalMuon->getEtaGmt() ////////////////////////////////////////////// + << " hwEta " << std::setw(4) + << finalMuon->getEtaGmt() ////////////////////////////////////////////// //<< std::setw(4) << " hwPhi " << finalMuon->getAlgoMuon()->getPhi() - << std::setw(4) << " hwPhi " << finalMuon->getPhiGmt() ///////////////////////////////////////////// - << " eta " << std::setw(9) << finalMuon->getEtaRad() /////////////////////////////////////////// - << " phi " << std::setw(9) << finalMuon->getPhiRad() << " " << layerHitBits - << " processor " << OmtfName(finalMuon->getProcessor(), finalMuon->trackFinderType(), omtfConfig) - << std::endl; + << std::setw(4) << " hwPhi " << finalMuon->getPhiGmt() ///////////////////////////////////////////// + << " eta " << std::setw(9) << finalMuon->getEtaRad() /////////////////////////////////////////// + << " phi " << std::setw(9) << finalMuon->getPhiRad() << " " << layerHitBits << " processor " + << OmtfName(finalMuon->getProcessor(), finalMuon->trackFinderType(), omtfConfig) << std::endl; } } edm::LogVerbatim("l1tOmtfEventPrint") << std::endl; @@ -350,9 +357,11 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMu edm::LogVerbatim("l1tOmtfEventPrint") << "\ngbCandidates" << std::endl; for (auto& gbCandidate : gbCandidatesInProcs[iProc]) edm::LogVerbatim("l1tOmtfEventPrint") - << " (" << std::setw(5) << gbCandidate->getPtConstr() << "," << std::setw(5) + << " (" << std::setw(5) << gbCandidate->getPtConstr() << "," + << std::setw(5) //<< ( (gbCandidate->getPtUnconstr() - 1) / 2 + 1 )<< "," //GMT scale - << ( gbCandidate->getPtUnconstr() == 0 ? 0 : ( (gbCandidate->getPtUnconstr() - 1) / 2 + 1 ) )<< "," //GMT scale + << (gbCandidate->getPtUnconstr() == 0 ? 0 : ((gbCandidate->getPtUnconstr() - 1) / 2 + 1)) + << "," //GMT scale << std::setw(5) << gbCandidate->getGpResultConstr().getFiredLayerCnt() << "," << std::setw(5) << gbCandidate->getGpResultUnconstr().getFiredLayerCnt() @@ -383,7 +392,7 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMu edm::LogVerbatim("l1tOmtfEventPrint") << "finalCandidates " << std::endl; std::ostringstream ostr; - //if (finalCandidates->size(0) > 0) + //if (finalCandidates->size(0) > 0) { int iMu = 1; for (auto& finalMuon : finalMuons) { @@ -403,7 +412,7 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMu << std::abs(finalMuon->getEtaGmt()) << "," //<getSign() << "," << std::setw(4) << 1 << "; "; //ChValid //<< " -- uPt " << std::setw(10) << uPt << " firedLayers " << finalCandidate.trackAddress().at(0); diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc index 296181a0ca676..1f1c900abf26a 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/StubsSimHitsMatching.cc @@ -91,9 +91,7 @@ void StubsSimHitsMatcher::beginRun(edm::EventSetup const& eventSetup) { } } -void StubsSimHitsMatcher::match(const edm::Event& iEvent, - const FinalMuonPtr& finalMuon, - std::ostringstream& ostr) { +void StubsSimHitsMatcher::match(const edm::Event& iEvent, const FinalMuonPtr& finalMuon, std::ostringstream& ostr) { ostr << "stubsSimHitsMatching ---------------" << std::endl; edm::Handle rpcSimHitsHandle; diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/NNRegression.h b/L1Trigger/L1TMuonOverlapPhase2/interface/NNRegression.h index 5fbb83cfb2592..450c3aeebae0d 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/NNRegression.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/NNRegression.h @@ -13,9 +13,7 @@ class NNRegression : public MlModelBase { public: - NNRegression(const edm::ParameterSet& edmCfg, - const OMTFConfiguration* omtfConfig, - std::string networkFile); + NNRegression(const edm::ParameterSet& edmCfg, const OMTFConfiguration* omtfConfig, std::string networkFile); ~NNRegression() override = default; void run(AlgoMuons::value_type& algoMuon, std::vector >& observers) override; diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h index dd21ad27cea79..9686ce9564466 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h @@ -34,13 +34,12 @@ class OmtfEmulation : public OMTFReconstruction { const edm::ESGetToken& propagatorEsToken) override; struct OmtfOutptuCollections { - std::unique_ptr constrSaMuons; //ip constrained candidates - std::unique_ptr unConstrSaMuons; //ip unconstrained candidates - std::unique_ptr regionalCandidates; //for backward compatibility of analyzers etc. + std::unique_ptr constrSaMuons; //ip constrained candidates + std::unique_ptr unConstrSaMuons; //ip unconstrained candidates + std::unique_ptr regionalCandidates; //for backward compatibility of analyzers etc. }; - OmtfOutptuCollections run(const edm::Event& iEvent, - const edm::EventSetup& evSetup); + OmtfOutptuCollections run(const edm::Event& iEvent, const edm::EventSetup& evSetup); private: MuStubsPhase2InputTokens& muStubsPhase2InputTokens; diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h index eaa8bcdfd5487..8358ea114bd01 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h @@ -8,7 +8,6 @@ #ifndef L1Trigger_L1TMuonOverlapPhase2_OMTFPROCESSORPHASE2_H_ #define L1Trigger_L1TMuonOverlapPhase2_OMTFPROCESSORPHASE2_H_ - #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h" #include "L1Trigger/L1TMuonOverlapPhase2/interface/MlModelBase.h" diff --git a/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.cc b/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.cc index cad7f239fdd63..46468721d11a3 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/plugins/L1TMuonOverlapPhase2TrackProducer.cc @@ -37,7 +37,6 @@ L1TMuonOverlapPhase2TrackProducer::L1TMuonOverlapPhase2TrackProducer(const edm:: propagatorEsToken(esConsumes( edm::ESInputTag("", "SteppingHelixPropagatorAlong"))), omtfEmulation(edmParameterSet, muStubsInputTokens, muStubsPhase2InputTokens) { - produces("OMTF"); //phase-1 collection produces("OMTFconstr"); produces("OMTFunconstr"); diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc b/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc index 7bea05f5e87f3..8f4251dcef375 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc @@ -41,7 +41,7 @@ void DtPhase2DigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers, std::ostringstream chamberName; //chamberName<.whNum", digiIt.whNum()); @@ -63,7 +63,7 @@ void DtPhase2DigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers, std::ostringstream chamberName; //chamberName<.whNum", thetaDigi.whNum()); @@ -76,7 +76,7 @@ void DtPhase2DigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers, } } - for(auto& chamberTree : chamberTrees) { + for (auto& chamberTree : chamberTrees) { chamberTree.second.add(".name", chamberTree.first); procDataTree.add_child("dtChamber", chamberTree.second); } diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc b/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc index e60af4bd1eda8..6648ca47ad126 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc @@ -90,8 +90,8 @@ namespace lutNN { } // namespace lutNN NNRegression::NNRegression(const edm::ParameterSet& edmCfg, - const OMTFConfiguration* omtfConfig, - std::string networkFile) + const OMTFConfiguration* omtfConfig, + std::string networkFile) : MlModelBase(omtfConfig), lutNetworkFP(make_unique()) { std::ifstream ifs(networkFile); @@ -355,7 +355,7 @@ bool omtfHitToEventInput(OmtfHit& hit, std::vector& inputs, unsigned int } void NNRegression::run(AlgoMuons::value_type& algoMuon, - std::vector>& observers) { + std::vector>& observers) { LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << std::endl; auto& gpResult = algoMuon->getGpResultConstr(); //int pdfMiddle = 1<<(omtfConfig->nPdfAddrBits()-1); @@ -447,12 +447,11 @@ void NNRegression::run(AlgoMuons::value_type& algoMuon, //algoMuon->setPtNNConstr(omtfConfig->ptGevToHw(calibratedHwPt)); - //here the pts are GeV double omtfPt = omtfConfig->hwPtToGev(algoMuon->getPtConstr()); double nnPt = nnResult.at(0); double combinedPt = nnPt; - if( nnPt < 2.5 || (nnResult[0] - omtfPt) > 0.75 * omtfPt) + if (nnPt < 2.5 || (nnResult[0] - omtfPt) > 0.75 * omtfPt) combinedPt = omtfPt; algoMuon->setPtNNConstr(combinedPt); diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfEmulation.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfEmulation.cc index f4ed6eafb2416..a0466a3ef71e9 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfEmulation.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfEmulation.cc @@ -19,7 +19,9 @@ OmtfEmulation::OmtfEmulation(const edm::ParameterSet& edmParameterSet, MuStubsInputTokens& muStubsInputTokens, MuStubsPhase2InputTokens& muStubsPhase2InputTokens) - : OMTFReconstruction(edmParameterSet, muStubsInputTokens), muStubsPhase2InputTokens(muStubsPhase2InputTokens), omtfProcPhase2(omtfConfig.get(), omtfProc) {} + : OMTFReconstruction(edmParameterSet, muStubsInputTokens), + muStubsPhase2InputTokens(muStubsPhase2InputTokens), + omtfProcPhase2(omtfConfig.get(), omtfProc) {} void OmtfEmulation::beginJob() { if (edmParameterSet.exists("usePhase2DTPrimitives") && edmParameterSet.getParameter("usePhase2DTPrimitives")) { @@ -35,20 +37,18 @@ void OmtfEmulation::beginJob() { } void OmtfEmulation::beginRun(edm::Run const& run, - edm::EventSetup const& eventSetup, - edm::ESGetToken& omtfParamsEsToken, - const MuonGeometryTokens& muonGeometryTokens, - const edm::ESGetToken& magneticFieldEsToken, - const edm::ESGetToken& propagatorEsToken) { - - OMTFReconstruction::beginRun(run, eventSetup, omtfParamsEsToken, muonGeometryTokens, magneticFieldEsToken, propagatorEsToken); + edm::EventSetup const& eventSetup, + edm::ESGetToken& omtfParamsEsToken, + const MuonGeometryTokens& muonGeometryTokens, + const edm::ESGetToken& magneticFieldEsToken, + const edm::ESGetToken& propagatorEsToken) { + OMTFReconstruction::beginRun( + run, eventSetup, omtfParamsEsToken, muonGeometryTokens, magneticFieldEsToken, propagatorEsToken); omtfProcPhase2.beginRun(edmParameterSet, eventSetup); } -OmtfEmulation::OmtfOutptuCollections OmtfEmulation::run( - const edm::Event& iEvent, - const edm::EventSetup& evSetup) { +OmtfEmulation::OmtfOutptuCollections OmtfEmulation::run(const edm::Event& iEvent, const edm::EventSetup& evSetup) { LogTrace("l1tOmtfEventPrint") << "\n" << __FUNCTION__ << ":" << __LINE__ << " iEvent " << iEvent.id().event() << endl; inputMaker->loadAndFilterDigis(iEvent); @@ -66,7 +66,7 @@ OmtfEmulation::OmtfOutptuCollections OmtfEmulation::run( ///The order is important: first put omtf_pos candidates, then omtf_neg. for (int bx = bxMin; bx <= bxMax; bx++) { - for(unsigned int iSide = 0; iSide < 2; ++iSide) { + for (unsigned int iSide = 0; iSide < 2; ++iSide) { l1t::tftype mtfType = (iSide == 0) ? l1t::tftype::omtf_pos : l1t::tftype::omtf_neg; for (unsigned int iProcessor = 0; iProcessor < omtfConfig->nProcessors(); ++iProcessor) { FinalMuons finalMuons = omtfProcPhase2.run(iProcessor, mtfType, bx, inputMaker.get(), observers); diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc index aa3b7ba0a10f8..33ea10054c91a 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc @@ -21,8 +21,8 @@ int OmtfPhase2AngleConverter::getProcessorPhi(int phiZero, l1t::tftype part, int } int OmtfPhase2AngleConverter::getGlobalEtaPhase2(DTChamberId dTChamberId, - const L1Phase2MuDTThContainer* dtThDigis, - int bxNum) const { + const L1Phase2MuDTThContainer* dtThDigis, + int bxNum) const { int dtThBins = 65536; //65536. for [-6.3,6.3] float kconv = 1 / (dtThBins / 2.); @@ -35,7 +35,7 @@ int OmtfPhase2AngleConverter::getGlobalEtaPhase2(DTChamberId dTChamberId, thetaDigi.scNum() == (dTChamberId.sector() - 1) && (thetaDigi.bxNum() - 20) == bxNum) { // get the theta digi float k = thetaDigi.k() * kconv; //-pow(-1.,z<0)*log(tan(atan(1/k)/2.)); - eta = -1. * std::copysign( log(fabs(tan(atan(1 / k) / 2.))), thetaDigi.z() ); + eta = -1. * std::copysign(log(fabs(tan(atan(1 / k) / 2.))), thetaDigi.z()); LogTrace("OMTFReconstruction") << "OmtfPhase2AngleConverter::getGlobalEta(" << dTChamberId << ") eta: " << eta << " k: " << k << " thetaDigi.k(): " << thetaDigi.k(); @@ -70,5 +70,5 @@ int OmtfPhase2AngleConverter::getGlobalEtaPhase2(DTChamberId dTChamberId, return eta; } - return 0; //should not be reached + return 0; //should not be reached } diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc index 1f1cbcf3346d3..2fd601a51309e 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc @@ -8,9 +8,9 @@ #include #include "L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h" -OmtfProcessorPhase2::OmtfProcessorPhase2(const OMTFConfiguration* omtfConfig, const unique_ptr& omtfProc): -omtfConfig(omtfConfig), omtfProc(omtfProc) { - +OmtfProcessorPhase2::OmtfProcessorPhase2(const OMTFConfiguration* omtfConfig, + const unique_ptr& omtfProc) + : omtfConfig(omtfConfig), omtfProc(omtfProc) { //TODO read from configuration //.....................rrrrrrrrccccdddddd //.....................765432109876543210 @@ -116,9 +116,7 @@ omtfConfig(omtfConfig), omtfProc(omtfProc) { //firedLayersToQuality[0b000000000000111100] = 8; } -OmtfProcessorPhase2::~OmtfProcessorPhase2() { - -} +OmtfProcessorPhase2::~OmtfProcessorPhase2() {} void OmtfProcessorPhase2::beginRun(const edm::ParameterSet& edmParameterSet, edm::EventSetup const& iSetup) { if (edmParameterSet.exists("neuralNetworkFile") && !mlModel) { @@ -145,8 +143,9 @@ void OmtfProcessorPhase2::assignQualityPhase2(AlgoMuons::value_type& algoMuon) { } LogTrace("OMTFReconstruction") << "OmtfEmulation::assignQualityPhase2 algoMuon->getFiredLayerBits() " - << std::bitset<18>(algoMuon->getFiredLayerBits()) - << " algoMuon->getEtaHw() " << algoMuon->getEtaHw() << " omtfConfig->etaToHwEta(1.25) "<< omtfConfig->etaToHwEta(1.25) << std::endl; + << std::bitset<18>(algoMuon->getFiredLayerBits()) << " algoMuon->getEtaHw() " + << algoMuon->getEtaHw() << " omtfConfig->etaToHwEta(1.25) " + << omtfConfig->etaToHwEta(1.25) << std::endl; if (abs(algoMuon->getEtaHw()) >= omtfConfig->etaToHwEta(1.25) && (algoMuon->getFiredLayerBits() == std::bitset<18>("100000001110000000").to_ulong() || @@ -156,7 +155,7 @@ void OmtfProcessorPhase2::assignQualityPhase2(AlgoMuons::value_type& algoMuon) { algoMuon->getFiredLayerBits() == std::bitset<18>("100000001010000000").to_ulong())) { algoMuon->setQuality(1); LogTrace("OMTFReconstruction") << "OmtfEmulation::assignQualityPhase2 assigned quality 1 for etaHw " - << algoMuon->getEtaHw() << std::endl; + << algoMuon->getEtaHw() << std::endl; return; } @@ -168,7 +167,9 @@ void OmtfProcessorPhase2::assignQualityPhase2(AlgoMuons::value_type& algoMuon) { } }; -void OmtfProcessorPhase2::convertToGmtScalesPhase2(unsigned int iProcessor, l1t::tftype mtfType, FinalMuonPtr& finalMuon) { +void OmtfProcessorPhase2::convertToGmtScalesPhase2(unsigned int iProcessor, + l1t::tftype mtfType, + FinalMuonPtr& finalMuon) { //ptAssignment (NN) is used only if there was valid candidate from pattern logic //it overrides the pt from the pattern logic if (mlModel) { @@ -176,19 +177,19 @@ void OmtfProcessorPhase2::convertToGmtScalesPhase2(unsigned int iProcessor, l1t: finalMuon->setPtGev(finalMuon->getAlgoMuon()->getPtNNConstr()); finalMuon->setSign(finalMuon->getAlgoMuon()->getChargeNNConstr() < 0 ? 1 : 0); - //TODO use getPtNNUnconstr when the network with upt is trained to set setPtUnconstrGev() LogTrace("OMTFReconstruction") << "OmtfEmulation::convertToGmtScalesPhase2 using Pt from NN " - << " iProcessor " << iProcessor<<" ptNN " << finalMuon->getAlgoMuon()->getPtNNConstr() - << " ptPatterns " << finalMuon->getAlgoMuon()->getPtConstr() - << " ChargeNN " <getAlgoMuon()->getChargeNNConstr() - << " Charge " <getAlgoMuon()->getChargeConstr() << std::endl; + << " iProcessor " << iProcessor << " ptNN " + << finalMuon->getAlgoMuon()->getPtNNConstr() << " ptPatterns " + << finalMuon->getAlgoMuon()->getPtConstr() << " ChargeNN " + << finalMuon->getAlgoMuon()->getChargeNNConstr() << " Charge " + << finalMuon->getAlgoMuon()->getChargeConstr() << std::endl; } //in getFinalMuons the PtGeV is set to 0 in this case, as it is like that for the phase-1. //but for the phase-2 pt = 0 means empty candidate, so we set 1 GeV in this case if (finalMuon->getAlgoMuon()->getPdfSumConstr() == 0 && finalMuon->getAlgoMuon()->getPtUnconstr() > 0) - finalMuon->setPtGev(1.0); //set to 1 GeV to be able to distinguish from pt=0, which means no candidate + finalMuon->setPtGev(1.0); //set to 1 GeV to be able to distinguish from pt=0, which means no candidate int maxPtHw = (1 << Phase2L1GMT::BITSPT) - 1; @@ -199,7 +200,6 @@ void OmtfProcessorPhase2::convertToGmtScalesPhase2(unsigned int iProcessor, l1t: finalMuon->setPtGmt(ptHwConstr); - int ptHwUnConstr = finalMuon->getPtUnconstrGev() * (1. / Phase2L1GMT::LSBpt); if (ptHwUnConstr >= maxPtHw) @@ -208,23 +208,24 @@ void OmtfProcessorPhase2::convertToGmtScalesPhase2(unsigned int iProcessor, l1t: finalMuon->setPtUnconstrGmt(ptHwUnConstr); LogTrace("OMTFReconstruction") << "convertToGmtScalesPhase2 finalMuon->getPtGev() iProcessor " << iProcessor - << " PtGev " << finalMuon->getPtGev()<< " PtUnconstrGev "<< finalMuon->getPtUnconstrGev() << std::endl; + << " PtGev " << finalMuon->getPtGev() << " PtUnconstrGev " + << finalMuon->getPtUnconstrGev() << std::endl; if (mtfType == l1t::omtf_pos) { finalMuon->setEtaGmt(finalMuon->getAlgoMuon()->getEtaHw()); - } - else { + } else { finalMuon->setEtaGmt((-1) * finalMuon->getAlgoMuon()->getEtaHw()); } int globPhi = omtfConfig->procPhiOmtfToGlobalPhiOmtf(iProcessor, finalMuon->getAlgoMuon()->getPhi()); int gmtPhiBins = 1 << Phase2L1GMT::BITSPHI; - int omtfToGmtFactorPhi = std::lround(gmtPhiBins * (1 << 12) / double(omtfConfig->nPhiBins()) ) ; + int omtfToGmtFactorPhi = std::lround(gmtPhiBins * (1 << 12) / double(omtfConfig->nPhiBins())); int gmtPhi = (globPhi * omtfToGmtFactorPhi) >> 12; finalMuon->setPhiGmt(gmtPhi); - static const int omtfToGmtFactorEta = std::lround(omtfConfig->etaUnit() / Phase2L1GMT::LSBeta ) ; //should be 2 - LogTrace("OMTFReconstruction") << "OmtfEmulation::convertToGmtScalesPhase2 omtfToGmtFactorEta " << omtfToGmtFactorEta << std::endl; + static const int omtfToGmtFactorEta = std::lround(omtfConfig->etaUnit() / Phase2L1GMT::LSBeta); //should be 2 + LogTrace("OMTFReconstruction") << "OmtfEmulation::convertToGmtScalesPhase2 omtfToGmtFactorEta " << omtfToGmtFactorEta + << std::endl; int gmtEta = (finalMuon->getAlgoMuon()->getEtaHw() * omtfToGmtFactorEta); if (mtfType == l1t::omtf_neg) gmtEta = -gmtEta; @@ -234,26 +235,26 @@ void OmtfProcessorPhase2::convertToGmtScalesPhase2(unsigned int iProcessor, l1t: } l1t::SAMuonCollection OmtfProcessorPhase2::getSAMuons(unsigned int iProcessor, - l1t::tftype mtfType, - FinalMuons& finalMuons, - bool costrainedPt) { + l1t::tftype mtfType, + FinalMuons& finalMuons, + bool costrainedPt) { l1t::SAMuonCollection saMuons; for (auto& finalMuon : finalMuons) { int charge = finalMuon->getSign(); unsigned int pt = costrainedPt ? finalMuon->getPtGmt() : finalMuon->getPtUnconstrGmt(); - int d0 = costrainedPt ? 0 : 50 / Phase2L1GMT::LSBSAd0; //finalMuon->getHwD0(); - if(costrainedPt == false) { + int d0 = costrainedPt ? 0 : 50 / Phase2L1GMT::LSBSAd0; //finalMuon->getHwD0(); + if (costrainedPt == false) { //this assures the collection of constrained and unconstrained muons have the same size //muons that are not displaced also should be in the unconstrained collection - if(finalMuon->getPtUnconstrGmt() == 0) { + if (finalMuon->getPtUnconstrGmt() == 0) { pt = finalMuon->getPtGmt(); d0 = 0; } } - LogTrace("OMTFReconstruction") << "OmtfEmulation::getSAMuons finalMuon->getPtGmt(): " - << finalMuon->getPtGmt() << " finalMuon->getPtUnconstrGmt() "<< finalMuon->getPtUnconstrGmt() << std::endl; + LogTrace("OMTFReconstruction") << "OmtfEmulation::getSAMuons finalMuon->getPtGmt(): " << finalMuon->getPtGmt() + << " finalMuon->getPtUnconstrGmt() " << finalMuon->getPtUnconstrGmt() << std::endl; int phi = finalMuon->getPhiGmt(); int eta = finalMuon->getEtaGmt(); @@ -279,8 +280,9 @@ l1t::SAMuonCollection OmtfProcessorPhase2::getSAMuons(unsigned int iProcessor, */ // Calculate Lorentz Vector - //TODO for the vertex constrained muon, the z0 and d0 by definition should be 0 - then why give it? - math::PtEtaPhiMLorentzVector p4Constr(pt * Phase2L1GMT::LSBpt, eta * Phase2L1GMT::LSBeta, phi * Phase2L1GMT::LSBphi, 0.0); + //TODO for the vertex constrained muon, the z0 and d0 by definition should be 0 - then why give it? + math::PtEtaPhiMLorentzVector p4Constr( + pt * Phase2L1GMT::LSBpt, eta * Phase2L1GMT::LSBeta, phi * Phase2L1GMT::LSBphi, 0.0); l1t::SAMuon saMuon(p4Constr, charge, pt, eta, phi, z0, d0, qual); saMuon.setTF(mtfType); //samuon.setWord(word); @@ -294,10 +296,10 @@ l1t::SAMuonCollection OmtfProcessorPhase2::getSAMuons(unsigned int iProcessor, } FinalMuons OmtfProcessorPhase2::run(unsigned int iProcessor, - l1t::tftype mtfType, - int bx, - OMTFinputMaker* inputMaker, - std::vector >& observers) { + l1t::tftype mtfType, + int bx, + OMTFinputMaker* inputMaker, + std::vector >& observers) { //uncomment if you want to check execution time of each method //boost::timer::auto_cpu_timer t("%ws wall, %us user in getProcessorCandidates\n"); @@ -361,7 +363,7 @@ FinalMuons OmtfProcessorPhase2::run(unsigned int iProcessor, convertToGmtScalesPhase2(iProcessor, mtfType, finalMuon); } - for(auto& finalMuon : finalMuons) { + for (auto& finalMuon : finalMuons) { finalMuon->setBx(bx); } @@ -370,6 +372,4 @@ FinalMuons OmtfProcessorPhase2::run(unsigned int iProcessor, } return finalMuons; - } - From d10eae7b678de176c72a478c23df92cfc731c0b0 Mon Sep 17 00:00:00 2001 From: Karol Bunkowski Date: Fri, 14 Nov 2025 11:17:09 +0100 Subject: [PATCH 06/12] Fixing a bug in DTTrigPhase2Prod::distribDigis --- .../plugins/DTTrigPhase2Prod.cc | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc b/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc index 5d31059221cba..2e0c78edc9ee4 100644 --- a/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc +++ b/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc @@ -177,9 +177,9 @@ class DTTrigPhase2Prod : public edm::stream::EDProducer<> { bool activateBuffer_; int superCellhalfspacewidth_; float superCelltimewidth_; - std::vector distribDigis(std::queue>& inQ); + std::vector distribDigis(std::queue>& inQ); void processDigi(std::queue>& inQ, - std::vector>*>& vec); + std::vector>>& vec); // RPC std::unique_ptr rpc_integrator_; @@ -375,14 +375,14 @@ void DTTrigPhase2Prod::produce(Event& iEvent, const EventSetup& iEventSetup) { tmpvec.clear(); // Distribute the digis from the queue into supercells - std::vector superCells; + std::vector superCells; superCells = distribDigis(timequeue); // Process each supercell & collect the resulting muonpaths (as the muonpaths std::vector is only enlarged each time // the groupings access it, it's not needed to "collect" the final products). while (!superCells.empty()) { - grouping_obj_->run(iEvent, iEventSetup, *(superCells.back()), muonpaths[chid.rawId()]); + grouping_obj_->run(iEvent, iEventSetup, superCells.back(), muonpaths[chid.rawId()]); superCells.pop_back(); } } else { @@ -1247,35 +1247,36 @@ int DTTrigPhase2Prod::assignQualityOrder(const metaPrimitive& mP) const { return qmap_.find(mP.quality)->second; } -std::vector DTTrigPhase2Prod::distribDigis(std::queue>& inQ) { - std::vector>*> tmpVector; +std::vector DTTrigPhase2Prod::distribDigis(std::queue>& inQ) { + // Use value-based containers to avoid returning pointers to local variables. + std::vector>> tmpVector; tmpVector.clear(); - std::vector collVector; + std::vector collVector; collVector.clear(); while (!inQ.empty()) { processDigi(inQ, tmpVector); } for (auto& sQ : tmpVector) { DTDigiCollection tmpColl; - while (!sQ->empty()) { - tmpColl.insertDigi((sQ->front().first), (sQ->front().second)); - sQ->pop(); + while (!sQ.empty()) { + tmpColl.insertDigi((sQ.front().first), (sQ.front().second)); + sQ.pop(); } - collVector.push_back(&tmpColl); + collVector.push_back(std::move(tmpColl)); } return collVector; } void DTTrigPhase2Prod::processDigi(std::queue>& inQ, - std::vector>*>& vec) { + std::vector>>& vec) { bool classified = false; if (!vec.empty()) { for (auto& sC : vec) { // Conditions for entering a super cell. - if ((sC->front().second.time() + superCelltimewidth_) > inQ.front().second.time()) { + if ((sC.front().second.time() + superCelltimewidth_) > inQ.front().second.time()) { // Time requirement - if (std::abs(sC->front().second.wire() - inQ.front().second.wire()) <= superCellhalfspacewidth_) { + if (std::abs(sC.front().second.wire() - inQ.front().second.wire()) <= superCellhalfspacewidth_) { // Spatial requirement - sC->push(std::move(inQ.front())); + sC.push(std::move(inQ.front())); classified = true; } } @@ -1293,7 +1294,7 @@ void DTTrigPhase2Prod::processDigi(std::queue>& inQ newQueue.push(tmpPair); inQ.pop(); - vec.push_back(&newQueue); + vec.push_back(std::move(newQueue)); } void DTTrigPhase2Prod::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { From 25023db3f156fb5dad587263352ff3ce90b697d1 Mon Sep 17 00:00:00 2001 From: Karol Bunkowski Date: Wed, 26 Nov 2025 12:02:15 +0100 Subject: [PATCH 07/12] Fixes in InputMakerPhase2 - using dtBxShift from ProcConfigurationBase ProcConfigurationBase.h: added dtBxShift. InputMakerPhase2.h: OMTFConfiguration moved from DtPhase2DigiToStubsConverterOmtf to DtPhase2DigiToStubsConverter. InputMakerPhase2.cc: Using config->dtBxShift() instead of the hardcoded value 20. --- .../interface/ProcConfigurationBase.h | 6 + .../src/Omtf/XMLConfigReader.cc | 206 ++++++++---------- .../src/ProcConfigurationBase.cc | 6 + .../src/Tools/EventCapture.cc | 7 +- .../interface/InputMakerPhase2.h | 15 +- .../src/InputMakerPhase2.cc | 43 ++-- .../L1TMuonOverlapPhase2/src/NNRegression.cc | 2 +- .../src/OmtfPhase2AngleConverter.cc | 2 +- 8 files changed, 141 insertions(+), 146 deletions(-) diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h b/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h index c287790893eaf..dc27315ca2152 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/ProcConfigurationBase.h @@ -67,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) { @@ -121,6 +125,8 @@ class ProcConfigurationBase { 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/src/Omtf/XMLConfigReader.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/XMLConfigReader.cc index aa0495f14de67..3f580ce6fb0f4 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/XMLConfigReader.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/XMLConfigReader.cc @@ -34,7 +34,10 @@ XERCES_CPP_NAMESPACE_USE // XMLConfigReader ////////////////////////////////// inline std::string _toString(XMLCh const *toTranscode) { - std::string tmp(xercesc::XMLString::transcode(toTranscode)); + // XMLString::transcode returns a temporary char* that must be released with XMLString::release + char *tmpC = xercesc::XMLString::transcode(toTranscode); + std::string tmp(tmpC); + XMLString::release(&tmpC); return tmp; } @@ -42,6 +45,31 @@ inline XMLCh *_toDOMS(std::string temp) { XMLCh *buff = XMLString::transcode(temp.c_str()); return buff; } + +// RAII guard for XMLCh* allocated by XMLString::transcode +// Ensures XMLString::release is called on destruction and is non-copyable (moveable). +struct XMLChGuard { + XMLCh *p_; + explicit XMLChGuard(XMLCh *p = nullptr) : p_(p) {} + XMLChGuard(const XMLChGuard &) = delete; + XMLChGuard &operator=(const XMLChGuard &) = delete; + XMLChGuard(XMLChGuard &&o) noexcept : p_(o.p_) { o.p_ = nullptr; } + XMLChGuard &operator=(XMLChGuard &&o) noexcept { + if (this != &o) { + if (p_) + xercesc::XMLString::release(&p_); + p_ = o.p_; + o.p_ = nullptr; + } + return *this; + } + ~XMLChGuard() { + if (p_) + xercesc::XMLString::release(&p_); + } + XMLCh *get() const { return p_; } + operator XMLCh *() const { return p_; } +}; //////////////////////////////////// //////////////////////////////////// XMLConfigReader::XMLConfigReader() { cms::concurrency::xercesInitialize(); } @@ -218,14 +246,12 @@ unsigned int XMLConfigReader::getPatternsVersion() const { xercesc::DOMDocument *doc = parser.getDocument(); assert(doc); - XMLCh *xmlOmtf = _toDOMS("OMTF"); - XMLCh *xmlVersion = _toDOMS("version"); + XMLChGuard xmlOmtf(_toDOMS("OMTF")); + XMLChGuard xmlVersion(_toDOMS("version")); DOMNode *aNode = doc->getElementsByTagName(xmlOmtf)->item(0); DOMElement *aOMTFElement = static_cast(aNode); version = std::stoul(_toString(aOMTFElement->getAttribute(xmlVersion)), nullptr, 16); - XMLString::release(&xmlOmtf); - XMLString::release(&xmlVersion); parser.resetDocumentPool(); } @@ -329,33 +355,33 @@ std::unique_ptr XMLConfigReader::buildGP(DOMElement *aGPEleme unsigned int patternGroup, unsigned int index, unsigned int aGPNumber) { - XMLCh *xmliEta = _toDOMS("iEta"); + XMLChGuard xmliEta(_toDOMS("iEta")); //index 0 means no number at the end std::ostringstream stringStr; if (index > 0) stringStr << "iPt" << index; else stringStr.str("iPt"); - XMLCh *xmliPt = _toDOMS(stringStr.str()); + XMLChGuard xmliPt(_toDOMS(stringStr.str())); stringStr.str(""); if (index > 0) stringStr << "value" << index; else stringStr.str("value"); - XMLCh *xmlValue = _toDOMS(stringStr.str()); + XMLChGuard xmlValue(_toDOMS(stringStr.str())); - XMLCh *xmliCharge = _toDOMS("iCharge"); - XMLCh *xmlLayer = _toDOMS("Layer"); - XMLCh *xmlRefLayer = _toDOMS("RefLayer"); - XMLCh *xmlmeanDistPhi = _toDOMS("meanDistPhi"); //for old version + XMLChGuard xmliCharge(_toDOMS("iCharge")); + XMLChGuard xmlLayer(_toDOMS("Layer")); + XMLChGuard xmlRefLayer(_toDOMS("RefLayer")); + XMLChGuard xmlmeanDistPhi(_toDOMS("meanDistPhi")); //for old version - XMLCh *xmlmeanDistPhi0 = _toDOMS("meanDistPhi0"); //for new version - XMLCh *xmlmeanDistPhi1 = _toDOMS("meanDistPhi1"); //for new version + XMLChGuard xmlmeanDistPhi0(_toDOMS("meanDistPhi0")); //for new version + XMLChGuard xmlmeanDistPhi1(_toDOMS("meanDistPhi1")); //for new version - XMLCh *xmlSelDistPhiShift = _toDOMS("selDistPhiShift"); + XMLChGuard xmlSelDistPhiShift(_toDOMS("selDistPhiShift")); - XMLCh *xmlPDF = _toDOMS("PDF"); + XMLChGuard xmlPDF(_toDOMS("PDF")); unsigned int iPt = std::atoi(_toString(aGPElement->getAttribute(xmliPt)).c_str()); int iEta = std::atoi(_toString(aGPElement->getAttribute(xmliEta)).c_str()); @@ -377,12 +403,12 @@ std::unique_ptr XMLConfigReader::buildGP(DOMElement *aGPEleme } stringStr.str(""); - XMLCh *xmlRefLayerThresh = _toDOMS("RefLayerThresh"); + XMLChGuard xmlRefLayerThresh(_toDOMS("RefLayerThresh")); if (index > 0) stringStr << "tresh" << index; else stringStr.str("tresh"); - XMLCh *xmlTresh = _toDOMS(stringStr.str()); + XMLChGuard xmlTresh(_toDOMS(stringStr.str())); stringStr.str(""); std::vector thresholds(aConfig.nRefLayers(), 0); @@ -446,14 +472,6 @@ std::unique_ptr XMLConfigReader::buildGP(DOMElement *aGPEleme } } } - XMLString::release(&xmliEta); - XMLString::release(&xmliPt); - XMLString::release(&xmliCharge); - XMLString::release(&xmlLayer); - XMLString::release(&xmlRefLayer); - XMLString::release(&xmlmeanDistPhi); - XMLString::release(&xmlPDF); - XMLString::release(&xmlValue); return aGP; } @@ -470,51 +488,51 @@ void XMLConfigReader::readConfig(L1TMuonOverlapParams *aConfig) const { parser.setValidationScheme(XercesDOMParser::Val_Auto); parser.setDoNamespaces(false); - XMLCh *xmlOMTF = _toDOMS("OMTF"); - XMLCh *xmlversion = _toDOMS("version"); - XMLCh *xmlGlobalData = _toDOMS("GlobalData"); - XMLCh *xmlnPdfAddrBits = _toDOMS("nPdfAddrBits"); - XMLCh *xmlnPdfValBits = _toDOMS("nPdfValBits"); - XMLCh *xmlnPhiBits = _toDOMS("nPhiBits"); - XMLCh *xmlnPhiBins = _toDOMS("nPhiBins"); - XMLCh *xmlnProcessors = _toDOMS("nProcessors"); - XMLCh *xmlnLogicRegions = _toDOMS("nLogicRegions"); - XMLCh *xmlnInputs = _toDOMS("nInputs"); - XMLCh *xmlnLayers = _toDOMS("nLayers"); - XMLCh *xmlnRefLayers = _toDOMS("nRefLayers"); - XMLCh *xmliProcessor = _toDOMS("iProcessor"); - XMLCh *xmlbarrelMin = _toDOMS("barrelMin"); - XMLCh *xmlbarrelMax = _toDOMS("barrelMax"); - XMLCh *xmlendcap10DegMin = _toDOMS("endcap10DegMin"); - XMLCh *xmlendcap10DegMax = _toDOMS("endcap10DegMax"); - XMLCh *xmlendcap20DegMin = _toDOMS("endcap20DegMin"); - XMLCh *xmlendcap20DegMax = _toDOMS("endcap20DegMax"); - XMLCh *xmlLayerMap = _toDOMS("LayerMap"); - XMLCh *xmlhwNumber = _toDOMS("hwNumber"); - XMLCh *xmllogicNumber = _toDOMS("logicNumber"); - XMLCh *xmlbendingLayer = _toDOMS("bendingLayer"); - XMLCh *xmlconnectedToLayer = _toDOMS("connectedToLayer"); - XMLCh *xmlRefLayerMap = _toDOMS("RefLayerMap"); - XMLCh *xmlrefLayer = _toDOMS("refLayer"); - XMLCh *xmlProcessor = _toDOMS("Processor"); - XMLCh *xmlRefLayer = _toDOMS("RefLayer"); - XMLCh *xmliRefLayer = _toDOMS("iRefLayer"); - XMLCh *xmliGlobalPhiStart = _toDOMS("iGlobalPhiStart"); - XMLCh *xmlRefHit = _toDOMS("RefHit"); - XMLCh *xmliRefHit = _toDOMS("iRefHit"); - XMLCh *xmliPhiMin = _toDOMS("iPhiMin"); - XMLCh *xmliPhiMax = _toDOMS("iPhiMax"); - XMLCh *xmliInput = _toDOMS("iInput"); - XMLCh *xmliRegion = _toDOMS("iRegion"); - XMLCh *xmlLogicRegion = _toDOMS("LogicRegion"); - XMLCh *xmlLayer = _toDOMS("Layer"); - XMLCh *xmliLayer = _toDOMS("iLayer"); - XMLCh *xmliFirstInput = _toDOMS("iFirstInput"); - XMLCh *xmlnHitsPerLayer = _toDOMS("nHitsPerLayer"); - XMLCh *xmlnRefHits = _toDOMS("nRefHits"); - XMLCh *xmlnTestRefHits = _toDOMS("nTestRefHits"); - XMLCh *xmlnGoldenPatterns = _toDOMS("nGoldenPatterns"); - XMLCh *xmlConnectionMap = _toDOMS("ConnectionMap"); + XMLChGuard xmlOMTF(_toDOMS("OMTF")); + XMLChGuard xmlversion(_toDOMS("version")); + XMLChGuard xmlGlobalData(_toDOMS("GlobalData")); + XMLChGuard xmlnPdfAddrBits(_toDOMS("nPdfAddrBits")); + XMLChGuard xmlnPdfValBits(_toDOMS("nPdfValBits")); + XMLChGuard xmlnPhiBits(_toDOMS("nPhiBits")); + XMLChGuard xmlnPhiBins(_toDOMS("nPhiBins")); + XMLChGuard xmlnProcessors(_toDOMS("nProcessors")); + XMLChGuard xmlnLogicRegions(_toDOMS("nLogicRegions")); + XMLChGuard xmlnInputs(_toDOMS("nInputs")); + XMLChGuard xmlnLayers(_toDOMS("nLayers")); + XMLChGuard xmlnRefLayers(_toDOMS("nRefLayers")); + XMLChGuard xmliProcessor(_toDOMS("iProcessor")); + XMLChGuard xmlbarrelMin(_toDOMS("barrelMin")); + XMLChGuard xmlbarrelMax(_toDOMS("barrelMax")); + XMLChGuard xmlendcap10DegMin(_toDOMS("endcap10DegMin")); + XMLChGuard xmlendcap10DegMax(_toDOMS("endcap10DegMax")); + XMLChGuard xmlendcap20DegMin(_toDOMS("endcap20DegMin")); + XMLChGuard xmlendcap20DegMax(_toDOMS("endcap20DegMax")); + XMLChGuard xmlLayerMap(_toDOMS("LayerMap")); + XMLChGuard xmlhwNumber(_toDOMS("hwNumber")); + XMLChGuard xmllogicNumber(_toDOMS("logicNumber")); + XMLChGuard xmlbendingLayer(_toDOMS("bendingLayer")); + XMLChGuard xmlconnectedToLayer(_toDOMS("connectedToLayer")); + XMLChGuard xmlRefLayerMap(_toDOMS("RefLayerMap")); + XMLChGuard xmlrefLayer(_toDOMS("refLayer")); + XMLChGuard xmlProcessor(_toDOMS("Processor")); + XMLChGuard xmlRefLayer(_toDOMS("RefLayer")); + XMLChGuard xmliRefLayer(_toDOMS("iRefLayer")); + XMLChGuard xmliGlobalPhiStart(_toDOMS("iGlobalPhiStart")); + XMLChGuard xmlRefHit(_toDOMS("RefHit")); + XMLChGuard xmliRefHit(_toDOMS("iRefHit")); + XMLChGuard xmliPhiMin(_toDOMS("iPhiMin")); + XMLChGuard xmliPhiMax(_toDOMS("iPhiMax")); + XMLChGuard xmliInput(_toDOMS("iInput")); + XMLChGuard xmliRegion(_toDOMS("iRegion")); + XMLChGuard xmlLogicRegion(_toDOMS("LogicRegion")); + XMLChGuard xmlLayer(_toDOMS("Layer")); + XMLChGuard xmliLayer(_toDOMS("iLayer")); + XMLChGuard xmliFirstInput(_toDOMS("iFirstInput")); + XMLChGuard xmlnHitsPerLayer(_toDOMS("nHitsPerLayer")); + XMLChGuard xmlnRefHits(_toDOMS("nRefHits")); + XMLChGuard xmlnTestRefHits(_toDOMS("nTestRefHits")); + XMLChGuard xmlnGoldenPatterns(_toDOMS("nGoldenPatterns")); + XMLChGuard xmlConnectionMap(_toDOMS("ConnectionMap")); parser.parse(configFile.c_str()); xercesc::DOMDocument *doc = parser.getDocument(); assert(doc); @@ -711,52 +729,6 @@ void XMLConfigReader::readConfig(L1TMuonOverlapParams *aConfig) const { // Reset the documents vector pool and release all the associated memory back to the system. parser.resetDocumentPool(); - - XMLString::release(&xmlOMTF); - XMLString::release(&xmlversion); - XMLString::release(&xmlGlobalData); - XMLString::release(&xmlnPdfAddrBits); - XMLString::release(&xmlnPdfValBits); - XMLString::release(&xmlnPhiBits); - XMLString::release(&xmlnPhiBins); - XMLString::release(&xmlnProcessors); - XMLString::release(&xmlnLogicRegions); - XMLString::release(&xmlnInputs); - XMLString::release(&xmlnLayers); - XMLString::release(&xmlnRefLayers); - XMLString::release(&xmliProcessor); - XMLString::release(&xmlbarrelMin); - XMLString::release(&xmlbarrelMax); - XMLString::release(&xmlendcap10DegMin); - XMLString::release(&xmlendcap10DegMax); - XMLString::release(&xmlendcap20DegMin); - XMLString::release(&xmlendcap20DegMax); - XMLString::release(&xmlLayerMap); - XMLString::release(&xmlhwNumber); - XMLString::release(&xmllogicNumber); - XMLString::release(&xmlbendingLayer); - XMLString::release(&xmlconnectedToLayer); - XMLString::release(&xmlRefLayerMap); - XMLString::release(&xmlrefLayer); - XMLString::release(&xmlProcessor); - XMLString::release(&xmlRefLayer); - XMLString::release(&xmliRefLayer); - XMLString::release(&xmliGlobalPhiStart); - XMLString::release(&xmlRefHit); - XMLString::release(&xmliRefHit); - XMLString::release(&xmliPhiMin); - XMLString::release(&xmliPhiMax); - XMLString::release(&xmliInput); - XMLString::release(&xmliRegion); - XMLString::release(&xmlLogicRegion); - XMLString::release(&xmlLayer); - XMLString::release(&xmliLayer); - XMLString::release(&xmliFirstInput); - XMLString::release(&xmlnHitsPerLayer); - XMLString::release(&xmlnRefHits); - XMLString::release(&xmlnTestRefHits); - XMLString::release(&xmlnGoldenPatterns); - XMLString::release(&xmlConnectionMap); } } ////////////////////////////////////////////////// diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/ProcConfigurationBase.cc b/L1Trigger/L1TMuonOverlapPhase1/src/ProcConfigurationBase.cc index 9ac334df6336d..d0e085d1f39fc 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/ProcConfigurationBase.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/ProcConfigurationBase.cc @@ -50,6 +50,12 @@ void ProcConfigurationBase::configureFromEdmParameterSet(const edm::ParameterSet << "lctCentralBx: " << edmParameterSet.getParameter("lctCentralBx") << std::endl; } + if (edmParameterSet.exists("dtBxShift")) { + dtBxShift_ = edmParameterSet.getParameter("dtBxShift"); + edm::LogVerbatim("OMTFReconstruction") + << "dtBxShift: " << edmParameterSet.getParameter("dtBxShift") << std::endl; + } + if (edmParameterSet.exists("minDtPhiQuality")) { minDtPhiQuality = edmParameterSet.getParameter("minDtPhiQuality"); edm::LogVerbatim("OMTFReconstruction") diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EventCapture.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EventCapture.cc index f9c84cfb80458..6cde5b241f3ea 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EventCapture.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/EventCapture.cc @@ -51,7 +51,8 @@ void EventCapture::beginRun(edm::EventSetup const& eventSetup) { } void EventCapture::observeEventBegin(const edm::Event& event) { - edm::LogImportant("l1tOmtfEventPrint") << "EventCapture::observeEventBegin event " << event.id() + edm::LogImportant("l1tOmtfEventPrint") << "EventCapture::observeEventBegin event " << event.id() << " auxBx " + << event.eventAuxiliary().bunchCrossing() << " auxBx " << event.bunchCrossing() << "*************************" << std::endl; simMuons.clear(); @@ -214,8 +215,8 @@ void EventCapture::observeEventEnd(const edm::Event& iEvent, FinalMuons& finalMu ///printing edm::LogVerbatim("l1tOmtfEventPrint") << "##################### EventCapture::observeEventEnd - dump of event " - << iEvent.id() << " #####################################################" - << std::endl; + << iEvent.id() << " bx " << iEvent.bunchCrossing() + << " #####################################################" << std::endl; edm::LogVerbatim("l1tOmtfEventPrint") << ostr.str() << endl; //printing sim muons diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h b/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h index 35a71b2cf2feb..73ea9df11bbec 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h @@ -27,9 +27,10 @@ struct MuStubsPhase2InputTokens { class DtPhase2DigiToStubsConverter : public DigiToStubsConverterBase { public: - DtPhase2DigiToStubsConverter(edm::EDGetTokenT inputTokenDtPh, + DtPhase2DigiToStubsConverter(const OMTFConfiguration* config, + edm::EDGetTokenT inputTokenDtPh, edm::EDGetTokenT inputTokenDtTh) - : inputTokenDtPh(inputTokenDtPh), inputTokenDtTh(inputTokenDtTh) {} + : config(config), inputTokenDtPh(inputTokenDtPh), inputTokenDtTh(inputTokenDtTh) {} ~DtPhase2DigiToStubsConverter() override {} @@ -59,6 +60,7 @@ class DtPhase2DigiToStubsConverter : public DigiToStubsConverterBase { } protected: + const OMTFConfiguration* config = nullptr; bool mergePhiAndTheta = true; edm::EDGetTokenT inputTokenDtPh; @@ -66,6 +68,8 @@ class DtPhase2DigiToStubsConverter : public DigiToStubsConverterBase { edm::Handle dtPhDigis; edm::Handle dtThDigis; + + int bunchCrossing = 0; }; class DtPhase2DigiToStubsConverterOmtf : public DtPhase2DigiToStubsConverter { @@ -74,9 +78,7 @@ class DtPhase2DigiToStubsConverterOmtf : public DtPhase2DigiToStubsConverter { const OmtfPhase2AngleConverter* angleConverter, edm::EDGetTokenT inputTokenDtPh, edm::EDGetTokenT inputTokenDtTh) - : DtPhase2DigiToStubsConverter(inputTokenDtPh, inputTokenDtTh), - config(*config), - angleConverter(*angleConverter) {} + : DtPhase2DigiToStubsConverter(config, inputTokenDtPh, inputTokenDtTh), angleConverter(*angleConverter) {} ~DtPhase2DigiToStubsConverterOmtf() override = default; @@ -95,7 +97,6 @@ class DtPhase2DigiToStubsConverterOmtf : public DtPhase2DigiToStubsConverter { bool acceptDigi(const DTChamberId& dTChamberId, unsigned int iProcessor, l1t::tftype procType) override; private: - const OMTFConfiguration& config; const OmtfPhase2AngleConverter& angleConverter; }; @@ -117,4 +118,4 @@ class InputMakerPhase2 : public OMTFinputMaker { l1t::tftype procTyp) {} }; -#endif /* L1Trigger_L1TMuonOverlapPhase2_InputMakerPhase2_h */ +#endif /* L1Trigger_L1TMuonOverlapPhase2_InputMakerPhase2_h */ \ No newline at end of file diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc b/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc index 8f4251dcef375..ee5a720034397 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc @@ -16,6 +16,7 @@ void DtPhase2DigiToStubsConverter::loadDigis(const edm::Event& event) { event.getByToken(inputTokenDtPh, dtPhDigis); event.getByToken(inputTokenDtTh, dtThDigis); + bunchCrossing = event.bunchCrossing(); } void DtPhase2DigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers, @@ -31,12 +32,19 @@ void DtPhase2DigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers, for (const auto& digiIt : *dtPhDigis->getContainer()) { DTChamberId detid(digiIt.whNum(), digiIt.stNum(), digiIt.scNum() + 1); + LogTrace("l1tOmtfEventPrint") << " L1Phase2MuDTPhDigi:35: detid " << detid << " digi " + << " whNum " << digiIt.whNum() << " scNum " << digiIt.scNum() << " stNum " + << digiIt.stNum() << " slNum " << digiIt.slNum() << " quality " << digiIt.quality() + << " rpcFlag " << digiIt.rpcFlag() << " phi " << digiIt.phi() << " phiBend " + << digiIt.phiBend() << " digBx " << digiIt.bxNum() << " correctedBx " + << digiIt.bxNum() - bunchCrossing << std::endl; + ///Check it the data fits into given processor input range if (!acceptDigi(detid, iProcessor, procTyp)) continue; - // HACK for Phase-2 (DT TPs are centered in bX=20) - if (digiIt.bxNum() - 20 >= bxFrom && digiIt.bxNum() - 20 <= bxTo) { + // HACK for Phase-2 (DT TPs are centered in bX=20 in MC, and 13(?) in data) + if (digiIt.bxNum() - config->dtBxShift() >= bxFrom && digiIt.bxNum() - config->dtBxShift() <= bxTo) { addDTphiDigi(muonStubsInLayers, digiIt, dtThDigis.product(), iProcessor, procTyp); std::ostringstream chamberName; @@ -56,7 +64,7 @@ void DtPhase2DigiToStubsConverter::makeStubs(MuonStubPtrs2D& muonStubsInLayers, } for (auto& thetaDigi : (*(dtThDigis->getContainer()))) { - if (thetaDigi.bxNum() - 20 >= bxFrom && thetaDigi.bxNum() - 20 <= bxTo) { + if (thetaDigi.bxNum() - config->dtBxShift() >= bxFrom && thetaDigi.bxNum() - config->dtBxShift() <= bxTo) { if (!mergePhiAndTheta) { addDTetaStubs(muonStubsInLayers, thetaDigi, iProcessor, procTyp); } @@ -110,24 +118,25 @@ void DtPhase2DigiToStubsConverterOmtf::addDTphiDigi(MuonStubPtrs2D& muonStubsInL stub.qualityHw = 0; } - if (stub.qualityHw < config.getMinDtPhiQuality()) + if (stub.qualityHw < config->getMinDtPhiQuality()) return; - unsigned int hwNumber = config.getLayerNumber(detid.rawId()); - if (config.getHwToLogicLayer().find(hwNumber) == config.getHwToLogicLayer().end()) + unsigned int hwNumber = config->getLayerNumber(detid.rawId()); + if (config->getHwToLogicLayer().find(hwNumber) == config->getHwToLogicLayer().end()) return; - auto iter = config.getHwToLogicLayer().find(hwNumber); + auto iter = config->getHwToLogicLayer().find(hwNumber); unsigned int iLayer = iter->second; - unsigned int iInput = OMTFinputMaker::getInputNumber(&config, detid.rawId(), iProcessor, procTyp); + unsigned int iInput = OMTFinputMaker::getInputNumber(config, detid.rawId(), iProcessor, procTyp); //MuonStub& stub = muonStubsInLayers[iLayer][iInput]; stub.type = MuonStub::DT_PHI_ETA; stub.phiHw = angleConverter.getProcessorPhi( - OMTFinputMaker::getProcessorPhiZero(&config, iProcessor), procTyp, digi.scNum(), digi.phi()); + OMTFinputMaker::getProcessorPhiZero(config, iProcessor), procTyp, digi.scNum(), digi.phi()); - stub.etaHw = angleConverter.getGlobalEtaPhase2(detid, dtThDigis, digi.bxNum() - 20); + //no config->dtBxShift() here, and also no shift inside getGlobalEtaPhase2 + stub.etaHw = angleConverter.getGlobalEtaPhase2(detid, dtThDigis, digi.bxNum()); if (iLayer == 0) stub.r = 431.175; //MB1 @@ -140,27 +149,27 @@ void DtPhase2DigiToStubsConverterOmtf::addDTphiDigi(MuonStubPtrs2D& muonStubsInL //in phase2, the phiB is 13 bits, and range is [-2, 2 rad] so 4 rad, 2^13 units/(4 rad) = 1^11/rad. //need to convert them to 512units==1rad (to use OLD PATTERNS...) - stub.phiBHw = digi.phiBend() * config.dtPhiBUnitsRad() / 2048; + stub.phiBHw = digi.phiBend() * config->dtPhiBUnitsRad() / 2048; //the cut if (stub.qualityHw >= config.getMinDtPhiBQuality()) is done in the ProcessorBase::restrictInput //as is is done like that in the firmware // need to shift 20-BX to roll-back the shift introduced by the DT TPs - stub.bx = digi.bxNum() - 20; + stub.bx = digi.bxNum() - config->dtBxShift(); //stub.timing = digi.getTiming(); //TODO what about sub-bx timing, is is available? stub.logicLayer = iLayer; stub.detId = detid; - OmtfName board(iProcessor, &config); + OmtfName board(iProcessor, config); LogTrace("l1tOmtfEventPrint") << board.name() << " L1Phase2MuDTPhDigi: detid " << detid << " digi " << " whNum " << digi.whNum() << " scNum " << digi.scNum() << " stNum " << digi.stNum() << " slNum " << digi.slNum() << " quality " << digi.quality() << " rpcFlag " - << digi.rpcFlag() << " phi " << digi.phi() << " phiBend " << digi.phiBend() - << std::endl; + << digi.rpcFlag() << " phi " << digi.phi() << " phiBend " << digi.phiBend() << " bx " + << digi.bxNum() << std::endl; LogTrace("l1tOmtfEventPrint") << board.name() << " stub: detid " << detid << " phi " << stub.phiHw << " eta " << stub.etaHw << " phiB " << stub.phiBHw << " bx " << stub.bx << " quality " << stub.qualityHw << " logicLayer " << stub.logicLayer << std::endl; - OMTFinputMaker::addStub(&config, muonStubsInLayers, iLayer, iInput, stub); + OMTFinputMaker::addStub(config, muonStubsInLayers, iLayer, iInput, stub); } void DtPhase2DigiToStubsConverterOmtf::addDTetaStubs(MuonStubPtrs2D& muonStubsInLayers, @@ -174,7 +183,7 @@ void DtPhase2DigiToStubsConverterOmtf::addDTetaStubs(MuonStubPtrs2D& muonStubsIn bool DtPhase2DigiToStubsConverterOmtf::acceptDigi(const DTChamberId& dTChamberId, unsigned int iProcessor, l1t::tftype procType) { - return OMTFinputMaker::acceptDtDigi(&config, dTChamberId, iProcessor, procType); + return OMTFinputMaker::acceptDtDigi(config, dTChamberId, iProcessor, procType); } InputMakerPhase2::InputMakerPhase2(const edm::ParameterSet& edmParameterSet, diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc b/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc index 6648ca47ad126..630c038aad7fd 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc @@ -451,7 +451,7 @@ void NNRegression::run(AlgoMuons::value_type& algoMuon, double omtfPt = omtfConfig->hwPtToGev(algoMuon->getPtConstr()); double nnPt = nnResult.at(0); double combinedPt = nnPt; - if (nnPt < 2.5 || (nnResult[0] - omtfPt) > 0.75 * omtfPt) + if (nnPt < 2.5 || (omtfPt < 0.75 * nnResult[0])) combinedPt = omtfPt; algoMuon->setPtNNConstr(combinedPt); diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc index 33ea10054c91a..5f128f912f388 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc @@ -32,7 +32,7 @@ int OmtfPhase2AngleConverter::getGlobalEtaPhase2(DTChamberId dTChamberId, int thetaDigiCnt = 0; for (const auto& thetaDigi : (*(dtThDigis->getContainer()))) { if (thetaDigi.whNum() == dTChamberId.wheel() && thetaDigi.stNum() == dTChamberId.station() && - thetaDigi.scNum() == (dTChamberId.sector() - 1) && (thetaDigi.bxNum() - 20) == bxNum) { + thetaDigi.scNum() == (dTChamberId.sector() - 1) && (thetaDigi.bxNum()) == bxNum) { // get the theta digi float k = thetaDigi.k() * kconv; //-pow(-1.,z<0)*log(tan(atan(1/k)/2.)); eta = -1. * std::copysign(log(fabs(tan(atan(1 / k) / 2.))), thetaDigi.z()); From d916a8444544ae1bd592e4498e6f7ebdf6a250e3 Mon Sep 17 00:00:00 2001 From: Michal Bluj Date: Fri, 23 Jan 2026 17:34:23 +0100 Subject: [PATCH 08/12] remove include of removed header --- L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h | 2 -- .../L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h | 2 +- L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h index c060a620b608d..7f41caf37a3f5 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFProcessor.h @@ -12,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" diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h index 08c308ac31930..4d7cbfd872d7a 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Tools/DataROOTDumper2.h @@ -123,4 +123,4 @@ class DataROOTDumper2 : public EmulationObserverBase { bool dumpKilledOmtfCands = false; }; -#endif /* L1T_OmtfP1_TOOLS_DATAROOTDUMPER2_H_ */ \ No newline at end of file +#endif /* L1T_OmtfP1_TOOLS_DATAROOTDUMPER2_H_ */ diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h b/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h index 73ea9df11bbec..20a1ebf276fd9 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h @@ -118,4 +118,4 @@ class InputMakerPhase2 : public OMTFinputMaker { l1t::tftype procTyp) {} }; -#endif /* L1Trigger_L1TMuonOverlapPhase2_InputMakerPhase2_h */ \ No newline at end of file +#endif /* L1Trigger_L1TMuonOverlapPhase2_InputMakerPhase2_h */ From 70b240d0ea0d85163a27bc411c9b9baa8783addb Mon Sep 17 00:00:00 2001 From: Michal Bluj Date: Thu, 5 Feb 2026 14:45:35 +0100 Subject: [PATCH 09/12] technical: removal of unused counters and explicite rounding instead of cast from float to int --- .../L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc | 4 ---- L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc index 1f6a03f2a4c9b..c7070bc2adcd0 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc @@ -800,7 +800,6 @@ void CandidateSimMuonMatcher::match(const FinalMuons& finalMuons, deltaPhiVertexProp->Fill(ptGen, simTrack.momentum().phi() - tsof.globalPosition().phi());*/ - unsigned int iCand = 0; bool matched = false; for (auto& muonCand : finalMuons) { //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive @@ -815,7 +814,6 @@ void CandidateSimMuonMatcher::match(const FinalMuons& finalMuons, matched = true; } } - iCand++; } if (!matched) { //adding matchingResults (i.e. simMuon in this case) also if it was not matched to any candidate @@ -972,7 +970,6 @@ std::vector CandidateSimMuonMatcher::matchSimple( std::vector CandidateSimMuonMatcher::collectMuonCands(const FinalMuons& finalMuons) { std::vector matchingResults; - unsigned int iCand = 0; for (auto& finalMuon : finalMuons) { //dropping very low quality candidates, as they are fakes usually - but it has no sense, then the results are not conclusive //if(muonCand->hwQual() > 1) @@ -985,7 +982,6 @@ std::vector CandidateSimMuonMatcher::collectMuonCands(const Fina matchingResults.push_back(result); } - iCand++; } return matchingResults; } diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc b/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc index ee5a720034397..8b45a581b1b38 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc @@ -139,9 +139,9 @@ void DtPhase2DigiToStubsConverterOmtf::addDTphiDigi(MuonStubPtrs2D& muonStubsInL stub.etaHw = angleConverter.getGlobalEtaPhase2(detid, dtThDigis, digi.bxNum()); if (iLayer == 0) - stub.r = 431.175; //MB1 + stub.r = 431; //round(431.175); //MB1 else if (iLayer == 2) { - stub.r = 512.475; //MB2 + stub.r = 512; //round(512.475); //MB2 } else if (iLayer == 4) { stub.r = 620; //round(619.675); //MB3, it is different than in the phase-1, as in the phase-2 it is a middle of the DT chamber, not muon station From 386f1479f3ce73b20e16a76b2727cc8cca9d4677 Mon Sep 17 00:00:00 2001 From: Michal Bluj Date: Thu, 5 Feb 2026 14:46:56 +0100 Subject: [PATCH 10/12] Fix of a logical bug The bug has had no impact as it was part of the final, redundant condition in an "else if" statement --- L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc b/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc index 630c038aad7fd..d152e77cc80f6 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc @@ -178,7 +178,7 @@ bool omtfHitWithQualAndRToEventInput(OmtfHit& hit, std::vector& inputs, u rangeFactor = rangeFactor * rBins; - } else if (hit.layer >= 10 || hit.layer <= 14) { //RPCb hits + } else if (hit.layer >= 10 && hit.layer <= 14) { //RPCb hits rangeFactor *= 4; } From cd5692cf3a65124251024bf5151aeb28c394fa9b Mon Sep 17 00:00:00 2001 From: Michal Bluj Date: Tue, 7 Apr 2026 16:41:27 +0200 Subject: [PATCH 11/12] Code cleaning and fixes, e.g. better use of const, cout=>MessageLogs, additional comments, etc. --- .../interface/Omtf/FinalMuon.h | 4 + .../interface/Omtf/OMTFConfiguration.h | 4 +- .../interface/Omtf/OMTFReconstruction.h | 4 +- .../interface/Omtf/OMTFinputMaker.h | 2 +- .../interface/Omtf/OmtfAngleConverter.h | 4 +- .../src/Omtf/OMTFConfiguration.cc | 2 +- .../src/Omtf/OMTFProcessor.cc | 6 +- .../src/Omtf/OMTFReconstruction.cc | 3 +- .../src/Omtf/OMTFinputMaker.cc | 2 +- .../src/Omtf/OmtfAngleConverter.cc | 3 +- .../src/Tools/CandidateSimMuonMatcher.cc | 38 ++++----- .../src/Tools/DataROOTDumper2.cc | 7 +- .../interface/InputMakerPhase2.h | 8 +- .../LutNetworkFixedPointRegression2Outputs.h | 1 + .../interface/NNRegression.h | 4 +- .../interface/OmtfEmulation.h | 10 +-- .../interface/OmtfPhase2AngleConverter.h | 2 +- .../interface/OmtfProcessorPhase2.h | 8 +- .../src/InputMakerPhase2.cc | 12 +-- .../L1TMuonOverlapPhase2/src/NNRegression.cc | 81 +++++++------------ .../L1TMuonOverlapPhase2/src/OmtfEmulation.cc | 10 +-- .../src/OmtfPhase2AngleConverter.cc | 32 ++++---- .../src/OmtfProcessorPhase2.cc | 28 ++----- 23 files changed, 117 insertions(+), 158 deletions(-) diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h index 810d182dad740..b6f6524dcc8e7 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/FinalMuon.h @@ -10,6 +10,10 @@ #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/AlgoMuon.h" +#include +#include +#include + class FinalMuon { public: FinalMuon() {}; diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h index 1ff8423146831..4a1e3c4410f9e 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h @@ -138,7 +138,7 @@ class OMTFConfiguration : public ProcConfigurationBase { //pt unit of the OMTF patrterns, the same as in the phase-1 uGMT //TODO refactor to omtfPtUnit - double ptUnit = 0.5; // GeV/unit + const double ptUnit = 0.5; // GeV/unit ///uGMT pt scale conversion //TODO refactor to omtfPtToGev double hwPtToGev(int hwPt) const override { return (hwPt == 0 ? 0 : (hwPt - 1.) * ptUnit); } @@ -181,7 +181,7 @@ class OMTFConfiguration : public ProcConfigurationBase { static int etaBit2Code(unsigned int bit); - double phiGmtUnit = 2. * M_PI / 576; //phase-1, from the interface note, should be defined somewhere globally + const double phiGmtUnit = 2. * M_PI / 576; //phase-1, from the interface note, should be defined somewhere globally ///iProcessor - 0...5 ///phiRad [-pi,pi] diff --git a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFReconstruction.h index 19e2152ee0090..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(); @@ -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 934f59f302a23..6ec97242e3964 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h +++ b/L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OmtfAngleConverter.h @@ -72,14 +72,14 @@ class OmtfAngleConverter { 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 const int findBTIgroup(const L1MuDTChambPhDigi& aDigi, const L1MuDTChambThContainer* dtThDigis); + virtual int findBTIgroup(const L1MuDTChambPhDigi& aDigi, const L1MuDTChambThContainer* dtThDigis) const; // pointers to the current geometry records unsigned long long _geom_cache_id = 0; diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc index ea1cde892c7e4..9e1f51b827a5c 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFConfiguration.cc @@ -376,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; } diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc index e849f9f12ad02..d651ae49fdcd7 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc @@ -86,7 +86,11 @@ void OMTFProcessor::init(const edm::ParameterSet& edmCfg, edm } if (this->myOmtfConfig->usePhiBExtrapolationMB1() || this->myOmtfConfig->usePhiBExtrapolationMB2()) { - extrapolFactors.resize(2 * 3, 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, diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc index 2c16a02fe44f6..9b5495d5d1ae0 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFReconstruction.cc @@ -26,7 +26,8 @@ #include ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// -OMTFReconstruction::OMTFReconstruction(const edm::ParameterSet& parameterSet, MuStubsInputTokens& muStubsInputTokens) +OMTFReconstruction::OMTFReconstruction(const edm::ParameterSet& parameterSet, + const MuStubsInputTokens& muStubsInputTokens) : muStubsInputTokens(muStubsInputTokens), omtfConfig(new OMTFConfiguration()), omtfProc(nullptr), diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinputMaker.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinputMaker.cc index 7922b988989b4..680b852c72978 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinputMaker.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFinputMaker.cc @@ -333,7 +333,7 @@ bool OMTFinputMaker::acceptDtDigi(const OMTFConfiguration* config, /////////////////////////////////////// /////////////////////////////////////// OMTFinputMaker::OMTFinputMaker(const edm::ParameterSet& edmParameterSet, - MuStubsInputTokens& muStubsInputTokens, + const MuStubsInputTokens& muStubsInputTokens, const OMTFConfiguration* config, std::unique_ptr angleConverter) : MuonStubMakerBase(config), config(config), angleConverter(std::move(angleConverter)) { diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc index f08e8759bc872..1e7d72dce3c58 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OmtfAngleConverter.cc @@ -253,7 +253,6 @@ int OmtfAngleConverter::getProcessorPhi( 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 @@ -414,7 +413,7 @@ bool OmtfAngleConverter::isCSCCounterClockwise(const CSCLayer* layer) const { } /////////////////////////////////////// /////////////////////////////////////// -const int OmtfAngleConverter::findBTIgroup(const L1MuDTChambPhDigi& aDigi, const L1MuDTChambThContainer* dtThDigis) { +int OmtfAngleConverter::findBTIgroup(const L1MuDTChambPhDigi& aDigi, const L1MuDTChambThContainer* dtThDigis) const { int bti_group = -1; const L1MuDTChambThDigi* theta_segm = diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc index c7070bc2adcd0..1f4db5aff3688 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/CandidateSimMuonMatcher.cc @@ -623,19 +623,19 @@ void CandidateSimMuonMatcher::match(const FinalMuonPtr& finalMuon, MatchingResul result.matchingLikelihood = 1. / (std::abs(result.deltaPhi) + 0.001); double mean = 0; - double treshold = 0; + double threshold = 0; //for displaced muons in H2ll //here a coarse threshold are used, as for dispalced muons - treshold = 0.15; //pt > 30 + threshold = 0.15; //pt > 30 if (trackPt < 10) //TODO!!!!!!!!!!!!!!!!!!!!! tune the threshold!!!!!! - treshold = 0.4; + threshold = 0.4; else if (trackPt < 30) //TODO!!!!!!!!!!!!!!! tune the threshold!!!!!! - treshold = 0.22; + threshold = 0.22; mean = 0; - if (std::abs(result.deltaPhi - mean) < treshold && std::abs(result.deltaEta) < 0.4) + if (std::abs(result.deltaPhi - mean) < threshold && std::abs(result.deltaEta) < 0.4) result.result = MatchingResult::ResultType::matched; } @@ -717,15 +717,9 @@ void CandidateSimMuonMatcher::propagate(MatchingResult& result) { if (result.simVertex) { ftsTrack = simTrackToFts(*(result.simTrack), *(result.simVertex)); } else { + //throw, to be sue that the issue is noticed. throw cms::Exception("CandidateSimMuonMatcher") << "CandidateSimMuonMatcher::propagate - simTrack exists but simVertex is missing!!!"; - //throw, to be sue that the issue is noticed. - // Alternatively, if simTrack exists but simVertex is missing, - // fall back to a default vertex at (0,0,0). Or doSimplePropagation(). - SimVertex defVtx; // default constructed vertex at origin - ftsTrack = simTrackToFts(*(result.simTrack), defVtx); - edm::LogImportant("l1tOmtfEventPrint") - << "CandidateSimMuonMatcher::propagate - simTrack has no simVertex, using default vertex" << std::endl; } } else if (result.trackingParticle) { if (result.trackingParticle->parentVertex().isNonnull()) @@ -923,25 +917,25 @@ std::vector CandidateSimMuonMatcher::matchSimple( //TODO histogram can be used, like in the usercode/L1MuonAnalyzer MuonMatcher::matchWithoutPorpagation //for prompt muons - /*double treshold = 0.3; + /*double threshold = 0.3; if (simTrack.momentum().pt() < 5) - treshold = 1.5; + threshold = 1.5; else if (simTrack.momentum().pt() < 8) - treshold = 0.8; + threshold = 0.8; else if (simTrack.momentum().pt() < 10) - treshold = 0.6; + threshold = 0.6; else if (simTrack.momentum().pt() < 20) - treshold = 0.5;*/ + threshold = 0.5;*/ - double treshold = 0.5; + double threshold = 0.5; if (simTrack.momentum().pt() < 5) - treshold = 1.5; + threshold = 1.5; else if (simTrack.momentum().pt() < 10) - treshold = 1.0; + threshold = 1.0; else if (simTrack.momentum().pt() < 25) - treshold = 0.7; + threshold = 0.7; - if (std::abs(result.deltaPhi) < treshold && std::abs(result.deltaEta) < 0.5) { + if (std::abs(result.deltaPhi) < threshold && std::abs(result.deltaEta) < 0.5) { result.result = MatchingResult::ResultType::matched; //matchingLikelihood is needed in the cleanMatching, so we put something result.matchingLikelihood = 1. / (std::abs(result.deltaPhi) + 0.001); diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc index db362b701ad23..098ef2cc2383c 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Tools/DataROOTDumper2.cc @@ -169,15 +169,16 @@ void DataROOTDumper2::observeEventEnd(const edm::Event& iEvent, FinalMuons& fina omtfEvent.muonPhi = trackingParticle->momentum().phi(); omtfEvent.muonPropEta = matchingResult.propagatedEta; omtfEvent.muonPropPhi = matchingResult.propagatedPhi; - omtfEvent.muonCharge = (std::abs(trackingParticle->pdgId()) == 13) ? trackingParticle->pdgId() / -13 : 0; + //omtfEvent.muonCharge = (std::abs(trackingParticle->pdgId()) == 13) ? trackingParticle->pdgId() / -13 : 0; omtfEvent.muonCharge = trackingParticle->charge(); if (trackingParticle->parentVertex().isNonnull()) { omtfEvent.muonDxy = trackingParticle->dxy(); omtfEvent.muonRho = trackingParticle->parentVertex()->position().Rho(); - for (auto& parentTrack : trackingParticle->parentVertex()->sourceTracks()) { - omtfEvent.parentPdgId = parentTrack->pdgId(); + // Normally, parentVertex should have only one sourceTrack (in this context a pion or kaon) + if (!trackingParticle->parentVertex()->sourceTracks().empty()) { + omtfEvent.parentPdgId = trackingParticle->parentVertex()->sourceTracks()[0]->pdgId(); LogTrace("l1MuonAnalyzerOmtf") << " DataROOTDumper2 parentTrackPdgId " << omtfEvent.parentPdgId << std::endl; } } diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h b/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h index 20a1ebf276fd9..143c1db146c8c 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h @@ -78,7 +78,7 @@ class DtPhase2DigiToStubsConverterOmtf : public DtPhase2DigiToStubsConverter { const OmtfPhase2AngleConverter* angleConverter, edm::EDGetTokenT inputTokenDtPh, edm::EDGetTokenT inputTokenDtTh) - : DtPhase2DigiToStubsConverter(config, inputTokenDtPh, inputTokenDtTh), angleConverter(*angleConverter) {} + : DtPhase2DigiToStubsConverter(config, inputTokenDtPh, inputTokenDtTh), angleConverter(angleConverter) {} ~DtPhase2DigiToStubsConverterOmtf() override = default; @@ -97,14 +97,14 @@ class DtPhase2DigiToStubsConverterOmtf : public DtPhase2DigiToStubsConverter { bool acceptDigi(const DTChamberId& dTChamberId, unsigned int iProcessor, l1t::tftype procType) override; private: - const OmtfPhase2AngleConverter& angleConverter; + const OmtfPhase2AngleConverter* angleConverter; }; class InputMakerPhase2 : public OMTFinputMaker { public: InputMakerPhase2(const edm::ParameterSet& edmParameterSet, - MuStubsInputTokens& muStubsInputTokens, - MuStubsPhase2InputTokens& muStubsPhase2InputTokens, + const MuStubsInputTokens& muStubsInputTokens, + const MuStubsPhase2InputTokens& muStubsPhase2InputTokens, const OMTFConfiguration* config, std::unique_ptr angleConverter); diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegression2Outputs.h b/L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegression2Outputs.h index 7471a1df4505b..7538ed62f9a35 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegression2Outputs.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/LutNetworkFixedPointRegression2Outputs.h @@ -173,6 +173,7 @@ namespace lutNN { //std::cout<<"lutLayer3_0.getLutOutSum()[0] "< scale * lut[x] + offset for the last layer } diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/NNRegression.h b/L1Trigger/L1TMuonOverlapPhase2/interface/NNRegression.h index 450c3aeebae0d..0e3058fc77a26 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/NNRegression.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/NNRegression.h @@ -13,13 +13,13 @@ class NNRegression : public MlModelBase { public: - NNRegression(const edm::ParameterSet& edmCfg, const OMTFConfiguration* omtfConfig, std::string networkFile); + NNRegression(const edm::ParameterSet& edmCfg, const OMTFConfiguration* omtfConfig, const std::string& networkFile); ~NNRegression() override = default; void run(AlgoMuons::value_type& algoMuon, std::vector >& observers) override; private: - unique_ptr lutNetworkFP; + std::unique_ptr lutNetworkFP; }; #endif /* L1Trigger_L1TMuonOverlapPhase2_PtAssigmentNNRegression_h */ diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h index 9686ce9564466..33421814dcefd 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h @@ -19,8 +19,8 @@ class OmtfEmulation : public OMTFReconstruction { public: OmtfEmulation(const edm::ParameterSet& edmParameterSet, - MuStubsInputTokens& muStubsInputTokens, - MuStubsPhase2InputTokens& muStubsPhase2InputTokens); + const MuStubsInputTokens& muStubsInputTokens, + const MuStubsPhase2InputTokens& muStubsPhase2InputTokens); void beginJob(); @@ -33,16 +33,16 @@ class OmtfEmulation : public OMTFReconstruction { const edm::ESGetToken& magneticFieldEsToken, const edm::ESGetToken& propagatorEsToken) override; - struct OmtfOutptuCollections { + struct OmtfOutptutCollections { std::unique_ptr constrSaMuons; //ip constrained candidates std::unique_ptr unConstrSaMuons; //ip unconstrained candidates std::unique_ptr regionalCandidates; //for backward compatibility of analyzers etc. }; - OmtfOutptuCollections run(const edm::Event& iEvent, const edm::EventSetup& evSetup); + OmtfOutptutCollections run(const edm::Event& iEvent, const edm::EventSetup& evSetup); private: - MuStubsPhase2InputTokens& muStubsPhase2InputTokens; + const MuStubsPhase2InputTokens& muStubsPhase2InputTokens; OmtfProcessorPhase2 omtfProcPhase2; }; diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h index 3908366a53d8b..ec188570ffe19 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfPhase2AngleConverter.h @@ -14,7 +14,7 @@ class OmtfPhase2AngleConverter : public OmtfAngleConverter { int getProcessorPhi(int phiZero, l1t::tftype part, int dtScNum, int dtPhi) const override; //using different name of the method to avoid hiding OmtfAngleConverter methods getGlobalEta - int getGlobalEtaPhase2(DTChamberId dTChamberId, const L1Phase2MuDTThContainer *dtThDigis, int bxNum) const; + int getGlobalEtaPhase2(const DTChamberId& dtChamberId, const L1Phase2MuDTThContainer* dtThetaDigis, int bxNum) const; }; #endif diff --git a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h index 8358ea114bd01..43f73aab99c96 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h +++ b/L1Trigger/L1TMuonOverlapPhase2/interface/OmtfProcessorPhase2.h @@ -16,7 +16,7 @@ class OmtfProcessorPhase2 { public: //Composition is used over inheritance here, primarily because the OMTFProcessor is a template class and is constructed in OMTFReconstruction - OmtfProcessorPhase2(const OMTFConfiguration* omtfConfig, const unique_ptr& omtfProc); + OmtfProcessorPhase2(const OMTFConfiguration* omtfConfig, const std::unique_ptr& omtfProc); virtual ~OmtfProcessorPhase2(); @@ -35,15 +35,15 @@ class OmtfProcessorPhase2 { l1t::SAMuonCollection getSAMuons(unsigned int iProcessor, l1t::tftype mtfType, FinalMuons& finalMuons, - bool costrainedPt); + bool constrainedPt); private: const OMTFConfiguration* omtfConfig; //reference to the unique_ptr is used here, because the omtfProc might be re-constructed in the OMTFReconstruction each run - const unique_ptr& omtfProc; + const std::unique_ptr& omtfProc; - unique_ptr mlModel; + std::unique_ptr mlModel; std::map firedLayersToQuality; }; diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc b/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc index 8b45a581b1b38..873b445a775b0 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/InputMakerPhase2.cc @@ -122,21 +122,21 @@ void DtPhase2DigiToStubsConverterOmtf::addDTphiDigi(MuonStubPtrs2D& muonStubsInL return; unsigned int hwNumber = config->getLayerNumber(detid.rawId()); - if (config->getHwToLogicLayer().find(hwNumber) == config->getHwToLogicLayer().end()) + auto iter = config->getHwToLogicLayer().find(hwNumber); + if (iter == config->getHwToLogicLayer().end()) return; - auto iter = config->getHwToLogicLayer().find(hwNumber); unsigned int iLayer = iter->second; unsigned int iInput = OMTFinputMaker::getInputNumber(config, detid.rawId(), iProcessor, procTyp); //MuonStub& stub = muonStubsInLayers[iLayer][iInput]; stub.type = MuonStub::DT_PHI_ETA; - stub.phiHw = angleConverter.getProcessorPhi( + stub.phiHw = angleConverter->getProcessorPhi( OMTFinputMaker::getProcessorPhiZero(config, iProcessor), procTyp, digi.scNum(), digi.phi()); //no config->dtBxShift() here, and also no shift inside getGlobalEtaPhase2 - stub.etaHw = angleConverter.getGlobalEtaPhase2(detid, dtThDigis, digi.bxNum()); + stub.etaHw = angleConverter->getGlobalEtaPhase2(detid, dtThDigis, digi.bxNum()); if (iLayer == 0) stub.r = 431; //round(431.175); //MB1 @@ -187,8 +187,8 @@ bool DtPhase2DigiToStubsConverterOmtf::acceptDigi(const DTChamberId& dTChamberId } InputMakerPhase2::InputMakerPhase2(const edm::ParameterSet& edmParameterSet, - MuStubsInputTokens& muStubsInputTokens, - MuStubsPhase2InputTokens& muStubsPhase2InputTokens, + const MuStubsInputTokens& muStubsInputTokens, + const MuStubsPhase2InputTokens& muStubsPhase2InputTokens, const OMTFConfiguration* config, std::unique_ptr angleConverter) : OMTFinputMaker(edmParameterSet, muStubsInputTokens, config, std::move(angleConverter)) { diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc b/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc index d152e77cc80f6..ab134f68f9ea6 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/NNRegression.cc @@ -91,10 +91,8 @@ namespace lutNN { NNRegression::NNRegression(const edm::ParameterSet& edmCfg, const OMTFConfiguration* omtfConfig, - std::string networkFile) + const std::string& networkFile) : MlModelBase(omtfConfig), lutNetworkFP(make_unique()) { - std::ifstream ifs(networkFile); - edm::LogImportant("OMTFReconstruction") << " " << __FUNCTION__ << ":" << __LINE__ << " networkFile " << networkFile << std::endl; @@ -121,9 +119,9 @@ struct OmtfHit { }; bool omtfHitWithQualAndRToEventInput(OmtfHit& hit, std::vector& inputs, unsigned int omtfRefLayer, bool print) { - int lustSize = 1024; //TODO change it if needed - int refLayers = 8; - float rangeSize = lustSize / (refLayers * 2); + const int lutSize = 1024; //TODO change it if needed + const int refLayers = 8; + float rangeSize = lutSize / (refLayers * 2); //float offset = (omtfRefLayer<<7) + rangeMiddle; //two ranges for each omtfRefLayer, so that two qualites can be used for each omtfRefLayer @@ -163,11 +161,11 @@ bool omtfHitWithQualAndRToEventInput(OmtfHit& hit, std::vector& inputs, u } else if ((hit.layer >= 6 && hit.layer <= 9) || (hit.layer >= 15)) { //CSC hits and RPCe hits int rBins = 16; - rangeSize = lustSize / (refLayers * rBins); + rangeSize = lutSize / (refLayers * rBins); rangeFactor = 4; int rBin = std::abs(hit.deltaR) >> 4; if (rBin >= rBins) { - //cout<<"rBin "<& inputs, u if (abs(hit.phiDist) >= ((rangeSize / 2 - 1) * rangeFactor)) { if (hit.valid) - cout //<<" muonPt "<& inputs, u inputs.at(hit.layer) = (float)hit.phiDist / (float)rangeFactor + offset; //the last address i.e. 1023 is reserved for the no-hit value, so interpolation between the 1022 and 1023 has no sense - if (inputs.at(hit.layer) >= lustSize - 2) - inputs.at(hit.layer) = lustSize - 2; + if (inputs.at(hit.layer) >= lutSize - 2) + inputs.at(hit.layer) = lutSize - 2; if (print || inputs.at(hit.layer) < 0) { - cout //<<"rawData "<inputs.at(hit.layer) < 0 !!!!!!!!!!!!!!!!!" << endl; - cout << endl; + edm::LogImportant("OMTFReconstruction") << " event->inputs.at(hit.layer) < 0 !!!!!!!!!!!!!!!!!" << endl; } - if (inputs[hit.layer] >= lustSize) { //TODO should be the size of the LUT of the first layer - cout << " event->inputs[hit.layer] >= " << lustSize << " !!!!!!!!!!!!!!!!!" << endl; + if (inputs[hit.layer] >= lutSize) { //TODO should be the size of the LUT of the first layer + edm::LogImportant("OMTFReconstruction") + << " event->inputs[hit.layer] >= " << lutSize << " !!!!!!!!!!!!!!!!!" << endl; } return true; } @@ -271,7 +268,7 @@ bool omtfHitWithQualToEventInput(OmtfHit& hit, std::vector& inputs, unsig rangeFactor *= 4; //TODO !!!!!!!!!!!!!!!!!!! if (abs(hit.phiDist) >= ((rangeMiddle - 1) * rangeFactor)) { - cout //<<" muonPt "<& inputs, unsig inputs.at(hit.layer) = 1022; if (print || inputs.at(hit.layer) < 0) { - cout //<<"rawData "<inputs.at(hit.layer) < 0 !!!!!!!!!!!!!!!!!" << endl; - cout << endl; + edm::LogImportant("OMTFReconstruction") << " event->inputs.at(hit.layer) < 0 !!!!!!!!!!!!!!!!!" << endl; } if (inputs[hit.layer] >= 1024) { //TODO should be the size of the LUT of the first layer - cout << " event->inputs[hit.layer] >= 1024 !!!!!!!!!!!!!!!!!" << endl; + edm::LogImportant("OMTFReconstruction") << " event->inputs[hit.layer] >= 1024 !!!!!!!!!!!!!!!!!" << endl; } return true; } @@ -336,13 +331,11 @@ bool omtfHitToEventInput(OmtfHit& hit, std::vector& inputs, unsigned int if (print || inputs.at(hit.layer) < 0) { edm::LogImportant("OMTFReconstruction") //<<"rawData "<inputs.at(hit.layer) < 0 !!!!!!!!!!!!!!!!!" << endl; - edm::LogImportant("OMTFReconstruction") << endl; } if (inputs[hit.layer] >= 1024) { //TODO should be the size of the LUT of the first layer @@ -451,7 +444,7 @@ void NNRegression::run(AlgoMuons::value_type& algoMuon, double omtfPt = omtfConfig->hwPtToGev(algoMuon->getPtConstr()); double nnPt = nnResult.at(0); double combinedPt = nnPt; - if (nnPt < 2.5 || (omtfPt < 0.75 * nnResult[0])) + if (nnPt < 2.5 || (omtfPt < 0.75 * nnPt)) combinedPt = omtfPt; algoMuon->setPtNNConstr(combinedPt); @@ -489,22 +482,4 @@ void NNRegression::run(AlgoMuons::value_type& algoMuon, for (auto& obs : observers) obs->addProcesorData("regressionNN", procDataTree); } - - //event.print(); - /* - std::vector pts(classifierToRegressions.size(), 0); - - unsigned int i =0; - for(auto& classifierToRegression : classifierToRegressions) { - auto orgValue = classifierToRegression->getValue(&event); - auto absOrgValue = std::abs(orgValue); - pts.at(i) = classifierToRegression->getCalibratedValue(absOrgValue); - pts.at(i) = std::copysign(pts.at(i), orgValue); - - LogTrace("OMTFReconstruction") <<" "<<__FUNCTION__<<":"<<__LINE__<<" orgValue "< - #include "L1Trigger/L1TMuonOverlapPhase2/interface/OmtfEmulation.h" #include "L1Trigger/L1TMuonOverlapPhase2/interface/InputMakerPhase2.h" @@ -17,8 +15,8 @@ #include OmtfEmulation::OmtfEmulation(const edm::ParameterSet& edmParameterSet, - MuStubsInputTokens& muStubsInputTokens, - MuStubsPhase2InputTokens& muStubsPhase2InputTokens) + const MuStubsInputTokens& muStubsInputTokens, + const MuStubsPhase2InputTokens& muStubsPhase2InputTokens) : OMTFReconstruction(edmParameterSet, muStubsInputTokens), muStubsPhase2InputTokens(muStubsPhase2InputTokens), omtfProcPhase2(omtfConfig.get(), omtfProc) {} @@ -48,7 +46,7 @@ void OmtfEmulation::beginRun(edm::Run const& run, omtfProcPhase2.beginRun(edmParameterSet, eventSetup); } -OmtfEmulation::OmtfOutptuCollections OmtfEmulation::run(const edm::Event& iEvent, const edm::EventSetup& evSetup) { +OmtfEmulation::OmtfOutptutCollections OmtfEmulation::run(const edm::Event& iEvent, const edm::EventSetup& evSetup) { LogTrace("l1tOmtfEventPrint") << "\n" << __FUNCTION__ << ":" << __LINE__ << " iEvent " << iEvent.id().event() << endl; inputMaker->loadAndFilterDigis(iEvent); @@ -56,7 +54,7 @@ OmtfEmulation::OmtfOutptuCollections OmtfEmulation::run(const edm::Event& iEvent obs->observeEventBegin(iEvent); } - OmtfOutptuCollections outptuCollections; + OmtfOutptutCollections outptuCollections; outptuCollections.constrSaMuons = std::make_unique(); outptuCollections.unConstrSaMuons = std::make_unique(); outptuCollections.regionalCandidates = std::make_unique(); diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc index 5f128f912f388..928f708b7b527 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfPhase2AngleConverter.cc @@ -20,33 +20,33 @@ int OmtfPhase2AngleConverter::getProcessorPhi(int phiZero, l1t::tftype part, int return config->foldPhi(phiConverted); } -int OmtfPhase2AngleConverter::getGlobalEtaPhase2(DTChamberId dTChamberId, - const L1Phase2MuDTThContainer* dtThDigis, +int OmtfPhase2AngleConverter::getGlobalEtaPhase2(const DTChamberId& dtChamberId, + const L1Phase2MuDTThContainer* dtThetaDigis, int bxNum) const { - int dtThBins = 65536; //65536. for [-6.3,6.3] - float kconv = 1 / (dtThBins / 2.); + const int dtThetaBins = 65536; //65536. for [-6.3,6.3] + const float kconv = 1 / (dtThetaBins / 2.); float eta = -999; // get the theta digi bool foundeta = false; int thetaDigiCnt = 0; - for (const auto& thetaDigi : (*(dtThDigis->getContainer()))) { - if (thetaDigi.whNum() == dTChamberId.wheel() && thetaDigi.stNum() == dTChamberId.station() && - thetaDigi.scNum() == (dTChamberId.sector() - 1) && (thetaDigi.bxNum()) == bxNum) { + for (const auto& thetaDigi : (*(dtThetaDigis->getContainer()))) { + if (thetaDigi.whNum() == dtChamberId.wheel() && thetaDigi.stNum() == dtChamberId.station() && + thetaDigi.scNum() == (dtChamberId.sector() - 1) && (thetaDigi.bxNum()) == bxNum) { // get the theta digi float k = thetaDigi.k() * kconv; //-pow(-1.,z<0)*log(tan(atan(1/k)/2.)); eta = -1. * std::copysign(log(fabs(tan(atan(1 / k) / 2.))), thetaDigi.z()); - LogTrace("OMTFReconstruction") << "OmtfPhase2AngleConverter::getGlobalEta(" << dTChamberId << ") eta: " << eta + LogTrace("OMTFReconstruction") << "OmtfPhase2AngleConverter::getGlobalEta(" << dtChamberId << ") eta: " << eta << " k: " << k << " thetaDigi.k(): " << thetaDigi.k(); thetaDigiCnt++; - //checking if the obtained eta has reasonable range - temporary fix - if ((dTChamberId.station() == 1 && (std::abs(eta) < 0.85 || std::abs(eta) > 1.20)) || - (dTChamberId.station() == 2 && (std::abs(eta) < 0.75 || std::abs(eta) > 1.04)) || - (dTChamberId.station() == 3 && (std::abs(eta) < 0.63 || std::abs(eta) > 0.92))) { + //checking if the obtained eta has a reasonable range as expected for the DT chambers in the wheels +-2 - temporary fix + if ((dtChamberId.station() == 1 && (std::abs(eta) < 0.85 || std::abs(eta) > 1.20)) || + (dtChamberId.station() == 2 && (std::abs(eta) < 0.75 || std::abs(eta) > 1.04)) || + (dtChamberId.station() == 3 && (std::abs(eta) < 0.63 || std::abs(eta) > 0.92))) { foundeta = false; /*edm::LogVerbatim("OMTFReconstruction") - << "OmtfPhase2AngleConverter::getGlobalEta(" << dTChamberId << ") wrong output eta: " << eta << " k: " << k + << "OmtfPhase2AngleConverter::getGlobalEta(" << dtChamberId << ") wrong output eta: " << eta << " k: " << k << " thetaDigi.k(): " << thetaDigi.k() << " quality " << thetaDigi.quality();*/ } else foundeta = true; @@ -61,11 +61,11 @@ int OmtfPhase2AngleConverter::getGlobalEtaPhase2(DTChamberId dTChamberId, return std::abs(config->etaToHwEta(eta)); } else { //Returning eta of the chamber middle - if (dTChamberId.station() == 1) + if (dtChamberId.station() == 1) eta = config->mb1W2Eta(); - else if (dTChamberId.station() == 2) + else if (dtChamberId.station() == 2) eta = config->mb2W2Eta(); - else if (dTChamberId.station() == 3) + else if (dtChamberId.station() == 3) eta = config->mb3W2Eta(); return eta; diff --git a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc index 2fd601a51309e..6641541888122 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc +++ b/L1Trigger/L1TMuonOverlapPhase2/src/OmtfProcessorPhase2.cc @@ -102,18 +102,6 @@ OmtfProcessorPhase2::OmtfProcessorPhase2(const OMTFConfiguration* omtfConfig, firedLayersToQuality[0b000011100000001101] = 8; firedLayersToQuality[0b100000011100000000] = 8; firedLayersToQuality[0b110000011110000001] = 8; - //firedLayersToQuality[0b000000000000110011] = 8; - //firedLayersToQuality[0b000000100110000011] = 8; - //firedLayersToQuality[0b110000000100000000] = 8; - //firedLayersToQuality[0b001011110001001101] = 8; - //firedLayersToQuality[0b010000100001000011] = 8; - //firedLayersToQuality[0b000001100000001100] = 8; - //firedLayersToQuality[0b000001110001000011] = 8; - //firedLayersToQuality[0b011000000010000000] = 8; - //firedLayersToQuality[0b001000110100000011] = 8; - //firedLayersToQuality[0b010001000011000000] = 8; - //firedLayersToQuality[0b100000000110000000] = 8; - //firedLayersToQuality[0b000000000000111100] = 8; } OmtfProcessorPhase2::~OmtfProcessorPhase2() {} @@ -211,12 +199,6 @@ void OmtfProcessorPhase2::convertToGmtScalesPhase2(unsigned int iProcessor, << " PtGev " << finalMuon->getPtGev() << " PtUnconstrGev " << finalMuon->getPtUnconstrGev() << std::endl; - if (mtfType == l1t::omtf_pos) { - finalMuon->setEtaGmt(finalMuon->getAlgoMuon()->getEtaHw()); - } else { - finalMuon->setEtaGmt((-1) * finalMuon->getAlgoMuon()->getEtaHw()); - } - int globPhi = omtfConfig->procPhiOmtfToGlobalPhiOmtf(iProcessor, finalMuon->getAlgoMuon()->getPhi()); int gmtPhiBins = 1 << Phase2L1GMT::BITSPHI; int omtfToGmtFactorPhi = std::lround(gmtPhiBins * (1 << 12) / double(omtfConfig->nPhiBins())); @@ -237,14 +219,14 @@ void OmtfProcessorPhase2::convertToGmtScalesPhase2(unsigned int iProcessor, l1t::SAMuonCollection OmtfProcessorPhase2::getSAMuons(unsigned int iProcessor, l1t::tftype mtfType, FinalMuons& finalMuons, - bool costrainedPt) { + bool constrainedPt) { l1t::SAMuonCollection saMuons; for (auto& finalMuon : finalMuons) { int charge = finalMuon->getSign(); - unsigned int pt = costrainedPt ? finalMuon->getPtGmt() : finalMuon->getPtUnconstrGmt(); - int d0 = costrainedPt ? 0 : 50 / Phase2L1GMT::LSBSAd0; //finalMuon->getHwD0(); - if (costrainedPt == false) { + unsigned int pt = constrainedPt ? finalMuon->getPtGmt() : finalMuon->getPtUnconstrGmt(); + int d0 = constrainedPt ? 0 : 50 / Phase2L1GMT::LSBSAd0; //finalMuon->getHwD0(); + if (constrainedPt == false) { //this assures the collection of constrained and unconstrained muons have the same size //muons that are not displaced also should be in the unconstrained collection if (finalMuon->getPtUnconstrGmt() == 0) { @@ -328,7 +310,7 @@ FinalMuons OmtfProcessorPhase2::run(unsigned int iProcessor, } //LogTrace("l1tOmtfEventPrint")<<"buildInputForProce "; t.report(); - omtfProc->processInput(iProcessor, mtfType, *(input.get()), observers); + omtfProc->processInput(iProcessor, mtfType, *input, observers); //LogTrace("l1tOmtfEventPrint")<<"processInput "; t.report(); AlgoMuons algoCandidates = omtfProc->sortResults(iProcessor, mtfType); From 70de9292eed2259c209ef190172b14d91f3d7eb0 Mon Sep 17 00:00:00 2001 From: Karol Bunkowski Date: Tue, 21 Apr 2026 18:54:44 +0200 Subject: [PATCH 12/12] Fixing pt for displaced-only muon OMTFProcessor.cc and OmtfProcessorPhase2.cc Fixing the condition to assign minimum pT (0 or 1 GeV) for the muons that have only unconstrained pt valid. Checking getFiredLayerCntConstr was missing. updating runMuonOverlap_run3_mc.py and runMuonOverlap.py --- .../src/Omtf/OMTFProcessor.cc | 5 +- .../test/runMuonOverlap_run3_mc.py | 53 ++++++++++--------- .../src/OmtfProcessorPhase2.cc | 3 +- .../test/runMuonOverlap.py | 13 ++--- 4 files changed, 38 insertions(+), 36 deletions(-) diff --git a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc index d651ae49fdcd7..441f1ff00ee6f 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc +++ b/L1Trigger/L1TMuonOverlapPhase1/src/Omtf/OMTFProcessor.cc @@ -293,7 +293,7 @@ void OMTFProcessor::convertToGmtScalesPhase1(unsigned int iPr 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) + 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 @@ -331,8 +331,6 @@ std::vector OMTFProcessor::getRegional std::vector result; for (auto& finalMuon : finalMuons) { - convertToGmtScalesPhase1(iProcessor, mtfType, finalMuon); - l1t::RegionalMuonCand candidate; candidate.setHwPt(finalMuon->getPtGmt()); @@ -908,6 +906,7 @@ FinalMuons OMTFProcessor::run(unsigned int iProcessor, FinalMuons finalMuons = getFinalMuons(iProcessor, mtfType, gbCandidates); for (auto& finalMuon : finalMuons) { + convertToGmtScalesPhase1(iProcessor, mtfType, finalMuon); finalMuon->setBx(bx); } diff --git a/L1Trigger/L1TMuonOverlapPhase1/test/runMuonOverlap_run3_mc.py b/L1Trigger/L1TMuonOverlapPhase1/test/runMuonOverlap_run3_mc.py index eaa6bb43d85a4..b6062ac0c5189 100644 --- a/L1Trigger/L1TMuonOverlapPhase1/test/runMuonOverlap_run3_mc.py +++ b/L1Trigger/L1TMuonOverlapPhase1/test/runMuonOverlap_run3_mc.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import FWCore.ParameterSet.Config as cms -process = cms.Process("L1TMuonEmulation") +from Configuration.Eras.Era_Run3_2025_cff import Run3_2025 +process = cms.Process("L1TMuonEmulation", Run3_2025) import os import sys @@ -42,8 +43,8 @@ # PostLS1 geometry used -process.load('Configuration.Geometry.GeometryExtended2015Reco_cff') -process.load('Configuration.Geometry.GeometryExtended2015_cff') +#process.load('Configuration.Geometry.GeometryExtended2023Reco_cff') +#process.load('Configuration.Geometry.GeometryExtended2023_cff') ############################ #process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_condDBv2_cff') #from Configuration.AlCa.GlobalTag_condDBv2 import GlobalTag @@ -53,18 +54,17 @@ # import of standard configurations process.load('Configuration.StandardSequences.Services_cff') process.load('SimGeneral.HepPDTESSource.pythiapdt_cfi') -process.load('Configuration.EventContent.EventContent_cff') -process.load('SimGeneral.MixingModule.mixNoPU_cfi') -#process.load('Configuration.Geometry.GeometryExtended2023D41Reco_cff') -#process.load('Configuration.Geometry.GeometryExtended2023D41_cff') -process.load('Configuration.StandardSequences.MagneticField_cff') +#process.load('Configuration.Geometry.GeometryExtended2017Reco_cff') +process.load("Configuration.StandardSequences.GeometryRecoDB_cff") +process.load('Configuration.StandardSequences.MagneticField_AutoFromDBCurrent_cff') #process.load('Configuration.StandardSequences.SimL1Emulator_cff') process.load('Configuration.StandardSequences.EndOfProcess_cff') process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') from Configuration.AlCa.GlobalTag import GlobalTag #process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:upgradePLS3', '') -process.GlobalTag = GlobalTag(process.GlobalTag, '103X_upgrade2023_realistic_v2', '') +#process.GlobalTag = GlobalTag(process.GlobalTag, '103X_upgrade2023_realistic_v2', '') +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:run3_mc_FULL', '') process.source = cms.Source('PoolSource', @@ -107,8 +107,8 @@ ####Event Setup Producer -process.load('L1Trigger.L1TMuonOverlapPhase1.fakeOmtfParams_cff') -process.omtfParams.configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0008.xml") +#process.load('L1Trigger.L1TMuonOverlapPhase1.fakeOmtfParams_cff') +#process.omtfParams.configXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/hwToLogicLayer_0x0008.xml") # process.omtfParams.patternsXMLFiles = cms.VPSet( # cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x00012_oldSample_3_30Files_grouped1_classProb17_recalib2.xml")), # #cms.PSet(patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x0009_oldSample_3_10Files_classProb1.xml") ), @@ -133,6 +133,7 @@ process.simOmtfDigis.dumpResultToXML = cms.bool(True) process.simOmtfDigis.eventCaptureDebug = cms.bool(True) + #process.simOmtfDigis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuonBayes/test/expert/omtf/Patterns_0x0009_oldSample_3_10Files.xml") #process.simOmtfDigis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x0009_oldSample_3_10Files.xml") #process.simOmtfDigis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x0003.xml") @@ -142,21 +143,21 @@ #process.simOmtfDigis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x00012_oldSample_3_30Files_grouped1_classProb1_recalib.xml") #process.simOmtfDigis.patternsXMLFile = cms.FileInPath("L1Trigger/L1TMuon/data/omtf_config/Patterns_0x00012_oldSample_3_30Files_grouped1_classProb17_recalib2.xml") -process.simOmtfDigis.sorterType = cms.string("byLLH") - -process.simOmtfDigis.rpcMaxClusterSize = cms.int32(3) -process.simOmtfDigis.rpcMaxClusterCnt = cms.int32(2) -process.simOmtfDigis.rpcDropAllClustersIfMoreThanMax = cms.bool(True) - -process.simOmtfDigis.goldenPatternResultFinalizeFunction = cms.int32(9) #valid values are 0, 1, 2, 3, 5 - -process.simOmtfDigis.noHitValueInPdf = cms.bool(True) #!!!!!!!!!!!!!! cab be true only of the patterns has the noHitValues in the bin 0 of the PDFs - -process.simOmtfDigis.minDtPhiQuality = cms.int32(2) -process.simOmtfDigis.minDtPhiBQuality = cms.int32(2) - - -process.simOmtfDigis.lctCentralBx = cms.int32(8)#<<<<<<<<<<<<<<<getAlgoMuon()->getPdfSumConstr() == 0 && finalMuon->getAlgoMuon()->getPtUnconstr() > 0) + if ((finalMuon->getAlgoMuon()->getPdfSumConstr() == 0 || finalMuon->getAlgoMuon()->getFiredLayerCntConstr() < 3) && + finalMuon->getAlgoMuon()->getPtUnconstr() > 0) finalMuon->setPtGev(1.0); //set to 1 GeV to be able to distinguish from pt=0, which means no candidate int maxPtHw = (1 << Phase2L1GMT::BITSPT) - 1; diff --git a/L1Trigger/L1TMuonOverlapPhase2/test/runMuonOverlap.py b/L1Trigger/L1TMuonOverlapPhase2/test/runMuonOverlap.py index 043749e6dd277..844f509f402b3 100644 --- a/L1Trigger/L1TMuonOverlapPhase2/test/runMuonOverlap.py +++ b/L1Trigger/L1TMuonOverlapPhase2/test/runMuonOverlap.py @@ -40,11 +40,11 @@ #SkipEvent = cms.untracked.vstring('ProductNotFound') ) #SkipEvent = cms.untracked.vstring('ProductNotFound') -process.source = cms.Source('PoolSource', - fileNames = cms.untracked.vstring('file:///eos/cms/store/group/dpg_trigger/comm_trigger/L1Trigger/OMTF/13_1_0_03_04_2024/SingleMu_ch0_OneOverPt_Run2029_13_1_0_03_04_2024/13_1_0_03_04_2024/240403_080928/0000/SingleMu_OneOverPt_1_100_m_1.root') +process.source = cms.Source('PoolSource', + fileNames = cms.untracked.vstring('file:///eos/cms/store/group/dpg_trigger/comm_trigger/L1Trigger/OMTF/PrivateProductionForOMTFStudy/13_1_0_03_04_2024/SingleMu_ch0_OneOverPt_Run2029_13_1_0_03_04_2024/13_1_0_03_04_2024/240403_080928/0000/SingleMu_OneOverPt_1_100_m_1.root') ) -process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(100)) +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1)) # import of standard configurations process.load('Configuration.StandardSequences.Services_cff') @@ -62,8 +62,8 @@ process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') from Configuration.AlCa.GlobalTag import GlobalTag -#process.GlobalTag = GlobalTag(process.GlobalTag, '131X_mcRun4_realistic_v9', '') -process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') +process.GlobalTag = GlobalTag(process.GlobalTag, '131X_mcRun4_realistic_v9', '') +#process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') process.TFileService = cms.Service("TFileService", fileName = cms.string('omtfAnalysis1.root'), closeFileFast = cms.untracked.bool(True) ) @@ -80,7 +80,8 @@ ####OMTF Emulator -process.load('L1Trigger.L1TMuonOverlapPhase2.simOmtfPhase2Digis_cfi') +#process.load('L1Trigger.L1TMuonOverlapPhase2.simOmtfPhase2Digis_cfi') +process.load('L1Trigger.L1TMuonOverlapPhase2.simOmtfPhase2Digis_DT_2_2_2_cff') process.simOmtfPhase2Digis.dumpResultToXML = cms.bool(True) process.simOmtfPhase2Digis.eventCaptureDebug = cms.bool(True)